[
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 傅小黑\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "README.md",
    "content": "### Notice: this project is deprecated. Please try my new blog engine [pugo](https://github.com/go-xiaohei/pugo).\n\n#Fxh.Go\n\nA fast and simple blog engine with [GoInk](https://github.com/fuxiaohei/GoInk) framework in Golang.\n\n[![Build Status](https://drone.io/github.com/fuxiaohei/GoBlog/status.png)](https://drone.io/github.com/fuxiaohei/GoBlog/latest)\n[![GoWalker](http://b.repl.ca/v1/Go_Walker-API_Documentation-green.png)](http://gowalker.org/github.com/fuxiaohei/GoBlog)\n\nCurrent version is **0.2.5** on 2014.02.28\n\nDevelopment board is in [Trello](https://trello.com/b/7AHrcQL8/fxh-go-with-goink).\n\n### Overview\n\n`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.\n\n`Fxh.Go` supports markdown contents as articles or pages, ajax comments and dynamic administration.\n\n`Fxh.Go` contains two kinds of content as article and page. They can be customized as you want.\n\n### Installation\n\n`Fxh.Go` requires **Go 1.2** or above.\n\n##### Gobuild.io\n\n[Gobuild.io](http://gobuild.io/) can build cross-platform executable file for pure go projects. You can download `Fxh.Go` binary from Gobuild.io.\n\n[![Gobuild Download](http://gobuild.io/badge/github.com/fuxiaohei/GoBlog/download.png)](http://gobuild.io/github.com/fuxiaohei/GoBlog)\n\n##### Manual\n\nUse go get command:\n\n    go get github.com/fuxiaohei/GoBlog\n\nThen you can find binary file `GoBlog(.exe)` in `$GOPATH/bin`.\n\n### Run\n\nMake a new dir to run `Fxh.Go`:\n\n    cd new_dir\n    Goblog\n\nThen it will unzip static files in `new_dir` , initialize raw data and start server at `localhost:9001`.\n\n##### Admin\n\nVisit `localhost:9001/login/` to enter administrator with username `admin` and password `admin`. You'd better change them after installed successfully.\n\n##### Deployment\n\nI prefer to use nginx as proxy. The server section in `nginx.conf`:\n\n        server {\n                listen       80;\n                server_name  your_domain;\n                charset utf-8;\n                access_log  /var/log/nginx/your_domain.access.log;\n\n                location / {\n                    proxy_pass http://127.0.0.1:9001;\n                }\n\n                location /static {\n                    root            /var/www/your_domain;  # binary file is in this directory\n                    expires         1d;\n                    add_header      Cache-Control public;\n                    access_log      off;\n                }\n        }\n\n### Questions\n\nCreate issues or pull requests here.\n\n### Products\n\n* [抛弃世俗之浮躁，留我钻研之刻苦](http://wuwen.org)\n* [FuXiaoHei.Me](http://fuxiaohei.me)\n\n### Thanks\n\n* [@Unknwon](https://github.com/Unknwon) on testing and [zip library](https://github.com/Unknwon/cae) support.\n\n### License\n\nThe MIT License\n\n"
  },
  {
    "path": "app/admin.go",
    "content": "package app\n\nimport \"github.com/fuxiaohei/GoBlog/app/handler\"\n\nfunc registerAdminHandler() {\n\t// add admin handlers\n\tApp.Get(\"/admin/\", handler.Auth, handler.Admin)\n\n\tApp.Route(\"GET,POST\", \"/admin/profile/\", handler.Auth, handler.AdminProfile)\n\n\tApp.Route(\"GET,POST\", \"/admin/password/\", handler.Auth, handler.AdminPassword)\n\n\tApp.Route(\"GET,POST\", \"/admin/article/write/\", handler.Auth, handler.ArticleWrite)\n\tApp.Get(\"/admin/articles/\", handler.Auth, handler.AdminArticle)\n\tApp.Route(\"GET,POST,DELETE\", \"/admin/article/:id/\", handler.Auth, handler.ArticleEdit)\n\n\tApp.Route(\"GET,POST\", \"/admin/page/write/\", handler.Auth, handler.PageWrite)\n\tApp.Get(\"/admin/pages/\", handler.Auth, handler.AdminPage)\n\tApp.Route(\"GET,POST,DELETE\", \"/admin/page/:id/\", handler.Auth, handler.PageEdit)\n\n\tApp.Route(\"GET,POST,PUT,DELETE\", \"/admin/comments/\", handler.Auth, handler.AdminComments)\n\n\tApp.Route(\"GET,POST\", \"/admin/setting/\", handler.Auth, handler.AdminSetting)\n\tApp.Post(\"/admin/setting/custom/\", handler.Auth, handler.CustomSetting)\n\tApp.Post(\"/admin/setting/nav/\", handler.Auth, handler.NavigatorSetting)\n\n\tApp.Route(\"GET,DELETE\", \"/admin/files/\", handler.Auth, handler.AdminFiles)\n\tApp.Post(\"/admin/files/upload/\", handler.Auth, handler.FileUpload)\n\n\tApp.Route(\"GET,POST\", \"/admin/plugins/\", handler.Auth, handler.AdminPlugin)\n\tApp.Route(\"GET,POST\", \"/admin/plugins/:plugin_key/\", handler.Auth, handler.PluginSetting)\n\n\tApp.Post(\"/admin/message/read/\", handler.Auth, handler.AdminMessageRead)\n}\n"
  },
  {
    "path": "app/app.go",
    "content": "package app\n\nimport (\n\t\"fmt\"\n\t\"github.com/fuxiaohei/GoBlog/app/handler\"\n\t\"github.com/fuxiaohei/GoBlog/app/model\"\n\t\"github.com/fuxiaohei/GoBlog/app/plugin\"\n\t\"github.com/fuxiaohei/GoBlog/app/utils\"\n\t\"github.com/fuxiaohei/GoInk\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/signal\"\n\t\"path\"\n\t\"runtime/debug\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n)\n\nvar (\n\t// APP VERSION, as date version\n\tVERSION = 20140228\n\t// Global GoInk application\n\tApp              *GoInk.App\n\tstaticFileSuffix = \".css,.js,.jpg,.jpeg,.png,.gif,.ico,.xml,.zip,.txt,.html,.otf,.svg,.eot,.woff,.ttf,.doc,.ppt,.xls,.docx,.pptx,.xlsx,.xsl\"\n\tuploadFileSuffix = \".jpg,.png,.gif,.zip,.txt,.doc,.docx,.xls,.xlsx,.ppt,.pptx\"\n)\n\nfunc init() {\n\t// init application\n\tApp = GoInk.New()\n\n\t// init some settings\n\tApp.Config().StringOr(\"app.static_dir\", \"static\")\n\tApp.Config().StringOr(\"app.log_dir\", \"tmp/log\")\n\tos.MkdirAll(App.Get(\"log_dir\"), os.ModePerm)\n\tos.MkdirAll(\"tmp/data\", os.ModePerm)\n\n\tApp.Config().IntOr(\"app.upload_size\", 1024*1024*10)\n\tApp.Config().StringOr(\"app.upload_files\", uploadFileSuffix)\n\tApp.Config().StringOr(\"app.upload_dir\", path.Join(App.Get(\"static_dir\"), \"upload\"))\n\tos.MkdirAll(App.Get(\"upload_dir\"), os.ModePerm)\n\n\tif App.Get(\"static_files\") != \"\" {\n\t\tstaticFileSuffix = App.Get(\"static_files\")\n\t}\n\n\tApp.Static(func(context *GoInk.Context) {\n\t\tstatic := App.Config().String(\"app.static_dir\")\n\t\turl := strings.TrimPrefix(context.Url, \"/\")\n\t\tif url == \"favicon.ico\" {\n\t\t\turl = path.Join(static, url)\n\t\t}\n\t\tif !strings.HasPrefix(url, static) {\n\t\t\treturn\n\t\t}\n\t\tif !strings.Contains(staticFileSuffix, context.Ext) {\n\t\t\tcontext.Status = 403\n\t\t\tcontext.End()\n\t\t\treturn\n\t\t}\n\t\tf, e := os.Stat(url)\n\t\tif e == nil {\n\t\t\tif f.IsDir() {\n\t\t\t\tcontext.Status = 403\n\t\t\t\tcontext.End()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\t/*_, e := os.Stat(url)\n\t\tif e != nil {\n\t\t\tcontext.Throw(404)\n\t\t\treturn\n\t\t}*/\n\t\thttp.ServeFile(context.Response, context.Request, url)\n\t\tcontext.IsEnd = true\n\t})\n\n\t// set recover handler\n\tApp.Recover(func(context *GoInk.Context) {\n\t\tgo LogError(append(append(context.Body, []byte(\"\\n\")...), debug.Stack()...))\n\t\ttheme := handler.Theme(context)\n\t\tif theme.Has(\"error/error.html\") {\n\t\t\ttheme.Layout(\"\").Render(\"error/error\", map[string]interface{}{\n\t\t\t\t\"error\":   string(context.Body),\n\t\t\t\t\"stack\":   string(debug.Stack()),\n\t\t\t\t\"context\": context,\n\t\t\t})\n\t\t} else {\n\t\t\tcontext.Body = append([]byte(\"<pre>\"), context.Body...)\n\t\t\tcontext.Body = append(context.Body, []byte(\"\\n\")...)\n\t\t\tcontext.Body = append(context.Body, debug.Stack()...)\n\t\t\tcontext.Body = append(context.Body, []byte(\"</pre>\")...)\n\t\t}\n\t\tcontext.End()\n\t})\n\n\t// set not found handler\n\tApp.NotFound(func(context *GoInk.Context) {\n\t\ttheme := handler.Theme(context)\n\t\tif theme.Has(\"error/notfound.html\") {\n\t\t\ttheme.Layout(\"\").Render(\"error/notfound\", map[string]interface{}{\n\t\t\t\t\"context\": context,\n\t\t\t})\n\t\t}\n\t\tcontext.End()\n\t})\n\n\t// add recover defer\n\tdefer func() {\n\t\te := recover()\n\t\tif e != nil {\n\t\t\tbytes := append([]byte(fmt.Sprint(e)+\"\\n\"), debug.Stack()...)\n\t\t\tLogError(bytes)\n\t\t\tprintln(\"panic error, crash down\")\n\t\t\tos.Exit(1)\n\t\t}\n\t}()\n\n\t// catch exit command\n\tgo catchExit()\n}\n\n// code from https://github.com/Unknwon/gowalker/blob/master/gowalker.go\nfunc catchExit() {\n\tsigTerm := syscall.Signal(15)\n\tsig := make(chan os.Signal)\n\tsignal.Notify(sig, os.Interrupt, sigTerm)\n\n\tfor {\n\t\tswitch <-sig {\n\t\tcase os.Interrupt, sigTerm:\n\t\t\tprintln(\"before exit, saving data\")\n\t\t\tmodel.SyncAll()\n\t\t\tprintln(\"ready to exit\")\n\t\t\tos.Exit(0)\n\t\t}\n\t}\n}\n\n// Init starts Fxh.Go application preparation.\n// Load models and plugins, update views.\nfunc Init() {\n\n\t// init storage\n\tmodel.Init(VERSION)\n\n\t// load all data\n\tmodel.All()\n\n\t// init plugin\n\tplugin.Init()\n\n\t// update plugin handlers\n\tplugin.Update(App)\n\n\tApp.View().FuncMap[\"DateInt64\"] = utils.DateInt64\n\tApp.View().FuncMap[\"DateString\"] = utils.DateString\n\tApp.View().FuncMap[\"DateTime\"] = utils.DateTime\n\tApp.View().FuncMap[\"Now\"] = utils.Now\n\tApp.View().FuncMap[\"Html2str\"] = utils.Html2str\n\tApp.View().FuncMap[\"FileSize\"] = utils.FileSize\n\tApp.View().FuncMap[\"Setting\"] = model.GetSetting\n\tApp.View().FuncMap[\"Navigator\"] = model.GetNavigators\n\tApp.View().FuncMap[\"Md2html\"] = utils.Markdown2HtmlTemplate\n\tApp.View().IsCache = (model.GetSetting(\"theme_cache\") == \"true\")\n\n\tprintln(\"app version @ \" + strconv.Itoa(model.GetVersion().Version))\n}\n\nfunc registerHomeHandler() {\n\tApp.Route(\"GET,POST\", \"/login/\", handler.Login)\n\tApp.Get(\"/logout/\", handler.Logout)\n\n\tApp.Get(\"/article/:id/:slug\", handler.Article)\n\tApp.Get(\"/page/:id/:slug\", handler.Page)\n\tApp.Get(\"/p/:page/\", handler.Home)\n\tApp.Post(\"/comment/:id/\", handler.Comment)\n\tApp.Get(\"/tag/:tag/\", handler.TagArticles)\n\tApp.Get(\"/tag/:tag/p/:page/\", handler.TagArticles)\n\n\tApp.Get(\"/feed/\", handler.Rss)\n\tApp.Get(\"/sitemap\", handler.SiteMap)\n\n\tApp.Get(\"/:slug\", handler.TopPage)\n\tApp.Get(\"/\", handler.Home)\n}\n\n// Run begins Fxh.Go http server.\nfunc Run() {\n\n\tregisterAdminHandler()\n\tregisterCmdHandler()\n\tregisterHomeHandler()\n\n\tApp.Run()\n}\n"
  },
  {
    "path": "app/cmd/backup.go",
    "content": "package cmd\n\nimport (\n\t\"github.com/Unknwon/cae/zip\"\n\t\"github.com/fuxiaohei/GoBlog/app/model\"\n\t\"github.com/fuxiaohei/GoBlog/app/utils\"\n\t\"github.com/fuxiaohei/GoInk\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"time\"\n)\n\nvar backupDir = \"backup\"\n\nfunc init() {\n\t// close zip terminal output\n\tzip.Verbose = false\n}\n\n// DoBackup backups whole files to zip archive.\n// If withData is false, it compresses static files to zip archive without data files, config files and install lock file.\nfunc DoBackup(app *GoInk.App, withData bool) (string, error) {\n\tos.Mkdir(backupDir, os.ModePerm)\n\t// create zip file name from time unix\n\tfilename := path.Join(backupDir, utils.DateTime(time.Now(), \"YYYYMMDDHHmmss\"))\n\tif withData {\n\t\tfilename += \".zip\"\n\t} else {\n\t\tfilename += \"_static.zip\"\n\t}\n\tz, e := zip.Create(filename)\n\tif e != nil {\n\t\treturn \"\", e\n\t}\n\troot, _ := os.Getwd()\n\tif withData {\n\t\t// if with data, add install lock file and config file\n\t\tlockFile := path.Join(root, \"install.lock\")\n\t\tif utils.IsFile(lockFile) {\n\t\t\tz.AddFile(\"install.lock\", lockFile)\n\t\t}\n\t\tconfigFile := path.Join(root, \"config.json\")\n\t\tif utils.IsFile(configFile) {\n\t\t\tz.AddFile(\"config.json\", configFile)\n\t\t}\n\t}\n\tz.AddDir(\"static/css\", path.Join(root, \"static\", \"css\"))\n\tz.AddDir(\"static/img\", path.Join(root, \"static\", \"img\"))\n\tz.AddDir(\"static/js\", path.Join(root, \"static\", \"js\"))\n\tz.AddDir(\"static/lib\", path.Join(root, \"static\", \"lib\"))\n\tz.AddFile(\"static/favicon.ico\", path.Join(root, \"static\", \"favicon.ico\"))\n\tif withData {\n\t\t// if with data, backup data files and uploaded files\n\t\tz.AddDir(\"data\", path.Join(root, \"data\"))\n\t\tz.AddDir(\"static/upload\", path.Join(root, \"static\", \"upload\"))\n\t}\n\tz.AddDir(app.View().Dir, path.Join(root, app.View().Dir))\n\te = z.Flush()\n\tif e != nil {\n\t\treturn \"\", e\n\t}\n\tprintln(\"backup success in \" + filename)\n\treturn filename, nil\n}\n\n// RemoveBackupFile removes backup zip file with filename(not filepath).\nfunc RemoveBackupFile(file string) {\n\tfile = path.Join(backupDir, file)\n\tos.Remove(file)\n}\n\n// GetBackupFileAbsPath returns backup zip absolute filepath by filename.\nfunc GetBackupFileAbsPath(name string) string {\n\treturn path.Join(backupDir, name)\n}\n\n// GetBackupFile returns fileinfo slice of all backup files.\nfunc GetBackupFiles() ([]os.FileInfo, error) {\n\tfi := make([]os.FileInfo, 0)\n\te := filepath.Walk(backupDir, func(_ string, info os.FileInfo, _ error) error {\n\t\tif info == nil {\n\t\t\treturn nil\n\t\t}\n\t\tif !info.IsDir() {\n\t\t\tfi = append([]os.FileInfo{info}, fi...)\n\t\t}\n\t\treturn nil\n\t})\n\treturn fi, e\n}\n\n// StartBackupTimer starts backup operation timer for auto backup stuff.\nfunc StartBackupTimer(app *GoInk.App, t int) {\n\tmodel.SetTimerFunc(\"backup-data\", 144, func() {\n\t\tfilename, e := DoBackup(app, true)\n\t\tif e != nil {\n\t\t\tmodel.CreateMessage(\"backup\", \"[0]\"+e.Error())\n\t\t} else {\n\t\t\tmodel.CreateMessage(\"backup\", \"[1]\"+filename)\n\t\t}\n\t\tprintln(\"backup files in\", t, \"hours\")\n\t})\n}\n"
  },
  {
    "path": "app/cmd/init.go",
    "content": "package cmd\n\nimport \"github.com/fuxiaohei/GoInk\"\n\nfunc Init(app *GoInk.App) {\n\tStartBackupTimer(app, 24)\n}\n"
  },
  {
    "path": "app/cmd/install.go",
    "content": "package cmd\n\nimport (\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"github.com/Unknwon/cae/zip\"\n\t\"github.com/fuxiaohei/GoBlog/app/utils\"\n\t\"io/ioutil\"\n\t\"os\"\n)\n\nvar (\n\ttmpZipFile      = \"tmp.zip\"\n\tinstallLockFile = \"install.lock\"\n)\n\nfunc CheckInstall() bool {\n\t_, e := os.Stat(installLockFile)\n\treturn e == nil\n}\n\nfunc ExtractBundleBytes() {\n\t// origin from https://github.com/wendal/gor/blob/master/gor/gor.go\n\tdecoder := base64.NewDecoder(base64.StdEncoding, bytes.NewBufferString(zipBytes))\n\tb, _ := ioutil.ReadAll(decoder)\n\tioutil.WriteFile(tmpZipFile, b, os.ModePerm)\n\tz, e := zip.Open(tmpZipFile)\n\tif e != nil {\n\t\tpanic(e)\n\t\tos.Exit(1)\n\t}\n\tz.ExtractTo(\"\")\n\tdefer func() {\n\t\tz.Close()\n\t\tdecoder = nil\n\t\tos.Remove(tmpZipFile)\n\t}()\n}\n\nfunc DoInstall() {\n\tExtractBundleBytes()\n\tioutil.WriteFile(installLockFile, []byte(fmt.Sprint(utils.Now())), os.ModePerm)\n\tprintln(\"install success\")\n}\n\nfunc DoUpdateZipBytes(file string) error {\n\t// copy from https://github.com/wendal/gor/blob/master/gor/gor.go\n\tbytes, _ := ioutil.ReadFile(file)\n\tzipWriter, _ := os.OpenFile(\"app/cmd/zip.go\", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, os.ModePerm)\n\theader := `package cmd\nconst zipBytes=\"`\n\tzipWriter.Write([]byte(header))\n\tencoder := base64.NewEncoder(base64.StdEncoding, zipWriter)\n\tencoder.Write(bytes)\n\tencoder.Close()\n\tzipWriter.Write([]byte(`\"`))\n\tzipWriter.Sync()\n\tzipWriter.Close()\n\tprintln(\"update success\")\n\treturn nil\n}\n"
  },
  {
    "path": "app/cmd/log.go",
    "content": "package cmd\n\nimport (\n\t\"github.com/fuxiaohei/GoInk\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path/filepath\"\n)\n\ntype logItem struct {\n\tName       string\n\tCreateTime int64\n\tText       string\n}\n\nfunc GetLogs(app *GoInk.App) []*logItem {\n\tdir := app.Get(\"log_dir\")\n\tlogs := make([]*logItem, 0)\n\tfilepath.Walk(dir, func(_ string, info os.FileInfo, err error) error {\n\t\tif err == nil {\n\t\t\tif info.IsDir() {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\text := filepath.Ext(info.Name())\n\t\t\tif ext != \".log\" {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tbytes, e := ioutil.ReadFile(filepath.Join(dir, info.Name()))\n\t\t\tif e != nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tl := new(logItem)\n\t\t\tl.Name = info.Name()\n\t\t\tl.CreateTime = info.ModTime().Unix()\n\t\t\tl.Text = string(bytes)\n\t\t\tlogs = append([]*logItem{l}, logs...)\n\t\t}\n\t\treturn nil\n\t})\n\treturn logs\n}\n\nfunc RemoveLogFile(app *GoInk.App, file string) {\n\tf := filepath.Join(app.Get(\"log_dir\"), file)\n\tos.Remove(f)\n}\n"
  },
  {
    "path": "app/cmd/monitor.go",
    "content": "package cmd\n\nimport (\n\t\"fmt\"\n\t\"github.com/fuxiaohei/GoBlog/app/utils\"\n\t\"runtime\"\n\t\"time\"\n)\n\ntype monitorStats struct {\n\tNumGoroutine int\n\tMemAllocated string\n\tMemMalloc    string\n\tMemTotal     string\n\tMemSys       string\n\tMemHeap      string\n\tMemGc        string\n\tLastGcTime   string\n}\n\nfunc ReadMemStats() *monitorStats {\n\tm := new(runtime.MemStats)\n\truntime.ReadMemStats(m)\n\tms := new(monitorStats)\n\tms.NumGoroutine = runtime.NumGoroutine()\n\tms.MemAllocated = utils.FileSize(int64(m.Alloc))\n\tms.MemTotal = utils.FileSize(int64(m.TotalAlloc))\n\tms.MemSys = utils.FileSize(int64(m.Sys))\n\tms.MemHeap = utils.FileSize(int64(m.HeapAlloc))\n\tms.MemMalloc = utils.FileSize(int64(m.Mallocs))\n\tms.LastGcTime = fmt.Sprintf(\"%.1fs\", float64(time.Now().UnixNano()-int64(m.LastGC))/1000/1000/1000)\n\tms.MemGc = utils.FileSize(int64(m.NextGC))\n\treturn ms\n}\n"
  },
  {
    "path": "app/cmd/reboot.go",
    "content": "package cmd\n"
  },
  {
    "path": "app/cmd/theme.go",
    "content": "package cmd\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/model\"\n\t\"github.com/fuxiaohei/GoInk\"\n\t\"io/ioutil\"\n\t\"path/filepath\"\n)\n\nvar adminTheme = \"admin\"\n\ntype themeItem struct {\n\tName       string\n\tFiles      []string\n\tErrorFiles []string\n\tLayout     []string\n}\n\nfunc SetThemeCache(ctx *GoInk.Context, cache bool) {\n\tctx.App().View().NoCache()\n\tctx.App().View().IsCache = cache\n\tif cache {\n\t\tmodel.SetSetting(\"theme_cache\", \"true\")\n\t} else {\n\t\tmodel.SetSetting(\"theme_cache\", \"false\")\n\t}\n\tmodel.SyncSettings()\n}\n\nfunc GetThemes(dir string) map[string]*themeItem {\n\tm := make(map[string]*themeItem)\n\tfiles, e := ioutil.ReadDir(dir)\n\tif e != nil {\n\t\tpanic(e)\n\t}\n\tfor _, fi := range files {\n\t\tif fi.IsDir() && fi.Name() != adminTheme {\n\t\t\ttheme, e := createThemeItem(filepath.Join(dir, fi.Name()))\n\t\t\tif e != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttheme.Name = fi.Name()\n\t\t\tm[fi.Name()] = theme\n\t\t}\n\t}\n\treturn m\n}\n\nfunc createThemeItem(dir string) (*themeItem, error) {\n\tfiles, e := ioutil.ReadDir(dir)\n\tif e != nil {\n\t\treturn nil, e\n\t}\n\ttheme := new(themeItem)\n\ttheme.Files = make([]string, 0)\n\ttheme.Layout = make([]string, 0)\n\tfor _, fi := range files {\n\t\tif fi.IsDir() {\n\t\t\tif fi.Name() == \"error\" {\n\t\t\t\ttheme.ErrorFiles, _ = filepath.Glob(filepath.Join(dir, fi.Name(), \"*.html\"))\n\t\t\t\tfor i, f := range theme.ErrorFiles {\n\t\t\t\t\ttheme.ErrorFiles[i] = filepath.Join(fi.Name(), filepath.Base(f))\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tf, _ := filepath.Glob(filepath.Join(dir, fi.Name(), \"*.html\"))\n\t\t\t\tfor _, ff := range f {\n\t\t\t\t\ttheme.Files = append(theme.Files, filepath.Join(fi.Name(), filepath.Base(ff)))\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\text := filepath.Ext(fi.Name())\n\t\t\tif ext == \".html\" {\n\t\t\t\ttheme.Files = append(theme.Files, fi.Name())\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif ext == \".layout\" {\n\t\t\t\ttheme.Layout = append(theme.Layout, fi.Name())\n\t\t\t}\n\t\t}\n\t}\n\treturn theme, nil\n}\n"
  },
  {
    "path": "app/cmd/upgrade.go",
    "content": "package cmd\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/model\"\n\t\"github.com/fuxiaohei/GoInk\"\n\t\"sort\"\n\t\"strconv\"\n)\n\nvar upgradeScript map[int]func(app *GoInk.App) bool\n\nfunc init() {\n\tupgradeScript = make(map[int]func(app *GoInk.App) bool)\n}\n\nfunc SetUpgradeScript(v int, script func(app *GoInk.App) bool) {\n\tupgradeScript[v] = script\n}\n\nfunc CheckUpgrade(v int, print bool) bool {\n\tmodel.Init(v)\n\tappV := model.GetVersion()\n\tb := v > appV.Version\n\tif b && print {\n\t\tprintln(\"app version @ \" + strconv.Itoa(v) + \" is ahead of current version @ \" + strconv.Itoa(appV.Version) + \" , please run 'GoBlog upgrade'\")\n\t}\n\treturn b\n}\n\nfunc DoUpgrade(v int, app *GoInk.App) {\n\tif !CheckUpgrade(v, false) {\n\t\tprintln(\"app version @\", v, \"is updated\")\n\t\treturn\n\t}\n\toldVersion := model.GetVersion().Version\n\tscriptIndex := []int{}\n\tfor vr, _ := range upgradeScript {\n\t\tif vr <= v && vr > oldVersion {\n\t\t\tscriptIndex = append(scriptIndex, vr)\n\t\t}\n\t}\n\tsort.Sort(sort.IntSlice(scriptIndex))\n\tfor _, cv := range scriptIndex {\n\t\tupgradeScript[cv](app)\n\t\tprintln(\"upgrade @\", cv, \"success\")\n\t}\n\tmodel.GetVersion().Version = v\n\tmodel.SyncVersion()\n\tprintln(\"app has upgraded to version @\", v, \"successfully, restart and keep enjoy !!\")\n}\n"
  },
  {
    "path": "app/cmd/zip.go",
    "content": "package cmd\nconst 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/8PDw//b29v/6+vr//f39////////////////////////////9/f3/+rq6v/d3d3+t7e3/46Ojv58fHzgh4eHcry8vBdwcHAdw8PDAICAgAAgICAAPz8/AJiYmADGxsYAl5eXAf///wDKysoNqampU319fY5wcHDFe3t793d3d/WBgYH5kZGR/KOjo/uzs7P7v7+/+8XFxfvGxsb7wMDA+7Ozs/ucnJz8gYGB+nh4ePpxcXHMiYmJi76+vjz///8FqqqqAf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8AAAAAAAAAFBLBwipcxPwvhAAAL4QAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAAAsAAABzdGF0aWNcaW1nL1BLBwgAAAAAAAAAAAAAAABQSwMEFAAIAAAAAAAAAAAAAAAAAAAAAAAAABEAAABzdGF0aWNcaW1nXGJnLnBuZ4lQTkcNChoKAAAADUlIRFIAAACWAAAAlggCAAAAs2PmtQAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAANmaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MjZFNEZDQkU1NUFBRTIxMTk3MDBCNTk5RTI5M0VBMDciIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MDk3MEYzQ0VCNUY4MTFFMjhDQzBFRkE5N0NDMjRCOTUiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MDk3MEYzQ0RCNUY4MTFFMjhDQzBFRkE5N0NDMjRCOTUiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpCQUFCQkVBMThGQjVFMjExQkJFM0FCRjQzOTM4QUVCRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoyNkU0RkNCRTU1QUFFMjExOTcwMEI1OTlFMjkzRUEwNyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsyOCusAACgjSURBVHja7N3tkmRHka1hdVLA/V8oIxDMHAOEdHZpdT/1KgrDDkNuHYSqfrRVZ2XujPCI8I/lyz0+ff31N4/H429/+9unT5++++67X//613/9619fXl6u33/1q199++2311+v33/zm9/85S9/uX7/6quv9t/rI9df98v12b3t+uV68fr49RAvXv/ude/Zk69frq/b63vz9fu+9/vvv78ee72yN1z/3RuuF6+/Xr9cr1xfcf2+YW9g11+v9+9P1yvXX7/74ef65frT9fpe3JP3wX3q+vf64PXL9co1+Oud1yu+dGO+XvGR68VJY2+4/t2bCe16yPWG650TxR5+l5z/8Ic/TQQbhKFcv2y2G8feM7lPFte/e8Rmu++4PnL99xrE9V+z3Rv2KeP+6oefCd3DJybD2Mf35o1737iVuF6cdPbxDXUj38Jfb/7qy8/1363uXt8zN0GD2Qc3QnO0BbcG++9Ge318O3WSPZZ8u2HPnzBvkvOrLK5xb/KT6XY90UyUtvAmsDfsi7s21yvXc6+3bStZgB0C7++g7biNZN+7yVw/Prin7VNGNcl++8PPHutkEJ+tsLftF6d2otxi70w75fuTL9qYd2J2wnaYrh+aYJPdRjHTyf0+OX/64x//Z+K73vTnP/95A7J3HKPrdarD7iDZjfga6PbmRL8R7z0+soHu/VuSfYvv3YGgb/fxyXef2mSqq/ccQjTnPXBP3mg3tj1kI3GMLNiO4M66veVLJ7jrUdt8lKTv3Ux36H3LJdippTvk/GAqrp/f/va31992Zq9nXaO83s10Vf8Q33aEnegN5kM5bF9v9zEh1Zb7Xq9fP3tlcpyZ3Gpdz9yobEwi3ngmqc3zev0SGbnMorCOW7M+7Xonbb/pbGo+29M5se5R1IzBT6rXA3fUbpLzqy38BxuH4vr+y8/eQB1tz04n7KGbrWnvsF+PciycLV7DlpBVn/Xen4513RdtPrwbKmiTnwGrbdsGd+731RPQDOReMYt9ak/ePrB4e+b2h1em+va9+y+lutc706fL+dPvfvf76/+1PXsWdeEcUF97kRCZX76Wudnyxr3JU4N75iZPy227OUxUH7doIp5D62jy90h849+kzHm/TxAVk0ltaeuO7Rjtr6Y5C2e7dNfWxXVktyfukPOnb775759gDzpDne0vzQ2+Sc6vipTIdm74UQ2nBFJ7HDluJ9p61WCMsEM2e7bvqtuyX6pauen72Rnap6pLnapt88WRW0vxwFZosuv+mHSEXzPGs4t750wAs0pdW+b9XJ/aE4SDl6mbcMQbDUCfLufPvqyoZb9zhK5HbDIbAfd3S2LXX+OexzFpbn9tef7yw4+YnSPDUB8Gw1Gz3Rhwofd0HTnuq+mujWpP23pzO+k667rxXwZpZ3pj23iuYW8Ym9H+3RqL2a8PAi6EGb5iQ23McIecP49489n+3ZdtuKYqbKpMJwJ+Y6V/ved61PUnjqKNvAnQQvPZeIb767b/JlmfZY4cl9ov880mO76AAzThVvqOsth0SvWvP/yIXjbTHXeaee8XV+yv+/bt1H0cQCN0uUnOn/7rv/5AL0/bbnpc8E0YEgbUEO2xt4fvwA/cCEBlBrGxsvnbj5tbQYB6Oh615xRa2/IfGowbzKrVSypsxsywu3ts0ThuVHEZX8RwTO5iO8byJjm/gAx83wbhK7d/GRLGgKKrjeW2CKsrZVv7+silgjgs262vav3L0TSk7778TPomw7LSh/bB1OmWzWpt1WE9e3PdDS5rYdXrs4vhxNH1Etkkh5gEuoE4zzfJ+cHFYDwXhTS05FYcHsdmdS0GyICJIprCWg7WZDdDMl9ghw82PaFMl4r2pgkZniqcakVqk3dAvvXF61mQ1DT/xrZX/LWR+3Yb9T7Nv/dvstuX0w28sJvk/AZR0mmbRv1+KnjiJkRLQllxJSAje0UcOguxL52XRTSbCWNTT9LBolG5ndWWe0jN7WQHyZu/2qDTzth0BinMkeFnORziBCHHdiohHGdrW8Qgb5LzC9VvuMQ6r5rZpIvrHO+dFW7RlsFp1ezXd0/dA1GrLeVWTGOv07FEOadgj9rmoPrYD2fO6VnMvhO5YW/NKEbvFNQLvR39xvtMLzR1MtlXd9mYtKfL+cGb5/lMG3C4PYvV2QbZpzY9fjCF0CTLFgxA42kTCsjDmYNW24OkvLW87BMEbtIpeAjtBC/s9EtDUrObtfVrdM80+nZw8zWqS6c1sdD0wibrZPPF7pPz2/mYlL0beGgHbUo7GcWLQf4NqjaHRleb8KRgxw0O9RHODodt52a6l4e90XLkQKnO98YzpQ3glsMS+FODcrnc+s19O8PJ2AnmqniCN2zwTucMpF14k5wf5rwRy/vsAEmhNabZ73u6vUPtbIfad1uM69x4sakTjmXjcSiUb5mq2bY1/4IX0vdf5WePlbun3h0ysuMoLro3qSYr9iIbuV84IDOQky/waHJjTW+S82tc+JFw+AnA3r3tDjl/jiuX3NqfD6CW3eIxLhgo7rAxbXfYttd7rnfKpZHRsMTrXLITLP/GOkCOZNk89lI0JrIcpAJL2wa36vtGDtTOkJz4EKxBSBsSIFB4w0lp5CqYOcKbzehXX34gizfJ+YUTz3JOs3H2NoLiArMle1A1huiqVsorLIQFA4nV0RJTTtbmw6gIMPgvwC0QlJBjp3AfYZJpJG7zFACfxTMZ7M2OsSwDoZhOzxy7UEjsDjm/Ei8GrtfR3wGavAy631R34IDwWbh5NNBOO3eviJaAttZj7+lq8VHpMZgnJw0Dw4EomYUqK+xH6TlSTXRQYiIfEaFAQsjE+WwwKlrYqtwk509/+tP/mcKx+IXsgMIbJetVrIgoqbgPxPU94kqxP1/OzAwYkHdLlc/HZSqInh2+ttKOBWVFQPzm5tPLSbGFl7KYX0fbSP07i4KHHSnY6dJb3F1ft13fjM/euf/u2GGkceJhcnaSGQkAOKjiFmsw2wwrrjl/upwf/IjN4TrpXLKuhGhs75wqo7WmYYB4/OOtyizZLDlfo2bMmajJ2VqW7DtkfJLaSOjAuQ8yVnUZBBI2BKh65lN4cH1w0GhV1vbKIsLyjujhna3rlwavG8/WdZvsPjm/Zu23yEvaiS6HdfHa4RQ7vNu8Hxb0n7KgN8n51Z2RAzPtQlDNdDsWpcHvxY2+pEoBHMZRiUazNBRsOYMCpkoNVI2Sy/bsdHIIYeUzujtnC1K3xgUW9szS4Bsh0OFbhv0i5bI5osZAEGGEMP0t1U1yfqmvwcHlpqNhCZjsR6OHDTaYBfrVDluPOjtOKtxEeFcWE6PIUtaDEMOV68ejEZvaIoLUPQprpliPOTY1SJtVeXBMRDtEYeXuk/PLQXEsMoLcMKMieIL4FaQoN6KpH+7JdvpwB9jV/stHYHvo4SmTiZgF6lZtKg43kLsrtuM9lqRT1G0oIJzPylGniJOSyRhZOBZ74FSiPdH00x1yfjENWeN92TUZ7kPx8h6yEtE2PSOrGyLnLkzmmNEYNS3Xv5c0551WjsyM8IAeLmuWs3qcWgleZ3fEJ7sH8gCzJjjnBr6Fn78R4ucX+23RiLV8upwfTmV5qAMFmI0d4e2sAzbc71MFdnQzmUWlGzbRSyI/wGZrXERpQLJBFcTKaXIQ97Qlzas/bflCd/AzyDWgh3MhRyie44J+hri+rF+dW3oPX+smOT+m4gyrkabcCjIyaGqh1d4J1lq8sgkTE0Co2Px7MvVhfjYxlN83wt0XIJsdkkBQGsidmWcPHW2+8O8CsHLLs0YKIVqMsSiwZVDWEoXQVtghs29ukvNjpVaFzAf7OjQ0MgClIBOzMQx3wV9TBCR70HB56p5JRhuiCJJolrGyLap89kCkv+rephEkwVsyWFdru0cydgd9x0haiptdZqVt6tAz3tewt+FukvNj+3TDLa2j9PXNyoSNQKQsPGpGqcV25cLW24So7U/LUYhq98GW7LJ8wgwUowXgh4t0hJ7OqAgBFQWwt4O4Yy3s2VHG19obrr9uV0GXWvDW7wJV3yHnT19//c32Gv45l8G2YpPLG5DooT3A8zPRsD5UFLM1jvJEJEhbw80oDi/u4S7sKfu4VTnYYDXMTfHgZVk8KyrN6duNZ8BKAbmhLRgkPZRgVWf66XJ+LYsB/Zmk8gC1IKSJCCuxwokq7FJ2DInTPL5rdkIiFKjfrFjzQbwhaqSLVLJQ10lNDJRkAkWPq1CGnnQlGn2K6xt3H282Wj9yTHfI+dFq8UmkDoW4dWqq9eYkaIhlQKux3oiH3v7dUjknlYtlYXBBW07NdG2N92ThcGn/krrcUayZSQfmzoEcVac2uBwqUQcrgOGCKXLwwemJ++T84HFB2cvNpW04svLO3g9VKc8HBHrk3zFBPleoRiWKqWFsLULzXwa/PlsJwf0vfQA3EFSweUJpwXiBJPtGuv/SXezT+0I17qKab9jTTXL+nMfq3pkNECYXEMFOULbj7DfslSMcYbBu1YS4zbu38Vn46A0kMF9mC/epKRN1lLRKixm48owWmZojxoalUovUsBUAu8ei6JsvG8aWq0SsWblJzp/Wd4bjXsI8C9G6Hg5h62+LyAyMb4FIq1uBUlBg4dd/dr+GFpk+Wc6tw2t4RHfXTTroMHy5ZmEcOA9vNC1/ffCCFkKUna3EQgpevNgcELM6E+JQIgx0JJTkgUNSp0UYOsIq5y3S8qA45jxnKeiWDDL8d8j5LdlU1c/5JlAsrvbxwFGvKdrcqGwcgqY3jwzDNtT88iMX06N8cKtF0Hu/hixFw22LVnXrUCBx0RJ7zYRaiIMDzmAffPud++UlBOx23tFe4Llyfg0qnBJQRRtstZCOO6R6fQC/bOpRryUwEMJzC+t8/xKimmqj58r58y5TCiwCpaPKSAf822LXcxfFH7ALTK8etv4ykoXdd3ILzW7LKUL9OXhN7yHh84n8MpePeT5oLF7h3bQfBoy0CRArOneUcW3FSJWN83qTnF/dmYNZXP+tJHPIZ8FMdoLKUp893WU+B6G7gD1PBypdokZZ9y3JAI78LNyxFmw8V86vJMRiPFtkJHmC20Hm6YHP+XWl3taRq8vn61vsw4tTRstlb6KxLmWDaHhVbS1V3LpA5AGe57KSrJESQx5HeTQge/GoMbBz/4BUYQ89X8777oHfMwBtRCG30tIIm1fDrIJV5Pi+EQfzQ0ZCriUEiKA1gp2/YMDmJan9IlI+ysA4+kUjKc+DNmCaTomBNdu1P7U+piUGq7CZSK/TeZ+cHzSeOXzur/cDrYir3Y5+pZFhHBWkl1kWGADAZrobXfD62kpGqa1+FW1EuA/uF1wj/gsSqV/QGlhfj23LSUDMRIYKvEWdApdbblWDmjrYyr7xyDbcJOfPHS8+Oo7+6x1Huwa+wqjua2n1aNhYlpHan31yChri8GZLv8Bmm4miSEIswLbund/nR+SuXWezTohJYmoELyp6R6RxSx0WLKy5JBuMTk3i8Za6bzfQ5JyXw23e0uJecMSq7Td9RZ03yfnlaEp8oOkCyba7amwLTuzJa26Wm25j2olet3hH4rskM7mLS+1snmXEshw411bl73Y7EcZNFu128tZh8AsyUHSGGkcifV9l0FrARsA3yfnBaBn0VDM2jniAlp960Y/IoEsbqZJEArO5yvPc8zWAwuYWC6M8Cah5HOO6VdE51gyhHtl4rdJDLQpcIle5QsmJ5eMCXcU5GqVu/Ct7ENfS6vfJ+YG3cvQbE2lSRK3rmeB0B6hhH+/IkWr5UuevNGLvx4MWyNNODDhORhtILImBCVfqN/YbkzaPfD6Fbj0qUcpVcQgwKhzE2QKn8KCJyiBauVrQO+T82o/0owTiiUWEoBalTxikN8n5pb1BpLZBTXix+l6xPQ34jKOtAA+aAtHzAwsnTk86T3UuuF5bgBFnqZEpGUG6HikN0puJdDRbj8+Stcta0XkxXE0RMNqBbmUImr3jdZecZz+wvtA+UYA4aUqou1naStQbarGbK+lnp+Jb08wGOGHkCGqRQ2ZjmhJpk54SgqFlRkigLWE5ggFDtTZL05c10w4kzRFCiMjhPjk/pI8PusNGKT7dloEtLQsBzm+zEe9p5yzMT+povId2cGQar9+vdYIgc2IbULYaXebFjikFe0s+pT1bWxahbQ6K1NpUSqGNhRrdYhS24Abp5ij0uU/OLzivJTG0uT1V1p59alMLWs5dnEJrpw5VjYIhGKAkn5jB74eDcFRCazKrN3lPf5sUdPKlZYoi7AxFDvN4SwxnNYcva0zKpDlYCucOOsV9cn5N+apI7uU2LQNobfFoelPTKOLTBmJYQFeTYf5tuse427zOyStTqJhAC5SO5nWDiRUhlF1R9Me24L5rlUHlgvQKarcVsRNZmuEBCHuxld/PlfPnDvkt3Scg9Vet5TQTitgX9JSQLC0qz2fN5lAJqEvEg6KJ4fxV+IXz2YxjEwL/VumzoxLxiXJ+yKOC2I/eEmK7olwS3DTkwbXF/m/h2dZs81xja+w/CDITyFqUaWJFxRKA4zq328WyxJ7ZZgdFZFi+ZRLatLLNa6Qa2vm5Dpo9ekAB0il3yPkBOlFTiYXOXIGMO/MdphYw1M6BTsTImpzBLKCUu6ClamTfpak5EbMijARHV4iiRRmMH+rhxrOmKhvAkAOIlb4qdEBKQg7vLOIKZBfs3iLnr7/+5qOV9vtW2jgfuhJs7TsXrKTeard/25q25NI75PxonZyFLVXLVuo1Aw5B73Co0pOQk97UU0ZiT9qhVLsWpwkY2q11MxHwwa85cuCrSdDJEClzstrf/rgnDUl1y4/CqvK0d70cVNV9tSzN+3rE58r5jep5tCnsmQUZi2ptqFagYe2pA3I1lPYEcGGh3pBAuoWxaX9As9rHxcjlKTUvyDeRvmjHgT2kVLYtjJDA8lB3VWI1q1snPA8R4V7ZRFoUcYec3y7+IoLe7Nk+U22P0rDG2/j9CulUEch8ttWEg7VjWu7XQWhHQinriRlz2uwbaYR6Cvsr+G32cgiOGuC6CftemRDuMXfRUjW86bZrK9v75PwoY7q8PGa2da0b6zi7vfGNPWjmjHI/imDF6b0ysFiiSLwefC8MkH4qbslmyBwdnUWLVhevkleR4D2qO1WNb44jwohlQTCtp8FPbO7zJjk/CHc5F9U6Sp/bOw0oxVnHOKrtlZzbz/Y4k9B2vzgEJcxDsA4q+z4r2uWGwEibLpYgLUR+8KnaFBsgrhO1WFBWz05qQZ1Bqg1ua3nd3O+T84ORmGe/r1dvrj2tnQ7bbTG/VmHlPqsrEE1bCck5CzDCz84WX2aKTnx2MLpKtqiCeuMFfUHOOMCc+/oX8LCmba/xUKFHTxU/CAmLTaUdej1MEbKb5PzKI6W7yxUoxaG5vYNB24xdEc5mtHtX2HuKg/Iz6Pt7PHDHTjF0b0ToPRLbKMflNAyPoLBnpT13b60qKVT0XDk/Gpwe/c92nFV0tmlEuwa0YHV/qsHvBXO9klgdpcogK4qg0ARsm5Y0NaPYlawPMvw8Rh5gczcaKLX/BPdK5MetBWq3b3HJJceOYYM5X3fI+dFrPvS5VjAHkm6Nbqt+mmQAr9S5730UZWCWRzvx6UghNy0aaT3tPoj9AME5Kpg3vTkjVutazvo17ROJ1ndkl+p91LC14tV+8sqWrZTa++T8dpEeF1bkhLDUNGMnBkrAscSb1ssVjgXfgvJts+PWlcqgBdOBxjlzWx62gVmSw9sXHffKtdnUURM6u4vp24ygasLDm7U2CuSwGt15oB/3fXL+3Kd9bKr37TgaPmOMb0f3DhHgtTFtKLpicVXaCA6HpSl+zKX6XTtbvcAPXIIBJgQWTbbPAr+0zlTv+moZt0ZM8xjVvuDyuC6DI21qrQYBwXOY75DzozdltOBPcNoyomIHBdJsnOYWeAq2UvtQTjQ12pyCiaP3pG3B3BvSdsfk1UvlOouOv6xiBqkJI2pWCUf7+W/l5oKKK6bGaREwhW5UdWLvkPPnKt+PW3n/32/lbVvb/ttuRuV9YQvcJOfXlG/BgnZHgwu0EBK94CiE7EdEcm0oipPPzrdOoC0G7OKWTyrm+5nWJLe7zXPl/Fqo/QvsP1G/pgKyAwr+qQE+yGeTmNvx7Fc5Qt6cKPMOOX/6/e//+C+qiPYT7H3HOrHBEYoKtn12L3TbRkZWtz2rNqFQ0vdtegyg8dXlPh1XI6np1dlXNNbuRP2WuRX/7JEigafL+XUJP6zaT7Bl20/huXJ+tJ10XTVFPcdNymggvqk367abP0UEG+Ql71O85wNWlmmi95Cjtv1t7b0Ifykk1nLfdqova+FoJ0zptRKq1y3tsEqijey6L2pvy/YFExPfJ+fHe5RBd2yVR80WtV4CDiIgK4GsFUztcw1Darcs17uj5TcDV8JPO3Y54kcPSGU0GGlOD5SunYFK6i3dtAWk1c/AEUl2/fqkG2Wql/y6T86Pdq4FUZJCcyigPBTjtgOYNMFdRxkKYanP48WIqKpeGvzCOPCGIWoAw93y4pp00IZbRCmx3l1cQv6UBNiBkoROtK17rzI7yqAslWivZJ875PxW/dwL4CRdSYr0BzO2blFN7HwQiq5OB3Cr7h+0sGYMXgVWlSWux8hFfH+DpUOzk+3UKhvDPCsnUfjRKqpeg9mroChb7S3rRiregID3WtKny/kBa26SHeOoranaRhGy3pLGXp6wnTKk1B4EaCFkNHWn428b7fTepWOowoZeEdlGPsARTsoGuYsxG2bp1jbb1rtjm17uRaJtGkuztRWQ4LV50Dvk/GhVph3UgqgZKis/heNWALdE9qKXFiJPCUzdodzb9fXRS4FVRCIqoIEHljZHP5t3VNm342NrWdTKKP5r5xe+Rjtio3fYEIo9pXmpzY1cG7Zvf/xzi5zXzPI/OKaWB9j5U0ZTx719m2+6cVc/nafL+fXmtF72AQIvysXm9/PNU9f+93KU1lf0FhapVERYwZ+62Rpwx7FBJHBu0rTHrVAvgj8ke+iAdmxs8dgTqyB63+1z5fzSU1J3rmAg2dXw0AnilWYD9C1rv/rWv9uJ7XuBfLe3YbBBWQGPjXPVYwgNDfto4abappcF4n+2okrO722zC6VzvyUN0WrQ5qHqvt4k51eMFLkYPbkIglNsF1ALJez2JhhUhiZrjp6cciuUqmsG2tecZBUYoHRWO5X+9f4SWdJ/f0uNSelHCvhWGyappIt+GaeNOymbcsObVLpDzg8b+Wi76N7P5rIZc2RfaXFBnua4rJH73ZoOPAB4hL5eIdNYvljXVN+cIAnegVv46nwBqfB2cml5Q9f4KL1o4QQFzkFtLcRWpTd71bSDeO6Q86O8oO7cukxNKVge8RbukFYprVGiKMquEBsdlRJ1JllTHg26IpVLHMc19Hp6kII2ZrMfTUTzP7UtgIwc9adMYMsqJKWPKXNBx/a/T86v7swvttoIHbvNOVZ5ig/eblycmr7YTmQ84Zar9cKRW+TMfioiWXhr07W70YEL21nOGTM78tJhFZrpNb5ObysHxmxDrqMv096mdMgVcrv5oZxEQZWDuNp/4BEXdGACzr90RwtIWybYUiaAi8DJxNtL+A45vxIvbq0xZ7SPvJJ5UmLv+5eqc/gPoIb0+vTnyvlzT4jlaxgSdYG9ofF91pSAYPbOTVN65mzEpDPPorZNV7Zi1u2q1HtAGMv9d0TC8qwUx8pk9c5lVTgyTW5ZwJkv9/Aga/UqNkXeQ1Xa68E2vUnOr7bwjUiTbn3HjYMf3Ur/xW6lfOCny/nt4tl2NDq67zRj2QvP5WIYAHdZ9Q7CbUw4SF3t1RI4BO130Ko2F3e1Pr3VFGXCa4cGZK+I2wPLAs9eyvU0QQgabcoFVqLKgL7Vrxfa0rz3HXJ+7Qr80THvuR3zWkDadh03yflhc02HqJLdUnOBuIIoQwKGUlG4T65K3VGQrms54FZO2NeEix3gOGpygsLV6hMhpqKItq3p1rZ1FEhUjXdRj80HTHB6iEWM0WSsfCfk5SY5v53Cjxt7/vGNPXV93TEg5Vvg0O8TiE6kN8n5c1Dxi2rE9P/lHhMo0tPl/JmQ/3NP5fz7Nw5rBvvJci6niAFoj6q2We593SUENL/D/qHPwPcOaL/NmXtrRCmBLf6z6497VR0pQtT4mzck9d+at5ZZ2UzFidBeWiTWAiusO6wfaSY5qR3c++T8qB4wbr3MSxVZ6Hq0zeTiHzfhODc4PO8JZMY3L6Cy672DLkqpjjJPLr4TxsGRLncUekPh0Qm+hZmm0BK7ApVSjGreQbU73JyXg/F1h5wfrZIlDj1hj/MLG+yJgSajjbTbxHRpGwBzGjeC1am0gzGnoHeiFEflEKr2LhQC5i+M6eg4HwS3o0mNv3z5sd/Bfuwr0yhvrBrbo9rPuf3kni7n13YJHwUuPwEZB0D6dDk/Wplw9Os/XIPjNlrgC6ZQuxOKkHplSw9KI5vWddp0PBHYhxrX5vBKWZBv2gEdoEN5ji7c9E2xfyyQYnVbieuD/BqVZrtoAs+zN768v5FSq4U75PwQLR1ms3ltf5Lvp81bOOFMyC+3E5SNM0TqKBYR1XZW5Gszoq70Vmwp0IZTxrw93vvud7CqCQzvuJN7wpEV6n18OPytGiiM3mosj7pDzq9BxUf7yZ8mIXyTnF+rfH8uie8DtDwq9FuEzinoVQFN5rkP82ghtd0tLjzIV8cZbVOKkt6G79SiM4R3yPlll8T2NJSDxaHv7YgT63jH0xhtrcUnhCo1yqlJQPQWMm7QCG31IJq7KN+yBUSNFt7asrzjtbqO05Sp0CakLMzMcHNhC9K5Hu/bCbedostQbpLzqyJ9z9r76BD8dBWtC/nT5fyQdsJpeN9HoF171QuKgaTu2i9UCqnWm5s+RxRQIiQqZNNLXnuTWJlwuB2iNPTDlqG4bWu7eyLodQvt3dT0SIGbZSKXLal3g+GhckqOsO1r75Pzj/JtwAJ2aA50actHS572UmmKtXfA1BtuJ4m2ZuzNvYIEAtJ5EFGjfNSWOBWAng6UE5h61MuNuha8DkZv2CAb7KbDqd/WmZZBit1TLqvc501yfq21f+7V0bRcS5xa6KVoqLGzQFVSpmzr9r0CXhcEKXmiV0SBlZ2n3dqFHuA+GB2YFc5jxaFZ7Jn7Uzk45cHyhly12GDjDjn/qJHYQYDopWFF8Xvjpz3S68jcX4zvpaZSLEzt1KLUjsretfX//D1GpXntcrc5q9J7G8OCcUieLArMxbUVivodBZA6or7o28iPy9m4IRqE3SHnF0BzO8UN6SnnWkDdDbjd6mt6+3UJ7e0kP5WovK9z3qfsXL1W5bU5Y0c/Z5Rt9MN2D6TMnf7jWnX1N9wfpAfUCo7GdOY8Z2qmHTJUlvcmKe7VHXL+nC8sUUA25KPV7BNbzW4Yt8jZJN09p5GPSn5sn6Pbiz6GVTVFktpXWSlJe1g6DetFLxWgecjWA8rqHGC+YH6Kdh01QbcoSp5kxQl7XdNwVRD6WLTCtthsr0s+WNuctfb8KGnx6XL+4JH+/HmkbbZcV5hoCuD2Fngwbtdm97go063v3sPxnnkwFbT8hv0FdhF6H2kNfaEZKraE+GwFh6zkhipJuQi6sSg257ZtOCVk3l8IUg/raGr9XDm/wdwfffPuTiveJOcH6sD1swQ6Yp27Ebh59A/xlRWBIi3VgkNWEBl91h5vUyOvF7Nu4c/Eh5fNnEBk6Bmx4yUycmlJcEtWPW0cg16T3jreLrbD3dtAiqNOqu17eIecX23hv1tzCPc2IEwc9xzhwx1Ngxpm1LaJFJuU4CLa7GaBEYnE1o4BkxJzRfUdl9OQMrndJOfPt4jW9nwU3d9RdL89cYecX9sl/AR7sK0gCrn9otzgm+T8ue/ML7Ns86fsfQpVeLqc365QMGFetZ4sBQN9h9J9vcRwhFxr6rKPt3rGL44MQ30YDEetiMxxMSM+rp0omTc0oN0+mz4tOqxXwgySq5e4Nm4XQB6c6yGxvEqd982QfIVunb2q4ulyfrRBqF7HPKXe01FUXkKHJ3lIX916u/uUDkoLzWfjGaIpbEqHz+JeR6koqUSya0/RIoqVvqMsNp1SfX/b8tHHAngkrtBck9ssS6VnbunRT5fza2VTb0QCCnPBAfki4rqUdSU+Uv//IPVf+/dcOb+ADHpVR7/SJZiNpUizlY91W5o5O/DliWB5O7cAQZyP6L4c8PZbZll7dUixciUv9BsLVB43d6O1LGK4cV4aR9dLPHLu8uzHBuI83yTnRzsOcb0ATlz/FjkcHalwEYSreCVt4ljMabKbIZkv0Lt34JA6eXK169lW4VQrUpu8A/KtL17PgqSm+Te2Xjx+RO7bba2YXApJcq0dg3hhN8n55WhipYVD/f52cXUxfROtlBVXAjKyV1qmJROGgSIRwXYenqSDRaNyO6stW7fedrGQvPmrDTrtDAk87D9+Viv6URd7uNvcr2drW6RZ6Dvk/KNSI0YSolivjC6uc9zm3+0l0stQq9nXiWegFJCiF8P5iIFOUoqViN693fLj/CORTKHX6TRZqg27WaG3W5C+LEYRUUe/8T7TC01FizqqiJm0p8v5R+lKpTTUTlnirA7mEmIdP5hCaJIFXw3GcXSEa9M56yd9Lx7X8PqyTxC43vDKjJkefYtTKzLpFYY99PX+j8pyEMm4neTY9IJ0YNe1tY9Pl/Pb+XAP8t4NPLSDNiWcF2gWyL9BlVLC3t1GCnYc0hhj1rJKnEFNkxSDFUJrm3MUxcXpOuRL4LmGqWqwSXP6s3f/bth4EpZf7wqO68Kbjee49fAmOT9aW4QChCtw3Fm8JcFLc2d21c52qH23xdhFDRagWdPZ+cbjUKg20xXVmn/Bi3JY2qnp6JXOR23Hp7LrF92X+woC1cOjNx8ct9ohJ4peak1vkvNrXPiRcPgJwN5eUvhcOT90/ettsQVq2S0e44KB4g4bk8vjZABWRVBfWUpsTJm2OWLwXA3UNE3tpWisDJRiaSrZOaUtWtgZkhPHoymx8Whw2ptjGuDi9Ta8UfymwRtn8g45v3Diy07kTUAuigvMluxB1RglirNSXmEhei9nE0AWpvdVmw+jIsBogyl3/4rS0O/ln5lkGqm3w9dn8UwGu2zVkks7ZYEEB7txwn1yfiVeDFyvo78DdNyD0m/6aPj1v2j4dZOcX2vtdZrU16GRUPsysl7Fisq7Pe6g/0Bc20T0Ljm37zNUnlDY21mLbrTWS6wRqMa9lTW/ufn0clJs4aUs9JRpHFIOoODBbXTADkFe7yHQi0LGZ+9U5KepcJ14mJyd1NsI2jqvfRCswWwzrLjm/OlyfvAjNoeV5laPtzUH11bhWe9GA+Lxj7cq6pJ66VnNWAnt/dIy3qdzpGTR+4GWQviWChOHxxaq1tGHiAeNVmVtrywiLO+oTYzcvSZ43XgQnXlAd8j5NWvvkqBGl2jtQNje+rHN+2FB/ykLepOcP9dUfNSb/S/qzRSZ6uQs1kSYdzRV3z9dzi/1NTi43HQ0LAFTr4yQkahEWu0OQzlMQp0dJxVuIrwri4lRZCnrQbStnL3CoxGb2iKCVJd9bJDFetqT+KCrtANVmwGKdojCyt0n55eD4lhkBLmhl9NS6+jVvd61V+s5TJvDdrrCc6kJriB1B4lAl56IWxdiVzYVhxvI3RXbtdNpM65FOoaetwNc1SnipGQyRhaORS/stSeORkFPl/P/FWAAzAIyJfeWFG8AAAAASUVORK5CYIJQSwcIm6PU7/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+VG9wPC9hPg0KICAgIHt7U2V0dGluZyBgY19mb290ZXJfZ2FgIHwgSHRtbH19DQo8L2Zvb3Rlcj4NCjxzY3JpcHQgc3JjPSIvc3RhdGljL2pzL2hvbWUuanMiPjwvc2NyaXB0Pg0KPC9i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SHRtbCBgPD94bWwtc3R5bGVzaGVldCB0eXBlPSJ0ZXh0L3hzbCIgaHJlZj0iL3N0YXRpYy9jc3Mvc2l0ZW1hcC54c2wiPz5gfX0NCjx1cmxzZXQgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vd3d3LnNpdGVtYXBzLm9yZy9zY2hlbWFzL3NpdGVtYXAvMC45IGh0dHA6Ly93d3cuc2l0ZW1hcHMub3JnL3NjaGVtYXMvc2l0ZW1hcC8wLjkvc2l0ZW1hcC54c2QiIHhtbG5zPSJodHRwOi8vd3d3LnNpdGVtYXBzLm9yZy9zY2hlbWFzL3NpdGVtYXAvMC45Ij4NCiAgICA8dXJsPg0KICAgICAgICA8bG9jPnt7Lkxpbmt9fTwvbG9jPg0KICAgICAgICA8bGFzdG1vZD57ey5DcmVhdGVkfX08L2xhc3Rtb2Q+DQogICAgICAgIDxjaGFuZ2VmcmVxPmRhaWx5PC9jaGFuZ2VmcmVxPg0KICAgICAgICA8cHJpb3JpdHk+MS4wPC9wcmlvcml0eT4NCiAgICA8L3VybD57e3JhbmdlIC5OYXZpZ2F0b3JzfX0NCiAgICA8dXJsPg0KICAgICAgICA8bG9jPnt7Lkxpbmt9fTwvbG9jPg0KICAgICAgICA8bGFzdG1vZD57ey5DcmVhdGVkfX08L2xhc3Rtb2Q+DQogICAgICAgIDxjaGFuZ2VmcmVxPndlZWtseTwvY2hhbmdlZnJlcT4NCiAgICAgICAgPHByaW9yaXR5PjAuNjwvcHJpb3JpdHk+DQogICAgPC91cmw+e3tlbmR9fXt7cmFuZ2UgLkFydGljbGVzfX0NCiAgICA8dXJsPg0KICAgICAgICA8bG9jPnt7Lkxpbmt9fTwvbG9jPg0KICAgICAgICA8bGFzdG1vZD57ey5DcmVhdGVkfX08L2xhc3Rtb2Q+DQogICAgICAgIDxjaGFuZ2VmcmVxPm1vbnRobHk8L2NoYW5nZWZyZXE+DQogICAgICAgIDxwcmlvcml0eT4wLjM8L3ByaW9yaXR5Pg0KICAgIDwvdXJsPnt7ZW5kfX0NCjwvdXJsc2V0PlBLBwgkMJGCpgMAAKYDAABQ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\""
  },
  {
    "path": "app/cmd.go",
    "content": "package app\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/cmd\"\n\t\"github.com/fuxiaohei/GoBlog/app/handler\"\n\t_ \"github.com/fuxiaohei/GoBlog/app/upgrade\"\n\t\"os\"\n)\n\n// Cmd starts command line application.\n// It captures command line arguments and executes proper operation.\n// Some operations will exit application when finished.\nfunc Cmd() {\n\targs := os.Args\n\tif len(args) > 1 {\n\t\tswitch args[1] {\n\t\tcase \"install\":\n\t\t\tcmd.DoInstall()\n\t\tcase \"update\":\n\t\t\tfile, _ := cmd.DoBackup(App, false)\n\t\t\tcmd.DoUpdateZipBytes(file)\n\t\tcase \"backup\":\n\t\t\tcmd.DoBackup(App, true)\n\t\tcase \"upgrade\":\n\t\t\tcmd.DoUpgrade(VERSION, App)\n\t\t}\n\t\tos.Exit(1)\n\t}\n\t// do install and run server together\n\tif !cmd.CheckInstall() {\n\t\tcmd.DoInstall()\n\t\treturn\n\t}\n\t// check app version\n\tif cmd.CheckUpgrade(VERSION, true) {\n\t\tos.Exit(1)\n\t\treturn\n\t}\n\n\t// begin cmd init\n\tcmd.Init(App)\n}\n\nfunc registerCmdHandler() {\n\tApp.Route(\"GET,POST,DELETE\", \"/cmd/backup/\", handler.Auth, handler.CmdBackup)\n\tApp.Get(\"/cmd/backup/file/\", handler.Auth, handler.CmdBackupFile)\n\n\tApp.Route(\"GET,POST,DELETE\", \"/cmd/message/\", handler.Auth, handler.CmdMessage)\n\tApp.Route(\"GET,DELETE\", \"/cmd/logs/\", handler.Auth, handler.CmdLogs)\n\tApp.Get(\"/cmd/monitor/\", handler.Auth, handler.CmdMonitor)\n\tApp.Route(\"GET,POST\", \"/cmd/theme/\", handler.Auth, handler.CmdTheme)\n\tApp.Route(\"GET,POST\", \"/cmd/reader/\", handler.Auth, handler.CmdReader)\n}\n"
  },
  {
    "path": "app/handler/admin.go",
    "content": "package handler\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/model\"\n\t\"github.com/fuxiaohei/GoBlog/app/plugin\"\n\t\"github.com/fuxiaohei/GoBlog/app/utils\"\n\t\"github.com/fuxiaohei/GoInk\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc Admin(context *GoInk.Context) {\n\tuid, _ := strconv.Atoi(context.Cookie(\"token-user\"))\n\tuser := model.GetUserById(uid)\n\tcontext.Layout(\"admin/admin\")\n\tcontext.Render(\"admin/home\", map[string]interface{}{\n\t\t\"Title\":    \"控制台\",\n\t\t\"Statis\":   model.NewStatis(),\n\t\t\"User\":     user,\n\t\t\"Messages\": model.GetUnreadMessages(),\n\t})\n}\n\nfunc AdminProfile(context *GoInk.Context) {\n\tuid, _ := strconv.Atoi(context.Cookie(\"token-user\"))\n\tuser := model.GetUserById(uid)\n\tif context.Method == \"POST\" {\n\t\tdata := context.Input()\n\t\tif !user.ChangeEmail(data[\"email\"]) {\n\t\t\tJson(context, false).Set(\"msg\", \"邮箱与别的用户重复\").End()\n\t\t\treturn\n\t\t}\n\t\tuser.Name = data[\"user\"]\n\t\tuser.Email = data[\"email\"]\n\t\tuser.Avatar = utils.Gravatar(user.Email, \"180\")\n\t\tuser.Url = data[\"url\"]\n\t\tuser.Nick = data[\"nick\"]\n\t\tuser.Bio = data[\"bio\"]\n\t\tJson(context, true).End()\n\t\tgo model.SyncUsers()\n\t\tgo model.UpdateCommentAdmin(user)\n\t\tcontext.Do(\"profile_update\", user)\n\t\treturn\n\t}\n\tcontext.Layout(\"admin/admin\")\n\tcontext.Render(\"admin/profile\", map[string]interface{}{\n\t\t\"Title\": \"个性资料\",\n\t\t\"User\":  user,\n\t})\n}\n\nfunc AdminPassword(context *GoInk.Context) {\n\tif context.Method == \"POST\" {\n\t\tuid, _ := strconv.Atoi(context.Cookie(\"token-user\"))\n\t\tuser := model.GetUserById(uid)\n\t\tif !user.CheckPassword(context.String(\"old\")) {\n\t\t\tJson(context, false).Set(\"msg\", \"旧密码错误\").End()\n\t\t\treturn\n\t\t}\n\t\tuser.ChangePassword(context.String(\"new\"))\n\t\tgo model.SyncUsers()\n\t\tJson(context, true).End()\n\t\tcontext.Do(\"password_update\", user)\n\t\treturn\n\t}\n\tcontext.Layout(\"admin/admin\")\n\tcontext.Render(\"admin/password\", map[string]interface{}{\n\t\t\"Title\": \"修改密码\",\n\t\t//\"User\":user,\n\t})\n}\n\nfunc AdminArticle(context *GoInk.Context) {\n\tarticles, pager := model.GetArticleList(context.Int(\"page\"), 10)\n\tcontext.Layout(\"admin/admin\")\n\tcontext.Render(\"admin/articles\", map[string]interface{}{\n\t\t\"Title\":    \"文章\",\n\t\t\"Articles\": articles,\n\t\t\"Pager\":    pager,\n\t})\n}\n\nfunc ArticleWrite(context *GoInk.Context) {\n\tif context.Method == \"POST\" {\n\t\tc := new(model.Content)\n\t\tc.Id = 0\n\t\tdata := context.Input()\n\t\tif !c.ChangeSlug(data[\"slug\"]) {\n\t\t\tJson(context, false).Set(\"msg\", \"固定链接重复\").End()\n\t\t\treturn\n\t\t}\n\t\tc.Title = data[\"title\"]\n\t\tc.Text = data[\"content\"]\n\t\tc.Tags = strings.Split(strings.Replace(data[\"tag\"], \"，\", \",\", -1), \",\")\n\t\tc.IsComment = data[\"comment\"] == \"1\"\n\t\tc.IsLinked = false\n\t\tc.AuthorId, _ = strconv.Atoi(context.Cookie(\"token-user\"))\n\t\tc.Template = \"blog.html\"\n\t\tc.Status = data[\"status\"]\n\t\tc.Format = \"markdown\"\n\t\tc.Hits = 1\n\t\tvar e error\n\t\tc, e = model.CreateContent(c, \"article\")\n\t\tif e != nil {\n\t\t\tJson(context, false).Set(\"msg\", e.Error()).End()\n\t\t\treturn\n\t\t}\n\t\tJson(context, true).Set(\"content\", c).End()\n\t\tcontext.Do(\"article_created\", c)\n\t\t//c.Type = \"article\"\n\t\treturn\n\t}\n\tcontext.Layout(\"admin/admin\")\n\tcontext.Render(\"admin/write_article\", map[string]interface{}{\n\t\t\"Title\": \"撰写文章\",\n\t})\n}\n\nfunc ArticleEdit(context *GoInk.Context) {\n\tid, _ := strconv.Atoi(context.Param(\"id\"))\n\tc := model.GetContentById(id)\n\tif c == nil {\n\t\tcontext.Redirect(\"/admin/articles/\")\n\t\treturn\n\t}\n\tif context.Method == \"DELETE\" {\n\t\tmodel.RemoveContent(c)\n\t\tJson(context, true).End()\n\t\treturn\n\t}\n\tif context.Method == \"POST\" {\n\t\tdata := context.Input()\n\t\tif !c.ChangeSlug(data[\"slug\"]) {\n\t\t\tJson(context, false).Set(\"msg\", \"固定链接重复\").End()\n\t\t\treturn\n\t\t}\n\t\tc.Title = data[\"title\"]\n\t\tc.Text = data[\"content\"]\n\t\tc.Tags = strings.Split(strings.Replace(data[\"tag\"], \"，\", \",\", -1), \",\")\n\t\tc.IsComment = data[\"comment\"] == \"1\"\n\t\t//c.IsLinked = false\n\t\t//c.AuthorId, _ = strconv.Atoi(context.Cookie(\"token-user\"))\n\t\t//c.Template = \"blog.html\"\n\t\tc.Status = data[\"status\"]\n\t\t//c.Format = \"markdown\"\n\t\tmodel.SaveContent(c)\n\t\tJson(context, true).Set(\"content\", c).End()\n\t\tcontext.Do(\"article_modified\", c)\n\t\t//c.Type = \"article\"\n\t\treturn\n\t}\n\tcontext.Layout(\"admin/admin\")\n\tcontext.Render(\"admin/edit_article\", map[string]interface{}{\n\t\t\"Title\":   \"编辑文章\",\n\t\t\"Article\": c,\n\t})\n}\n\nfunc PageWrite(context *GoInk.Context) {\n\tif context.Method == \"POST\" {\n\t\tc := new(model.Content)\n\t\tc.Id = 0\n\t\tdata := context.Input()\n\t\tif !c.ChangeSlug(data[\"slug\"]) {\n\t\t\tJson(context, false).Set(\"msg\", \"固定链接重复\").End()\n\t\t\treturn\n\t\t}\n\t\tc.Title = data[\"title\"]\n\t\tc.Text = data[\"content\"]\n\t\tc.Tags = make([]string, 0)\n\t\tc.IsComment = data[\"comment\"] == \"1\"\n\t\tc.IsLinked = data[\"link\"] == \"1\"\n\t\tc.AuthorId, _ = strconv.Atoi(context.Cookie(\"token-user\"))\n\t\tc.Template = \"page.html\"\n\t\tc.Status = data[\"status\"]\n\t\tc.Format = \"markdown\"\n\t\tc.Hits = 1\n\t\tvar e error\n\t\tc, e = model.CreateContent(c, \"page\")\n\t\tif e != nil {\n\t\t\tJson(context, false).Set(\"msg\", e.Error()).End()\n\t\t\treturn\n\t\t}\n\t\tJson(context, true).Set(\"content\", c).End()\n\t\t//c.Type = \"article\"\n\t\tcontext.Do(\"page_created\", c)\n\t\treturn\n\t}\n\tcontext.Layout(\"admin/admin\")\n\tcontext.Render(\"admin/write_page\", map[string]interface{}{\n\t\t\"Title\": \"撰写页面\",\n\t})\n}\n\nfunc AdminPage(context *GoInk.Context) {\n\tpages, pager := model.GetPageList(context.Int(\"page\"), 10)\n\tcontext.Layout(\"admin/admin\")\n\tcontext.Render(\"admin/pages\", map[string]interface{}{\n\t\t\"Title\": \"页面\",\n\t\t\"Pages\": pages,\n\t\t\"Pager\": pager,\n\t})\n}\n\nfunc PageEdit(context *GoInk.Context) {\n\tid, _ := strconv.Atoi(context.Param(\"id\"))\n\tc := model.GetContentById(id)\n\tif c == nil {\n\t\tcontext.Redirect(\"/admin/pages/\")\n\t\treturn\n\t}\n\tif context.Method == \"DELETE\" {\n\t\tmodel.RemoveContent(c)\n\t\tJson(context, true).End()\n\t\treturn\n\t}\n\tif context.Method == \"POST\" {\n\t\tdata := context.Input()\n\t\tif !c.ChangeSlug(data[\"slug\"]) {\n\t\t\tJson(context, false).Set(\"msg\", \"固定链接重复\").End()\n\t\t\treturn\n\t\t}\n\t\tc.Title = data[\"title\"]\n\t\tc.Text = data[\"content\"]\n\t\t//c.Tags = strings.Split(strings.Replace(data[\"tag\"], \"，\", \",\", -1), \",\")\n\t\tc.IsComment = data[\"comment\"] == \"1\"\n\t\tc.IsLinked = data[\"link\"] == \"1\"\n\t\t//c.AuthorId, _ = strconv.Atoi(context.Cookie(\"token-user\"))\n\t\t//c.Template = \"blog.html\"\n\t\tc.Status = data[\"status\"]\n\t\t//c.Format = \"markdown\"\n\t\tmodel.SaveContent(c)\n\t\tJson(context, true).Set(\"content\", c).End()\n\t\tcontext.Do(\"page_modified\", c)\n\t\t//c.Type = \"article\"\n\t\treturn\n\t}\n\tcontext.Layout(\"admin/admin\")\n\tcontext.Render(\"admin/edit_page\", map[string]interface{}{\n\t\t\"Title\": \"编辑文章\",\n\t\t\"Page\":  c,\n\t})\n}\n\nfunc AdminSetting(context *GoInk.Context) {\n\tif context.Method == \"POST\" {\n\t\tdata := context.Input()\n\t\tfor k, v := range data {\n\t\t\tif v == \"\" {\n\t\t\t\tif data[k+\"_def\"] != \"\" {\n\t\t\t\t\tv = data[k+\"_def\"]\n\t\t\t\t}\n\t\t\t}\n\t\t\tmodel.SetSetting(k, v)\n\t\t}\n\t\tmodel.SyncSettings()\n\t\tJson(context, true).End()\n\t\tcontext.Do(\"setting_saved\")\n\t\treturn\n\t}\n\tcontext.Layout(\"admin/admin\")\n\tcontext.Render(\"admin/setting\", map[string]interface{}{\n\t\t\"Title\":      \"配置\",\n\t\t\"Custom\":     model.GetCustomSettings(),\n\t\t\"Navigators\": model.GetNavigators(),\n\t})\n}\n\nfunc CustomSetting(context *GoInk.Context) {\n\tkeys := context.Strings(\"key\")\n\tvalues := context.Strings(\"value\")\n\tfor i, k := range keys {\n\t\tif len(k) < 1 {\n\t\t\tcontinue\n\t\t}\n\t\tmodel.SetSetting(\"c_\"+k, values[i])\n\t}\n\tmodel.SyncSettings()\n\tJson(context, true).End()\n\tcontext.Do(\"setting_saved\")\n\treturn\n}\n\nfunc NavigatorSetting(context *GoInk.Context) {\n\torder := context.Strings(\"order\")\n\ttext := context.Strings(\"text\")\n\ttitle := context.Strings(\"title\")\n\tlink := context.Strings(\"link\")\n\tmodel.SetNavigators(order, text, title, link)\n\tJson(context, true).End()\n\tcontext.Do(\"setting_saved\")\n\treturn\n}\n\nfunc AdminComments(context *GoInk.Context) {\n\tif context.Method == \"DELETE\" {\n\t\tid := context.Int(\"id\")\n\t\tcmt := model.GetCommentById(id)\n\t\tmodel.RemoveComment(cmt.Cid, id)\n\t\tJson(context, true).End()\n\t\tcontext.Do(\"comment_delete\", id)\n\t\treturn\n\t}\n\tif context.Method == \"PUT\" {\n\t\tid := context.Int(\"id\")\n\t\tcmt2 := model.GetCommentById(id)\n\t\tcmt2.Status = \"approved\"\n\t\tcmt2.GetReader().Active = true\n\t\tmodel.SaveComment(cmt2)\n\t\tJson(context, true).End()\n\t\tcontext.Do(\"comment_change_status\", cmt2)\n\t\treturn\n\t}\n\tif context.Method == \"POST\" {\n\t\t// get required data\n\t\tpid := context.Int(\"pid\")\n\t\tcid := model.GetCommentById(pid).Cid\n\t\tuid, _ := strconv.Atoi(context.Cookie(\"token-user\"))\n\t\tuser := model.GetUserById(uid)\n\n\t\tco := new(model.Comment)\n\t\tco.Author = user.Nick\n\t\tco.Email = user.Email\n\t\tco.Url = user.Url\n\t\tco.Content = context.String(\"content\")\n\t\tco.Avatar = utils.Gravatar(co.Email, \"50\")\n\t\tco.Pid = pid\n\t\tco.Ip = context.Ip\n\t\tco.UserAgent = context.UserAgent\n\t\tco.IsAdmin = true\n\t\tmodel.CreateComment(cid, co)\n\t\tJson(context, true).Set(\"comment\", co.ToJson()).End()\n\t\tmodel.CreateMessage(\"comment\", co)\n\t\tcontext.Do(\"comment_reply\", co)\n\t\treturn\n\t}\n\tpage := context.IntOr(\"page\", 1)\n\tcomments, pager := model.GetCommentList(page, 10)\n\tcontext.Layout(\"admin/admin\")\n\tcontext.Render(\"admin/comments\", map[string]interface{}{\n\t\t\"Title\":    \"评论\",\n\t\t\"Comments\": comments,\n\t\t\"Pager\":    pager,\n\t})\n}\n\nfunc AdminPlugin(context *GoInk.Context) {\n\tif context.Method == \"POST\" {\n\t\taction := context.String(\"action\")\n\t\tif action == \"\" {\n\t\t\tJson(context, false).End()\n\t\t\treturn\n\t\t}\n\t\tpln := context.String(\"plugin\")\n\t\tif action == \"activate\" {\n\t\t\tplugin.Activate(pln)\n\t\t\tplugin.Update(context.App())\n\t\t\tJson(context, true).End()\n\t\t\tcontext.Do(\"plugin_activated\", pln)\n\t\t\treturn\n\t\t}\n\t\tif action == \"deactivate\" {\n\t\t\tplugin.Deactivate(pln)\n\t\t\tJson(context, true).End()\n\t\t\tcontext.Do(\"plugin_deactivated\", pln)\n\t\t\treturn\n\t\t}\n\t\tcontext.Status = 405\n\t\tJson(context, false).End()\n\t\treturn\n\t}\n\tcontext.Layout(\"admin/admin\")\n\tcontext.Render(\"admin/plugin\", map[string]interface{}{\n\t\t\"Title\":   \"插件\",\n\t\t\"Plugins\": plugin.GetPlugins(),\n\t})\n}\n\nfunc PluginSetting(context *GoInk.Context) {\n\tkey := context.Param(\"plugin_key\")\n\tif key == \"\" {\n\t\tcontext.Redirect(\"/admin/plugins/\")\n\t\treturn\n\t}\n\tp := plugin.GetPluginByKey(key)\n\tif p == nil {\n\t\tcontext.Redirect(\"/admin/plugins/\")\n\t\treturn\n\t}\n\tif context.Method == \"POST\" {\n\t\tp.SetSetting(context.Input())\n\t\tJson(context, true).End()\n\t\tcontext.Do(\"plugin_setting_saved\", p)\n\t\treturn\n\t}\n\tcontext.Layout(\"admin/admin\")\n\tcontext.Render(\"admin/plugin_setting\", map[string]interface{}{\n\t\t\"Title\": \"插件 - \" + p.Name(),\n\t\t\"Form\":  p.Form(),\n\t})\n}\n\nfunc AdminMessageRead(context *GoInk.Context) {\n\tid := context.Int(\"id\")\n\tif id < 0 {\n\t\tJson(context, false).End()\n\t\treturn\n\t}\n\tm := model.GetMessage(id)\n\tif m == nil {\n\t\tJson(context, false).End()\n\t\treturn\n\t}\n\tmodel.SaveMessageRead(m)\n\tJson(context, true).End()\n}\n"
  },
  {
    "path": "app/handler/cmd.go",
    "content": "package handler\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/cmd\"\n\t\"github.com/fuxiaohei/GoBlog/app/model\"\n\t\"github.com/fuxiaohei/GoInk\"\n)\n\nfunc CmdBackup(context *GoInk.Context) {\n\tif context.Method == \"POST\" {\n\t\tfile, e := cmd.DoBackup(context.App(), true)\n\t\tif e != nil {\n\t\t\tJson(context, false).Set(\"msg\", e.Error()).End()\n\t\t\treturn\n\t\t}\n\t\tJson(context, true).Set(\"file\", file).End()\n\t\tcontext.Do(\"bakcup_success\", file)\n\t\tmodel.CreateMessage(\"backup\", \"[1]\"+file)\n\t\treturn\n\t}\n\tif context.Method == \"DELETE\" {\n\t\tfile := context.String(\"file\")\n\t\tif file == \"\" {\n\t\t\tJson(context, false).End()\n\t\t\treturn\n\t\t}\n\t\tcmd.RemoveBackupFile(file)\n\t\tJson(context, true).End()\n\t\tcontext.Do(\"backup_delete\", file)\n\t\treturn\n\t}\n\tfiles, _ := cmd.GetBackupFiles()\n\tcontext.Layout(\"admin/cmd\")\n\tcontext.Render(\"admin/cmd/backup\", map[string]interface{}{\n\t\t\"Files\": files,\n\t\t\"Title\": \"备份\",\n\t})\n}\n\nfunc CmdBackupFile(context *GoInk.Context) {\n\tfile := context.String(\"file\")\n\tcontext.Download(cmd.GetBackupFileAbsPath(file))\n\tcontext.Do(\"backup_download\", file)\n}\n\nfunc CmdMessage(context *GoInk.Context) {\n\tcontext.Layout(\"admin/cmd\")\n\tcontext.Render(\"admin/cmd/message\", map[string]interface{}{\n\t\t\"Title\":    \"消息\",\n\t\t\"Messages\": model.GetMessages(),\n\t})\n}\n\nfunc CmdLogs(context *GoInk.Context) {\n\tif context.Method == \"DELETE\" {\n\t\tcmd.RemoveLogFile(context.App(), context.String(\"file\"))\n\t\tJson(context, true).End()\n\t\treturn\n\t}\n\tcontext.Layout(\"admin/cmd\")\n\tcontext.Render(\"admin/cmd/log\", map[string]interface{}{\n\t\t\"Title\": \"日志\",\n\t\t\"Logs\":  cmd.GetLogs(context.App()),\n\t})\n}\n\nfunc CmdMonitor(ctx *GoInk.Context) {\n\tctx.Layout(\"admin/cmd\")\n\tctx.Render(\"admin/cmd/monitor\", map[string]interface{}{\n\t\t\"Title\": \"系统监控\",\n\t\t\"M\":     cmd.ReadMemStats(),\n\t})\n}\n\nfunc CmdTheme(ctx *GoInk.Context) {\n\tif ctx.Method == \"POST\" {\n\t\tchange := ctx.String(\"cache\")\n\t\tif change != \"\" {\n\t\t\tcmd.SetThemeCache(ctx, change == \"true\")\n\t\t\tJson(ctx, true).End()\n\t\t\treturn\n\t\t}\n\t\ttheme := ctx.String(\"theme\")\n\t\tif theme != \"\" {\n\t\t\tmodel.SetSetting(\"site_theme\", theme)\n\t\t\tmodel.SyncSettings()\n\t\t\tJson(ctx, true).End()\n\t\t\treturn\n\t\t}\n\t\treturn\n\t}\n\tctx.Layout(\"admin/cmd\")\n\tctx.Render(\"admin/cmd/theme\", map[string]interface{}{\n\t\t\"Title\":        \"主题\",\n\t\t\"Themes\":       cmd.GetThemes(ctx.App().Get(\"view_dir\")),\n\t\t\"CurrentTheme\": model.GetSetting(\"site_theme\"),\n\t})\n}\n\nfunc CmdReader(ctx *GoInk.Context) {\n\tif ctx.Method == \"POST\" {\n\t\temail := ctx.String(\"email\")\n\t\tmodel.RemoveReader(email)\n\t\tJson(ctx, true).End()\n\t\treturn\n\t}\n\tctx.Layout(\"admin/cmd\")\n\tctx.Render(\"admin/cmd/reader\", map[string]interface{}{\n\t\t\"Title\":   \"读者\",\n\t\t\"Readers\": model.GetReaders(),\n\t})\n}\n"
  },
  {
    "path": "app/handler/func.go",
    "content": "package handler\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/model\"\n\t\"github.com/fuxiaohei/GoInk\"\n\t\"path\"\n\t\"strconv\"\n)\n\ntype jsonContext struct {\n\tcontext *GoInk.Context\n\tdata    map[string]interface{}\n}\n\n// Json creates a json context response.\nfunc Json(context *GoInk.Context, res bool) *jsonContext {\n\tc := new(jsonContext)\n\tc.context = context\n\tc.data = make(map[string]interface{})\n\tc.data[\"res\"] = res\n\treturn c\n}\n\nfunc (jc *jsonContext) Set(key string, v interface{}) *jsonContext {\n\tjc.data[key] = v\n\treturn jc\n}\n\nfunc (jc *jsonContext) End() {\n\tjc.context.Json(jc.data)\n}\n\ntype themeContext struct {\n\tcontext *GoInk.Context\n\ttheme   string\n}\n\n// Theme creates themed context response.\nfunc Theme(context *GoInk.Context) *themeContext {\n\tt := new(themeContext)\n\tt.context = context\n\tt.theme = model.GetSetting(\"site_theme\")\n\tif t.theme == \"\" {\n\t\tt.theme = \"default\"\n\t}\n\treturn t\n}\n\nfunc (tc *themeContext) Layout(layout string) *themeContext {\n\tif layout == \"\" {\n\t\ttc.context.Layout(\"\")\n\t\treturn tc\n\t}\n\ttc.context.Layout(path.Join(tc.theme, layout))\n\treturn tc\n}\n\nfunc (tc *themeContext) Render(tpl string, data map[string]interface{}) {\n\ttc.context.Render(path.Join(tc.theme, tpl), data)\n}\n\nfunc (tc *themeContext) Tpl(tpl string, data map[string]interface{}) string {\n\treturn tc.context.Tpl(path.Join(tc.theme, tpl), data)\n}\n\nfunc (tc *themeContext) Has(tpl string) bool {\n\tfile := path.Join(tc.theme, tpl)\n\treturn tc.context.App().View().Has(file)\n}\n\n// CommentHtml returns rendered comment template html with own content.\nfunc CommentHtml(context *GoInk.Context, c *model.Content) string {\n\tthm := Theme(context)\n\tif !thm.Has(\"comment.html\") {\n\t\treturn \"\"\n\t}\n\treturn thm.Tpl(\"comment\", map[string]interface{}{\n\t\t\"Content\":  c,\n\t\t\"Comments\": c.Comments,\n\t})\n}\n\n// SidebarHtml returns rendered sidebar template html.\nfunc SidebarHtml(context *GoInk.Context) string {\n\tthm := Theme(context)\n\tif !thm.Has(\"sidebar.html\") {\n\t\treturn \"\"\n\t}\n\tpopSize, _ := strconv.Atoi(model.GetSetting(\"popular_size\"))\n\tif popSize < 1 {\n\t\tpopSize = 4\n\t}\n\tcmtSize, _ := strconv.Atoi(model.GetSetting(\"recent_comment_size\"))\n\tif cmtSize < 1 {\n\t\tcmtSize = 3\n\t}\n\treturn thm.Tpl(\"sidebar\", map[string]interface{}{\n\t\t\"Popular\":       model.GetPopularArticleList(popSize),\n\t\t\"RecentComment\": model.GetCommentRecentList(cmtSize),\n\t\t\"Tags\":          model.GetContentTags(),\n\t})\n}\n"
  },
  {
    "path": "app/handler/home.go",
    "content": "package handler\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/model\"\n\t\"github.com/fuxiaohei/GoBlog/app/utils\"\n\t\"github.com/fuxiaohei/GoInk\"\n\t\"net/url\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc Login(context *GoInk.Context) {\n\tif context.Method == \"POST\" {\n\t\tdata := context.Input()\n\t\tuser := model.GetUserByName(data[\"user\"])\n\t\tif user == nil {\n\t\t\tJson(context, false).End()\n\t\t\treturn\n\t\t}\n\t\tif !user.CheckPassword(data[\"password\"]) {\n\t\t\tJson(context, false).End()\n\t\t\treturn\n\t\t}\n\t\texp := 3600 * 24 * 3\n\t\texpStr := strconv.Itoa(exp)\n\t\ts := model.CreateToken(user, context, int64(exp))\n\t\tcontext.Cookie(\"token-user\", strconv.Itoa(s.UserId), expStr)\n\t\tcontext.Cookie(\"token-value\", s.Value, expStr)\n\t\tJson(context, true).End()\n\t\treturn\n\t}\n\tif context.Cookie(\"token-value\") != \"\" {\n\t\tcontext.Redirect(\"/admin/\")\n\t\treturn\n\t}\n\tcontext.Render(\"admin/login\", nil)\n}\n\nfunc Auth(context *GoInk.Context) {\n\ttokenValue := context.Cookie(\"token-value\")\n\ttoken := model.GetTokenByValue(tokenValue)\n\tif token == nil {\n\t\tcontext.Redirect(\"/logout/\")\n\t\tcontext.End()\n\t\treturn\n\t}\n\tif !token.IsValid() {\n\t\tcontext.Redirect(\"/logout/\")\n\t\tcontext.End()\n\t\treturn\n\t}\n}\n\nfunc Logout(context *GoInk.Context) {\n\tcontext.Cookie(\"token-user\", \"\", \"-3600\")\n\tcontext.Cookie(\"token-value\", \"\", \"-3600\")\n\tcontext.Redirect(\"/login/\")\n}\n\nfunc TagArticles(ctx *GoInk.Context) {\n\tctx.Layout(\"home\")\n\tpage, _ := strconv.Atoi(ctx.Param(\"page\"))\n\ttag, _ := url.QueryUnescape(ctx.Param(\"tag\"))\n\tsize := getArticleListSize()\n\tarticles, pager := model.GetTaggedArticleList(tag, page, getArticleListSize())\n\t// fix dotted tag\n\tif len(articles) < 1 && strings.Contains(tag, \"-\") {\n\t\tarticles, pager = model.GetTaggedArticleList(strings.Replace(tag, \"-\", \".\", -1), page, size)\n\t}\n\tTheme(ctx).Layout(\"home\").Render(\"index\", map[string]interface{}{\n\t\t\"Articles\":    articles,\n\t\t\"Pager\":       pager,\n\t\t\"SidebarHtml\": SidebarHtml(ctx),\n\t\t\"Tag\":         tag,\n\t\t\"Title\":       tag,\n\t})\n}\n\nfunc Home(context *GoInk.Context) {\n\tcontext.Layout(\"home\")\n\tpage, _ := strconv.Atoi(context.Param(\"page\"))\n\tarticles, pager := model.GetPublishArticleList(page, getArticleListSize())\n\tdata := map[string]interface{}{\n\t\t\"Articles\":    articles,\n\t\t\"Pager\":       pager,\n\t\t\"SidebarHtml\": SidebarHtml(context),\n\t}\n\tif page > 1 {\n\t\tdata[\"Title\"] = \"第 \" + strconv.Itoa(page) + \" 页\"\n\t}\n\tTheme(context).Layout(\"home\").Render(\"index\", data)\n}\n\nfunc Article(context *GoInk.Context) {\n\tid, _ := strconv.Atoi(context.Param(\"id\"))\n\tslug := context.Param(\"slug\")\n\tarticle := model.GetContentById(id)\n\tif article == nil {\n\t\tcontext.Redirect(\"/\")\n\t\treturn\n\t}\n\tif article.Slug != slug || article.Type != \"article\" {\n\t\tcontext.Redirect(\"/\")\n\t\treturn\n\t}\n\tarticle.Hits++\n\tTheme(context).Layout(\"home\").Render(\"article\", map[string]interface{}{\n\t\t\"Title\":       article.Title,\n\t\t\"Article\":     article,\n\t\t\"CommentHtml\": CommentHtml(context, article),\n\t})\n}\n\nfunc Page(context *GoInk.Context) {\n\tid, _ := strconv.Atoi(context.Param(\"id\"))\n\tslug := context.Param(\"slug\")\n\tarticle := model.GetContentById(id)\n\tif article == nil || article.Status != \"publish\" {\n\t\tcontext.Redirect(\"/\")\n\t\treturn\n\t}\n\tif article.Slug != slug || article.Type != \"page\" {\n\t\tcontext.Redirect(\"/\")\n\t\treturn\n\t}\n\tarticle.Hits++\n\tTheme(context).Layout(\"home\").Render(\"page\", map[string]interface{}{\n\t\t\"Title\": article.Title,\n\t\t\"Page\":  article,\n\t\t//\"CommentHtml\": Comments(context, article),\n\t})\n}\n\nfunc TopPage(context *GoInk.Context) {\n\tslug := context.Param(\"slug\")\n\tpage := model.GetContentBySlug(slug)\n\tif page == nil || page.Status != \"publish\" {\n\t\tcontext.Redirect(\"/\")\n\t\treturn\n\t}\n\tif page.IsLinked && page.Type == \"page\" {\n\t\tTheme(context).Layout(\"home\").Render(\"page\", map[string]interface{}{\n\t\t\t\"Title\": page.Title,\n\t\t\t\"Page\":  page,\n\t\t})\n\t\tpage.Hits++\n\t\treturn\n\t}\n\tcontext.Redirect(\"/\")\n}\n\nfunc Comment(context *GoInk.Context) {\n\tcid, _ := strconv.Atoi(context.Param(\"id\"))\n\tif cid < 1 {\n\t\tJson(context, false).End()\n\t\treturn\n\t}\n\tif model.GetContentById(cid) == nil {\n\t\tJson(context, false).End()\n\t\treturn\n\t}\n\tdata := context.Input()\n\tmsg := validateComment(data)\n\tif msg != \"\" {\n\t\tJson(context, false).Set(\"msg\", msg).End()\n\t\treturn\n\t}\n\tco := new(model.Comment)\n\tco.Author = data[\"user\"]\n\tco.Email = data[\"email\"]\n\tco.Url = data[\"url\"]\n\tco.Content = data[\"content\"]\n\tco.Avatar = utils.Gravatar(co.Email, \"50\")\n\tco.Pid, _ = strconv.Atoi(data[\"pid\"])\n\tco.Ip = context.Ip\n\tco.UserAgent = context.UserAgent\n\tco.IsAdmin = false\n\tmodel.CreateComment(cid, co)\n\tJson(context, true).Set(\"comment\", co.ToJson()).End()\n\tmodel.CreateMessage(\"comment\", co)\n\tcontext.Do(\"comment_created\", co)\n}\n\nfunc validateComment(data map[string]string) string {\n\tif utils.IsEmptyString(data[\"user\"]) || utils.IsEmptyString(data[\"content\"]) {\n\t\treturn \"称呼，邮箱，内容必填\"\n\t}\n\tif !utils.IsEmail(data[\"email\"]) {\n\t\treturn \"邮箱格式错误\"\n\t}\n\tif !utils.IsEmptyString(data[\"url\"]) && !utils.IsURL(data[\"url\"]) {\n\t\treturn \"网址格式错误\"\n\t}\n\treturn \"\"\n}\n\nfunc getArticleListSize() int {\n\tsize, _ := strconv.Atoi(model.GetSetting(\"article_size\"))\n\tif size < 1 {\n\t\tsize = 5\n\t}\n\treturn size\n}\n"
  },
  {
    "path": "app/handler/rss.go",
    "content": "package handler\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/model\"\n\t\"github.com/fuxiaohei/GoBlog/app/utils\"\n\t\"github.com/fuxiaohei/GoInk\"\n\t\"strings\"\n\t\"time\"\n)\n\nfunc SiteMap(ctx *GoInk.Context) {\n\tbaseUrl := model.GetSetting(\"site_url\")\n\tprintln(baseUrl)\n\tarticle, _ := model.GetPublishArticleList(1, 50)\n\tnavigators := model.GetNavigators()\n\tnow := time.Unix(utils.Now(), 0).Format(time.RFC3339)\n\n\tarticleMap := make([]map[string]string, len(article))\n\tfor i, a := range article {\n\t\tm := make(map[string]string)\n\t\tm[\"Link\"] = strings.Replace(baseUrl+a.Link(), baseUrl+\"/\", baseUrl, -1)\n\t\tm[\"Created\"] = time.Unix(a.CreateTime, 0).Format(time.RFC3339)\n\t\tarticleMap[i] = m\n\t}\n\n\tnavMap := make([]map[string]string, 0)\n\tfor _, n := range navigators {\n\t\tm := make(map[string]string)\n\t\tif n.Link == \"/\" {\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(n.Link, \"/\") {\n\t\t\tm[\"Link\"] = strings.Replace(baseUrl+n.Link, baseUrl+\"/\", baseUrl, -1)\n\t\t} else {\n\t\t\tm[\"Link\"] = n.Link\n\t\t}\n\t\tm[\"Created\"] = now\n\t\tnavMap = append(navMap, m)\n\t}\n\n\tctx.ContentType(\"text/xml\")\n\tbytes, e := ctx.App().View().Render(\"sitemap.xml\", map[string]interface{}{\n\t\t\"Title\":      model.GetSetting(\"site_title\"),\n\t\t\"Link\":       baseUrl,\n\t\t\"Created\":    now,\n\t\t\"Articles\":   articleMap,\n\t\t\"Navigators\": navMap,\n\t})\n\tif e != nil {\n\t\tpanic(e)\n\t}\n\tctx.Body = bytes\n\n}\n\nfunc Rss(ctx *GoInk.Context) {\n\tbaseUrl := model.GetSetting(\"site_url\")\n\tarticle, _ := model.GetPublishArticleList(1, 20)\n\tauthor := model.GetUsersByRole(\"ADMIN\")[0]\n\n\tarticleMap := make([]map[string]string, len(article))\n\tfor i, a := range article {\n\t\tm := make(map[string]string)\n\t\tm[\"Title\"] = a.Title\n\t\tm[\"Link\"] = strings.Replace(baseUrl+a.Link(), baseUrl+\"/\", baseUrl, -1)\n\t\tm[\"Author\"] = author.Nick\n\t\tstr := utils.Markdown2Html(a.Content())\n\t\tstr = strings.Replace(str, `src=\"/`, `src=\"`+strings.TrimSuffix(baseUrl, \"/\")+\"/\", -1)\n\t\tstr = strings.Replace(str, `href=\"/`, `href=\"`+strings.TrimSuffix(baseUrl, \"/\")+\"/\", -1)\n\t\tm[\"Desc\"] = str\n\t\tm[\"Created\"] = time.Unix(a.CreateTime, 0).Format(time.RFC822)\n\t\tarticleMap[i] = m\n\t}\n\n\tctx.ContentType(\"application/rss+xml;charset=UTF-8\")\n\n\tbytes, e := ctx.App().View().Render(\"rss.xml\", map[string]interface{}{\n\t\t\"Title\":    model.GetSetting(\"site_title\"),\n\t\t\"Link\":     baseUrl,\n\t\t\"Desc\":     model.GetSetting(\"site_description\"),\n\t\t\"Created\":  time.Unix(utils.Now(), 0).Format(time.RFC822),\n\t\t\"Articles\": articleMap,\n\t})\n\tif e != nil {\n\t\tpanic(e)\n\t}\n\tctx.Body = bytes\n}\n"
  },
  {
    "path": "app/handler/upload.go",
    "content": "package handler\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/model\"\n\t\"github.com/fuxiaohei/GoInk\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"os\"\n\t\"path\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc AdminFiles(context *GoInk.Context) {\n\tif context.Method == \"DELETE\" {\n\t\tid := context.Int(\"id\")\n\t\tmodel.RemoveFile(id)\n\t\tJson(context, true).End()\n\t\tcontext.Do(\"attach_delete\", id)\n\t\treturn\n\t}\n\tfiles, pager := model.GetFileList(context.Int(\"page\"), 10)\n\tcontext.Layout(\"admin/admin\")\n\tcontext.Render(\"admin/files\", map[string]interface{}{\n\t\t\"Title\": \"媒体文件\",\n\t\t\"Files\": files,\n\t\t\"Pager\": pager,\n\t})\n}\n\nfunc FileUpload(context *GoInk.Context) {\n\tvar req *http.Request\n\treq = context.Request\n\treq.ParseMultipartForm(32 << 20)\n\tf, h, e := req.FormFile(\"file\")\n\tif e != nil {\n\t\tJson(context, false).Set(\"msg\", e.Error()).End()\n\t\treturn\n\t}\n\tdata, _ := ioutil.ReadAll(f)\n\tmaxSize := context.App().Config().Int(\"app.upload_size\")\n\tdefer func() {\n\t\tf.Close()\n\t\tdata = nil\n\t\th = nil\n\t}()\n\tif len(data) >= maxSize {\n\t\tJson(context, false).Set(\"msg\", \"文件应小于10M\").End()\n\t\treturn\n\t}\n\tif !strings.Contains(context.App().Config().String(\"app.upload_files\"), path.Ext(h.Filename)) {\n\t\tJson(context, false).Set(\"msg\", \"文件只支持Office文件，图片和zip存档\").End()\n\t\treturn\n\t}\n\tff := new(model.File)\n\tff.Name = h.Filename\n\tff.Type = context.StringOr(\"type\", \"image\")\n\tff.Size = int64(len(data))\n\tff.ContentType = h.Header[\"Content-Type\"][0]\n\tff.Author, _ = strconv.Atoi(context.Cookie(\"token-user\"))\n\tff.Url = model.CreateFilePath(context.App().Get(\"upload_dir\"), ff)\n\te = ioutil.WriteFile(ff.Url, data, os.ModePerm)\n\tif e != nil {\n\t\tJson(context, false).Set(\"msg\", e.Error()).End()\n\t\treturn\n\t}\n\tmodel.CreateFile(ff)\n\tJson(context, true).Set(\"file\", ff).End()\n\tcontext.Do(\"attach_created\", ff)\n}\n"
  },
  {
    "path": "app/log.go",
    "content": "package app\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/utils\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path\"\n)\n\n// LogErrors logs error bytes to tmp/log directory.\nfunc LogError(bytes []byte) {\n\tdir := App.Config().String(\"app.log_dir\")\n\tfile := path.Join(dir, utils.DateInt64(utils.Now(), \"MMDDHHmmss.log\"))\n\tioutil.WriteFile(file, bytes, os.ModePerm)\n}\n"
  },
  {
    "path": "app/model/article.go",
    "content": "package model\n\nimport \"github.com/fuxiaohei/GoBlog/app/utils\"\n\nfunc generatePublishArticleIndex() {\n\tarr := make([]int, 0)\n\tfor _, id := range contentsIndex[\"article\"] {\n\t\tc := GetContentById(id)\n\t\tif c.Status == \"publish\" {\n\t\t\tarr = append(arr, id)\n\t\t}\n\t}\n\tcontentsIndex[\"article-publish\"] = arr\n}\n\n// GetPublishArticleList gets published article list and pager.\nfunc GetPublishArticleList(page, size int) ([]*Content, *utils.Pager) {\n\tindex := contentsIndex[\"article-publish\"]\n\tpager := utils.NewPager(page, size, len(index))\n\tarticles := make([]*Content, 0)\n\tif len(index) < 1 {\n\t\treturn articles, pager\n\t}\n\tif page > pager.Pages {\n\t\treturn articles, pager\n\t}\n\tfor i := pager.Begin; i <= pager.End; i++ {\n\t\tarticles = append(articles, GetContentById(index[i-1]))\n\t}\n\treturn articles, pager\n}\n\n// GetArticleList gets articles list and pager no matter article status.\nfunc GetArticleList(page, size int) ([]*Content, *utils.Pager) {\n\tindex := contentsIndex[\"article\"]\n\tpager := utils.NewPager(page, size, len(index))\n\tarticles := make([]*Content, 0)\n\tif len(index) < 1 {\n\t\treturn articles, pager\n\t}\n\tif page > pager.Pages {\n\t\treturn articles, pager\n\t}\n\tfor i := pager.Begin; i <= pager.End; i++ {\n\t\tarticles = append(articles, GetContentById(index[i-1]))\n\t}\n\treturn articles, pager\n}\n\n// GetPopularArticleList returns popular articles list.\n// Popular articles are ordered by comment number.\nfunc GetPopularArticleList(size int) []*Content {\n\tindex := contentsIndex[\"article-pop\"]\n\tpager := utils.NewPager(1, size, len(index))\n\tarticles := make([]*Content, 0)\n\tif len(index) < 1 {\n\t\treturn articles\n\t}\n\tif 1 > pager.Pages {\n\t\treturn articles\n\t}\n\tfor i := pager.Begin; i <= pager.End; i++ {\n\t\tarticles = append(articles, GetContentById(index[i-1]))\n\t}\n\treturn articles\n}\n\n// GetTaggedArticleList returns tagged articles list.\n// These articles contains same one tag.\nfunc GetTaggedArticleList(tag string, page, size int) ([]*Content, *utils.Pager) {\n\tindex := contentsIndex[\"t-\"+tag]\n\tpager := utils.NewPager(page, size, len(index))\n\tarticles := make([]*Content, 0)\n\tif len(index) < 1 {\n\t\treturn articles, pager\n\t}\n\tif page > pager.Pages {\n\t\treturn articles, pager\n\t}\n\tfor i := pager.Begin; i <= pager.End; i++ {\n\t\tarticles = append(articles, GetContentById(index[i-1]))\n\t}\n\treturn articles, pager\n}\n"
  },
  {
    "path": "app/model/comment.go",
    "content": "package model\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/utils\"\n\t\"html/template\"\n\t\"sort\"\n\t\"strings\"\n)\n\nvar (\n\treaders       map[string]*Reader\n\tcomments      map[int]*Comment\n\tcommentsIndex []int\n\tcommentMaxId  int\n)\n\n// Comment Reader struct.\n// Saving comment reader for visiting wall usage or other statics.\ntype Reader struct {\n\tAuthor   string\n\tEmail    string\n\tUrl      string\n\tActive   bool\n\tComments int\n\tRank     int\n}\n\n// Inc increases Reader's rank.\nfunc (r *Reader) Inc() {\n\tr.Rank++\n\tif r.Rank > 1 {\n\t\tr.Active = true\n\t}\n}\n\n// Dec decreases Reader's rank.\nfunc (r *Reader) Dec() {\n\tr.Rank--\n\tif r.Rank < 1 {\n\t\tr.Active = false\n\t}\n}\n\n// Comment struct defines a comment item data.\ntype Comment struct {\n\tId         int\n\tAuthor     string\n\tEmail      string\n\tUrl        string\n\tAvatar     string\n\tContent    string\n\tCreateTime int64\n\t// Content id\n\tCid int\n\t// Parent Comment id\n\tPid       int\n\tStatus    string\n\tIp        string\n\tUserAgent string\n\t// Is comment of admin\n\tIsAdmin bool\n}\n\n// ParentMd returns parent comment simple message as markdown text.\nfunc (c *Comment) ParentMd() string {\n\tif c.Pid < 1 {\n\t\treturn \"\"\n\t}\n\tco := GetCommentById(c.Pid)\n\tif co == nil {\n\t\treturn \"> 已失效\"\n\t}\n\tstr := \"> @\" + co.Author + \"\\n\\n\"\n\tstr += \"> \" + co.Content + \"\\n\"\n\treturn str\n}\n\n// ToJson converts comment struct to public json map.\n// It can hide some private fields, such as email.\nfunc (c *Comment) ToJson() map[string]interface{} {\n\tm := make(map[string]interface{})\n\tm[\"id\"] = c.Id\n\tm[\"author\"] = c.Author\n\t//m[\"email\"] = c.Email\n\tm[\"url\"] = c.Url\n\tm[\"avatar\"] = c.Avatar\n\tm[\"content\"] = c.Content\n\tm[\"create_time\"] = c.CreateTime\n\tm[\"pid\"] = c.Pid\n\tm[\"status\"] = c.Status\n\tm[\"ip\"] = c.Ip\n\tm[\"user_agent\"] = c.UserAgent\n\tm[\"parent_md\"] = c.ParentMd()\n\treturn m\n}\n\n// IsValid returns whether this comment is valid to show.\n// If this comment is not approved or its parent is missing, return false.\nfunc (c *Comment) IsValid() bool {\n\tif c.Status != \"approved\" {\n\t\treturn false\n\t}\n\tif c.Pid > 0 {\n\t\tif GetCommentById(c.Pid) == nil {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// IsRemovable returns whether this comment can remove.\n// If content or parent comment of this comment is removed, return true.\nfunc (c *Comment) IsRemovable() bool {\n\tif GetContentById(c.Cid) == nil {\n\t\treturn true\n\t}\n\tif c.Pid > 0 {\n\t\tif GetCommentById(c.Pid) == nil {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// GetReader returns the reader item of this comment.\nfunc (c *Comment) GetReader() *Reader {\n\tfor _, r := range readers {\n\t\tif r.Email == c.Email {\n\t\t\treturn r\n\t\t}\n\t}\n\treturn nil\n}\n\n// GetContent returns the content item of this comment.\nfunc (c *Comment) GetContent() *Content {\n\treturn GetContentById(c.Cid)\n}\n\n// CreateReader creates a reader from a comment.\nfunc CreateReader(c *Comment) {\n\tr := new(Reader)\n\tr.Author = c.Author\n\tr.Email = c.Email\n\tr.Url = c.Url\n\tr.Active = false\n\tr.Comments = 1\n\tr.Rank = 0\n\treaders[r.Email] = r\n\tgo SyncReaders()\n}\n\n// CreateComment creates a comment and links it to the cid content.\nfunc CreateComment(cid int, c *Comment) {\n\tcommentMaxId += Storage.TimeInc(4)\n\tc.Id = commentMaxId\n\tc.CreateTime = utils.Now()\n\tc.Status = \"check\"\n\tc.Cid = cid\n\t// escape content\n\tc.Content = strings.Replace(utils.Html2str(template.HTMLEscapeString(c.Content)), \"\\n\", \"<br/>\", -1)\n\t// if empty url, use # instead.\n\tif c.Url == \"\" {\n\t\tc.Url = \"#\"\n\t}\n\t// if admin comment, must be approved.\n\tif c.IsAdmin {\n\t\tc.Status = \"approved\"\n\t} else {\n\t\t// if common comment, get reader status for checking status.\n\t\tr := c.GetReader()\n\t\tif r != nil {\n\t\t\tif r.Active {\n\t\t\t\tc.Status = \"approved\"\n\t\t\t}\n\t\t} else {\n\t\t\tCreateReader(c)\n\t\t}\n\t}\n\t// update comment memory data\n\tcomments[c.Id] = c\n\tcommentsIndex = append([]int{c.Id}, commentsIndex...)\n\t// append to content\n\tcontent := GetContentById(cid)\n\tcontent.Comments = append(content.Comments, c)\n\tgo SyncContent(content)\n}\n\n// SaveComment saves a comment and related updates content and reader data.\nfunc SaveComment(c *Comment) {\n\tcnt := GetContentById(c.Cid)\n\tgo SyncContent(cnt)\n\tgo SyncReaders()\n}\n\nfunc removeOneComment(cid int, id int) {\n\tdelete(comments, id)\n\tfor n, c := range commentsIndex {\n\t\tif c == id {\n\t\t\tcommentsIndex = append(commentsIndex[:n], commentsIndex[n+1:]...)\n\t\t\tbreak\n\t\t}\n\t}\n\tcnt := GetContentById(cid)\n\tif cnt == nil {\n\t\treturn\n\t}\n\tfor n, c := range cnt.Comments {\n\t\tif c.Id == id {\n\t\t\tcnt.Comments = append(cnt.Comments[:n], cnt.Comments[n+1:]...)\n\t\t}\n\t}\n}\n\n// RemoveComment removes a comment by id and updates content iten by cid.\nfunc RemoveComment(cid int, id int) {\n\tremoveOneComment(cid, id)\n\tcnt := GetContentById(cid)\n\tif cnt == nil {\n\t\treturn\n\t}\n\tgo SyncContent(cnt)\n}\n\n// GetCommentById returns a comment by id.\nfunc GetCommentById(id int) *Comment {\n\treturn comments[id]\n}\n\n// GetCommentList returns a comments list and pager.\n// This list scans all comments no matter its status.\nfunc GetCommentList(page, size int) ([]*Comment, *utils.Pager) {\n\tindex := commentsIndex\n\tpager := utils.NewPager(page, size, len(index))\n\tcomments := make([]*Comment, 0)\n\tif page > pager.Pages {\n\t\treturn comments, pager\n\t}\n\tfor i := pager.Begin; i <= pager.End; i++ {\n\t\tcomments = append(comments, GetCommentById(index[i-1]))\n\t}\n\treturn comments, pager\n}\n\n// GetCommentRecentList returns a comments list of recent comments.\n// Recent comments are approved and no parent and not admin comment.\n// It's ordered by comment id desc.\nfunc GetCommentRecentList(size int) []*Comment {\n\tcomments, i := make([]*Comment, 0), 0\n\tfor _, id := range commentsIndex {\n\t\tif i >= size {\n\t\t\treturn comments\n\t\t}\n\t\tc := GetCommentById(id)\n\t\tif c.Pid < 1 && c.IsAdmin == false && c.Status == \"approved\" {\n\t\t\tcomments = append(comments, c)\n\t\t\ti++\n\t\t}\n\t}\n\treturn comments\n}\n\n// SyncReaders writes all readers data.\nfunc SyncReaders() {\n\tStorage.Set(\"readers\", readers)\n}\n\n// LoadReaders loads all readers from storage json.\nfunc LoadReaders() {\n\treaders = make(map[string]*Reader)\n\tStorage.Get(\"readers\", &readers)\n}\n\n// GetReaders returns slice of all readers\nfunc GetReaders() []*Reader {\n\tr, i := make([]*Reader, len(readers)), 0\n\tfor _, rd := range readers {\n\t\tr[i] = rd\n\t\ti++\n\t}\n\treturn r\n}\n\n// RemoveReader removes a reader by his email.\nfunc RemoveReader(email string) {\n\tdelete(readers, email)\n\tSyncReaders()\n}\n\n// LoadComments loads all comments from contents.\nfunc LoadComments() {\n\tcomments = make(map[int]*Comment)\n\tcommentsIndex = make([]int, 0)\n\tcommentMaxId = 0\n\tfor _, c := range contents {\n\t\tif len(c.Comments) < 1 {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, cm := range c.Comments {\n\t\t\tcomments[cm.Id] = cm\n\t\t\tcommentsIndex = append(commentsIndex, cm.Id)\n\t\t\tif cm.Id > commentMaxId {\n\t\t\t\tcommentMaxId = cm.Id\n\t\t\t}\n\t\t}\n\t}\n\tsort.Sort(sort.Reverse(sort.IntSlice(commentsIndex)))\n}\n\n// UpdateCommentAdmin updates comment author data if admin user data updated.\n// It only updates admin comments.\nfunc UpdateCommentAdmin(user *User) {\n\tfor _, co := range comments {\n\t\tif co.IsAdmin {\n\t\t\tco.Author = user.Nick\n\t\t\tco.Email = user.Email\n\t\t\tco.Url = user.Url\n\t\t\tco.Avatar = utils.Gravatar(co.Email, \"50\")\n\t\t}\n\t}\n}\n\n// RecycleComments cleans removable comments.\nfunc RecycleComments() {\n\treaderTmp := make(map[string][]int)\n\tfor _, co := range comments {\n\t\tif co.IsRemovable() {\n\t\t\tremoveOneComment(co.Cid, co.Id)\n\t\t\tcontinue\n\t\t}\n\t\tr := co.GetReader()\n\t\tif r == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif _, ok := readerTmp[r.Email]; !ok {\n\t\t\treaderTmp[r.Email] = make([]int, 0)\n\t\t}\n\t\treaderTmp[r.Email] = append(readerTmp[r.Email], co.Id)\n\t}\n\tfor _, r := range readers {\n\t\tif _, ok := readerTmp[r.Email]; ok {\n\t\t\tr.Comments = len(readerTmp[r.Email])\n\t\t}\n\t}\n\tSyncContents()\n\tSyncReaders()\n}\n\nfunc startCommentsTimer() {\n\tSetTimerFunc(\"comment-recycle\", 36, func() {\n\t\tprintln(\"recycle comments in 6 hours timer\")\n\t\tRecycleComments()\n\t})\n}\n"
  },
  {
    "path": "app/model/content.go",
    "content": "package model\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"github.com/fuxiaohei/GoBlog/app/utils\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strings\"\n)\n\nvar (\n\tcontents      map[int]*Content\n\tcontentMaxId  int\n\tcontentsIndex map[string][]int\n\ttags          []*Tag\n)\n\n// Content instance, defines content data items.\ntype Content struct {\n\tId    int\n\tTitle string\n\tSlug  string\n\tText  string\n\t// Rendered string\n\ttextRendered string\n\t//Category   string\n\tTags []string\n\n\tCreateTime int64\n\tEditTime   int64\n\tUpdateTime int64\n\n\t// IsComment opens or closes comment\n\tIsComment bool\n\t// IsLinked makes pager link as top level link /link.html\n\tIsLinked bool\n\t//IsTop     bool\n\n\tAuthorId int\n\n\t// Template makes pager use own template file\n\tTemplate string\n\n\tType   string\n\tStatus string\n\n\t// Format defines the content text format type. Now only support markdown.\n\tFormat string\n\n\tComments []*Comment\n\tHits     int\n}\n\n// TagString returns content tags in a string that's joined by \",\".\nfunc (cnt *Content) TagString() string {\n\treturn strings.Join(cnt.Tags, \",\")\n}\n\n// GetTags returns tags struct in this content.\nfunc (cnt *Content) GetTags() []*Tag {\n\ttgs := make([]*Tag, len(cnt.Tags))\n\tfor i, t := range cnt.Tags {\n\t\ttgs[i] = &Tag{Name: t}\n\t}\n\treturn tgs\n}\n\n// Link returns content link as {type}/{id}/{slug}.html.\n// If content isn't published, return \"#\".\n// If content is page and top linked, return {slug}.html as top level link.\nfunc (cnt *Content) Link() string {\n\tif cnt.Status != \"publish\" {\n\t\treturn \"#\"\n\t}\n\tif cnt.IsLinked {\n\t\treturn \"/\" + cnt.Slug + \".html\"\n\t}\n\treturn fmt.Sprintf(\"/%s/%d/%s.html\", cnt.Type, cnt.Id, cnt.Slug)\n}\n\n// Content returns whole content text.\n// If enable go-markdown, return markdown-rendered content.\nfunc (cnt *Content) Content() string {\n\ttxt := strings.Replace(cnt.Text, \"<!--more-->\", \"\", -1)\n\tif GetSetting(\"enable_go_markdown\") == \"true\" {\n\t\tif cnt.textRendered == \"\" {\n\t\t\tcnt.textRendered = utils.Markdown2Html(txt)\n\t\t}\n\t\treturn cnt.textRendered\n\t}\n\treturn txt\n}\n\n// Summary returns content summary.\n// Summary text means the part before page-break <!--more-->.\n// It can be go-markdown rendered.\nfunc (cnt *Content) Summary() string {\n\ttext := strings.Split(cnt.Text, \"<!--more-->\")[0]\n\tif GetSetting(\"enable_go_markdown\") == \"true\" {\n\t\treturn utils.Markdown2Html(text)\n\t}\n\treturn text\n}\n\n// CommentNum returns content comments number.\n// If comment are checking or, its parent are lost, do not count it.\nfunc (cnt *Content) CommentNum() int {\n\tmax := len(cnt.Comments)\n\tfor _, c := range cnt.Comments {\n\t\tif !c.IsValid() {\n\t\t\tmax--\n\t\t}\n\t}\n\treturn max\n}\n\n// ChangeSlug changes content's slug.\n// It checks whether this slug is unique.\nfunc (cnt *Content) ChangeSlug(slug string) bool {\n\tc2 := GetContentBySlug(slug)\n\tif c2 == nil {\n\t\tcnt.Slug = slug\n\t\treturn true\n\t}\n\tif c2.Id != cnt.Id {\n\t\treturn false\n\t}\n\tcnt.Slug = slug\n\treturn true\n}\n\n// User returns content author user instance.\nfunc (cnt *Content) User() *User {\n\treturn GetUserById(cnt.AuthorId)\n}\n\n// Content Tag struct. It convert tag string to proper struct or link.\ntype Tag struct {\n\tName string\n\tCid  []int\n}\n\n// Link returns tag name url-encoded link.\nfunc (t *Tag) Link() string {\n\treturn \"/tag/\" + url.QueryEscape(strings.Replace(t.Name, \".\", \"-\", -1))\n}\n\n// GetContentById gets a content by given id.\nfunc GetContentById(id int) *Content {\n\treturn contents[id]\n}\n\n// GetContentBySlug gets a content by given slug.\nfunc GetContentBySlug(slug string) *Content {\n\tfor _, c := range contents {\n\t\tif c.Slug == slug {\n\t\t\treturn c\n\t\t}\n\t}\n\treturn nil\n}\n\n// CreateContent creates new content.\n// t means content type, article or page.\nfunc CreateContent(c *Content, t string) (*Content, error) {\n\tc2 := GetContentBySlug(c.Slug)\n\tif c2 != nil {\n\t\treturn nil, errors.New(\"slug-repeat\")\n\t}\n\tcontentMaxId += Storage.TimeInc(3)\n\tc.Id = contentMaxId\n\tc.CreateTime = utils.Now()\n\tc.EditTime = c.CreateTime\n\tc.UpdateTime = c.CreateTime\n\tc.Comments = make([]*Comment, 0)\n\tc.Type = t\n\tc.Hits = 1\n\tc.textRendered = \"\"\n\tcontents[c.Id] = c\n\tcontentsIndex[c.Type] = append([]int{c.Id}, contentsIndex[c.Type]...)\n\tgeneratePublishArticleIndex()\n\tgo SyncContent(c)\n\treturn c, nil\n}\n\n// SaveContent saves changed content.\n// It will re-generate related indexes.\nfunc SaveContent(c *Content) {\n\tc.EditTime = utils.Now()\n\t// clean rendered cache text\n\tc.textRendered = \"\"\n\tgeneratePublishArticleIndex()\n\tgo SyncContent(c)\n}\n\n// RemoveContent removes a content.\n// Not delete file really, just change status to DELETE.\n// This content can't be loaded in memory from storage json.\nfunc RemoveContent(c *Content) {\n\tdelete(contents, c.Id)\n\tfor i, id := range contentsIndex[c.Type] {\n\t\tif c.Id == id {\n\t\t\tcontentsIndex[c.Type] = append(contentsIndex[c.Type][:i], contentsIndex[c.Type][i+1:]...)\n\t\t\tbreak\n\t\t}\n\t}\n\tc.Status = \"DELETE\"\n\tgeneratePublishArticleIndex()\n\tgo SyncContent(c)\n}\n\n// SyncContent writes a content to storage json.\nfunc SyncContent(c *Content) {\n\tkey := fmt.Sprintf(\"content/%s-%d\", c.Type, c.Id)\n\tStorage.Set(key, c)\n}\n\n// SyncContents writes all contents to storage json.\nfunc SyncContents() {\n\tfor _, c := range contents {\n\t\tSyncContent(c)\n\t}\n}\n\n// LoadContents loads all contents, then generates indexes.\nfunc LoadContents() {\n\tcontents = make(map[int]*Content)\n\tcontentsIndex = make(map[string][]int)\n\tcontentMaxId = 0\n\tarticleIndex := make([]int, 0)\n\tpageIndex := make([]int, 0)\n\t// walk files in directory\n\tfilepath.Walk(filepath.Join(Storage.dir, \"content\"), func(_ string, info os.FileInfo, err error) error {\n\t\tif err == nil {\n\t\t\t// ignore dir and sub-dir\n\t\t\tif info.IsDir() {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tc := new(Content)\n\t\t\tfile := strings.Replace(\"content/\"+info.Name(), filepath.Ext(info.Name()), \"\", -1)\n\t\t\tStorage.Get(file, c)\n\t\t\tif c.Id > 0 {\n\t\t\t\t// ignore DELETE status\n\t\t\t\tif c.Status != \"DELETE\" {\n\t\t\t\t\tcontents[c.Id] = c\n\t\t\t\t\tif c.Type == \"article\" {\n\t\t\t\t\t\tarticleIndex = append(articleIndex, c.Id)\n\t\t\t\t\t}\n\t\t\t\t\tif c.Type == \"page\" {\n\t\t\t\t\t\tpageIndex = append(pageIndex, c.Id)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif c.Id > contentMaxId {\n\t\t\t\t\tcontentMaxId = c.Id\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t})\n\t// sort indexes as desc order\n\tsort.Sort(sort.Reverse(sort.IntSlice(articleIndex)))\n\tsort.Sort(sort.Reverse(sort.IntSlice(pageIndex)))\n\tcontentsIndex[\"article\"] = articleIndex\n\tcontentsIndex[\"page\"] = pageIndex\n}\n\nfunc startContentSyncTimer() {\n\tSetTimerFunc(\"content-sync\", 6, func() {\n\t\tprintln(\"write contents in 1 hour timer\")\n\t\tSyncContents()\n\t})\n}\n\nfunc generateContentTmpIndexes() {\n\tvar (\n\t\tpopTmp     = make([][2]int, 0)\n\t\tpopIndex   = make([]int, 0)\n\t\ttagIndexes = make(map[string][]int)\n\t\tdata       = make(map[string][]int)\n\t)\n\tfor _, c := range contents {\n\t\tif c.Status == \"publish\" && c.Type == \"article\" {\n\t\t\t// pop temp index\n\t\t\tpopTmp = append(popTmp, [2]int{c.Id, c.CommentNum()})\n\t\t\tif len(c.Tags) > 0 {\n\t\t\t\tfor _, t := range c.Tags {\n\t\t\t\t\tif tagIndexes[t] == nil {\n\t\t\t\t\t\ttagIndexes[t] = make([]int, 0)\n\t\t\t\t\t}\n\t\t\t\t\ttagIndexes[t] = append(tagIndexes[t], c.Id)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// sort popular list\n\tutils.SortInt(popTmp)\n\tfor _, p := range popTmp {\n\t\tpopIndex = append(popIndex, p[0])\n\t}\n\tcontentsIndex[\"article-pop\"] = popIndex\n\n\t// assemble indexes map\n\tdata[\"pop-index\"] = popIndex\n\ttags = make([]*Tag, 0)\n\tfor tag, index := range tagIndexes {\n\t\tif strings.TrimSpace(tag) == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tsort.Sort(sort.Reverse(sort.IntSlice(index)))\n\t\tdata[\"t-\"+tag] = index\n\t\tcontentsIndex[\"t-\"+tag] = index\n\t\tt := new(Tag)\n\t\tt.Name = tag\n\t\tt.Cid = index\n\t\ttags = append(tags, t)\n\t}\n\n\t// write to tmp data\n\tTmpStorage.Set(\"contents\", data)\n}\n\n// GetContentTags returns all tags.\nfunc GetContentTags() []*Tag {\n\treturn tags\n}\n\nfunc startContentTmpIndexesTimer() {\n\tSetTimerFunc(\"content-indexes\", 36, func() {\n\t\tprintln(\"write content indexes in 6 hours timer\")\n\t\tgenerateContentTmpIndexes()\n\t})\n}\n"
  },
  {
    "path": "app/model/file.go",
    "content": "package model\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/utils\"\n\t\"os\"\n\t\"path\"\n\t\"strconv\"\n)\n\nvar (\n\tfiles     []*File\n\tfileMaxId int\n)\n\ntype File struct {\n\tId          int\n\tName        string\n\tUploadTime  int64\n\tUrl         string\n\tContentType string\n\tAuthor      int\n\tIsUsed      bool\n\tSize        int64\n\tType        string\n\tHits        int\n}\n\nfunc CreateFile(f *File) *File {\n\tfileMaxId += Storage.TimeInc(3)\n\tf.Id = fileMaxId\n\tf.UploadTime = utils.Now()\n\tf.IsUsed = true\n\tf.Hits = 0\n\tfiles = append([]*File{f}, files...)\n\tgo SyncFiles()\n\treturn f\n}\n\nfunc CreateFilePath(dir string, f *File) string {\n\tos.MkdirAll(dir, os.ModePerm)\n\tname := utils.DateInt64(utils.Now(), \"YYYYMMDDHHmmss\")\n\tname += strconv.Itoa(Storage.TimeInc(10)) + path.Ext(f.Name)\n\treturn path.Join(dir, name)\n}\n\nfunc GetFileList(page, size int) ([]*File, *utils.Pager) {\n\tpager := utils.NewPager(page, size, len(files))\n\tf := make([]*File, 0)\n\tif page > pager.Pages || len(files) < 1 {\n\t\treturn f, pager\n\t}\n\tfor i := pager.Begin; i <= pager.End; i++ {\n\t\tf = files[pager.Begin-1 : pager.End]\n\t}\n\treturn f, pager\n}\n\nfunc RemoveFile(id int) {\n\tfor i, f2 := range files {\n\t\tif id == f2.Id {\n\t\t\tfiles = append(files[:i], files[i+1:]...)\n\t\t\tos.Remove(f2.Url)\n\t\t}\n\t}\n\tgo SyncFiles()\n}\n\nfunc SyncFiles() {\n\tStorage.Set(\"files\", files)\n}\n\nfunc LoadFiles() {\n\tfiles = make([]*File, 0)\n\tfileMaxId = 0\n\tStorage.Get(\"files\", &files)\n\tfor _, f := range files {\n\t\tif f.Id > fileMaxId {\n\t\t\tfileMaxId = f.Id\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "app/model/locker.go",
    "content": "package model\n\nimport \"sync\"\n\nvar locker sync.Mutex\n\nfunc init() {\n\tlocker = sync.Mutex{}\n}\n"
  },
  {
    "path": "app/model/message.go",
    "content": "package model\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/utils\"\n\t\"strings\"\n)\n\nvar (\n\tmessages         []*Message\n\tmessageMaxId     int\n\tmessageGenerator map[string]func(v interface{}) string\n)\n\nfunc init() {\n\tmessageGenerator = make(map[string]func(v interface{}) string)\n\tmessageGenerator[\"comment\"] = generateCommentMessage\n\tmessageGenerator[\"backup\"] = generateBackupMessage\n}\n\ntype Message struct {\n\tId         int\n\tType       string\n\tCreateTime int64\n\tData       string\n\tIsRead     bool\n}\n\nfunc CreateMessage(tp string, data interface{}) *Message {\n\tm := new(Message)\n\tm.Type = tp\n\tm.Data = messageGenerator[tp](data)\n\tif m.Data == \"\" {\n\t\tprintln(\"message generator returns empty\")\n\t\treturn nil\n\t}\n\tm.CreateTime = utils.Now()\n\tm.IsRead = false\n\tmessageMaxId += Storage.TimeInc(3)\n\tm.Id = messageMaxId\n\tmessages = append([]*Message{m}, messages...)\n\tSyncMessages()\n\treturn m\n}\n\nfunc SetMessageGenerator(name string, fn func(v interface{}) string) {\n\tmessageGenerator[name] = fn\n}\n\nfunc GetMessage(id int) *Message {\n\tfor _, m := range messages {\n\t\tif m.Id == id {\n\t\t\treturn m\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc GetUnreadMessages() []*Message {\n\tms := make([]*Message, 0)\n\tfor _, m := range messages {\n\t\tif m.IsRead {\n\t\t\tcontinue\n\t\t}\n\t\tms = append(ms, m)\n\t}\n\treturn ms\n}\n\nfunc GetMessages() []*Message {\n\treturn messages\n}\n\nfunc GetTypedMessages(tp string, unread bool) []*Message {\n\tms := make([]*Message, 0)\n\tfor _, m := range messages {\n\t\tif m.Type == tp {\n\t\t\tif unread {\n\t\t\t\tif !m.IsRead {\n\t\t\t\t\tms = append(ms, m)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tms = append(ms, m)\n\t\t\t}\n\t\t}\n\t}\n\treturn ms\n}\n\nfunc SaveMessageRead(m *Message) {\n\tm.IsRead = true\n\tSyncMessages()\n}\n\nfunc SyncMessages() {\n\tStorage.Set(\"messages\", messages)\n}\n\nfunc LoadMessages() {\n\tmessages = make([]*Message, 0)\n\tmessageMaxId = 0\n\tStorage.Get(\"messages\", &messages)\n\tfor _, m := range messages {\n\t\tif m.Id > messageMaxId {\n\t\t\tmessageMaxId = m.Id\n\t\t}\n\t}\n}\n\nfunc RecycleMessages() {\n\tfor i, m := range messages {\n\t\tif m.CreateTime+3600*24*3 < utils.Now() {\n\t\t\tmessages = messages[:i]\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc generateCommentMessage(co interface{}) string {\n\tc, ok := co.(*Comment)\n\tif !ok {\n\t\treturn \"\"\n\t}\n\tcnt := GetContentById(c.Cid)\n\ts := \"\"\n\tif c.Pid < 1 {\n\t\ts = \"<p>\" + c.Author + \"同学，在文章《\" + cnt.Title + \"》发表评论：\"\n\t\ts += utils.Html2str(c.Content) + \"</p>\"\n\t} else {\n\t\tp := GetCommentById(c.Pid)\n\t\ts = \"<p>\" + p.Author + \"同学，在文章《\" + cnt.Title + \"》的评论：\"\n\t\ts += utils.Html2str(p.Content) + \"</p>\"\n\t\ts += \"<p>\" + c.Author + \"同学的回复：\"\n\t\ts += utils.Html2str(c.Content) + \"</p>\"\n\t}\n\treturn s\n}\n\nfunc generateBackupMessage(co interface{}) string {\n\tstr := co.(string)\n\tif strings.HasPrefix(str, \"[0]\") {\n\t\treturn \"备份全站失败: \" + strings.TrimPrefix(str, \"[0]\") + \".\"\n\t}\n\treturn \"备份全站到 \" + strings.TrimPrefix(str, \"[1]\") + \" 成功.\"\n}\n\nfunc startMessageTimer() {\n\tSetTimerFunc(\"message-sync\", 9, func() {\n\t\tprintln(\"write messages in 1.5 hour timer\")\n\t\tRecycleMessages()\n\t\tSyncMessages()\n\t})\n}\n"
  },
  {
    "path": "app/model/page.go",
    "content": "package model\n\nimport \"github.com/fuxiaohei/GoBlog/app/utils\"\n\n// GetPageList gets pages list and pager no matter page status.\n// In common cases, no need to get a list or pagers for public page.\nfunc GetPageList(page, size int) ([]*Content, *utils.Pager) {\n\tindex := contentsIndex[\"page\"]\n\tpager := utils.NewPager(page, size, len(index))\n\tpages := make([]*Content, 0)\n\tif len(index) < 1 {\n\t\treturn pages, pager\n\t}\n\tif page > pager.Pages {\n\t\treturn pages, pager\n\t}\n\tfor i := pager.Begin; i <= pager.End; i++ {\n\t\tpages = append(pages, GetContentById(index[i-1]))\n\t}\n\treturn pages, pager\n}\n"
  },
  {
    "path": "app/model/setting.go",
    "content": "package model\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype navItem struct {\n\tOrder int\n\tText  string\n\tTitle string\n\tLink  string\n}\n\nvar (\n\tsettings   map[string]string\n\tnavigators []*navItem\n)\n\nfunc GetSetting(key string) string {\n\treturn settings[key]\n}\n\nfunc GetCustomSettings() map[string]string {\n\tm := make(map[string]string)\n\tfor k, v := range settings {\n\t\tif strings.HasPrefix(k, \"c_\") {\n\t\t\tm[strings.TrimPrefix(k, \"c_\")] = v\n\t\t}\n\t}\n\treturn m\n}\n\nfunc SetSetting(key string, v string) {\n\tsettings[key] = v\n}\n\nfunc SyncSettings() {\n\tStorage.Set(\"settings\", settings)\n}\n\nfunc LoadSettings() {\n\tsettings = make(map[string]string)\n\tStorage.Get(\"settings\", &settings)\n}\n\nfunc SortNavigators() {\n\tl := len(navigators)\n\tfor i := 1; i < l; i++ {\n\t\tfor j := i; j > 0; j-- {\n\t\t\tif navigators[j].Order < navigators[j-1].Order {\n\t\t\t\tnavigators[j], navigators[j-1] = navigators[j-1], navigators[j]\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc LoadNavigators() {\n\tnavigators = make([]*navItem, 0)\n\tStorage.Get(\"navigators\", &navigators)\n\tSortNavigators()\n}\n\nfunc SetNavigators(order []string, text []string, title []string, link []string) {\n\tnavs := make([]*navItem, len(text))\n\tfor i, t := range text {\n\t\tn := new(navItem)\n\t\tn.Order, _ = strconv.Atoi(order[i])\n\t\tn.Text = t\n\t\tn.Title = title[i]\n\t\tn.Link = link[i]\n\t\tnavs[i] = n\n\t}\n\tnavigators = navs\n\tSyncNavigators()\n}\n\nfunc DefaultNavigators() {\n\tn := new(navItem)\n\tn.Order = 1\n\tn.Text = \"文章\"\n\tn.Title = \"文章\"\n\tn.Link = \"/\"\n\tn2 := new(navItem)\n\tn2.Order = 2\n\tn2.Text = \"关于\"\n\tn2.Title = \"关于\"\n\tn2.Link = \"/about-me.html\"\n\tn3 := new(navItem)\n\tn3.Order = 3\n\tn3.Text = \"好友\"\n\tn3.Title = \"好友\"\n\tn3.Link = \"/friends.html\"\n\tnavigators = []*navItem{n, n2, n3}\n\tStorage.Set(\"navigators\", navigators)\n}\n\nfunc SyncNavigators() {\n\tStorage.Set(\"navigators\", navigators)\n\tSortNavigators()\n}\n\nfunc GetNavigators() []*navItem {\n\treturn navigators\n}\n"
  },
  {
    "path": "app/model/statis.go",
    "content": "package model\n\ntype Statis struct {\n\tComments int\n\tArticles int\n\tPages    int\n\tFiles    int\n\tVersion  int\n\tReaders  int\n}\n\nfunc NewStatis() *Statis {\n\ts := new(Statis)\n\ts.Comments = len(commentsIndex)\n\ts.Articles = len(contentsIndex[\"article\"])\n\ts.Pages = len(contentsIndex[\"page\"])\n\ts.Files = len(files)\n\ts.Version = GetVersion().Version\n\ts.Readers = len(GetReaders())\n\treturn s\n}\n"
  },
  {
    "path": "app/model/storage.go",
    "content": "package model\n\nimport (\n\t\"encoding/json\"\n\t\"github.com/fuxiaohei/GoBlog/app/utils\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path\"\n\t\"strconv\"\n)\n\nvar (\n\tappVersion int\n\t// global data storage instance\n\tStorage *jsonStorage\n\t// global tmp data storage instance. Temp data are generated for special usages, will not backup.\n\tTmpStorage *jsonStorage\n)\n\ntype jsonStorage struct {\n\tdir string\n}\n\nfunc (jss *jsonStorage) Init(dir string) {\n\tjss.dir = dir\n}\n\nfunc (jss *jsonStorage) Has(key string) bool {\n\tfile := path.Join(jss.dir, key+\".json\")\n\t_, e := os.Stat(file)\n\treturn e == nil\n}\n\nfunc (jss *jsonStorage) Get(key string, v interface{}) {\n\tfile := path.Join(jss.dir, key+\".json\")\n\tbytes, e := ioutil.ReadFile(file)\n\tif e != nil {\n\t\tprintln(\"read storage '\" + key + \"' error\")\n\t\treturn\n\t}\n\te = json.Unmarshal(bytes, v)\n\tif e != nil {\n\t\tprintln(\"json decode '\" + key + \"' error\")\n\t}\n}\n\nfunc (jss *jsonStorage) Set(key string, v interface{}) {\n\tlocker.Lock()\n\tdefer locker.Unlock()\n\n\tbytes, e := json.Marshal(v)\n\tif e != nil {\n\t\tprintln(\"json encode '\" + key + \"' error\")\n\t\treturn\n\t}\n\tfile := path.Join(jss.dir, key+\".json\")\n\te = ioutil.WriteFile(file, bytes, 0777)\n\tif e != nil {\n\t\tprintln(\"write storage '\" + key + \"' error\")\n\t}\n}\n\nfunc (jss *jsonStorage) Dir(name string) {\n\tos.MkdirAll(path.Join(jss.dir, name), os.ModePerm)\n}\n\nfunc writeDefaultData() {\n\t// write user\n\tu := new(User)\n\tu.Id = Storage.TimeInc(10)\n\tu.Name = \"admin\"\n\tu.Password = utils.Sha1(\"adminxxxxx\")\n\tu.Nick = \"管理员\"\n\tu.Email = \"admin@example.com\"\n\tu.Url = \"http://example.com/\"\n\tu.CreateTime = utils.Now()\n\tu.Bio = \"这是站点的管理员，你可以添加一些个人介绍，支持换行不支持markdown\"\n\tu.LastLoginTime = u.CreateTime\n\tu.Role = \"ADMIN\"\n\tStorage.Set(\"users\", []*User{u})\n\n\t// write token\n\tStorage.Set(\"tokens\", map[string]*Token{})\n\n\t// write contents\n\ta := new(Content)\n\ta.Id = Storage.TimeInc(9)\n\ta.Title = \"欢迎使用 Fxh.Go\"\n\ta.Slug = \"welcome-fxh-go\"\n\ta.Text = \"如果您看到这篇文章,表示您的 blog 已经安装成功.\"\n\ta.Tags = []string{\"Fxh.Go\"}\n\ta.CreateTime = utils.Now()\n\ta.EditTime = a.CreateTime\n\ta.UpdateTime = a.CreateTime\n\ta.IsComment = true\n\ta.IsLinked = false\n\ta.AuthorId = u.Id\n\ta.Type = \"article\"\n\ta.Status = \"publish\"\n\ta.Format = \"markdown\"\n\ta.Template = \"blog.html\"\n\ta.Hits = 1\n\t// write comments\n\tco := new(Comment)\n\tco.Author = u.Nick\n\tco.Email = u.Email\n\tco.Url = u.Url\n\tco.Content = \"欢迎加入使用 Fxh.Go\"\n\tco.Avatar = utils.Gravatar(co.Email, \"50\")\n\tco.Pid = 0\n\tco.Ip = \"127.0.0.1\"\n\tco.UserAgent = \"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17\"\n\tco.IsAdmin = true\n\tco.Id = Storage.TimeInc(7)\n\tco.CreateTime = utils.Now()\n\tco.Status = \"approved\"\n\tco.Cid = a.Id\n\ta.Comments = []*Comment{co}\n\tStorage.Set(\"content/article-\"+strconv.Itoa(a.Id), a)\n\n\t// write pages\n\tp := new(Content)\n\tp.Id = a.Id + Storage.TimeInc(6)\n\tp.Title = \"关于\"\n\tp.Slug = \"about-me\"\n\tp.Text = \"本页面由 Fxh.Go 创建, 这只是个测试页面.\"\n\tp.Tags = []string{}\n\tp.CreateTime = utils.Now()\n\tp.EditTime = p.CreateTime\n\tp.UpdateTime = p.UpdateTime\n\tp.IsComment = true\n\tp.IsLinked = true\n\tp.AuthorId = u.Id\n\tp.Type = \"page\"\n\tp.Status = \"publish\"\n\tp.Format = \"markdown\"\n\tp.Comments = make([]*Comment, 0)\n\tp.Template = \"page.html\"\n\tp.Hits = 1\n\tStorage.Set(\"content/page-\"+strconv.Itoa(p.Id), p)\n\tp2 := new(Content)\n\tp2.Id = p.Id + Storage.TimeInc(6)\n\tp2.Title = \"好友\"\n\tp2.Slug = \"friends\"\n\tp2.Text = \"本页面由 Fxh.Go 创建, 这只是个测试页面.\"\n\tp2.Tags = []string{}\n\tp2.CreateTime = utils.Now()\n\tp2.EditTime = p2.CreateTime\n\tp2.UpdateTime = p2.UpdateTime\n\tp2.IsComment = true\n\tp2.IsLinked = true\n\tp2.AuthorId = u.Id\n\tp2.Type = \"page\"\n\tp2.Status = \"publish\"\n\tp2.Format = \"markdown\"\n\tp2.Comments = make([]*Comment, 0)\n\tp2.Template = \"page.html\"\n\tp2.Hits = 1\n\tStorage.Set(\"content/page-\"+strconv.Itoa(p2.Id), p2)\n\n\t// write new reader\n\tStorage.Set(\"readers\", map[string]*Reader{})\n\n\t// write version\n\tv := new(version)\n\tv.Name = \"Fxh.Go\"\n\tv.BuildTime = utils.Now()\n\tv.Version = appVersion\n\tStorage.Set(\"version\", v)\n\n\t// write settings\n\ts := map[string]string{\n\t\t\"site_title\":         \"Fxh.Go\",\n\t\t\"site_sub_title\":     \"Go开发的简单博客\",\n\t\t\"site_keywords\":      \"Fxh.Go,Golang,Blog\",\n\t\t\"site_description\":   \"Go语言开发的简单博客程序\",\n\t\t\"site_url\":           \"http://localhost/\",\n\t\t\"article_size\":       \"4\",\n\t\t\"site_theme\":         \"default\",\n\t\t\"enable_go_markdown\": \"false\",\n\t\t\"c_footer_weibo\":     \"#\",\n\t\t\"c_footer_github\":    \"#\",\n\t\t\"c_footer_email\":     \"#\",\n\t\t\"c_home_avatar\":      \"/static/img/site.png\",\n\t\t\"c_footer_ga\":        \"<!-- google analytics or other -->\",\n\t}\n\tStorage.Set(\"settings\", s)\n\n\t// write files\n\tStorage.Set(\"files\", []*File{})\n\n\t// write message\n\tStorage.Set(\"messages\", []*Message{})\n\n\t// write navigators\n\tn := new(navItem)\n\tn.Order = 1\n\tn.Text = \"文章\"\n\tn.Title = \"文章\"\n\tn.Link = \"/\"\n\tn2 := new(navItem)\n\tn2.Order = 2\n\tn2.Text = \"关于\"\n\tn2.Title = \"关于\"\n\tn2.Link = \"/about-me.html\"\n\tn3 := new(navItem)\n\tn3.Order = 3\n\tn3.Text = \"好友\"\n\tn3.Title = \"好友\"\n\tn3.Link = \"/friends.html\"\n\tStorage.Set(\"navigators\", []*navItem{n, n2, n3})\n\n\t// write default tmp data\n\twriteDefaultTmpData()\n}\n\nfunc writeDefaultTmpData() {\n\tTmpStorage.Set(\"contents\", make(map[string][]int))\n}\n\nfunc loadAllData() {\n\tloadVersion()\n\tLoadSettings()\n\tLoadNavigators()\n\tLoadUsers()\n\tLoadTokens()\n\tLoadContents()\n\tLoadMessages()\n\tLoadReaders()\n\tLoadComments()\n\tLoadFiles()\n}\n\n// TimeInc returns time step value devided by d int with time unix stamp.\nfunc (jss *jsonStorage) TimeInc(d int) int {\n\treturn int(utils.Now())%d + 1\n}\n\n// Init does model initialization.\n// If first run, write default data.\n// v means app.Version number. It's needed for version data.\nfunc Init(v int) {\n\tappVersion = v\n\tStorage = new(jsonStorage)\n\tStorage.Init(\"data\")\n\tTmpStorage = new(jsonStorage)\n\tTmpStorage.dir = \"tmp/data\"\n\tif !Storage.Has(\"version\") {\n\t\tos.Mkdir(Storage.dir, os.ModePerm)\n\t\tos.Mkdir(path.Join(Storage.dir, \"content\"), os.ModePerm)\n\t\tos.Mkdir(path.Join(Storage.dir, \"plugin\"), os.ModePerm)\n\t\twriteDefaultData()\n\t}\n}\n\n// All loads all data from storage to memory.\n// Start timers for content, comment and message.\nfunc All() {\n\tloadAllData()\n\t// generate indexes\n\tSyncIndexes()\n\t// start model timer, do all timer stuffs\n\tStartModelTimer()\n}\n\nfunc SyncIndexes() {\n\t// generate indexes\n\tgeneratePublishArticleIndex()\n\tgenerateContentTmpIndexes()\n}\n\n// SyncAll writes all current memory data to storage files.\nfunc SyncAll() {\n\tSyncContents()\n\tSyncMessages()\n\tSyncFiles()\n\tSyncReaders()\n\tSyncSettings()\n\tSyncNavigators()\n\tSyncTokens()\n\tSyncUsers()\n\tSyncVersion()\n}\n"
  },
  {
    "path": "app/model/timer.go",
    "content": "package model\n\nimport (\n\t\"time\"\n)\n\ntype timerFunc struct {\n\tFn     func()\n\tTicker int\n}\n\nvar (\n\ttimerCount int\n\ttimerFuncs map[string]*timerFunc\n)\n\nfunc init() {\n\ttimerCount = 0\n\ttimerFuncs = make(map[string]*timerFunc)\n}\n\n// SetTimerFunc adds timer func for time ticker.\n// Ticker means step time, after ticker size step passed, do function.\n// Name is unique name of func.If set same name func, use the last one.\nfunc SetTimerFunc(name string, ticker int, fn func()) {\n\ttfn := new(timerFunc)\n\ttfn.Fn = fn\n\ttfn.Ticker = ticker\n\ttimerFuncs[name] = tfn\n}\n\n// ChangeTimerFunc can change timer func by given name.\n// If the func of name is none, do not change anything, print error message.\nfunc ChangeTimerFunc(name string, ticker int, fn func()) {\n\tif _, ok := timerFuncs[name]; ok {\n\t\ttimerFuncs[name].Fn = fn\n\t\ttimerFuncs[name].Ticker = ticker\n\t} else {\n\t\tprintln(\"change invalid timer func : \" + name)\n\t}\n}\n\n// DelTimerFunc deletes timer func.\nfunc DelTimerFunc(name string) {\n\tdelete(timerFuncs, name)\n}\n\n// GetTimerFuncs returns registered timer func with its name and ticker int.\nfunc GetTimerFuncs() map[string]int {\n\tm := make(map[string]int)\n\tfor n, f := range timerFuncs {\n\t\tm[n] = f.Ticker\n\t}\n\treturn m\n}\n\n// StartModelTimer adds models' timer and starts time ticker.\n// The default step is 10 min once.\nfunc StartModelTimer() {\n\t// start all timers\n\tstartCommentsTimer()\n\tstartContentSyncTimer()\n\tstartContentTmpIndexesTimer()\n\tstartMessageTimer()\n\t// start time ticker\n\tticker := time.NewTicker(time.Duration(10) * time.Minute)\n\tgo doTimers(ticker.C)\n}\n\nfunc doTimers(c <-chan time.Time) {\n\tfor {\n\t\t<-c\n\t\ttimerCount++\n\t\tfor _, tfn := range timerFuncs {\n\t\t\tif timerCount%tfn.Ticker == 0 {\n\t\t\t\ttfn.Fn()\n\t\t\t}\n\t\t}\n\t\tif timerCount > 999 {\n\t\t\ttimerCount = 0\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "app/model/token.go",
    "content": "package model\n\nimport (\n\t\"fmt\"\n\t\"github.com/fuxiaohei/GoBlog/app/utils\"\n\t\"github.com/fuxiaohei/GoInk\"\n)\n\nvar tokens map[string]*Token\n\ntype Token struct {\n\tValue      string\n\tUserId     int\n\tCreateTime int64\n\tExpireTime int64\n}\n\n// check token is valid or expired.\nfunc (t *Token) IsValid() bool {\n\tif GetUserById(t.UserId) == nil {\n\t\treturn false\n\t}\n\treturn t.ExpireTime > utils.Now()\n}\n\n// create new token from user and context.\nfunc CreateToken(u *User, context *GoInk.Context, expire int64) *Token {\n\tt := new(Token)\n\tt.UserId = u.Id\n\tt.CreateTime = utils.Now()\n\tt.ExpireTime = t.CreateTime + expire\n\tt.Value = utils.Sha1(fmt.Sprintf(\"%s-%s-%d-%d\", context.Ip, context.UserAgent, t.CreateTime, t.UserId))\n\ttokens[t.Value] = t\n\tgo SyncTokens()\n\treturn t\n}\n\n// get token by token value.\nfunc GetTokenByValue(v string) *Token {\n\treturn tokens[v]\n}\n\n// get tokens of given user.\nfunc GetTokensByUser(u *User) []*Token {\n\tts := make([]*Token, 0)\n\tfor _, t := range tokens {\n\t\tif t.UserId == u.Id {\n\t\t\tts = append(ts, t)\n\t\t}\n\t}\n\treturn ts\n}\n\n// remove a token by token value.\nfunc RemoveToken(v string) {\n\tdelete(tokens, v)\n\tgo SyncTokens()\n}\n\n// clean all expired tokens in memory.\n// do not write to json.\nfunc CleanTokens() {\n\tfor k, t := range tokens {\n\t\tif !t.IsValid() {\n\t\t\tdelete(tokens, k)\n\t\t}\n\t}\n}\n\n// write tokens to json.\n// it calls CleanTokens before writing.\nfunc SyncTokens() {\n\tCleanTokens()\n\tStorage.Set(\"tokens\", tokens)\n}\n\n// load all tokens from json.\nfunc LoadTokens() {\n\ttokens = make(map[string]*Token)\n\tStorage.Get(\"tokens\", &tokens)\n}\n"
  },
  {
    "path": "app/model/user.go",
    "content": "package model\n\nimport (\n\t\"errors\"\n\t\"github.com/fuxiaohei/GoBlog/app/utils\"\n)\n\nvar (\n\tusers     []*User\n\tuserMaxId int\n)\n\ntype User struct {\n\tId            int\n\tName          string\n\tPassword      string\n\tNick          string\n\tEmail         string\n\tAvatar        string\n\tUrl           string\n\tBio           string\n\tCreateTime    int64\n\tLastLoginTime int64\n\tRole          string\n}\n\n// check user password.\nfunc (u *User) CheckPassword(pwd string) bool {\n\treturn utils.Sha1(pwd+\"xxxxx\") == u.Password\n}\n\n// change user email.\n// check unique.\nfunc (u *User) ChangeEmail(email string) bool {\n\tu2 := GetUserByEmail(u.Email)\n\tif u2.Id != u.Id {\n\t\treturn false\n\t}\n\tu.Email = email\n\treturn true\n}\n\n// change user password.\nfunc (u *User) ChangePassword(pwd string) {\n\tu.Password = utils.Sha1(pwd + \"xxxxx\")\n}\n\n// get a user by given id.\nfunc GetUserById(id int) *User {\n\tfor _, u := range users {\n\t\tif u.Id == id {\n\t\t\treturn u\n\t\t}\n\t}\n\treturn nil\n}\n\n// get a user by given name.\nfunc GetUserByName(name string) *User {\n\tfor _, u := range users {\n\t\tif u.Name == name {\n\t\t\treturn u\n\t\t}\n\t}\n\treturn nil\n}\n\n// get a user by given email.\nfunc GetUserByEmail(email string) *User {\n\tfor _, u := range users {\n\t\tif u.Email == email {\n\t\t\treturn u\n\t\t}\n\t}\n\treturn nil\n}\n\n// get users of given role.\nfunc GetUsersByRole(role string) []*User {\n\tus := make([]*User, 0)\n\tfor _, u := range users {\n\t\tif u.Role == role {\n\t\t\tus = append(us, u)\n\t\t}\n\t}\n\treturn us\n}\n\n// create new user.\nfunc CreateUser(u *User) error {\n\tif GetUserByName(u.Email) != nil {\n\t\treturn errors.New(\"email-repeat\")\n\t}\n\tuserMaxId += Storage.TimeInc(5)\n\tu.Id = userMaxId\n\tu.CreateTime = utils.Now()\n\tu.LastLoginTime = u.CreateTime\n\tusers = append(users, u)\n\tgo SyncUsers()\n\treturn nil\n}\n\n// remove a user.\nfunc RemoveUser(u *User) {\n\tfor i, u2 := range users {\n\t\tif u2.Id == u.Id {\n\t\t\tusers = append(users[:i], users[i+1:]...)\n\t\t\tbreak\n\t\t}\n\t}\n\tgo SyncUsers()\n}\n\n// write users to json.\nfunc SyncUsers() {\n\tStorage.Set(\"users\", users)\n}\n\nfunc LoadUsers() {\n\tusers = make([]*User, 0)\n\tuserMaxId = 0\n\tStorage.Get(\"users\", &users)\n\tfor _, u := range users {\n\t\tif u.Id > userMaxId {\n\t\t\tuserMaxId = u.Id\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "app/model/version.go",
    "content": "package model\n\nvar ver *version\n\ntype version struct {\n\tName           string\n\tBuildTime      int64\n\tVersion        int\n\tCurrentVersion int\n}\n\nfunc loadVersion() {\n\tver = new(version)\n\tStorage.Get(\"version\", ver)\n}\n\nfunc GetVersion() *version {\n\tif ver == nil {\n\t\tloadVersion()\n\t}\n\treturn ver\n}\n\nfunc SyncVersion() {\n\tStorage.Set(\"version\", ver)\n}\n"
  },
  {
    "path": "app/plugin/email.go",
    "content": "package plugin\n\nimport (\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"github.com/fuxiaohei/GoBlog/app/model\"\n\t\"github.com/fuxiaohei/GoInk\"\n\t\"html/template\"\n\t\"net/mail\"\n\t\"net/smtp\"\n\t\"path\"\n\t\"strings\"\n)\n\nvar (\n\t// email template original from http://ben-lab.com/tech/1789.html\n\temailReplyTemplate = `<table style=\"width: 99.8%;height:99.8% \"><tbody><tr><td style=\"background:#FAFAFA\">\n    <div style=\"background-color:white;border-top:2px solid #0079BC;box-shadow:0 1px 3px #AAAAAA;line-height:180%;padding:0 15px 12px;width:500px;margin:50px auto;color:#555555;font-family:'Century Gothic','Trebuchet MS','Hiragino Sans GB',微软雅黑,'Microsoft Yahei',Tahoma,Helvetica,Arial,'SimSun',sans-serif;font-size:12px;\">\n        <h2 style=\"border-bottom:1px solid #DDD;font-size:14px;font-weight:normal;padding:13px 0 10px 8px;\"><span style=\"color: #0079bc;font-weight: bold;\">&gt; </span>您在<a style=\"text-decoration:none;color: #e64346;\" href=\"{{.link}}\"> {{.site}} </a>上的留言有回复啦！</h2>\n        <div style=\"padding:0 12px 0 12px;margin-top:18px\">\n            <p><strong>{{.author_p}}</strong> 同学，您曾在文章《{{.title}}》上发表评论:</p>\n            <p style=\"background-color: #f5f5f5;border: 0px solid #DDD;padding: 10px 15px;margin:18px 0\">{{.text_p}}</p>\n            <p><strong>{{.author}}</strong> 给您的回复如下:</p>\n            <p style=\"background-color: #f5f5f5;border: 0px solid #DDD;padding: 10px 15px;margin:18px 0\">{{.text}}</p>\n            <p>您可以点击 <a style=\"text-decoration:none; color:#0079BC\" href=\"{{.permalink}}\">查看回复的完整內容 </a>，欢迎再次光临 <a style=\"text-decoration:none; color:#0079bc\" href=\"{{.link}}\">{{.site}} </a>。</p>\n        </div>\n    </div>\n</td></tr></tbody></table>`\n\temailCreatedTemplate = `<table style=\"width: 99.8%;height:99.8% \"><tbody><tr><td style=\"background:#FAFAFA\">\n    <div style=\"background-color:white;border-top:2px solid #0079BC;box-shadow:0 1px 3px #AAAAAA;line-height:180%;padding:0 15px 12px;width:500px;margin:50px auto;color:#555555;font-family:'Century Gothic','Trebuchet MS','Hiragino Sans GB',微软雅黑,'Microsoft Yahei',Tahoma,Helvetica,Arial,'SimSun',sans-serif;font-size:12px;\">\n        <h2 style=\"border-bottom:1px solid #DDD;font-size:14px;font-weight:normal;padding:13px 0 10px 8px;\"><span style=\"color: #0079bc;font-weight: bold;\">&gt; </span>{{.author}} 在<a style=\"text-decoration:none;color: #e64346;\" href=\"{{.link}}\"> {{.site}} </a>上的文章 《{{.title}}》 发表了评论！</h2>\n        <div style=\"padding:0 12px 0 12px;margin-top:18px\">\n            <p><strong>{{.author}}</strong> 同学，在文章《{{.title}}》上发表评论:</p>\n            <p style=\"background-color: #f5f5f5;border: 0px solid #DDD;padding: 10px 15px;margin:18px 0\">{{.text}}</p>\n            <p>您可以点击 <a style=\"text-decoration:none; color:#0079BC\" href=\"{{.permalink}}\">查看完整內容 </a>，欢迎再次光临 <a style=\"text-decoration:none; color:#0079bc\" href=\"{{.link}}\">{{.site}} </a>。</p>\n        </div>\n    </div>\n</td></tr></tbody></table>`\n)\n\n// Email plugin instance, contains activation status, handler status, settings and templates.\ntype EmailPlugin struct {\n\tisActive            bool\n\tisHandlerRegistered bool\n\tsettings            map[string]string\n\ttemplates           map[string]*template.Template\n}\n\nfunc init() {\n\tEmailPlugin := new(EmailPlugin)\n\tEmailPlugin.isActive = false\n\tEmailPlugin.isHandlerRegistered = false\n\tEmailPlugin.settings = make(map[string]string)\n\tEmailPlugin.templates = make(map[string]*template.Template)\n\t// load templates\n\tt1, e := template.New(\"reply\").Parse(emailReplyTemplate)\n\tif e != nil {\n\t\tpanic(e)\n\t}\n\tEmailPlugin.templates[\"reply\"] = t1\n\tt2, e2 := template.New(\"created\").Parse(emailCreatedTemplate)\n\tif e2 != nil {\n\t\tpanic(e)\n\t}\n\tEmailPlugin.templates[\"created\"] = t2\n\tregister(EmailPlugin)\n}\n\n// Name returns email plugin name\nfunc (p *EmailPlugin) Name() string {\n\treturn \"邮件提醒\"\n}\n\n// Key returns email plugin unique key.\nfunc (p *EmailPlugin) Key() string {\n\treturn \"email_notify_plugin\"\n}\n\n// Desc returns email plugin descripition.\nfunc (p *EmailPlugin) Desc() string {\n\treturn \"评论及回复等邮件提醒\"\n}\n\n// ToStorage creates plugin storage map for plugin list json.\nfunc (p *EmailPlugin) ToStorage() map[string]interface{} {\n\tm := make(map[string]interface{})\n\tm[\"name\"] = p.Name()\n\tm[\"description\"] = p.Desc()\n\tm[\"is_activate\"] = p.isActive\n\treturn m\n}\n\n// Activate activates email plugin.\n// It will change activate status to on.\n// If the handlers are not registered, it will add handlers to router table.\nfunc (p *EmailPlugin) Activate() {\n\tif p.isHandlerRegistered {\n\t\tp.isActive = true\n\t\treturn\n\t}\n\tif model.Storage.Has(\"plugin/\" + p.Key()) {\n\t\tmodel.Storage.Get(\"plugin/\"+p.Key(), &p.settings)\n\t}\n\t// email middleware handler\n\tfn := func(context *GoInk.Context) {\n\t\tcontext.On(\"comment_created\", func(co interface{}) {\n\t\t\tif !p.isActive {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tgo func() {\n\t\t\t\tif len(p.settings[\"smtp_host\"]) < 1 || len(p.settings[\"smtp_email_user\"]) < 1 || len(p.settings[\"smtp_email_password\"]) < 1 {\n\t\t\t\t\tprintln(\"no setting in smtp email plugin\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tp.sendEmail(co.(*model.Comment), true)\n\t\t\t}()\n\t\t})\n\t\tcontext.On(\"comment_reply\", func(co interface{}) {\n\t\t\tif !p.isActive {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tgo func() {\n\t\t\t\tif len(p.settings[\"smtp_host\"]) < 1 || len(p.settings[\"smtp_email_user\"]) < 1 || len(p.settings[\"smtp_email_password\"]) < 1 {\n\t\t\t\t\tfmt.Println(\"no setting in smtp email plugin\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tp.sendEmail(co.(*model.Comment), false)\n\t\t\t}()\n\t\t})\n\t}\n\tHandler(\"comment_email_notify\", fn, false)\n\tp.SetSetting(p.settings)\n\tp.isActive = true\n\tp.isHandlerRegistered = true\n}\n\n// Deactivate closes this email plugin.\nfunc (p *EmailPlugin) Deactivate() {\n\tp.isActive = false\n}\n\n// IsActive returns plugin activation status.\nfunc (p *EmailPlugin) IsActive() bool {\n\treturn p.isActive\n}\n\n// Version returns plugin version string.\nfunc (p *EmailPlugin) Version() string {\n\treturn \"0.1.5\"\n}\n\n// HasSetting returns bool of setting form existing.\nfunc (p *EmailPlugin) HasSetting() bool {\n\treturn true\n}\n\n// Form returns the form template string for email plugin.\nfunc (p *EmailPlugin) Form() string {\n\treturn `<h4 class=\"title\">\n        SMTP 邮箱提醒设置\n    </h4>\n    <p class=\"item\">\n        <label for=\"smtp-addr\">SMTP服务器</label>\n        <input class=\"ipt\" id=\"smtp-addr\" type=\"text\" name=\"smtp_host\" placeholder=\"SMTP服务器地址，如 smtp.gmail.com:465\" value=\"` + p.settings[\"smtp_host\"] + `\"/>\n    </p>\n    <p class=\"item\">\n        <label for=\"smtp-email\">SMTP邮箱</label>\n        <input class=\"ipt\" id=\"smtp-email\" type=\"email\" name=\"smtp_email_user\" placeholder=\"使用SMTP的邮箱\" value=\"` + p.settings[\"smtp_email_user\"] + `\"/>\n    </p>\n    <p class=\"item\">\n        <label for=\"smtp-password\">邮箱密码</label>\n        <input class=\"ipt\" id=\"smtp-password\" type=\"text\" name=\"smtp_email_password\" placeholder=\"邮箱密码\" value=\"` + p.settings[\"smtp_email_password\"] + `\"/>\n    </p>\n    <p class=\"submit item\">\n        <label>&nbsp;</label>\n        <button class=\"btn btn-blue\">保存设置</button>\n        <span class=\"tip\">暂不支持验证，请自行保证正确</span>\n    </p>`\n}\n\n// SetSettings saves plugin settings to json.\nfunc (p *EmailPlugin) SetSetting(settings map[string]string) {\n\tp.settings = settings\n\tmodel.Storage.Set(\"plugin/\"+p.Key(), p.settings)\n}\n\nfunc (p *EmailPlugin) sendEmail(co *model.Comment, isCreate bool) {\n\tvar (\n\t\ttpl     *template.Template\n\t\tbuff    bytes.Buffer\n\t\tpco     *model.Comment\n\t\tcontent *model.Content\n\t\terr     error\n\t\tuser    *model.User\n\t\ttitle   string\n\t\tfrom    mail.Address\n\t\tto      mail.Address\n\t)\n\n\t// get article or page content instance\n\tcontent = model.GetContentById(co.Cid)\n\tif content == nil {\n\t\tprintln(\"error content getting in email plugin\")\n\t\treturn\n\t}\n\t// email for notify new commment creation\n\tif co.Pid < 1 {\n\t\ttpl = p.templates[\"created\"]\n\n\t\terr = tpl.Execute(&buff, map[string]interface{}{\n\t\t\t\"link\":      model.GetSetting(\"site_url\"),\n\t\t\t\"site\":      model.GetSetting(\"site_title\"),\n\t\t\t\"author\":    co.Author,\n\t\t\t\"text\":      template.HTML(co.Content),\n\t\t\t\"title\":     content.Title,\n\t\t\t\"permalink\": path.Join(model.GetSetting(\"site_url\"), content.Link()),\n\t\t})\n\t\tif err != nil {\n\t\t\tfmt.Println(err)\n\t\t\treturn\n\t\t}\n\t\tuser = model.GetUsersByRole(\"ADMIN\")[0]\n\t\tfrom = mail.Address{\"no-reply@\" + model.GetSetting(\"site_url\"), p.settings[\"smtp_email_user\"]}\n\t\tto = mail.Address{user.Nick, user.Email}\n\t\ttitle = co.Author + \"在您的网站发表新评论\"\n\t\tp.sendSmtp(from, to, title, buff.Bytes())\n\t\treturn\n\t}\n\t// send mail for the author of comment replying to\n\tpco = model.GetCommentById(co.Pid)\n\ttpl = p.templates[\"reply\"]\n\terr = tpl.Execute(&buff, map[string]interface{}{\n\t\t\"link\":      model.GetSetting(\"site_url\"),\n\t\t\"site\":      model.GetSetting(\"site_title\"),\n\t\t\"author_p\":  pco.Author,\n\t\t\"text_p\":    template.HTML(pco.Content),\n\t\t\"author\":    co.Author,\n\t\t\"text\":      template.HTML(co.Content),\n\t\t\"title\":     content.Title,\n\t\t\"permalink\": path.Join(model.GetSetting(\"site_url\"), content.Link()),\n\t})\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tuser = model.GetUsersByRole(\"ADMIN\")[0]\n\n\tfrom = mail.Address{pco.Author + \"@\" + model.GetSetting(\"site_url\"), p.settings[\"smtp_email_user\"]}\n\tto = mail.Address{pco.Author, pco.Email}\n\ttitle = \"您的评论有了回复\"\n\tp.sendSmtp(from, to, title, buff.Bytes())\n\t// send email to notice admin new comment creation\n\t// this comment is a reply comment\n\tif isCreate {\n\t\tgo func() {\n\t\t\ttpl = p.templates[\"created\"]\n\n\t\t\terr = tpl.Execute(&buff, map[string]interface{}{\n\t\t\t\t\"link\":      model.GetSetting(\"site_url\"),\n\t\t\t\t\"site\":      model.GetSetting(\"site_title\"),\n\t\t\t\t\"author\":    co.Author,\n\t\t\t\t\"text\":      template.HTML(\"回复\" + pco.Author + \":<br/>\" + co.Content),\n\t\t\t\t\"title\":     content.Title,\n\t\t\t\t\"permalink\": path.Join(model.GetSetting(\"site_url\"), content.Link()),\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\tfmt.Println(err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tuser = model.GetUsersByRole(\"ADMIN\")[0]\n\t\t\tfrom = mail.Address{\"no-reply@\" + model.GetSetting(\"site_url\"), p.settings[\"smtp_email_user\"]}\n\t\t\tto = mail.Address{user.Nick, user.Email}\n\t\t\ttitle = co.Author + \"在您的网站发表新评论\"\n\t\t\tp.sendSmtp(from, to, title, buff.Bytes())\n\t\t}()\n\t}\n}\n\n// send email via smtp\nfunc (p *EmailPlugin) sendSmtp(from mail.Address, to mail.Address, title string, body []byte) {\n\t// set email vars\n\tb64 := base64.NewEncoding(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\")\n\thost := p.settings[\"smtp_host\"]\n\temail := p.settings[\"smtp_email_user\"]\n\n\theader := make(map[string]string)\n\theader[\"From\"] = from.String()\n\theader[\"To\"] = to.String()\n\theader[\"Subject\"] = fmt.Sprintf(\"=?UTF-8?B?%s?=\", b64.EncodeToString([]byte(title)))\n\theader[\"MIME-Version\"] = \"1.0\"\n\theader[\"Content-Type\"] = \"text/html; charset=UTF-8\"\n\theader[\"Content-Transfer-Encoding\"] = \"base64\"\n\n\tmessage := \"\"\n\tfor k, v := range header {\n\t\tmessage += fmt.Sprintf(\"%s: %s\\r\\n\", k, v)\n\t}\n\tmessage += \"\\r\\n\" + b64.EncodeToString(body)\n\n\tauth := smtp.PlainAuth(\n\t\t\"\",\n\t\temail,\n\t\tp.settings[\"smtp_email_password\"],\n\t\tstrings.Split(host, \":\")[0],\n\t)\n\n\terr := smtp.SendMail(\n\t\thost,\n\t\tauth,\n\t\temail,\n\t\t[]string{to.Address},\n\t\t[]byte(message),\n\t)\n\tprintln(\"send to email \", to.String(), fmt.Sprint(err))\n}\n"
  },
  {
    "path": "app/plugin/hello.go",
    "content": "package plugin\n\nimport (\n\t\"fmt\"\n\t\"github.com/fuxiaohei/GoInk\"\n\t\"time\"\n)\n\ntype HelloPlugin struct {\n\tisActive            bool\n\tisHandlerRegistered bool\n}\n\nfunc init() {\n\thelloPlugin := new(HelloPlugin)\n\thelloPlugin.isActive = true\n\thelloPlugin.isHandlerRegistered = false\n\tregister(helloPlugin)\n}\n\nfunc (p *HelloPlugin) Name() string {\n\treturn \"Sample Hello Plugin\"\n}\n\nfunc (p *HelloPlugin) Key() string {\n\treturn \"hello_plugin\"\n}\n\nfunc (p *HelloPlugin) Desc() string {\n\treturn \"插件样例，页面最后输出执行时间 <!-- excute time --> 注释\"\n}\n\nfunc (p *HelloPlugin) ToStorage() map[string]interface{} {\n\tm := make(map[string]interface{})\n\tm[\"name\"] = p.Name()\n\tm[\"description\"] = p.Desc()\n\tm[\"is_activate\"] = p.isActive\n\treturn m\n}\n\nfunc (p *HelloPlugin) Activate() {\n\tif p.isHandlerRegistered {\n\t\tp.isActive = true\n\t\treturn\n\t}\n\tfn := func(context *GoInk.Context) {\n\t\tnow := time.Now()\n\t\tcontext.On(GoInk.CONTEXT_RENDERED, func() {\n\t\t\tif p.isActive {\n\t\t\t\tduration := time.Since(now)\n\t\t\t\tstr := fmt.Sprint(duration)\n\t\t\t\t//context.Body = append(context.Body, []byte(str)...)\n\t\t\t\tcontext.Header[\"X-Exec-Time\"] = str\n\t\t\t}\n\t\t})\n\t}\n\tHandler(\"hello_plugin\", fn, false)\n\t/*Route(\"hello_handler\", \"GET\", \"/hello/\", func(context *GoInk.Context) {\n\t\tcontext.Body = []byte(\"Hello!\")\n\t})*/\n\tp.isHandlerRegistered = true\n\tp.isActive = true\n}\n\nfunc (p *HelloPlugin) Deactivate() {\n\tp.isActive = false\n}\n\nfunc (p *HelloPlugin) IsActive() bool {\n\treturn p.isActive\n}\n\nfunc (p *HelloPlugin) Version() string {\n\treturn \"0.0.1\"\n}\n\nfunc (p *HelloPlugin) HasSetting() bool {\n\treturn false\n}\n\nfunc (p *HelloPlugin) Form() string {\n\treturn \"\"\n}\n\nfunc (p *HelloPlugin) SetSetting(settings map[string]string) {\n\n}\n"
  },
  {
    "path": "app/plugin/plugin.go",
    "content": "package plugin\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/model\"\n\t\"github.com/fuxiaohei/GoInk\"\n)\n\ntype PluginInterface interface {\n\tName() string\n\tKey() string\n\tDesc() string\n\tVersion() string\n\n\tActivate()\n\tDeactivate()\n\tIsActive() bool\n\n\tHasSetting() bool\n\tForm() string\n\tSetSetting(settings map[string]string)\n\n\tToStorage() map[string]interface{}\n}\n\ntype pluginRoute struct {\n\tMethod  string\n\tPattern string\n\tHandler GoInk.Handler\n}\n\nvar (\n\tpluginStorage map[string]map[string]interface{}\n\tpluginMap     map[string]PluginInterface\n\tmiddleHandler map[string]GoInk.Handler\n\tinterHandler  map[string]GoInk.Handler\n\tusedHandler   map[string]map[string]bool\n\trouteHandler  map[string]pluginRoute\n)\n\nfunc init() {\n\tif pluginMap == nil {\n\t\tpluginMap = make(map[string]PluginInterface)\n\t}\n\t//pluginMap = make(map[string]PluginInterface)\n\tpluginStorage = make(map[string]map[string]interface{})\n\tmiddleHandler = make(map[string]GoInk.Handler)\n\trouteHandler = make(map[string]pluginRoute)\n\tinterHandler = make(map[string]GoInk.Handler)\n\tusedHandler = make(map[string]map[string]bool)\n\tusedHandler[\"middle\"] = make(map[string]bool)\n\tusedHandler[\"inter\"] = make(map[string]bool)\n\tusedHandler[\"route\"] = make(map[string]bool)\n}\n\nfunc Init() {\n\tvar isChanged = false\n\tif model.Storage.Has(\"plugins\") {\n\t\tmodel.Storage.Get(\"plugins\", &pluginStorage)\n\t}\n\t// activate\n\tfor k, p := range pluginMap {\n\t\t_, ok := pluginStorage[k]\n\t\tif !ok {\n\t\t\tpluginStorage[k] = p.ToStorage()\n\t\t\tisChanged = true\n\t\t}\n\t\tif pluginStorage[k][\"is_activate\"].(bool) {\n\t\t\tp.Activate()\n\t\t} else {\n\t\t\tp.Deactivate()\n\t\t}\n\t}\n\t// clean deleted\n\tfor k, _ := range pluginStorage {\n\t\tif pluginMap[k] == nil {\n\t\t\tdelete(pluginStorage, k)\n\t\t\tisChanged = true\n\t\t}\n\t}\n\tif isChanged {\n\t\tmodel.Storage.Set(\"plugins\", pluginStorage)\n\t}\n}\n\nfunc register(plugin PluginInterface) {\n\tif pluginMap == nil {\n\t\tpluginMap = make(map[string]PluginInterface)\n\t}\n\tpluginMap[plugin.Key()] = plugin\n}\n\nfunc Handler(name string, h GoInk.Handler, inter bool) {\n\tif inter {\n\t\tinterHandler[name] = h\n\t} else {\n\t\tmiddleHandler[name] = h\n\t}\n}\n\nfunc Route(name string, method string, pattern string, handler GoInk.Handler) {\n\tpr := pluginRoute{}\n\tpr.Method = method\n\tpr.Handler = handler\n\tpr.Pattern = pattern\n\trouteHandler[name] = pr\n}\n\nfunc Handlers() (map[string]map[string]GoInk.Handler, map[string]pluginRoute) {\n\tm := make(map[string]map[string]GoInk.Handler)\n\tm[\"middle\"] = middleHandler\n\tm[\"inter\"] = interHandler\n\treturn m, routeHandler\n}\n\nfunc GetPlugins() map[string]PluginInterface {\n\treturn pluginMap\n}\n\nfunc GetPluginByKey(key string) PluginInterface {\n\treturn pluginMap[key]\n}\n\nfunc Activate(name string) {\n\tp, ok := pluginMap[name]\n\tif !ok {\n\t\tprintln(\"activate null plugin \" + name)\n\t\treturn\n\t}\n\tp.Activate()\n\tpluginStorage[p.Key()] = p.ToStorage()\n\tmodel.Storage.Set(\"plugins\", pluginStorage)\n\tprintln(\"activate\", p.Key())\n}\n\nfunc Deactivate(name string) {\n\tp, ok := pluginMap[name]\n\tif !ok {\n\t\tprintln(\"deactivate null plugin \" + name)\n\t\treturn\n\t}\n\tp.Deactivate()\n\tpluginStorage[p.Key()] = p.ToStorage()\n\tmodel.Storage.Set(\"plugins\", pluginStorage)\n\tprintln(\"deactivate\", p.Key())\n}\n\nfunc Update(app *GoInk.App) {\n\tpluginHandlers, routeHandlers := Handlers()\n\n\tif len(routeHandlers) > 0 {\n\t\tfor n, h := range routeHandlers {\n\t\t\tif usedHandler[\"route\"][n] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tapp.Route(h.Method, h.Pattern, h.Handler)\n\t\t\tusedHandler[\"route\"][n] = true\n\t\t}\n\t}\n\n\tif len(pluginHandlers[\"middle\"]) > 0 {\n\t\tfor n, h := range pluginHandlers[\"middle\"] {\n\t\t\tif usedHandler[\"middle\"][n] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tapp.Use(h)\n\t\t\tusedHandler[\"middle\"][n] = true\n\t\t\t//println(\"use plugin middle handler\",n)\n\t\t}\n\t\t//fmt.Println(usedHandler)\n\t}\n\n\tif len(pluginHandlers[\"inter\"]) > 0 {\n\t\tfor name, h := range pluginHandlers[\"inter\"] {\n\t\t\tif usedHandler[\"inter\"][name] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif name == \"static\" {\n\t\t\t\tapp.Static(h)\n\t\t\t\tusedHandler[\"inter\"][name] = true\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif name == \"recover\" {\n\t\t\t\tapp.Recover(h)\n\t\t\t\tusedHandler[\"inter\"][name] = true\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif name == \"notfound\" {\n\t\t\t\tapp.NotFound(h)\n\t\t\t\tusedHandler[\"inter\"][name] = true\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "app/upgrade/v20140130.go",
    "content": "package upgrade\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/cmd\"\n\t\"github.com/fuxiaohei/GoBlog/app/model\"\n\t\"github.com/fuxiaohei/GoBlog/app/plugin\"\n\t\"github.com/fuxiaohei/GoInk\"\n\t\"os\"\n\t\"path\"\n)\n\nfunc init() {\n\tcmd.SetUpgradeScript(20140130, upgrade_20140130)\n}\n\nfunc upgrade_20140130(app *GoInk.App) bool {\n\n\t// change settings\n\tmodel.LoadSettings()\n\tmodel.SetSetting(\"c_footer_ga\", \"<!-- google analytics or other -->\")\n\tmodel.SetSetting(\"enable_go_markdown\", \"false\")\n\tmodel.SetSetting(\"enable_go_markdown_def\", \"false\")\n\tmodel.SetSetting(\"site_theme\", \"default\")\n\tmodel.SetSetting(\"site_theme_def\", \"default\")\n\tmodel.SetSetting(\"c_home_avatar\", \"/static/img/site.png\")\n\tmodel.SyncSettings()\n\n\t// init plugin\n\tplugin.Init()\n\tmodel.Storage.Dir(\"plugin\")\n\n\t// remove static files\n\tos.RemoveAll(app.Get(\"view_dir\"))\n\tos.RemoveAll(path.Join(app.Get(\"static_dir\"), \"less\"))\n\tos.RemoveAll(path.Join(app.Get(\"static_dir\"), \"css\"))\n\tos.RemoveAll(path.Join(app.Get(\"static_dir\"), \"img\"))\n\tos.RemoveAll(path.Join(app.Get(\"static_dir\"), \"js\"))\n\tos.RemoveAll(path.Join(app.Get(\"static_dir\"), \"lib\"))\n\tos.Remove(path.Join(app.Get(\"static_dir\"), \"favicon.ico\"))\n\n\t// extract current static files\n\tcmd.ExtractBundleBytes()\n\n\t// \"c_footer_ga\":        \"<!-- google analytics or other -->\",\n\t// \"enable_go_markdown\": \"true\",\n\t// \"enable_go_markdown_def\": \"false\",\n\t// \"site_theme\": \"ling\",\n\t// \"site_theme_def\": \"default\",\n\treturn true\n}\n"
  },
  {
    "path": "app/upgrade/v20140131.go",
    "content": "package upgrade\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/cmd\"\n\t\"github.com/fuxiaohei/GoInk\"\n\t\"os\"\n\t\"path\"\n)\n\nfunc init() {\n\tcmd.SetUpgradeScript(20140131, upgrade_20140131)\n}\n\nfunc upgrade_20140131(app *GoInk.App) bool {\n\n\t// re-write all data to non-indent json\n\t/*model.All()\n\tmodel.SyncContents()\n\tmodel.SyncFiles()\n\tmodel.SyncReaders()\n\tmodel.SyncSettings()\n\tmodel.SyncTokens()\n\tmodel.SyncUsers()\n\tmodel.SyncVersion()*/\n\n\t// update ling template\n\tos.RemoveAll(path.Join(app.Get(\"view_dir\"), \"ling\"))\n\tcmd.ExtractBundleBytes()\n\n\treturn true\n}\n"
  },
  {
    "path": "app/upgrade/v20140209.go",
    "content": "package upgrade\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/cmd\"\n\t\"github.com/fuxiaohei/GoBlog/app/model\"\n\t\"github.com/fuxiaohei/GoInk\"\n\t\"os\"\n\t\"path\"\n)\n\nfunc init() {\n\tcmd.SetUpgradeScript(20140209, upgrade_20140209)\n}\n\nfunc upgrade_20140209(app *GoInk.App) bool {\n\t// clean template\n\tvDir := app.Get(\"view_dir\")\n\tos.Remove(path.Join(vDir, \"admin.layout\"))\n\tos.Remove(path.Join(vDir, \"cmd.layout\"))\n\n\t// write default menu setting\n\tmodel.DefaultNavigators()\n\n\t// write message storage\n\tmodel.Storage.Set(\"messages\",[]*model.Message{})\n\n\tcmd.ExtractBundleBytes()\n\treturn true\n}\n"
  },
  {
    "path": "app/upgrade/v20140228.go",
    "content": "package upgrade\n\nimport (\n\t\"github.com/fuxiaohei/GoBlog/app/cmd\"\n\t\"github.com/fuxiaohei/GoBlog/app/model\"\n\t\"github.com/fuxiaohei/GoInk\"\n)\n\nfunc init() {\n\tcmd.SetUpgradeScript(20140228, upgrade_20140228)\n}\n\nfunc upgrade_20140228(_ *GoInk.App) bool {\n\n\t// change settings\n\tmodel.LoadSettings()\n\tmodel.SetSetting(\"popular_size\", \"4\")\n\tmodel.SetSetting(\"recent_comment_size\", \"3\")\n\tmodel.SetSetting(\"theme_cache\", \"false\")\n\tmodel.SyncSettings()\n\n\t// overwrite zip bundle bytes\n\tcmd.ExtractBundleBytes()\n\treturn true\n}\n"
  },
  {
    "path": "app/utils/avatar.go",
    "content": "package utils\n\nimport (\n\t\"crypto/md5\"\n\t\"fmt\"\n)\n\n// generate gravatar link by email.\nfunc Gravatar(email string, size string) string {\n\tu := \"http://1.gravatar.com/avatar/\"\n\tu += encodeAvatarEmail(email) + \"?s=\" + size\n\treturn u\n}\n\n// encode user password by sha1 with salt string from config.\nfunc encodeAvatarEmail(email string) string {\n\th := md5.New()\n\th.Write([]byte(email))\n\tbs := h.Sum(nil)\n\treturn fmt.Sprintf(\"%x\", bs)\n}\n"
  },
  {
    "path": "app/utils/crypto.go",
    "content": "package utils\n\nimport (\n\t\"crypto/sha1\"\n\t\"fmt\"\n\t\"io\"\n)\n\nfunc Sha1(raw string) string {\n\tt := sha1.New()\n\tio.WriteString(t, raw)\n\treturn fmt.Sprintf(\"%x\", t.Sum(nil))\n}\n"
  },
  {
    "path": "app/utils/date.go",
    "content": "package utils\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// Format unix time int64 to string\nfunc DateInt64(ti int64, format string) string {\n\tt := time.Unix(int64(ti), 0)\n\treturn DateTime(t, format)\n}\n\n// Format unix time string to string\nfunc DateString(ts string, format string) string {\n\ti, _ := strconv.ParseInt(ts, 10, 64)\n\treturn DateInt64(i, format)\n}\n\n// Format time.Time struct to string\n// MM - month - 01\n// M - month - 1, single bit\n// DD - day - 02\n// D - day 2\n// YYYY - year - 2006\n// YY - year - 06\n// HH - 24 hours - 03\n// H - 24 hours - 3\n// hh - 12 hours - 03\n// h - 12 hours - 3\n// mm - minute - 04\n// m - minute - 4\n// ss - second - 05\n// s - second = 5\nfunc DateTime(t time.Time, format string) string {\n\tres := strings.Replace(format, \"MM\", t.Format(\"01\"), -1)\n\tres = strings.Replace(res, \"M\", t.Format(\"1\"), -1)\n\tres = strings.Replace(res, \"DD\", t.Format(\"02\"), -1)\n\tres = strings.Replace(res, \"D\", t.Format(\"2\"), -1)\n\tres = strings.Replace(res, \"YYYY\", t.Format(\"2006\"), -1)\n\tres = strings.Replace(res, \"YY\", t.Format(\"06\"), -1)\n\tres = strings.Replace(res, \"HH\", fmt.Sprintf(\"%02d\", t.Hour()), -1)\n\tres = strings.Replace(res, \"H\", fmt.Sprintf(\"%d\", t.Hour()), -1)\n\tres = strings.Replace(res, \"hh\", t.Format(\"03\"), -1)\n\tres = strings.Replace(res, \"h\", t.Format(\"3\"), -1)\n\tres = strings.Replace(res, \"mm\", t.Format(\"04\"), -1)\n\tres = strings.Replace(res, \"m\", t.Format(\"4\"), -1)\n\tres = strings.Replace(res, \"ss\", t.Format(\"05\"), -1)\n\tres = strings.Replace(res, \"s\", t.Format(\"5\"), -1)\n\treturn res\n}\n\n// Get unix stamp int64 of now\nfunc Now() int64 {\n\treturn time.Now().Unix()\n}\n"
  },
  {
    "path": "app/utils/file.go",
    "content": "package utils\n\nimport (\n\t\"fmt\"\n\t\"os\"\n)\n\nfunc FileSize(size int64) string {\n\ts := float64(size)\n\tif s > 1024*1024 {\n\t\treturn fmt.Sprintf(\"%.1f M\", s/(1024*1024))\n\t}\n\tif s > 1024 {\n\t\treturn fmt.Sprintf(\"%.1f K\", s/1024)\n\t}\n\treturn fmt.Sprintf(\"%f B\", s)\n}\n\nfunc IsFile(path string) bool {\n\tf, e := os.Stat(path)\n\tif e != nil {\n\t\treturn false\n\t}\n\tif f.IsDir() {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc IsDir(path string) bool {\n\tf, e := os.Stat(path)\n\tif e != nil {\n\t\treturn false\n\t}\n\treturn f.IsDir()\n}\n"
  },
  {
    "path": "app/utils/html.go",
    "content": "package utils\n\nimport (\n\t\"github.com/russross/blackfriday\"\n\t\"html/template\"\n\t\"regexp\"\n\t\"strings\"\n)\n\nfunc Html2str(html string) string {\n\tsrc := string(html)\n\n\t//将HTML标签全转换成小写\n\tre, _ := regexp.Compile(\"\\\\<[\\\\S\\\\s]+?\\\\>\")\n\tsrc = re.ReplaceAllStringFunc(src, strings.ToLower)\n\n\t//去除STYLE\n\tre, _ = regexp.Compile(\"\\\\<style[\\\\S\\\\s]+?\\\\</style\\\\>\")\n\tsrc = re.ReplaceAllString(src, \"\")\n\n\t//去除SCRIPT\n\tre, _ = regexp.Compile(\"\\\\<script[\\\\S\\\\s]+?\\\\</script\\\\>\")\n\tsrc = re.ReplaceAllString(src, \"\")\n\n\t//去除所有尖括号内的HTML代码，并换成换行符\n\tre, _ = regexp.Compile(\"\\\\<[\\\\S\\\\s]+?\\\\>\")\n\tsrc = re.ReplaceAllString(src, \"\\n\")\n\n\t//去除连续的换行符\n\tre, _ = regexp.Compile(\"\\\\s{2,}\")\n\tsrc = re.ReplaceAllString(src, \"\\n\")\n\n\treturn strings.TrimSpace(src)\n}\n\nfunc Markdown2Html(text string) string {\n\treturn string(blackfriday.MarkdownCommon([]byte(text)))\n}\n\nfunc Markdown2HtmlTemplate(text string) template.HTML {\n\treturn template.HTML(Markdown2Html(text))\n}\n"
  },
  {
    "path": "app/utils/pager.go",
    "content": "package utils\n\ntype Pager struct {\n\tCurrent   int\n\tSize      int\n\tTotal     int\n\tPages     int\n\tPageSlice []int\n\tBegin     int\n\tEnd       int\n\tPrev      int\n\tNext      int\n\tIsPrev    bool\n\tIsNext    bool\n}\n\nfunc NewPager(page, size, total int) *Pager {\n\tif page < 1 {\n\t\tpage = 1\n\t}\n\tp := new(Pager)\n\tp.Current = page\n\tp.Size = size\n\tp.Total = total\n\tp.Pages = total / size\n\tif total%size > 0 {\n\t\tp.Pages += 1\n\t}\n\tp.PageSlice = make([]int, p.Pages)\n\tfor i := 1; i <= p.Pages; i++ {\n\t\tp.PageSlice[i-1] = i\n\t}\n\tp.Begin = (page-1)*size + 1\n\tif p.Begin < 1 {\n\t\tp.Begin = 1\n\t}\n\tif p.Begin > p.Total {\n\t\tp.Begin = p.Total\n\t}\n\tp.End = page * size\n\tif p.End > p.Total {\n\t\tp.End = p.Total\n\t}\n\tp.Prev = p.Current - 1\n\tp.IsPrev = true\n\tif p.Prev < 1 {\n\t\tp.Prev = 1\n\t\tp.IsPrev = false\n\t}\n\tp.Next = p.Current + 1\n\tp.IsNext = true\n\tif p.Next > p.Pages {\n\t\tp.Next = p.Pages\n\t\tp.IsNext = false\n\t}\n\treturn p\n}\n"
  },
  {
    "path": "app/utils/sorter.go",
    "content": "\npackage utils\n\nimport \"sort\"\n\ntype intSorter [][2]int\n\nfunc (is intSorter) Len() int {\n\treturn len(is)\n}\n\nfunc (is intSorter) Swap(i, j int) {\n\tis[i], is[j] = is[j], is[i]\n}\n\nfunc (is intSorter) Less(i,j int)bool{\n\treturn is[i][1] > is[j][1]\n}\n\n// Sort [][2]int by the second element of [2].\nfunc SortInt(s [][2]int){\n\tsort.Sort(intSorter(s))\n}\n"
  },
  {
    "path": "app/utils/validator.go",
    "content": "package utils\n\nimport (\n\t\"regexp\"\n\t\"strings\"\n)\n\nvar (\n\tregexEmail   *regexp.Regexp\n\tregexASCII   *regexp.Regexp\n\tregexEnglish *regexp.Regexp\n\tregexURL     *regexp.Regexp\n)\n\nfunc init() {\n\tregexEmail, _ = regexp.Compile(`(?i)[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\\.)+[A-Z]{2,6}`)\n\tregexASCII, _ = regexp.Compile(`^[a-zA-Z0-9-]+$`)\n\tregexEnglish, _ = regexp.Compile(`^[a-zA-Z]+$`)\n\tregexURL, _ = regexp.Compile(`(ftp|http|https):\\/\\/(\\w+:{0,1}\\w*@)?(\\S+)(:[0-9]+)?(\\/|\\/([\\w#!:.?+=&%@!\\-\\/]))?`)\n}\n\nfunc IsEmptyString(str string) bool {\n\treturn len(str) == 0\n}\n\nfunc IsEmail(str string) bool {\n\treturn regexEmail.MatchString(str)\n}\n\nfunc IsURL(str string) bool {\n\treturn regexURL.MatchString(str)\n}\n\nfunc IsLonger(str string, length int) bool {\n\treturn len(str) > length\n}\n\nfunc IsShorter(str string, length int) bool {\n\treturn len(str) < length\n}\n\nfunc IsASCII(str string) bool {\n\treturn regexASCII.MatchString(str)\n}\n\nfunc IsEnglish(str string) bool {\n\treturn regexEnglish.MatchString(str)\n}\n\nfunc IsContain(str string, contain string) bool {\n\treturn strings.Contains(str, contain)\n}\n"
  },
  {
    "path": "main.go",
    "content": "package main\n\nimport \"github.com/fuxiaohei/GoBlog/app\"\n\nfunc main() {\n\tapp.Cmd()\n\tapp.Init()\n\tapp.Run()\n}\n"
  },
  {
    "path": "static/css/admin.css",
    "content": "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}"
  },
  {
    "path": "static/css/cmd.css",
    "content": "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}"
  },
  {
    "path": "static/css/codemirror.css",
    "content": "/* BASICS */\n\n.CodeMirror {\n    /* Set height, width, borders, and global font properties here */\n    font-family: Consolas, \"Microsoft YaHei\", \"Courier New\", Arial;\n    height: 660px;\n    font-size: 13px;\n    border:1px solid #999;\n}\n\n.CodeMirror-scroll {\n    /* Set scrolling behaviour here */\n    overflow: auto;\n}\n\n/* PADDING */\n\n.CodeMirror-lines {\n    padding: 4px 0; /* Vertical padding around content */\n}\n\n.CodeMirror pre {\n    padding: 0 4px; /* Horizontal padding of content */\n}\n\n.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {\n    background-color: white; /* The little square between H and V scrollbars */\n}\n\n/* GUTTER */\n\n.CodeMirror-gutters {\n    border-right: 1px solid #ddd;\n    background-color: #f7f7f7;\n    white-space: nowrap;\n}\n\n.CodeMirror-linenumbers {\n}\n\n.CodeMirror-linenumber {\n    padding: 0 3px 0 5px;\n    min-width: 20px;\n    text-align: right;\n    color: #555;\n    line-height: 20px;\n}\n\n/* CURSOR */\n\n.CodeMirror div.CodeMirror-cursor {\n    border-left: 1px solid black;\n    z-index: 3;\n}\n\n/* Shown when moving in bi-directional text */\n.CodeMirror div.CodeMirror-secondarycursor {\n    border-left: 1px solid silver;\n}\n\n.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {\n    width: auto;\n    border: 0;\n    background: #7e7;\n    z-index: 1;\n}\n\n/* Can style cursor different in overwrite (non-insert) mode */\n.CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {\n}\n\n.cm-tab {\n    display: inline-block;\n}\n\n/* DEFAULT THEME */\n\n.cm-s-default .cm-keyword {\n    color: #708;\n}\n\n.cm-s-default .cm-atom {\n    color: #219;\n}\n\n.cm-s-default .cm-number {\n    color: #164;\n}\n\n.cm-s-default .cm-def {\n    color: #00f;\n}\n\n.cm-s-default .cm-variable {\n    color: black;\n}\n\n.cm-s-default .cm-variable-2 {\n    color: #05a;\n}\n\n.cm-s-default .cm-variable-3 {\n    color: #085;\n}\n\n.cm-s-default .cm-property {\n    color: black;\n}\n\n.cm-s-default .cm-operator {\n    color: black;\n}\n\n.cm-s-default .cm-comment {\n    color: #a50;\n}\n\n.cm-s-default .cm-string {\n    color: #a11;\n}\n\n.cm-s-default .cm-string-2 {\n    color: #f50;\n}\n\n.cm-s-default .cm-meta {\n    color: #555;\n}\n\n.cm-s-default .cm-qualifier {\n    color: #555;\n}\n\n.cm-s-default .cm-builtin {\n    color: #30a;\n}\n\n.cm-s-default .cm-bracket {\n    color: #997;\n}\n\n.cm-s-default .cm-tag {\n    color: #170;\n}\n\n.cm-s-default .cm-attribute {\n    color: #00c;\n}\n\n.cm-s-default .cm-header {\n    color: blue;\n}\n\n.cm-s-default .cm-quote {\n    color: #090;\n}\n\n.cm-s-default .cm-hr {\n    color: #999;\n}\n\n.cm-s-default .cm-link {\n    color: #00c;\n}\n\n.cm-negative {\n    color: #d44;\n}\n\n.cm-positive {\n    color: #292;\n}\n\n.cm-header, .cm-strong {\n    font-weight: bold;\n}\n\n.cm-em {\n    font-style: italic;\n}\n\n.cm-link {\n    text-decoration: underline;\n}\n\n.cm-s-default .cm-error {\n    color: #f00;\n}\n\n.cm-invalidchar {\n    color: #f00;\n}\n\ndiv.CodeMirror span.CodeMirror-matchingbracket {\n    color: #0f0;\n}\n\ndiv.CodeMirror span.CodeMirror-nonmatchingbracket {\n    color: #f22;\n}\n\n.CodeMirror-activeline-background {\n    background: #e8f2ff;\n}\n\n/* STOP */\n\n/* The rest of this file contains styles related to the mechanics of\n   the editor. You probably shouldn't touch them. */\n\n.CodeMirror {\n    line-height: 1;\n    position: relative;\n    overflow: hidden;\n    background: white;\n    color: black;\n}\n\n.CodeMirror-scroll {\n    /* 30px is the magic margin used to hide the element's real scrollbars */\n    /* See overflow: hidden in .CodeMirror */\n    margin-bottom: -30px;\n    margin-right: -30px;\n    padding-bottom: 30px;\n    padding-right: 30px;\n    height: 100%;\n    outline: none; /* Prevent dragging from highlighting the element */\n    position: relative;\n    -moz-box-sizing: content-box;\n    box-sizing: content-box;\n}\n\n.CodeMirror-sizer {\n    position: relative;\n}\n\n/* The fake, visible scrollbars. Used to force redraw during scrolling\n   before actuall scrolling happens, thus preventing shaking and\n   flickering artifacts. */\n.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {\n    position: absolute;\n    z-index: 6;\n    display: none;\n}\n\n.CodeMirror-vscrollbar {\n    right: 0;\n    top: 0;\n    overflow-x: hidden;\n    overflow-y: scroll;\n}\n\n.CodeMirror-hscrollbar {\n    bottom: 0;\n    left: 0;\n    overflow-y: hidden;\n    overflow-x: scroll;\n}\n\n.CodeMirror-scrollbar-filler {\n    right: 0;\n    bottom: 0;\n}\n\n.CodeMirror-gutter-filler {\n    left: 0;\n    bottom: 0;\n}\n\n.CodeMirror-gutters {\n    position: absolute;\n    left: 0;\n    top: 0;\n    padding-bottom: 30px;\n    z-index: 3;\n}\n\n.CodeMirror-gutter {\n    white-space: normal;\n    height: 100%;\n    -moz-box-sizing: content-box;\n    box-sizing: content-box;\n    padding-bottom: 30px;\n    margin-bottom: -32px;\n    display: inline-block;\n    /* Hack to make IE7 behave */\n    *zoom: 1;\n    *display: inline;\n}\n\n.CodeMirror-gutter-elt {\n    position: absolute;\n    cursor: default;\n    z-index: 4;\n}\n\n.CodeMirror-lines {\n    cursor: text;\n}\n\n.CodeMirror pre {\n    /* Reset some styles that the rest of the page might have set */\n    -moz-border-radius: 0;\n    -webkit-border-radius: 0;\n    border-radius: 0;\n    border-width: 0;\n    background: transparent;\n    font-family: inherit;\n    font-size: inherit;\n    margin: 0;\n    line-height: 20px;\n    color: inherit;\n    z-index: 2;\n    position: relative;\n    overflow: visible;\n    word-wrap: break-word;\n    white-space: pre-wrap;\n    word-break: break-all;\n}\n\n.CodeMirror-wrap pre {\n    word-wrap: break-word;\n    white-space: pre-wrap;\n    word-break: normal;\n}\n\n.CodeMirror-code pre {\n    width: -webkit-fit-content;\n    width: -moz-fit-content;\n    width: fit-content;\n}\n\n.CodeMirror-wrap .CodeMirror-code pre {\n    border-right: none;\n    width: auto;\n}\n\n.CodeMirror-linebackground {\n    position: absolute;\n    left: 0;\n    right: 0;\n    top: 0;\n    bottom: 0;\n    z-index: 0;\n}\n\n.CodeMirror-linewidget {\n    position: relative;\n    z-index: 2;\n    overflow: auto;\n}\n\n.CodeMirror-widget {\n}\n\n.CodeMirror-wrap .CodeMirror-scroll {\n    overflow-x: hidden;\n}\n\n.CodeMirror-measure {\n    position: absolute;\n    width: 100%;\n    height: 0;\n    overflow: hidden;\n    visibility: hidden;\n}\n\n.CodeMirror-measure pre {\n    position: static;\n}\n\n.CodeMirror div.CodeMirror-cursor {\n    position: absolute;\n    visibility: hidden;\n    border-right: none;\n    width: 0;\n}\n\n.CodeMirror-focused div.CodeMirror-cursor {\n    visibility: visible;\n}\n\n.CodeMirror-selected {\n    background: #d9d9d9;\n}\n\n.CodeMirror-focused .CodeMirror-selected {\n    background: #d7d4f0;\n}\n\n.cm-searching {\n    background: #ffa;\n    background: rgba(255, 255, 0, .4);\n}\n\n/* IE7 hack to prevent it from returning funny offsetTops on the spans */\n.CodeMirror span {\n    *vertical-align: text-bottom;\n}\n\n@media print {\n    /* Hide the cursor when printing */\n    .CodeMirror div.CodeMirror-cursor {\n        visibility: hidden;\n    }\n}\n\n.cm-s-base16-dark.CodeMirror {\n    background: #151515;\n    color: #e0e0e0;\n}\n\n.cm-s-base16-dark div.CodeMirror-selected {\n    background: #202020 !important;\n}\n\n.cm-s-base16-dark .CodeMirror-gutters {\n    background: #151515;\n    border-right: 0px;\n}\n\n.cm-s-base16-dark .CodeMirror-linenumber {\n    color: #555;\n}\n\n.cm-s-base16-dark .CodeMirror-cursor {\n    border-left: 1px solid #b0b0b0 !important;\n}\n\n.cm-s-base16-dark span.cm-comment {\n    color: #8f5536;\n}\n\n.cm-s-base16-dark span.cm-atom {\n    color: #aa759f;\n}\n\n.cm-s-base16-dark span.cm-number {\n    color: #aa759f;\n}\n\n.cm-s-base16-dark span.cm-property, .cm-s-base16-dark span.cm-attribute {\n    color: #90a959;\n}\n\n.cm-s-base16-dark span.cm-keyword {\n    color: #ac4142;\n}\n\n.cm-s-base16-dark span.cm-string {\n    color: #f4bf75;\n}\n\n.cm-s-base16-dark span.cm-variable {\n    color: #90a959;\n}\n\n.cm-s-base16-dark span.cm-variable-2 {\n    color: #6a9fb5;\n}\n\n.cm-s-base16-dark span.cm-def {\n    color: #d28445;\n}\n\n.cm-s-base16-dark span.cm-bracket {\n    color: #e0e0e0;\n}\n\n.cm-s-base16-dark span.cm-tag {\n    color: #ac4142;\n}\n\n.cm-s-base16-dark span.cm-link {\n    color: #aa759f;\n}\n\n.cm-s-base16-dark span.cm-error {\n    background: #ac4142;\n    color: #b0b0b0;\n}\n\n.cm-s-base16-dark .CodeMirror-activeline-background {\n    background: #2F2F2F !important;\n}\n\n.cm-s-base16-dark .CodeMirror-matchingbracket {\n    text-decoration: underline;\n    color: white !important;\n}\n"
  },
  {
    "path": "static/css/common.css",
    "content": "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}"
  },
  {
    "path": "static/css/highlight.css",
    "content": "/*\n\nSunburst-like style (c) Vasily Polovnyov <vast@whiteants.net>\n\n*/\n\npre code {\n    display: block; padding: 0.5em;\n    background: #000; color: #f8f8f8;\n}\n\npre .comment,\npre .template_comment,\npre .javadoc {\n    color: #aeaeae;\n    font-style: italic;\n}\n\npre .keyword,\npre .ruby .function .keyword,\npre .request,\npre .status,\npre .nginx .title {\n    color: #E28964;\n}\n\npre .function .keyword,\npre .sub .keyword,\npre .method,\npre .list .title {\n    color: #99CF50;\n}\n\npre .string,\npre .tag .value,\npre .cdata,\npre .filter .argument,\npre .attr_selector,\npre .apache .cbracket,\npre .date,\npre .tex .command,\npre .coffeescript .attribute {\n    color: #65B042;\n}\n\npre .subst {\n    color: #DAEFA3;\n}\n\npre .regexp {\n    color: #E9C062;\n}\n\npre .title,\npre .sub .identifier,\npre .pi,\npre .tag,\npre .tag .keyword,\npre .decorator,\npre .shebang,\npre .prompt {\n    color: #89BDFF;\n}\n\npre .class .title,\npre .haskell .type,\npre .smalltalk .class,\npre .javadoctag,\npre .yardoctag,\npre .phpdoc {\n    text-decoration: underline;\n}\n\npre .symbol,\npre .ruby .symbol .string,\npre .number {\n    color: #3387CC;\n}\n\npre .params,\npre .variable,\npre .clojure .attribute {\n    color: #3E87E3;\n}\n\npre .css .tag,\npre .rules .property,\npre .pseudo,\npre .tex .special {\n    color: #CDA869;\n}\n\npre .css .class {\n    color: #9B703F;\n}\n\npre .rules .keyword {\n    color: #C5AF75;\n}\n\npre .rules .value {\n    color: #CF6A4C;\n}\n\npre .css .id {\n    color: #8B98AB;\n}\n\npre .annotation,\npre .apache .sqbracket,\npre .nginx .built_in {\n    color: #9B859D;\n}\n\npre .preprocessor,\npre .pragma {\n    color: #8996A8;\n}\n\npre .hexcolor,\npre .css .value .number {\n    color: #DD7B3B;\n}\n\npre .css .function {\n    color: #DAD085;\n}\n\npre .diff .header,\npre .chunk,\npre .tex .formula {\n    background-color: #0E2231;\n    color: #F8F8F8;\n    font-style: italic;\n}\n\npre .diff .change {\n    background-color: #4A410D;\n    color: #F8F8F8;\n}\n\npre .addition {\n    background-color: #253B22;\n    color: #F8F8F8;\n}\n\npre .deletion {\n    background-color: #420E09;\n    color: #F8F8F8;\n}\n\npre .coffeescript .javascript,\npre .javascript .xml,\npre .tex .formula,\npre .xml .javascript,\npre .xml .vbscript,\npre .xml .css,\npre .xml .cdata {\n    opacity: 0.5;\n}\n\npre .go .typename{\n    color: #ffbc54;\n}"
  },
  {
    "path": "static/css/ling.css",
    "content": "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}}"
  },
  {
    "path": "static/css/saber.css",
    "content": "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}}"
  },
  {
    "path": "static/css/sitemap.xsl",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xsl:stylesheet version=\"2.0\" \n                xmlns:html=\"http://www.w3.org/TR/REC-html40\"\n                xmlns:sitemap=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n                xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n\t<xsl:output method=\"html\" version=\"1.0\" encoding=\"UTF-8\" indent=\"yes\"/>\n\t<xsl:template match=\"/\">\n\t\t<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\t\t\t<head>\n\t\t\t\t<title>XML Sitemap</title>\n\t\t\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n\t\t\t\t<style type=\"text/css\">\n\t\t\t\t\tbody {\n\t\t\t\t\t\tfont-family:\"Lucida Grande\",\"Lucida Sans Unicode\",Tahoma,Verdana;\n\t\t\t\t\t\tfont-size:13px;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t#intro {\n\t\t\t\t\t\tbackground-color:#CFEBF7;\n\t\t\t\t\t\tborder:1px #2580B2 solid;\n\t\t\t\t\t\tpadding:5px 13px 5px 13px;\n\t\t\t\t\t\tmargin:10px;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t#intro p {\n\t\t\t\t\t\tline-height:\t16.8667px;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\ttd {\n\t\t\t\t\t\tfont-size:11px;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tth {\n\t\t\t\t\t\ttext-align:left;\n\t\t\t\t\t\tpadding-right:30px;\n\t\t\t\t\t\tfont-size:11px;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\ttr.high {\n\t\t\t\t\t\tbackground-color:whitesmoke;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t#footer {\n\t\t\t\t\t\tpadding:2px;\n\t\t\t\t\t\tmargin:10px;\n\t\t\t\t\t\tfont-size:8pt;\n\t\t\t\t\t\tcolor:gray;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t#footer a {\n\t\t\t\t\t\tcolor:gray;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\ta {\n\t\t\t\t\t\tcolor:black;\n\t\t\t\t\t}\n\t\t\t\t</style>\n\t\t\t</head>\n\t\t\t<body>\n\t\t\t\t<h1>XML Sitemap</h1>\n\t\t\t\t<div id=\"intro\">\n\t\t\t\t\t<p>\n\t\t\t\t\t\tThis is a XML Sitemap which is supposed to be processed by search engines like <a href=\"http://www.google.com\">Google</a>, <a href=\"http://search.msn.com\">MSN Search</a> and <a href=\"http://www.yahoo.com\">YAHOO</a>.<br />\n\t\t\t\t\t\t<!--It was generated using the Blogging-Software <a href=\"http://wordpress.org/\">WordPress</a> and the <a href=\"http://www.arnebrachhold.de/redir/sitemap-home/\" title=\"Google Sitemap Generator Plugin for WordPress\">Google Sitemap Generator Plugin</a> by <a href=\"http://www.arnebrachhold.de/\">Arne Brachhold</a>.<br />-->\n\t\t\t\t\t\tYou can find more information about XML sitemaps on <a href=\"http://sitemaps.org\">sitemaps.org</a> and Google's <a href=\"http://code.google.com/sm_thirdparty.html\">list of sitemap programs</a>.\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"content\">\n\t\t\t\t\t<table cellpadding=\"5\">\n\t\t\t\t\t\t<tr style=\"border-bottom:1px black solid;\">\n\t\t\t\t\t\t\t<th>URL</th>\n\t\t\t\t\t\t\t<th>Priority</th>\n\t\t\t\t\t\t\t<th>Change Frequency</th>\n\t\t\t\t\t\t\t<th>LastChange (GMT)</th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t<xsl:variable name=\"lower\" select=\"'abcdefghijklmnopqrstuvwxyz'\"/>\n\t\t\t\t\t\t<xsl:variable name=\"upper\" select=\"'ABCDEFGHIJKLMNOPQRSTUVWXYZ'\"/>\n\t\t\t\t\t\t<xsl:for-each select=\"sitemap:urlset/sitemap:url\">\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<xsl:if test=\"position() mod 2 != 1\">\n\t\t\t\t\t\t\t\t\t<xsl:attribute  name=\"class\">high</xsl:attribute>\n\t\t\t\t\t\t\t\t</xsl:if>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t<xsl:variable name=\"itemURL\">\n\t\t\t\t\t\t\t\t\t\t<xsl:value-of select=\"sitemap:loc\"/>\n\t\t\t\t\t\t\t\t\t</xsl:variable>\n\t\t\t\t\t\t\t\t\t<a href=\"{$itemURL}\">\n\t\t\t\t\t\t\t\t\t\t<xsl:value-of select=\"sitemap:loc\"/>\n\t\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t<xsl:value-of select=\"concat(sitemap:priority*100,'%')\"/>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t<xsl:value-of select=\"concat(translate(substring(sitemap:changefreq, 1, 1),concat($lower, $upper),concat($upper, $lower)),substring(sitemap:changefreq, 2))\"/>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t<xsl:value-of select=\"concat(substring(sitemap:lastmod,0,11),concat(' ', substring(sitemap:lastmod,12,5)))\"/>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t</xsl:for-each>\n\t\t\t\t\t</table>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"footer\">\n\t\t\t\t\tGenerated with <a href=\"http://www.arnebrachhold.de/redir/sitemap-home/\" title=\"Google Sitemap Generator Plugin for WordPress\">Google Sitemap Generator Plugin for WordPress</a> by <a href=\"http://www.arnebrachhold.de/\">Arne Brachhold</a>. This XSLT template is released under GPL.\n\t\t\t\t</div>\n\t\t\t</body>\n\t\t</html>\n\t</xsl:template>\n</xsl:stylesheet>"
  },
  {
    "path": "static/css/style.css",
    "content": "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}}"
  },
  {
    "path": "static/js/home.js",
    "content": "$(document).ready(function () {\n    //fixHeader();\n    topButton();\n    renderMarkdown();\n    initComment();\n});\n\nfunction fixHeader() {\n    var $nav = $('#nav');\n    var top = $nav.offset().top;\n    console.log(top);\n    $(window).scroll(function () {\n        if (top < $(this).scrollTop()) {\n            $nav.addClass(\"fixed\").removeClass(\"text-center\");\n        } else {\n            $nav.removeClass(\"fixed\").addClass(\"text-center\");\n        }\n    });\n}\n\nfunction topButton() {\n    var top = $('#nav').offset().top;\n    var $top = $('#go-top');\n    $(window).scroll(function () {\n        if (top < $(this).scrollTop()) {\n            $top.removeClass(\"hide\");\n        } else {\n            $top.addClass('hide');\n        }\n    });\n    $top.on(\"click\", function () {\n        $('body,html').animate({scrollTop: 0}, 500);\n        return false;\n    })\n}\n\nfunction renderMarkdown() {\n    var $md = $('.markdown');\n    $md.each(function (i, item) {\n        $(item).html(marked($(item).html().replace(/&gt;/g, '>')));\n    });\n    var code = $md.find('pre code');\n    if (code.length) {\n        $(\"<link>\").attr({ rel: \"stylesheet\", type: \"text/css\", href: \"/static/css/highlight.css\"}).appendTo(\"head\");\n        $.getScript(\"/static/lib/highlight.min.js\", function () {\n            code.each(function (i, item) {\n                hljs.highlightBlock(item)\n            });\n        });\n    }\n}\n\nfunction initComment() {\n    var $list = $('#comment-list');\n    if (!$list.length) {\n        return;\n    }\n    if (localStorage.getItem(\"comment-author\")) {\n        $('#comment-author').val(localStorage.getItem(\"comment-author\"));\n        $('#comment-email').val(localStorage.getItem(\"comment-email\"));\n        $('#comment-url').val(localStorage.getItem(\"comment-url\"));\n        $('#comment-avatar').attr(\"src\", localStorage.getItem(\"comment-avatar\"));\n        $('.c-avatar').removeClass(\"null\");\n    }\n    $('#comment-content').on(\"focus\", function () {\n        if ($('.c-avatar').hasClass(\"null\")) {\n            $('.c-avatar-field').remove();\n            $('.c-info-fields').removeClass(\"hide\");\n        }\n    });\n    $('.not-me').on(\"click\", function () {\n        $('.c-avatar-field').remove();\n        $('.c-info-fields').removeClass(\"hide\");\n        return false;\n    });\n    $('#comment-show').on(\"click\", \".enable\", function () {\n        $(\"#comment-show\").remove();\n        $('#comment-form').removeClass(\"hide\");\n    });\n    $('#comment-form').ajaxForm(function (json) {\n        if (json.res) {\n            localStorage.setItem(\"comment-author\", $('#comment-author').val());\n            localStorage.setItem(\"comment-email\", $('#comment-email').val());\n            localStorage.setItem(\"comment-url\", $('#comment-url').val());\n            localStorage.setItem(\"comment-avatar\", json.comment.avatar);\n            var tpl = $($('#comment-tpl').html());\n            tpl.find(\".c-avatar\").attr(\"src\", json.comment.avatar).attr(\"alt\", json.comment.author);\n            tpl.find(\".c-author\").attr(\"href\", json.comment.url).text(json.comment.author);\n            tpl.find(\".c-reply\").attr(\"rel\", json.comment.id);\n            tpl.find(\".c-content\").html(json.comment.content);\n            if (json.comment.parent_md) {\n                tpl.find(\".c-p-md\").html(marked(json.comment.parent_md));\n            } else {\n                tpl.find(\".c-p-md\").remove();\n            }\n            tpl.attr(\"id\", \"comment-\" + json.comment.id);\n            if (json.comment.status == \"approved\") {\n                tpl.find(\".c-check\").remove();\n            }\n            $list.append(tpl);\n            $('.cancel-reply').trigger(\"click\");\n            $('#comment-content').val(\"\");\n        } else {\n            alert(\"提交失败!\");\n        }\n    });\n    $list.on(\"click\", \".c-reply\", function () {\n        $('.reply-md').remove();\n        var id = $(this).attr(\"rel\");\n        var pc = $('#comment-' + id);\n        var md = \"> @\" + pc.find(\".c-author\").text() + \"\\n\\n\";\n        md += \"> \" + pc.find(\".c-content\").html() + \"\\n\";\n        $('#comment-content').before('<div class=\"reply-md markdown\">' + marked(md) + '</div>');\n        $('#comment-parent').val(id);\n        if ($('#comment-show').length) {\n            $('#comment-show .enable').trigger(\"click\");\n        }\n        $('.cancel-reply').show();\n        var top = $('#comment-form').offset().top;\n        $('body,html').animate({scrollTop: top}, 500);\n        return false;\n    });\n    $('.cancel-reply').on(\"click\", function () {\n        $('.reply-md').remove();\n        $('#comment-parent').val(0);\n        $(this).hide();\n        return false;\n    });\n}\n"
  },
  {
    "path": "static/js/upload.js",
    "content": "function initUpload(p) {\n    $('#attach-show').on(\"click\", function () {\n        $('#attach-upload').trigger(\"click\");\n    });\n    $('#attach-upload').on(\"change\", function () {\n        if (confirm(\"立即上传?\")) {\n            var bar = $('<p class=\"file-progress inline-block\">0%</p>');\n            $('#attach-form').ajaxSubmit({\n                \"beforeSubmit\": function () {\n                    $(p).before(bar);\n                },\n                \"uploadProgress\": function (event, position, total, percentComplete) {\n                    var percentVal = percentComplete + '%';\n                    bar.css(\"width\", percentVal).html(percentVal);\n                },\n                \"success\": function (json) {\n                    if (!json.res) {\n                        bar.html(json.msg).addClass(\"err\");\n                        setTimeout(function () {\n                            bar.remove();\n                        }, 5000);\n                    } else {\n                        bar.html(\"/\" + json.file.Url + \"&nbsp;&nbsp;&nbsp;(@\" + json.file.Name + \")\");\n                    }\n                    $('#attach-upload').val(\"\");\n                }\n            });\n        } else {\n            $(this).val(\"\");\n        }\n    });\n}"
  },
  {
    "path": "static/koala-config.json",
    "content": "{\n\t\"mappings\": [\n\t\t{\n\t\t\t\"src\": \"less\",\n\t\t\t\"dest\": \"css\"\n\t\t}\n\t],\n\n\t\"ignores\": [\"*.css\"],\n\n\t\"options\": {\n\n\t\t\"outputStyle\": \"compress\",\n\n\n\t\t\"lineComments\": true,\n\n\t\t\"debugInfo\": false,\n\n\t\t\"strictMath\": true,\n\n\t\t\"strictUnits\": false\n\t},\n\n\t\"customOptions\": [],\n\n\t\"includePaths\": []\n}"
  },
  {
    "path": "static/less/admin.less",
    "content": "@import \"common\";\n\n#header {\n  height: 39px;\n  background-color: @white0;\n  border-bottom: 1px solid @black3;\n  line-height: 39px;\n  .box-shadow(0, 0, 2px, @gray1);\n  .nav {\n    > a {\n      display: inline-block;\n      padding: 0 18px;\n      border-left: 1px solid @gray1;\n      border-right: 1px solid @gray1;\n      color: @black2;\n      &:hover {\n        border-color: @blue1;\n        background-color: @blue1;\n        color: @white1;\n      }\n      margin-left: -1px;\n    }\n  }\n  .logo {\n    line-height: 36px;\n    padding: 0 14px 0 0;\n    margin: 0;\n    font-size: 14px;\n  }\n  .nav-item {\n    display: inline-block;\n    padding: 0 18px;\n    border-left: 1px solid @gray1;\n    border-right: 1px solid @gray1;\n    color: @black2;\n    margin-right: -1px;\n    &:hover {\n      background-color: @gray3;\n    }\n  }\n  .out {\n    color: @red2;\n    &:hover {\n      border-color: @red1;\n      background-color: @red1;\n      color: @white1;\n    }\n  }\n}\n\n#footer{\n  padding: 24px;\n  background: @white3;\n  border-top: 1px solid @gray2;\n  margin-top: 30px;\n  color: @black3;\n  font-size: 12px;\n  p{\n    margin-bottom: 0;\n  }\n  a{\n    color: @black3;\n    padding:6px 12px;\n    &:hover{\n      border-bottom: 1px dashed @gray0;\n    }\n  }\n}\n\n.admin {\n  margin: 24px auto 48px auto;\n}\n\n#profile {\n  width: 800px;\n  .admin;\n  .avatar {\n    img {\n      width: 180px;\n      padding: 4px;\n      background-color: @white0;\n      border: 1px solid @gray2;\n      .border-radius(4px);\n      height: 180px;\n    }\n  }\n  .ipt {\n    width: 280px;\n  }\n  .invalid {\n    margin-left: 75px;\n  }\n  .bio{\n    margin-left: 75px;\n    height: 160px;\n  }\n}\n\n#password {\n  width: 400px;\n  .admin;\n  .invalid {\n    margin-left: 75px;\n  }\n}\n\n#article-list {\n  li {\n    .bottom-line(8px);\n    > * {\n      margin-right: 16px;\n    }\n    .time, .comment {\n      font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n      color: @black3;\n    }\n    .comment {\n      color: @green2;\n      .fa {\n        margin-right: 6px;\n      }\n    }\n    .is-comment {\n      color: @red0;\n      .fa {\n        margin-right: 6px;\n      }\n    }\n    .del, .edit {\n      opacity: 0;\n    }\n    &:hover {\n      .del, .edit {\n        opacity: 1;\n      }\n    }\n    &:first-child {\n      h4 {\n        padding-top: 0;\n      }\n    }\n  }\n  margin-bottom: 24px;\n}\n\n#article-form {\n  .admin;\n  input.title {\n    width: 100%;\n    box-sizing: border-box;\n    border-bottom: none;\n    margin-bottom: -1px;\n    font-size: 18px;\n  }\n  select {\n    padding: 4px 6px;\n  }\n  .preview {\n    border: 1px solid #999;\n    background-color: @white0;\n    box-sizing: border-box;\n    padding: 0 12px;\n    height: 700px;\n    margin-left: -1px;\n    border-radius: 2px;\n    overflow-x: scroll;\n  }\n  .form-vertical{\n    width: 100%;\n    margin-top: 18px;\n    input.ipt{\n      width: 300px;\n    }\n    .item{\n      float: left;\n      margin-right: 18px;\n    }\n    .btn{\n      margin-right: 16px;\n    }\n    .invalid{\n      display: inline;\n    }\n  }\n  .file-progress{\n    padding: 0 12px;\n    background: fade(@blue0,20%);\n    color: @black2;\n    font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n    box-sizing: border-box;\n    .border-radius(2px);\n  }\n  .file-progress.err{\n    background: fade(@red0,20%);\n    color: @red3;\n  }\n}\n\n#setting-nav{\n  width: 1000px;\n  margin-top: 24px;\n  li{\n    display: inline-block;\n    margin: 0 12px;\n    a{\n      padding:3px 10px;\n    }\n    a:hover,a.current{\n      border-bottom: 2px solid @blue2;\n    }\n  }\n  .bottom-line(12px);\n}\n\n.setting-panel{\n  display: none;\n}\n\n.setting-form {\n  width: 820px;\n  .admin;\n  .ipt {\n    width: 480px;\n  }\n  .invalid {\n    margin-left: 75px;\n  }\n  label{\n    min-width: 10em;\n  }\n  .tip.block{\n    margin-left: 12em;\n  }\n}\n\n#setting-custom-form{\n  width: 1000px;\n  input.key{\n    width: 240px;\n  }\n  input.value{\n    width: 640px;\n  }\n  .item{\n    .bottom-line(12px);\n  }\n  .del{\n    margin-left: 12px;\n    color: @red1;\n    font-size: 12px;\n  }\n  .tip{\n    margin-left: 0;\n  }\n}\n\n#setting-nav-form{\n  width:1000px;\n  .item{\n    .bottom-line(12px);\n  }\n  span.label{\n    margin-right: 6px;\n  }\n  input.order{\n    width: 2.5em;\n    min-width: 0;\n  }\n  input.text{\n    width: 80px;\n    min-width: 0;\n  }\n  input.title{\n    width: 150px;\n    min-width: 0;\n  }\n  input.link{\n    width: 340px;\n  }\n  .del{\n    margin-left: 12px;\n    color: @red1;\n  }\n}\n\n#comment-list{\n  .c-avatar{\n    width: 48px;\n    height: 48px;\n    padding: 2px;\n    border: 1px solid @gray1;\n    .border-radius(2px);\n    margin-right: 18px;\n  }\n  .comment{\n    .bottom-line(12px);\n  }\n  .c-meta{\n    > *{\n      margin-right: 16px;\n    }\n  }\n  .c-time{\n    color: @black3;\n    font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n    .fa{\n      margin-right: 6px;\n    }\n  }\n  .c-cnt,.c-email{\n    color: @black3;\n    font-size: 12px;\n  }\n  .c-author{\n    font-size: 13px;\n  }\n  .c-author.admin{\n    .lbl-red;\n  }\n  .c-p-md{\n    margin-top: 8px;\n    font-size: 12px;\n    line-height: 18px;\n    color: @black2;\n  }\n  .c-section{\n    max-width: 830px;\n  }\n  .c-check,.c-del{\n    color: @red1;\n    .fa{\n      margin-right: 6px;\n    }\n    &:hover{\n      color: @red3;\n    }\n  }\n  .c-reply,.c-check,.c-del{\n    font-size: 12px;\n  }\n}\n\n#comment-form{\n  padding-top: 12px;\n  .btn{\n    margin-right: 24px;\n  }\n  display: none;\n  margin-left: 72px;\n}\n\n#comment-content{\n  width: 500px;\n  height: 80px;\n  margin-right: 24px;\n}\n\n#files-list{\n  li.file{\n      .bottom-line(8px);\n    >*{\n      margin-right: 16px;\n    }\n    &:hover{\n      .del{\n        opacity: 1 !important;\n      }\n    }\n  }\n  .upload-time{\n    color: @black3;\n    font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n  }\n  .del{\n    color: @red1;\n  }\n  .file-progress{\n    padding: 0 12px;\n    background: fade(@blue0,20%);\n    color: @black2;\n    font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n    box-sizing: border-box;\n    .border-radius(2px);\n  }\n  .file-progress.err{\n    background: fade(@red0,20%);\n    color: @red3;\n  }\n  .size{\n    width: 4em;\n    display: inline-block;\n  }\n}\n\n#plugin-list{\n  li{\n    .bottom-line(16px);\n    .desc{\n      margin-bottom: 0;\n      width: 99%;\n      color: @black3;\n    }\n    a.lbl{\n      padding: 0 8px;\n      margin-left: 16px;\n    }\n    .version{\n      color: @green3;\n      margin-left: 16px;\n    }\n    .name{\n      font-size: 16px;\n    }\n    .active{\n      width: 12px;\n      height: 12px;\n      margin-right: 16px;\n      padding: 0;\n      margin-top: 10px;\n    }\n    .setting{\n      margin-left: 16px;\n    }\n  }\n}\n\n#plugin-setting-form{\n  p.item{\n    clear: both;\n  }\n  label{\n    float: left;\n    min-width: 6em;\n    text-align: right;\n    margin-right: 2em;\n  }\n  .title{\n    padding-top: 0;\n    margin-bottom: 18px;\n  }\n  input.ipt{\n    width: 600px;\n  }\n}\n\n#dashboard{\n  .grid-1-5{\n    margin-right: 2%;\n  }\n  .quick-link{\n    li{\n      list-style: inside disc;\n      .bottom-line(6px);\n    }\n  }\n  .stats{\n    .lbl{\n      padding: 1px 5px;\n      margin: 0 3px;\n    }\n  }\n  .activity{\n    .msg{\n      padding: 8px 12px;\n      .bottom-line(8px);\n      line-height: 24px;\n      font-size: 12px;\n      .time{\n        font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n      }\n      .data{\n        color: @black2;\n        margin-left: 1.2em;\n        p{\n          margin-bottom: 0;\n          line-height: 24px;\n        }\n      }\n      .read{\n        top:0;\n        right:12px;\n        opacity: 0;\n        &:hover{\n          color: @red1;\n        }\n      }\n      &:hover{\n        background: fade(@blue0,6%);\n        .read{\n          opacity: 1;\n        }\n      }\n    }\n  }\n}"
  },
  {
    "path": "static/less/cmd.less",
    "content": "@import \"common\";\n\n.cmd {\n  margin: 24px 48px\n}\n\n.cmd-header {\n  .bottom-line(12px);\n}\n\n#backup-btn,#theme-cache-btn{\n  margin: 10px 0 0 30px;\n  min-width: 0;\n  padding: 0 2em;\n}\n\n#theme-cache-btn{\n  .btn-red;\n}\n\n#theme-cache-btn.true{\n  .btn-green;\n}\n\n.cmd-list li{\n  .bottom-line(12px);\n}\n\n#backup-list{\n  li{\n    list-style: disc inside;\n    >span,>a{\n      margin-right: 16px;\n    }\n    font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n    .del{\n      color: @red1;\n      opacity: 0;\n    }\n    .link{\n      margin-left: 12px;\n    }\n    &:hover{\n      .del{\n        opacity: 1;\n      }\n    }\n  }\n}\n\n#message-list{\n  .message{\n    padding: 8px 12px;\n    .bottom-line(8px);\n    line-height: 24px;\n    font-size: 12px;\n    .time{\n      font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n    }\n    .data{\n      color: @black2;\n      margin-left: 1.2em;\n      p{\n        margin-bottom: 0;\n        line-height: 24px;\n      }\n    }\n    .read{\n      top:0;\n      right:12px;\n      opacity: 0;\n      &:hover{\n        color: @red1;\n      }\n    }\n    &:hover{\n      .read{\n        opacity: 1;\n      }\n    }\n  }\n}\n\n#log-list{\n  .log{\n    font-size: 12px;\n  }\n  .name{\n    margin-right: 1.5em;\n    font-weight: bold;\n  }\n  .time,.name{\n    font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n  }\n  .text{\n    line-height: 20px;\n    font-family: Consolas, \"Courier New\", Arial;\n    color: @black2;\n    padding: 8px 12px;\n    background: @white4;\n  }\n  .remove{\n    top:0;\n    right:12px;\n    color: @red1;\n  }\n}\n\n#theme-list{\n  span{\n    margin-left: 12px;\n  }\n  span.file{\n    color: @blue1;\n  }\n  span.error-file{\n    color: @red2;\n  }\n  h5{\n    cursor: pointer;\n  }\n}\n\n#reader-list{\n  li{\n    > *{\n      margin-right: 18px;\n    }\n  }\n  .email{\n    color: @black3;\n  }\n  .comments{\n    font-family:Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n    font-size: 12px;\n    padding: 2px 6px;\n  }\n}"
  },
  {
    "path": "static/less/common/base.less",
    "content": "@import \"var\";\n\n// ------------- basic ui -------------------\nhtml, body {\n  font-family: Ubuntu, Consolas, \"Microsoft YaHei\", Verdana, Tahoma, Arial, sans-serif;\n  font-size: 14px;\n  line-height: 30px;\n  color: @black1;\n  background-color: @white1;\n}\n\na {\n  text-decoration: none;\n  color: @blue1;\n  &:hover {\n    color: @blue2;\n  }\n}\n\np {\n  margin-bottom: 18px;\n}\n\nh1, h2, h3, h4, h5, h6 {\n  padding: 12px 0;\n}\n\nh1 {\n  font-size: 28px;\n}\n\nh2 {\n  font-size: 24px;\n}\n\nh3 {\n  font-size: 21px;\n}\n\nh4 {\n  font-size: 19px;\n}\n\nh5 {\n  font-size: 16px;\n}\n\nh6 {\n  font-size: 14px;\n}\n\n.text-left {\n  text-align: left;\n}\n\n.text-right {\n  text-align: right;\n}\n\n.text-center {\n  text-align: center;\n}\n\n.left {\n  float: left;\n}\n\n.right {\n  float: right;\n}\n\n.absolute {\n  position: absolute;\n}\n\n.relative {\n  position: relative;\n}\n\n.clear:after {\n  visibility: hidden;\n  display: block;\n  font-size: 0;\n  content: \" \";\n  clear: both;\n  height: 0\n}\n\n.vertical-middle {\n  vertical-align: middle;\n}\n\n.inline {\n  display: inline;\n}\n\n.inline-block {\n  display: inline-block;\n}\n\n.block {\n  display: block;\n}\n\n.fade-out {\n  opacity: 0;\n}\n\n.hide {\n  display: none !important;\n}\n"
  },
  {
    "path": "static/less/common/form.less",
    "content": "@import \"base\";\n\ninput,textarea,select,button{\n  font-family: Ubuntu, Consolas, \"Microsoft YaHei\", Verdana, Tahoma, Arial, sans-serif;\n}\n\n.form {\n  legend {\n    font-size: 18px;\n    margin-bottom: 14px;\n  }\n  label {\n    .inline-block;\n    margin-right: 12px;\n  }\n  .ipt {\n    padding: 8px 12px;\n    border: 1px solid @black3;\n    .border-radius(2px);\n    &:focus {\n      border-color: @blue1;\n    }\n    outline: none;\n    min-width: 180px;\n  }\n  .chk {\n    display: inline-block;\n    margin: 2px 6px 0 0;\n    line-height: normal;\n  }\n  .field {\n    margin-bottom: 24px;\n  }\n  .invalid{\n    margin-right: 12px;\n  }\n  .tip{\n    font-size: 13px;\n    color: @black3;\n    margin-left: 12px;\n  }\n}\n\n.form-vertical {\n  label {\n    display: block;\n    margin-bottom: 8px;\n  }\n  .ipt{\n    width: 100%;\n    box-sizing: border-box;\n  }\n  .invalid{\n    margin-right: 0;\n    margin-top: 6px;\n  }\n}\n\n.form-align {\n  label {\n    .inline-block;\n    min-width: 60px;\n    text-align: right;\n  }\n  .invalid{\n    margin-right: 0;\n    margin-top: 6px;\n  }\n}\n\n.btn{\n  min-width: 120px;\n  height: 36px;\n  background-color: @gray1;\n  color: @black1;\n  .border-radius(2px);\n  outline: none;\n  border: none;\n  &:hover{\n    background-color: @black3;\n    cursor: pointer;\n  }\n  margin: 0;\n}\n\na.btn{\n  line-height: 36px;\n  color: @white0;\n}\n\n.btn-red{\n  background-color: @red1;\n  &:hover{\n    background-color: @red2;\n  }\n  color: @white1;\n}\n\n.btn-blue{\n  background-color: @blue1;\n  &:hover{\n    background-color: @blue2;\n  }\n  color: @white1;\n}\n\n.btn-green{\n  background-color: @green1;\n  &:hover{\n    background-color: @green2;\n  }\n  color: @white1;\n}"
  },
  {
    "path": "static/less/common/grid.less",
    "content": "@import \"base\";\n\n.container {\n  max-width: 1200px;\n  margin: auto;\n}\n\n.container960 {\n  max-width: 960px;\n  margin: auto;\n}\n\n.grid-1-2 {\n  width: 50%;\n}\n\n.grid-1-3 {\n  width: 33.3333%;\n}\n\n.grid-1-4 {\n  width: 25%;\n}\n\n.grid-1-5 {\n  width: 20%;\n}\n\n.grid-1-6 {\n  width: 16.6666%;\n}\n\n.grid-2-3 {\n  width: 66.6666%;\n}\n\n.grid-3-4 {\n  width: 75%;\n}\n\n.grid-3-5{\n  width: 60%;\n}\n\n.grid-4-5{\n  width: 80%;\n}\n\n.grid-5-6 {\n  width: 83.3333%;\n}\n"
  },
  {
    "path": "static/less/common/label.less",
    "content": "@import \"base\";\n\n.lbl {\n  padding: 4px 12px;\n  background-color: @gray1;\n  color: @black1;\n  .border-radius(2px);\n}\n\n.lbl-red {\n  background-color: @red1;\n  color: @white1;\n}\n\na.lbl{\n  line-height: 26px;\n}\n\na.lbl-red {\n  &:hover {\n    background-color: @red2;\n    color: @white1;\n  }\n}\n\n.lbl-blue {\n  background-color: @blue1;\n  color: @white1;\n}\n\na.lbl-blue {\n  &:hover {\n    background-color: @blue2;\n    color: @white1;\n  }\n}\n\n.lbl-green {\n  background-color: @green1;\n  color: @white1;\n}\n\na.lbl-green {\n  &:hover {\n    background-color: @green2;\n    color: @white1;\n  }\n}"
  },
  {
    "path": "static/less/common/markdown.less",
    "content": "@import \"var\";\n.markdown{\n  h1,h2,h3,h4,h5,h6{\n    padding:18px 0 9px 0;\n    font-weight: bold;\n  }\n  h1{\n    font-size: 24px;\n  }\n  h2{\n    font-size: 21px;\n  }\n  h1,h2{\n    .bottom-line(10px);\n  }\n  h3{\n    font-size: 19px;\n  }\n  h4{\n    font-size: 18px;\n  }\n  h5{\n    font-size: 16px;\n  }\n  h6{\n    font-size: 14px;\n  }\n  p{\n    margin-bottom: 10px;\n  }\n  ul{\n    list-style: disc inside;\n  }\n  ol{\n    list-style: decimal inside;\n  }\n  code{\n      font-family: Consolas, \"Courier New\", Arial;\n  }\n  p code{\n    color: @red2;\n  }\n  blockquote{\n    padding: 8px 18px;\n    border-left: 4px solid @gray1;\n    background-color: @white1;\n    p{\n      margin-bottom: 0;\n    }\n  }\n  pre code{\n    font-size: 12px;\n    line-height: 18px !important;\n    padding: 8px 18px;\n    display: block;\n    margin: 12px 0 18px 0;\n  }\n  ol,ul{\n    margin: 12px 24px;\n  }\n  p img{\n    max-width: 99%;\n    height: auto;\n    margin: 0 auto;\n    display: block;\n  }\n  table{\n    margin: 12px 0;\n    width: 98%;\n    th,td{\n      border: 1px solid @gray1;\n      padding: 4px 12px;\n    }\n    thead{\n      background: @white3;\n    }\n  }\n}"
  },
  {
    "path": "static/less/common/pager.less",
    "content": "@import \"var\";\n\n.pager {\n  .item {\n    padding: 2px 8px;\n    margin: 0 6px;\n    color: @black1;\n    display: inline-block;\n    line-height: 20px;\n    a {\n      color: @black1;\n    }\n    &:hover {\n      background-color: @blue1;\n      .border-radius(2px);\n      a {\n        color: @white0;\n      }\n    }\n  }\n  .current {\n    background-color: @black2;\n    color: @white1;\n    .border-radius(2px);\n    a {\n      color: @white1;\n    }\n    &:hover {\n      background-color: @blue1;\n    }\n  }\n}"
  },
  {
    "path": "static/less/common/reset.less",
    "content": "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 {\n  margin: 0;\n  padding: 0;\n}\n\nheader, footer, section, article, aside, nav, hgroup, address, figure, figcaption, menu, details {\n  display: block;\n}\n\naudio, canvas, video {\n  display: inline-block;\n}\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\nfieldset, img {\n  border: 0;\n}\n\naddress, caption, cite, code, dfn, em, th, var {\n  font-style: normal;\n  font-weight: normal;\n}\n\nol, ul {\n  list-style: none;\n}\n\ncaption, th {\n  text-align: left;\n}\n\nh1, h2, h3, h4, h5, h6 {\n  font-size: 100%;\n  font-weight: normal;\n}\n\nq:before, q:after {\n  content: '';\n}\n\nabbr, acronym {\n  border: 0;\n  font-variant: normal;\n}\n\nsup {\n  vertical-align: text-top;\n}\n\nsub {\n  vertical-align: text-bottom;\n}\n\ninput, textarea, select {\n  font-family: inherit;\n  font-size: inherit;\n  font-weight: inherit;\n}\n\nlegend {\n  color: #000;\n}"
  },
  {
    "path": "static/less/common/var.less",
    "content": "@black0: #000;\n@black1: #333;\n@black2: #666;\n@black3: #999;\n@black4: #BBB;\n\n@white0: #FFFFFF;\n@white1: #FBFBFB;\n@white2: #F9F9F9;\n@white3: #F6F6F6;\n@white4: #F3F3F3;\n\n@gray0: #BBB;\n@gray1: #CCC;\n@gray2: #DDD;\n@gray3: #EEE;\n\n@blue0: #0096df;\n@blue1: #0079bc;\n@blue2: #005b9b;\n@blue3: #00377a;\n\n@red0: #ff4447;\n@red1: #E64346;\n@red2: #c7383a;\n@red3: #aa393c;\n\n@green0: #93d090;\n@green1: #7ab277;\n@green2: #649462;\n@green3: #507650;\n\n.bottom-line(@distance,@color:@gray2,@style:dashed) {\n  margin-bottom: @distance;\n  padding-bottom: @distance;\n  border-bottom: 1px @style @color;\n}\n\n.border-radius (@radius) {\n  border-radius: @radius;\n  -moz-border-radius: @radius;\n  -webkit-border-radius: @radius;\n}\n\n.box-shadow (@x: 0, @y: 0, @blur: 1px, @color: @black1) {\n  box-shadow: @arguments;\n  -moz-box-shadow: @arguments;\n  -webkit-box-shadow: @arguments;\n}\n\n.text-shadow (@x: 0, @y: 0, @blur: 1px, @color: @black3) {\n  text-shadow: @arguments;\n  -moz-text-shadow: @arguments;\n  -webkit-text-shadow: @arguments;\n}"
  },
  {
    "path": "static/less/common.less",
    "content": "@import \"common/var\";\n@import \"common/reset\";\n@import \"common/base\";\n@import \"common/grid\";\n@import \"common/form\";\n@import \"common/label\";\n@import \"common/pager\";\n@import \"common/markdown\";\n::-webkit-scrollbar{width:8px;margin-right:2px;}\n::-webkit-scrollbar-track-piece{background-color:#F5F5F5;border-left:1px solid #D2D2D2;}\n::-webkit-scrollbar-thumb{background:#9FA09C;width:8px;}\n::-webkit-scrollbar-thumb:hover{background:#B7B8AD;}"
  },
  {
    "path": "static/less/ling.less",
    "content": "@import \"common\";\n\nhtml, body {\n  background: @white4;\n}\n\n#header {\n  background: #0093C4;\n  min-width: 120px;\n  padding: 40px 0 48px 0;\n  color: @white1;\n  a {\n    &:hover {\n      color: @white0;\n      .text-shadow(0, 0, 3px, @black1);\n    }\n  }\n}\n\n#header-img {\n  width: 96px;\n  height: 96px;\n  .border-radius(50px);\n}\n\n#header-h {\n  line-height: 94px;\n  a {\n    color: @white1;\n  }\n  color: @white1;\n  padding: 0;\n  margin-left: 24px;\n}\n\n#header-sub {\n  color: @white4;\n  margin-left: 1.2em;\n  font-size: 16px;\n}\n\n#nav {\n  line-height: 90px;\n  li {\n    line-height: 50px;\n    margin-left: 44px;\n    a {\n      font-size: 18px;\n      color: @white4;\n      display: block;\n      &:hover {\n        color: @white0;\n        .text-shadow(0, 0, 3px, @black1);\n      }\n    }\n  }\n}\n\n#footer {\n  padding: 30px 40px;\n  color: @black3;\n}\n\n#main {\n  margin: 30px auto;\n}\n\n#go-top {\n  bottom: 50px;\n  right: 40px;\n  position: fixed;\n  color: @white0;\n  padding-top: 6px;\n  padding-bottom: 8px;\n  opacity: 0.4;\n}\n\n#article-container {\n  height: 100%;\n  .comments, .views {\n    font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n  }\n  .comments {\n    width: 56px;\n    height: 56px;\n    a {\n      color: @white0;\n    }\n    .border-radius(36px);\n    line-height: 56px;\n    font-size: 24px;\n    padding: 0;\n    margin-top: 40px;\n    margin-left: 8px;\n    border: 6px solid @white0;\n    .box-shadow(0, 0, 2px, @black3);\n    &:hover {\n      .box-shadow(0, 0, 4px, @black2);\n    }\n  }\n  .views {\n    top: 14px;\n    left: 0;\n    width: 36px;\n    height: 36px;\n    line-height: 36px;\n    .border-radius(30px);\n    padding: 0;\n    border: 4px solid @white0;\n    .box-shadow(0, 0, 2px, @black3);\n  }\n  .main {\n    margin-left: 116px;\n    .border-radius(4px);\n    .box-shadow(0, 1px, 2px, @gray0);\n    background: @white0;\n    padding: 18px 24px;\n    &:before {\n      content: \"\";\n      display: block;\n      border: 11px solid transparent;\n      border-right-color: @white0;\n      position: absolute;\n      top: 63px;\n      left: -22px;\n    }\n    h3.title {\n      font-size: 28px;\n      padding-bottom: 24px;\n    }\n    .time-info {\n      color: @black3;\n      .bottom-line(20px);\n      text-indent: 1em;\n      font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n    }\n  }\n  article {\n    margin-bottom: 50px;\n  }\n  .article-single {\n    .main {\n      margin-left: 0;\n      &:before {\n        display: none;\n      }\n    }\n    .meta {\n      right: 44px;\n      top: -36px;\n    }\n    .views {\n      width: 56px;\n      height: 56px;\n      .border-radius(36px);\n      line-height: 56px;\n      font-size: 24px;\n      padding: 0;\n      border: 6px solid @white0;\n    }\n  }\n  .tag {\n    a {\n      margin: 0 4px;\n      color: @black3;\n    }\n  }\n}\n\n#article-pager {\n  margin-left: 116px;\n  .item {\n    margin: 0;\n    color: @white0;\n    background: @black3;\n    padding: 12px 18px;\n    &:hover {\n      background: @blue1;\n    }\n    .border-radius(4px);\n  }\n}\n\n#comment {\n  .border-radius(4px);\n  .box-shadow(0, 1px, 2px, @gray0);\n  background: @white0;\n  padding: 18px 24px;\n  .meta {\n    right: -24px;\n    top: -30px;\n    .comments {\n      margin-left: 0;\n      margin-top: 0;\n    }\n  }\n}\n\n#comment-list {\n  .comment {\n    margin-bottom: 32px;\n  }\n  .c-avatar {\n    margin-right: 18px;\n    .border-radius(4px);\n    margin-top: 6px;\n  }\n  .c-meta {\n    p {\n      margin-bottom: 0;\n    }\n    .c-time {\n      color: @black3;\n      font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n    }\n    .c-author {\n      font-size: 16px;\n      color: @black1;\n      display: block;\n      &:hover {\n        color: @blue2;\n      }\n    }\n    .c-reply {\n      color: @white0;\n      background: @gray2;\n      padding: 3px 10px;\n      &:hover {\n        background-color: @blue1;\n      }\n    }\n  }\n  .c-content {\n    padding-top: 4px;\n  }\n  .c-check {\n    font-size: 13px;\n    color: @red1;\n    margin-left: 12px;\n  }\n  .c-p-md {\n    margin-top: 12px;\n    font-size: 12px;\n    line-height: 20px;\n    color: @black2;\n  }\n}\n\n#comment-show {\n  margin-bottom: 32px;\n}\n\n#comment-title {\n  .bottom-line(20px);\n}\n\n#comment-form {\n  width: 80%;\n  margin: auto;\n  margin-bottom: 30px;\n  .c-info {\n    width: 26%;\n    .ipt {\n      width: 100%;\n      box-sizing: border-box;\n      min-width: 0;\n    }\n  }\n  .c-content {\n    width: 70%;\n  }\n  .c-avatar {\n    .border-radius(4px);\n    margin-top: 6px;\n    width: 50px;\n  }\n  .reply-md {\n    margin-bottom: 16px;\n    font-size: 12px;\n    line-height: 20px;\n    color: @black2;\n  }\n  .cancel-reply {\n    border: none;\n    &:hover {\n      cursor: pointer;\n    }\n    margin-left: 18px;\n    display: none;\n  }\n}\n\n#comment-content {\n  width: 100%;\n  box-sizing: border-box;\n  height: 180px;\n  resize: none;\n}\n\n@media only screen and (max-width: 960px) {\n  .container960 {\n    padding: 0 24px;\n    width: auto;\n  }\n}\n\n@media only screen and (max-width: 760px) {\n  .container960 {\n    padding: 0 24px;\n    width: auto;\n  }\n\n  #article-container {\n    .main {\n      margin-left: 0;\n    }\n    .meta {\n      display: none;\n    }\n    .main:before {\n      display: none;\n    }\n  }\n\n  #comment-form {\n    .c-info, .c-content {\n      width: 100%;\n      float: left;\n    }\n    .c-info {\n      text-align: left;\n    }\n  }\n\n  #nav, #header-h {\n    line-height: 50px;\n  }\n\n  #footer {\n    span {\n      float: none;\n      text-align: center;\n    }\n  }\n\n  #article-pager {\n    margin-left: 0;\n  }\n}\n\n@media only screen and (max-width: 560px) {\n  .container960 {\n    padding: 0;\n    width: auto;\n  }\n\n  #article-pager{\n    margin: 0 12px;\n  }\n\n  #header-h {\n    margin-left: 24px;\n  }\n\n  #header-img {\n    display: none;\n  }\n\n  #comment-form {\n    width: 100%;\n  }\n\n  #nav {\n    float: left;\n    margin-left: 24px;\n    li {\n      margin-left: 0;\n      margin-right: 44px;\n    }\n  }\n\n  #footer {\n    span {\n      float: none;\n      display: block;\n    }\n  }\n}\n\n@media only screen and (max-width: 480px) {\n  #header-sub {\n    display: none;\n  }\n}"
  },
  {
    "path": "static/less/saber.less",
    "content": "@import \"common\";\n\nhtml, body {\n  background: @white2;\n}\n\n#header {\n  background: #FFF;\n  box-shadow: 0 0 4px @black2;\n  line-height: 60px;\n  padding: 12px 0 18px 0;\n  position: fixed;\n  width: 100%;\n  top:0;\n  z-index: 99;\n}\n\n#header-img {\n  width: 60px;\n  height: 60px;\n  margin-right: 24px;\n  border-radius: 30px;\n  vertical-align: middle;\n}\n\n#header-h, #header-sub {\n  padding: 0 18px 0 0;\n}\n\n#header-sub {\n  font-size: 13px;\n  color: @black3;\n}\n\n#nav {\n  margin-right: -18px;\n  li {\n    a {\n      margin-left: 24px;\n      padding: 0 18px;\n      &:hover {\n        .lbl;\n        .lbl-blue;\n        padding: 6px 18px;\n      }\n      font-size: 15px;\n    }\n  }\n}\n\n#footer {\n  padding: 30px 40px;\n  color: @black3;\n}\n\n#main {\n  margin-top: 132px;\n  margin-bottom: 48px;\n}\n\n#go-top {\n  bottom: 50px;\n  right: 40px;\n  position: fixed;\n  color: @white0;\n  padding-top: 6px;\n  padding-bottom: 8px;\n  opacity: 0.4;\n}\n\n#article-container {\n  article {\n    .bottom-line(40px, @black4);\n    margin-bottom: 50px;\n  }\n  .tag-banner {\n    font-size: 16px;\n    .bottom-line(20px, @black4);\n    margin-bottom: 28px;\n  }\n  .meta {\n    .comments {\n      margin-bottom: 0;\n      margin-top: 8px;\n      margin-right: 18px;\n      font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n      padding-bottom: 2px;\n      a {\n        color: @white0;\n        font-size: 18px;\n        display: block;\n        cursor: pointer;\n      }\n    }\n    .views {\n      top: -8px;\n      left: -12px;\n      padding: 2px 6px;\n      line-height: 20px;\n      text-align: center;\n      font-size: 12px;\n      font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n      margin-bottom: 0;\n    }\n  }\n  .title {\n    .bottom-line(24px);\n    font-size: 24px;\n  }\n  .content {\n    margin-top: -12px;\n  }\n  .info {\n    margin-bottom: 0;\n    span {\n      border-right: 1px dashed @black3;\n      padding-right: 12px;\n      margin-right: 12px;\n    }\n    color: @black3;\n    font-size: 12px;\n    .tag {\n      a {\n        margin-left: 4px;\n      }\n    }\n  }\n  .article-single {\n    h3.title {\n      padding-top: 0;\n    }\n    .views {\n      color: #fff;\n      font-size: 18px;\n    }\n  }\n}\n\n#article-pager {\n  a {\n    margin: 0;\n  }\n  a:hover {\n    color: @white1;\n  }\n}\n\n#article-sidebar {\n  .sidebar {\n    .title {\n      padding-top: 0;\n    }\n    margin-bottom: 24px;\n  }\n}\n\n#pop-article-sidebar {\n  .list {\n    li {\n      .bottom-line(8px);\n    }\n  }\n  .pop-num {\n    padding: 4px;\n    margin-left: 12px;\n    font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n    font-size: 12px;\n  }\n}\n\n#recent-comment-sidebar {\n  .list {\n    li {\n      .bottom-line(8px);\n    }\n  }\n  .author {\n    padding: 4px 6px;\n    margin-right: 6px;\n  }\n}\n\n#comment {\n  h4 {\n    padding-top: 0;\n  }\n  .comments {\n    a {\n      color: #fff;\n      font-size: 18px;\n    }\n  }\n}\n\n#comment-list {\n  .comment {\n    margin-bottom: 32px;\n  }\n  .c-avatar {\n    margin-right: 18px;\n    .border-radius(4px);\n    margin-top: 6px;\n  }\n  .c-meta {\n    p {\n      margin-bottom: 0;\n    }\n    .c-time {\n      color: @black3;\n      font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n    }\n    .c-author {\n      font-size: 16px;\n      color: @black1;\n      display: block;\n      &:hover {\n        color: @blue2;\n      }\n    }\n    .c-reply {\n      color: @white0;\n      background: @gray2;\n      padding: 3px 10px;\n      &:hover {\n        background-color: @blue1;\n      }\n    }\n  }\n  .c-content {\n    padding-top: 4px;\n  }\n  .c-check {\n    font-size: 13px;\n    color: @red1;\n    margin-left: 12px;\n  }\n  .c-p-md {\n    margin-top: 12px;\n    font-size: 12px;\n    line-height: 20px;\n    color: @black2;\n  }\n}\n\n#comment-show {\n  margin-bottom: 32px;\n}\n\n#comment-title {\n  .bottom-line(20px);\n}\n\n#comment-form {\n  width: 80%;\n  margin: auto;\n  margin-bottom: 30px;\n  .c-info {\n    width: 26%;\n    .ipt {\n      width: 100%;\n      box-sizing: border-box;\n      min-width: 0;\n    }\n  }\n  .c-content {\n    width: 70%;\n  }\n  .c-avatar {\n    .border-radius(4px);\n    margin-top: 6px;\n    width: 50px;\n  }\n  .reply-md {\n    margin-bottom: 16px;\n    font-size: 12px;\n    line-height: 20px;\n    color: @black2;\n  }\n  .cancel-reply {\n    border: none;\n    &:hover {\n      cursor: pointer;\n    }\n    margin-left: 18px;\n    display: none;\n  }\n}\n\n#comment-content {\n  width: 100%;\n  box-sizing: border-box;\n  height: 180px;\n  resize: none;\n}\n\n@media only screen and (max-width: 1248px) {\n  .container {\n    padding: 0 24px;\n    width: auto;\n  }\n}\n\n@media only screen and (max-width: 960px) {\n  .container960 {\n    padding: 0 24px;\n    width: auto;\n  }\n  #article-container.left{\n    width: 100%;\n  }\n  #article-sidebar{\n    display: none;\n  }\n}\n\n\n@media only screen and (max-width: 760px) {\n\n  #header-sub{\n    display: none;\n  }\n\n  #header{\n    padding: 12px 0;\n  }\n\n  #article-container {\n    .main {\n      margin-left: 0;\n    }\n    .meta {\n      display: none;\n    }\n    .main:before {\n      display: none;\n    }\n  }\n\n  #comment-form {\n    .c-info, .c-content {\n      width: 100%;\n      float: left;\n    }\n    .c-info {\n      text-align: left;\n    }\n  }\n\n  #footer {\n    span {\n      display: block;\n      float: none;\n      text-align: center;\n    }\n  }\n\n  #article-pager {\n    margin-left: 0;\n  }\n}\n\n@media only screen and (max-width: 560px) {\n  #article-container{\n    .views{\n      display: none;\n    }\n  }\n}"
  },
  {
    "path": "static/less/style.less",
    "content": "@import \"common\";\n\nhtml,body{\n  background: url(\"../img/bg.png\") repeat;\n}\n\n#header{\n  background: url(\"../img/header.gif\") repeat #4c7298;\n  min-width: 120px;\n  padding: 30px 0;\n  color: @white1;\n}\n\n#header-img{\n  width: 96px;\n  height: 96px;\n  background-color: @white0;\n  border: 1px solid @gray1;\n  .border-radius(50px);\n}\n\n#header-h{\n  padding-top: 24px;\n  a{\n    color: @white0;\n    font-weight: bold;\n  }\n  font-size: 32px;\n}\n\n#nav{\n  height: 54px;\n  background-color: @white1;\n  .box-shadow(0,0,2px,@gray0);\n  border-bottom: 1px solid @gray1;\n  li{\n    line-height: 50px;\n    padding: 0 18px;\n    a{\n      font-size: 16px;\n      color: @black1;\n      padding: 0 32px;\n      display: block;\n      &:hover{\n        border-bottom: 4px solid @blue1;\n      }\n    }\n  }\n}\n\n#nav.fixed{\n  position: fixed;\n  width: 100%;\n  top:0;\n}\n\n#main{\n  margin: 30px auto;\n}\n\n#footer{\n  color: @gray1;\n  background-color: #1c2429;\n  padding: 24px 0;\n  a{\n    color: @gray1;\n  }\n  p{\n    margin-bottom: 9px;\n    font-weight: bold;\n    letter-spacing: 1px;\n    a{\n      margin: 0 16px;\n      &:hover{\n        color: @white1;\n      }\n      .fa{\n        margin-right: 8px;\n      }\n    }\n  }\n}\n\n#go-top{\n  bottom:50px;\n  right:40px;\n  position: fixed;\n  color: @white0;\n  padding-top: 6px;\n  padding-bottom: 8px;\n  opacity: 0.4;\n}\n\n#article-container{\n  .meta{\n    width: 108px;\n    line-height: 24px;\n    .fa{\n      margin-right: 8px;\n    }\n    .comments,.views,.time{\n      font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n    }\n    .time{\n      color: @white0;\n    }\n    a{\n      color: @white0;\n      &:hover{\n        color: @white0;\n      }\n    }\n  }\n  .main{\n    margin-left: 140px;\n  }\n  h3.title{\n    padding: 8px 16px;\n    background-color: #4c7298;\n    border-top-left-radius: 2px;\n    border-top-right-radius: 2px;\n    a{\n      color: @gray3;\n      &:hover{\n        color: @white0;\n      }\n    }\n  }\n  .content{\n    background-color: @white0;\n    border:1px solid @gray1;\n    border-top: none;\n    padding: 18px 24px 24px;\n  }\n  .info{\n    margin-bottom: 0;\n    background-color: @white1;\n    border:1px solid @gray1;\n    border-top: none;\n    border-bottom-left-radius: 2px;\n    border-bottom-right-radius: 2px;\n    .fa{\n      margin-right: 8px;\n    }\n    .share .fa{\n      margin-right: 0;\n    }\n    /*\n    .weibo .fa:hover{\n      color: @red1;\n    }*/\n    >*{\n      padding: 6px 18px;\n    }\n    > span{\n      border-right: 1px solid @gray1;\n    }\n    .right{\n      border-left: 1px solid @gray1;\n      border-right: none;\n    }\n    color: @black3;\n    .read{\n      color: @black3;\n      &:hover{\n        background-color: @blue1;\n        color: @white1;\n      }\n    }\n    .time,.views span{\n      font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n    }\n    .tag a{\n      margin: 0 4px;\n      color: @black3;\n      &:hover{\n        color: @black1;\n      }\n    }\n  }\n  article{\n    margin-bottom: 48px;\n  }\n  .tag-banner{\n    text-align: center;\n    font-size: 18px;\n    margin-bottom: 30px;\n  }\n}\n\n#comment{\n  margin-top: -24px;\n  border: 1px solid @gray1;\n  .border-radius(2px);\n  padding:24px;\n  background: @white0;\n}\n\n#comment-form{\n  width: 80%;\n  margin: auto;\n  .c-info{\n    width: 26%;\n    .ipt{\n      width: 100%;\n      box-sizing: border-box;\n      min-width:0;\n    }\n  }\n  .c-content{\n    width: 70%;\n  }\n  .c-avatar{\n    width: 48px;\n    height: 48px;\n    padding: 2px;\n    border: 1px solid @gray1;\n    .border-radius(2px);\n  }\n  .reply-md{\n    margin-bottom: 16px;\n    font-size: 12px;\n    line-height: 20px;\n    color: @black2;\n  }\n  .cancel-reply{\n    border: none;\n    &:hover{\n      cursor: pointer;\n    }\n    margin-left: 18px;\n    display: none;\n  }\n}\n\n#comment-content{\n  width: 100%;\n  box-sizing: border-box;\n  height: 180px;\n  resize: none;\n}\n\n#comment-list{\n  .c-avatar{\n    width: 48px;\n    height: 48px;\n    padding: 2px;\n    border: 1px solid @gray1;\n    .border-radius(2px);\n    margin-right: 18px;\n  }\n  .comment{\n    .bottom-line(18px);\n  }\n  .c-meta{\n    > *{\n      margin-right: 16px;\n    }\n  }\n  .c-time{\n    color: @black3;\n    font-family: Verdana, Tahoma, '微软雅黑', '宋体', sans-serif;\n    .fa{\n      margin-right: 6px;\n    }\n  }\n  .c-reply{\n    color: @black3;\n    &:hover{\n      color: @black1;\n    }\n  }\n  .c-author{\n    font-size: 13px;\n  }\n  .c-author.admin{\n    .lbl-red;\n  }\n  .c-p-md{\n    margin-top: 12px;\n    font-size: 12px;\n    line-height: 20px;\n    color: @black2;\n  }\n  .c-section{\n    max-width: 830px;\n  }\n  .c-check{\n    font-size: 13px;\n    color: @red1;\n    .fa{\n      margin-right: 6px;\n    }\n  }\n}\n\n@media only screen and (max-width: 960px) {\n  .container960{\n    padding:0 24px;\n    width: auto;\n  }\n}\n\n@media only screen and (max-width: 760px) {\n  .container960{\n    padding:0 24px;\n    width: auto;\n  }\n  #article-container{\n    .main{\n      margin-left: 0;\n    }\n    .meta.left{\n      display: none;\n    }\n  }\n  #comment-form{\n    .c-info,.c-content{\n      width: 100%;\n      float: left;\n    }\n    .c-info{\n      text-align: left;\n    }\n  }\n}\n\n@media only screen and (max-width: 560px) {\n  .container960{\n    padding:0;\n    width: auto;\n  }\n  #nav{\n    li{\n      padding: 0 10px;\n    }\n  }\n  #header-img{\n    float: left;\n    width: 64px;\n    height: 64px;\n    margin-left: 24px;\n  }\n  #header-h{\n    padding:17px;\n    font-size: 24px;\n    float: left;\n  }\n  #header-sub{\n    display: none;\n  }\n  #article-container{\n    .tag,.time{\n      display: none;\n    }\n  }\n  #comment-form{\n    width: 100%;\n  }\n}\n\n@media only screen and (max-width: 480px) {\n  .container960{\n    padding:0;\n    width: auto;\n  }\n  #header-h{\n    float: none;\n  }\n  #header-img{\n    display: none;\n  }\n  #header-sub{\n    display: none;\n  }\n  #comment-list{\n    .c-avatar{\n      display: none;\n    }\n  }\n  #nav li a{\n    padding: 0 16px;\n  }\n}"
  },
  {
    "path": "view/admin/admin.layout",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\"/>\n    <title>{{.Title}} - Fxh.Go</title>\n    <link rel=\"stylesheet\" href=\"/static/css/admin.css\"/>\n    <script src=\"http://libs.baidu.com/jquery/1.8.3/jquery.min.js\"></script>\n    <script src=\"/static/lib/jquery.form.min.js\"></script>\n    <script src=\"/static/lib/validate.min.js\"></script>\n</head>\n<body>\n<div id=\"header\" class=\"clear\">\n    <div class=\"container clear\">\n        <h3 class=\"logo left\">Fxh.Go - <span>{{.Title}}</span></h3>\n        <div class=\"nav left relative\">\n            <a class=\"dashboard left\" href=\"/admin/\">控制台</a>\n            <a class=\"article left\" href=\"/admin/articles/\" title=\"文章\">文章</a></a>\n            <a class=\"pages left\" href=\"/admin/pages/\" title=\"独立页面\">页面</a>\n            <a class=\"comments left\" href=\"/admin/comments/\" title=\"评论\">评论</a>\n            <a class=\"files left\" href=\"/admin/files/\" title=\"媒体文件\">文件</a>\n            <a class=\"plugins left\" href=\"/admin/plugins/\" title=\"插件\">插件</a>\n            <a class=\"setting left\" href=\"/admin/setting/\" title=\"设置\">设置</a>\n        </div>\n        <a class=\"out nav-item right\" href=\"/logout/\" title=\"退出\">退出</a>\n        <a class=\"profile nav-item right\" href=\"/admin/profile/\" title=\"我\">我</a>\n        <a class=\"front nav-item right\" href=\"/\" target=\"_blank\" title=\"查看网站\">前台</a>\n    </div>\n</div>\n{@Content}\n<div id=\"footer\" class=\"clear\">\n    <div class=\"container clear\">\n       <p class=\"links text-center\">\n           <a class=\"theme\" href=\"/cmd/theme/\">主题</a>\n           <a class=\"reader\" href=\"/cmd/reader/\">读者</a>\n           <a class=\"stat\" href=\"/cmd/message/\">消息</a>\n           <a class=\"backup\" href=\"/cmd/backup/\">备份</a>\n           <a class=\"err\" href=\"/cmd/logs/\">日志</a>\n           <a class=\"sys\" href=\"/cmd/monitor/\">系统</a>\n       </p>\n        <p class=\"cp text-center\">Proudly Powered by Fxh.Go</p>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "view/admin/articles.html",
    "content": "<ul id=\"article-list\" class=\"container960 admin\">\n    <li>\n        <a class=\"lbl lbl-blue\" href=\"/admin/article/write/\">添加文章</a>\n    </li>{{range .Articles}}\n    <li>\n        <span class=\"time\">{{DateInt64 .CreateTime \"MM.DD\"}}</span><h4 class=\"inline-block title\"><a href=\"{{.Link}}\" target=\"_blank\">{{.Title}}</a></h4>{{if ne .Status \"publish\"}}\n        <span class=\"lbl status\">草稿</span>{{end}}\n        <span class=\"slug\">{{.Slug}}</span>{{if eq .IsComment false}}\n        <span class=\"is-comment\">关评</span>{{end}}\n        <span class=\"count\">{{.CommentNum}} / {{.Hits}}</span>\n        <a class=\"edit lbl lbl-green\" href=\"/admin/article/{{.Id}}/\" rel=\"{{.Id}}\">编辑</a>\n        <a class=\"del lbl lbl-red\" href=\"/admin/article/{{.Id}}/\" rel=\"{{.Id}}\">删除</a>\n    </li>{{end}}\n</ul>\n<ul id=\"article-pager\" class=\"pager container960\">{{range .Pager.PageSlice}}\n    <li class=\"item{{if eq $.Pager.Current .}} current{{end}}\"><a href=\"/admin/articles/?page={{.}}\">{{.}}</a></li>{{end}}\n</ul>\n<script>\n    $(\".del\").on(\"click\",function(e){\n        e.preventDefault();\n        if(confirm(\"删除文章将使相关内容失效！确认？\")){\n            var id = $(this).attr(\"rel\");\n            $.ajax({\n                \"url\":\"/admin/article/\"+id+\"/\",\n                \"type\":\"delete\",\n                \"success\":function(json){\n                    if(json.res){\n                        alert(\"已删除\");\n                        window.location.reload();\n                    }else{\n                        alert(json.msg);\n                    }\n                }\n            })\n        }\n    });\n</script>"
  },
  {
    "path": "view/admin/cmd/backup.html",
    "content": "<header class=\"cmd-header clear\">\n    <h1 class=\"cmd-title left\">备份数据</h1>\n    <button class=\"btn btn-blue left\" id=\"backup-btn\">备份</button>\n</header>\n<ul class=\"cmd-list\" id=\"backup-list\">{{range .Files}}\n    <li>\n        <span class=\"time\">{{DateTime .ModTime \"MM.DD HH:mm\"}}</span>\n        <span class=\"name\">{{.Name}} <a class=\"link\" href=\"/cmd/backup/file?file={{.Name}}\">下载</a></span>\n        <span class=\"size\">{{FileSize .Size}}</span>\n        <a class=\"del\" href=\"#\" rel=\"{{.Name}}\">删除</a>\n    </li>{{end}}\n</ul>\n<script>\n    $(function () {\n        $('#backup-btn').on(\"click\", function () {\n            $.ajax({\n                type: \"post\",\n                beforeSend: function () {\n                    $('.cmd-list').prepend('<li class=\"backup-loading\">备份中..</li>');\n                    $('#backup-btn').hide();\n                },\n                success: function (json) {\n                    if (json.res) {\n                        $('.backup-loading').remove();\n                        $('.cmd-list').prepend('<li class=\"backup-result\">刚刚备份到 ' + json.file + '</li>');\n                    } else {\n                        alert(json.msg);\n                    }\n                    $('#backup-btn').show();\n                }\n            });\n            return false;\n        });\n        $('.del').on(\"click\", function () {\n            var that = this;\n            $.ajax({\n                url: \"/cmd/backup/?file=\" + $(this).attr(\"rel\"),\n                type: \"delete\",\n                success: function (json) {\n                    if(json.res){\n                        $(that).parent().remove();\n                    }\n                }\n            });\n            return false;\n        })\n    })\n</script>"
  },
  {
    "path": "view/admin/cmd/log.html",
    "content": "<header class=\"cmd-header\">\n    <h1 class=\"cmd-title\">错误日志</h1>\n</header>\n<ul class=\"cmd-list\" id=\"log-list\">{{range .Logs}}\n    <li class=\"log relative\">\n        <span class=\"name inline-block\">{{.Name}}</span>\n        <span class=\"time inline-block\">{{DateInt64 .CreateTime \"MM.DD HH:mm\"}}</span>\n        <pre class=\"text\">{{.Text}}</pre>\n        <a class=\"remove absolute\" href=\"/cmd/logs/?file={{.Name}}\">删除</a>\n    </li>{{end}}\n</ul>\n<script>\n    $(document).ready(function () {\n        $('.remove').on(\"click\", function () {\n            if (confirm(\"确认删除记录\")) {\n                var $this = $(this);\n                $.ajax({\n                    type:\"delete\",\n                    url:$this.attr(\"href\"),\n                   success:function(json){\n                       if(json.res){\n                           $this.parent().remove();\n                       }\n                   }\n                })\n            }\n            return false;\n        });\n    });\n</script>"
  },
  {
    "path": "view/admin/cmd/message.html",
    "content": "<header class=\"cmd-header\">\n    <h1 class=\"cmd-title\">消息记录</h1>\n</header>\n<ul class=\"cmd-list\" id=\"message-list\">{{range .Messages}}\n    <li class=\"message relative\">\n        <span class=\"time\">{{DateInt64 .CreateTime \"MM.DD HH:mm\"}}</span>\n        <div class=\"data\">{{Html .Data}}</div>\n    </li>{{end}}\n</ul>"
  },
  {
    "path": "view/admin/cmd/monitor.html",
    "content": "<header class=\"cmd-header\">\n    <h1 class=\"cmd-title\">系统监控</h1>\n</header>\n<ul class=\"cmd-list\" id=\"monitor-list\">\n    <li><span>Goroutine数量</span>： <strong>{{.M.NumGoroutine}}</strong></li>\n    <li><span>系统内存分配</span>： <strong>{{.M.MemSys}}</strong></li>\n    <li><span>实际内存占用</span>： <strong>{{.M.MemHeap}}</strong></li>\n    <li><span>强制回收极限</span>： <strong>{{.M.MemGc}}</strong></li>\n    <li><span>上次回收时间</span>： <strong>{{.M.LastGcTime}}</strong> ago</li>\n</ul>"
  },
  {
    "path": "view/admin/cmd/reader.html",
    "content": "<header class=\"cmd-header clear\">\n    <h1 class=\"cmd-title left\">读者</h1>\n</header>\n<ul class=\"cmd-list\" id=\"reader-list\">\n    <li>\n        如果删除读者，不会影响读者已有的评论；但此后该读者的新评论需要审核。\n    </li>{{range .Readers}}\n    <li>\n        <a class=\"lbl lbl-blue author\" href=\"{{.Url}}\" target=\"_blank\">{{.Author}}</a>\n        <span class=\"email\">{{.Email}}</span>\n        <span class=\"lbl lbl-red comments\">{{.Comments}}</span>\n        <a class=\"del\" href=\"#\">删除</a>\n    </li>{{end}}\n</ul>\n<script>\n    $(function(){\n        $('.del').on(\"click\", function () {\n            var $this = $(this);\n            var email = $this.parent().find('.email').text();\n            console.log(email);\n            $.post(\"/cmd/reader/\", {\"email\": email}, function (json) {\n                if (json.res) {\n                    $this.parent().remove();\n                }\n            });\n            return false;\n        });\n    });\n</script>"
  },
  {
    "path": "view/admin/cmd/theme.html",
    "content": "<header class=\"cmd-header clear\">\n    <h1 class=\"cmd-title left\">主题风格</h1>\n    <button class=\"btn left {{Setting `theme_cache`}}\" id=\"theme-cache-btn\">缓存({{Setting \"theme_cache\"}})</button>\n</header>\n<ul class=\"cmd-list\" id=\"theme-list\">{{range .Themes}}\n    <li>{{if eq .Name $.CurrentTheme}}\n        <h5 class=\"theme-name inline-block lbl lbl-blue\">{{.Name}}</h5>{{else}}\n        <h5 class=\"theme-name inline-block\">{{.Name}}</h5>{{end}}{{range .Layout}}\n        <span class=\"lbl lbl-green layout\">{{.}}</span>{{end}}{{range .Files}}\n        <span class=\"file\">{{.}}</span>{{end}}{{range .ErrorFiles}}\n        <span class=\"error-file\">{{.}}</span>{{end}}\n    </li>{{end}}\n</ul>\n<p>主题名对应视图中的目录。高亮的主题即当前使用的主题。单击主题名即可切换现用主题。</p>\n<script>\n    $(function () {\n        $('#theme-cache-btn').on(\"click\", function (e) {\n            var $this = $(this);\n            var change = \"true\";\n            if ($this.hasClass(\"true\")) {\n                change = \"false\";\n            }\n            $.post(\"/cmd/theme/\", {\"cache\": change}, function (json) {\n                if (json.res) {\n                    $this.removeClass(\"true\").removeClass(\"false\").addClass(change).text(\"缓存(\" + change + \")\");\n                }\n            });\n        });\n        $('.theme-name').on(\"click\",function(e){\n            var $this = $(this);\n            if($this.hasClass(\"lbl\")){\n                return false;\n            }\n            $.post(\"/cmd/theme/\",{\"theme\":$this.text()},function(json){\n               if(json.res){\n                   $(\".theme-name.lbl\").removeClass(\"lbl\").removeClass(\"lbl-blue\");\n                   $this.addClass(\"lbl\").addClass(\"lbl-blue\");\n               }\n            });\n            return false;\n        })\n    });\n</script>"
  },
  {
    "path": "view/admin/cmd.layout",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\"/>\n    <title>{{.Title}} - Fxh.Go</title>\n    <link rel=\"stylesheet\" href=\"/static/css/cmd.css\"/>\n    <link rel=\"stylesheet\" href=\"http://libs.baidu.com/fontawesome/4.0.3/css/font-awesome.min.css\"/>\n    <script src=\"http://libs.baidu.com/jquery/1.8.3/jquery.min.js\"></script>\n</head>\n<body class=\"cmd\">\n{@Content}\n<p class=\"back\"><a href=\"javascript:history.back()\">Back</a></p>\n</body>\n</html>"
  },
  {
    "path": "view/admin/comments.html",
    "content": "<div id=\"comment-list\" class=\"admin container960\">{{range .Comments}}\n    <div class=\"comment clear\" id=\"comment-{{.Id}}\">\n        <img class=\"c-avatar left\" src=\"{{.Avatar}}\" alt=\"{{.Author}}\"/>\n        <div class=\"c-section left\">\n            <div class=\"c-meta\">\n                <a class=\"lbl lbl-blue c-author{{if .IsAdmin}} admin{{end}}\" href=\"{{.Url}}\" target=\"_blank\">{{.Author}}{{if .IsAdmin}}&nbsp;&nbsp;(admin){{end}}</a>\n                <span class=\"c-time\">{{DateInt64 .CreateTime \"MM.DD HH:mm\"}}</span>\n                <span class=\"c-email\">{{.Email}}</span>{{if .GetContent}}\n                <span class=\"c-cnt\">@{{.GetContent.Title}}</span>{{else}}\n                <span class=\"c-cnt\">@无效</span>{{end}}{{if ne .Status \"approved\"}}\n                <a class=\"c-check\" href=\"#\" rel=\"{{.Id}}\" title=\"审核\">审核中</a>{{end}}\n                <a class=\"c-reply\" href=\"#\" rel=\"{{.Id}}\" title=\"回复\">回复</a>\n                <a class=\"c-del\" href=\"#\" rel=\"{{.Id}}\" title=\"删除\">删除</a>\n            </div>\n            <section class=\"c-content\">{{Html .Content}}</section>{{if .ParentMd}}\n            <div class=\"c-p-md markdown\">{{Html .ParentMd}}</div>{{end}}\n        </div>\n    </div>{{end}}\n    <ul id=\"article-pager\" class=\"pager container960\">{{range .Pager.PageSlice}}\n        <li class=\"item{{if eq $.Pager.Current .}} current{{end}}\"><a href=\"/admin/comments/?page={{.}}\">{{.}}</a></li>{{end}}\n    </ul>\n    <form id=\"comment-form\" action=\"/admin/comments/\" class=\"form clear left\" method=\"post\">\n        <textarea class=\"ipt left\" name=\"content\" id=\"comment-content\" required=\"required\"></textarea>\n        <button class=\"btn btn-blue\" id=\"comment-submit\">回复评论</button>\n        <button class=\"btn btn-green\" id=\"comment-close\">关闭回复</button>\n        <input type=\"hidden\" value=\"0\" id=\"comment-parent\" name=\"pid\"/>\n    </form>\n</div>\n<script>\n    $(function () {\n        $('.c-del').on(\"click\", function () {\n            if (confirm(\"删除评论将使相关内容无效!\")) {\n                var id = $(this).attr(\"rel\");\n                $.ajax({\n                    type: \"delete\",\n                    url: \"/admin/comments/?id=\" + id,\n                    success: function (json) {\n                        if (json.res) {\n                            $('#comment-' + id).remove();\n                        } else {\n                            alert(\"删除失败\");\n                        }\n                    }\n                })\n            }\n            return false;\n        });\n        $('.c-check').on(\"click\", function () {\n            if (confirm(\"审核后此作者将不再标记审核!\")) {\n                var id = $(this).attr(\"rel\");\n                $.ajax({\n                    type: \"put\",\n                    url: \"/admin/comments/?id=\" + id,\n                    success: function (json) {\n                        if (json.res) {\n                            $('#comment-' + id).find(\".c-check\").remove();\n                        } else {\n                            alert(\"审核失败\");\n                        }\n                    }\n                })\n            }\n            return false;\n        });\n        $('.c-reply').on(\"click\",function(){\n            var id = $(this).attr(\"rel\");\n            $('#comment-'+id).append($('#comment-form').detach().show());\n            $('#comment-parent').val(id);\n           return false;\n        });\n        $('#comment-form').ajaxForm(function(json){\n            if(json.res){\n                alert(\"已回复\");\n                window.location.href = \"/admin/comments/\";\n            }else{\n                alert(\"回复失败\");\n            }\n        });\n        $('#comment-close').on(\"click\",function(){\n            $('#comment-form').hide();\n            $('#comment-parent').val(0);\n            $('#comment-content').val(\"\");\n        })\n    });\n</script>"
  },
  {
    "path": "view/admin/edit_article.html",
    "content": "<style>\n    @import \"/static/css/codemirror.css\";\n    @import \"/static/css/highlight.css\";\n</style>\n<form id=\"article-form\" class=\"form clear container\" action=\"#\" method=\"post\">\n    <div class=\"left grid-1-2\">\n        <input class=\"ipt title\" id=\"title\" type=\"text\" required=\"required\" name=\"title\" placeholder=\"文章标题\" value=\"{{.Article.Title}}\"/>\n        <textarea name=\"content\" id=\"content\" class=\"ipt\">{{Html .Article.Text}}</textarea>\n    </div>\n    <div class=\"left grid-1-2\">\n        <div class=\"preview markdown\"></div>\n    </div>\n    <div class=\"form-vertical left\">\n        <button class=\"btn btn-green left\" type=\"button\" id=\"attach-show\">添加附件</button>\n        <p class=\"item\">\n            <span for=\"slug\">固定链接</span>&nbsp;&nbsp;&nbsp;\n            <input id=\"slug\" class=\"ipt\" type=\"text\" name=\"slug\" required=\"required\" placeholder=\"文章的唯一链接\" value=\"{{.Article.Slug}}\"/>\n        </p>\n        <p class=\"item\">\n            <span>标签</span>&nbsp;&nbsp;\n            <input id=\"tag\" class=\"ipt\" type=\"text\" name=\"tag\" placeholder=\"文章的标签\" value=\"{{.Article.TagString}}\"/>\n        </p>\n        <p class=\"item\">\n            <span>保存状态</span>&nbsp;&nbsp;\n            <select name=\"status\" id=\"status\">\n                <option value=\"publish\"{{if eq .Article.Status \"publish\"}} selected{{end}}>公开</option>\n                <option value=\"draft\"{{if eq .Article.Status \"draft\"}} selected{{end}}>草稿</option>\n            </select>\n        </p>\n        <p class=\"item\">\n            <span>允许评论</span>&nbsp;&nbsp;\n            <select name=\"comment\" id=\"is-comment\">\n                <option value=\"1\"{{if eq .Article.IsComment true}} selected{{end}}>允许</option>\n                <option value=\"0\"{{if eq .Article.IsComment false}} selected{{end}}>关闭</option>\n            </select>\n        </p>\n    </div>\n    <p class=\"submit text-right\" id=\"article-submit\">\n        <span class=\"invalid lbl lbl-red hide\" id=\"slug-invalid\">固定链接由字母，数字和-组成</span>\n        <button class=\"btn btn-blue\">保存文章</button>\n    </p>\n</form>\n<form class=\"form hide\" id=\"attach-form\" action=\"/admin/files/upload/\" enctype=\"multipart/form-data\" method=\"post\">\n    <input id=\"attach-upload\" type=\"file\" name=\"file\"/>\n</form>\n<script src=\"/static/lib/codemirror.min.js\"></script>\n<script src=\"/static/lib/codemirror-mode.min.js\"></script>\n<script src=\"/static/lib/marked.min.js\"></script>\n<script src=\"/static/lib/highlight.min.js\"></script>\n<script src=\"/static/js/upload.js\"></script>\n<script>\n    $(function () {\n        var editor = CodeMirror.fromTextArea(document.getElementById(\"content\"), {\n            mode: 'markdown',\n            lineNumbers: true,\n            theme: \"default\",\n            extraKeys: {\"Enter\": \"newlineAndIndentContinueMarkdownList\"}\n        });\n        editor.on(\"change\", function () {\n            var str = editor.getValue();\n            $('.preview').html(marked(str)).find(\"pre code\").each(function (i, e) {\n                hljs.highlightBlock(e);\n            });\n        });\n        new FormValidator(\"article-form\", [\n            {\"name\": \"slug\", \"rules\": \"alpha_dash\"}\n        ], function (errors, e) {\n            e.preventDefault();\n            $('.invalid').hide();\n            if (errors.length) {\n                $(\"#\" + errors[0].id + \"-invalid\").removeClass(\"hide\").show();\n                return;\n            }\n            $('#article-form').ajaxSubmit(function (json) {\n                if (json.res) {\n                    if (confirm(\"已保存，去查看？还是继续编辑\")) {\n                        window.location.href = \"/admin/articles/\";\n                    }\n                } else {\n                    alert(json.msg);\n                }\n            });\n        });\n        initUpload(\"#article-submit\");\n    });\n</script>"
  },
  {
    "path": "view/admin/edit_page.html",
    "content": "<style>\n    @import \"/static/css/codemirror.css\";\n    @import \"/static/css/highlight.css\";\n</style>\n<form id=\"article-form\" class=\"form clear container\" action=\"#\" method=\"post\">\n    <div class=\"left grid-1-2\">\n        <input class=\"ipt title\" id=\"title\" type=\"text\" required=\"required\" name=\"title\" placeholder=\"页面标题\" value=\"{{.Page.Title}}\"/>\n        <textarea name=\"content\" id=\"content\" class=\"ipt\">{{Html .Page.Text}}</textarea>\n    </div>\n    <div class=\"left grid-1-2\">\n        <div class=\"preview markdown\"></div>\n    </div>\n    <div class=\"form-vertical left\">\n        <button class=\"btn btn-green left\" type=\"button\" id=\"attach-show\">添加附件</button>\n        <p class=\"item\">\n            <span for=\"slug\">固定链接</span>&nbsp;&nbsp;&nbsp;\n            <input id=\"slug\" class=\"ipt\" type=\"text\" name=\"slug\" required=\"required\" placeholder=\"页面的唯一链接\" value=\"{{.Page.Slug}}\"/>\n        </p>\n        <p class=\"item\">\n            <span>保存状态</span>&nbsp;&nbsp;\n            <select name=\"status\" id=\"status\">\n                <option value=\"publish\"{{if eq .Page.Status \"publish\"}} selected{{end}}>公开</option>\n                <option value=\"draft\"{{if eq .Page.Status \"draft\"}} selected{{end}}>草稿</option>\n            </select>\n        </p>\n        <p class=\"item\">\n            <span>允许评论</span>&nbsp;&nbsp;\n            <select name=\"comment\" id=\"is-comment\">\n                <option value=\"1\"{{if eq .Page.IsComment true}} selected{{end}}>允许</option>\n                <option value=\"0\"{{if eq .Page.IsComment false}} selected{{end}}>关闭</option>\n            </select>\n        </p>\n        <p class=\"item\">\n            <span>置顶链接</span>&nbsp;&nbsp;\n            <select name=\"link\" id=\"is-link\">\n                <option value=\"0\"{{if eq .Page.IsLinked false}} selected{{end}}>关闭</option>\n                <option value=\"1\"{{if eq .Page.IsLinked true}} selected{{end}}>允许</option>\n            </select>\n        </p>\n    </div>\n    <p class=\"submit text-right\" id=\"article-submit\">\n        <span class=\"invalid lbl lbl-red hide\" id=\"slug-invalid\">固定链接由字母，数字和-组成</span>\n        <button class=\"btn btn-blue\">保存文章</button>\n    </p>\n</form>\n<form class=\"form hide\" id=\"attach-form\" action=\"/admin/files/upload/\" enctype=\"multipart/form-data\" method=\"post\">\n    <input id=\"attach-upload\" type=\"file\" name=\"file\"/>\n</form>\n<script src=\"/static/lib/codemirror.min.js\"></script>\n<script src=\"/static/lib/codemirror-mode.min.js\"></script>\n<script src=\"/static/lib/marked.min.js\"></script>\n<script src=\"/static/lib/highlight.min.js\"></script>\n<script src=\"/static/js/upload.js\"></script>\n<script>\n    $(function () {\n        var editor = CodeMirror.fromTextArea(document.getElementById(\"content\"), {\n            mode: 'markdown',\n            lineNumbers: true,\n            theme: \"default\",\n            extraKeys: {\"Enter\": \"newlineAndIndentContinueMarkdownList\"}\n        });\n        editor.on(\"change\", function () {\n            var str = editor.getValue();\n            $('.preview').html(marked(str)).find(\"pre code\").each(function (i, e) {\n                hljs.highlightBlock(e);\n            });\n        });\n        new FormValidator(\"article-form\", [\n            {\"name\": \"slug\", \"rules\": \"alpha_dash\"}\n        ], function (errors, e) {\n            e.preventDefault();\n            $('.invalid').hide();\n            if (errors.length) {\n                $(\"#\" + errors[0].id + \"-invalid\").removeClass(\"hide\").show();\n                return;\n            }\n            $('#article-form').ajaxSubmit(function (json) {\n                if (json.res) {\n                    if (confirm(\"已保存，去查看？还是继续编辑\")) {\n                        window.location.href = \"/admin/pages/\";\n                    }\n                } else {\n                    alert(json.msg);\n                }\n            });\n        });\n        initUpload(\"#article-submit\");\n    });\n</script>"
  },
  {
    "path": "view/admin/files.html",
    "content": "<ul id=\"files-list\" class=\"admin container960 pager\">\n    <li class=\"file\" id=\"files-btn-li\">\n        <button class=\"btn btn-green\" id=\"attach-show\">添加附件</button>\n    </li>{{range .Files}}\n    <li class=\"file\" id=\"file-{{.Id}}\">\n        <span class=\"upload-time\">{{DateInt64 .UploadTime \"MM.DD\"}}</span>\n        <span class=\"size\">{{FileSize .Size}}</span>\n        <span class=\"name\">{{.Name}}</span>\n        <a class=\"link\" href=\"/{{.Url}}\" target=\"_blank\" title=\"/{{.Url}}\">查看</a>\n        <a class=\"del fade-out\" href=\"#\" rel=\"{{.Id}}\" title=\"删除附件\">删除</a>\n    </li>{{end}}\n    {{range .Pager.PageSlice}}\n    <li class=\"item{{if eq $.Pager.Current .}} current{{end}}\"><a href=\"/admin/files/?page={{.}}\">{{.}}</a></li>{{end}}\n</ul>\n<form class=\"form hide\" id=\"attach-form\" action=\"/admin/files/upload/\" enctype=\"multipart/form-data\" method=\"post\">\n    <input id=\"attach-upload\" type=\"file\" name=\"file\"/>\n</form>\n<script src=\"/static/js/upload.js\"></script>\n<script>\n    $(function () {\n        initUpload(\"#attach-show\");\n        $(\".del\").on(\"click\", function () {\n            if (confirm(\"删除附件相关链接会失效!\")) {\n                var id = $(this).attr(\"rel\");\n                $.ajax({\n                    \"type\": \"delete\",\n                    \"url\": \"/admin/files/?id=\" + id,\n                    \"success\": function (json) {\n                        if(json.res){\n                            $('#file-'+id).remove();\n                        }else{\n                            alert(json.msg);\n                        }\n                    }\n                });\n            }\n            return false;\n        })\n    });\n</script>"
  },
  {
    "path": "view/admin/home.html",
    "content": "<div class=\"admin container clear\" id=\"dashboard\">\n    <div class=\"grid-1-5 left\">\n        <div class=\"welcome\">\n            <h4>Welcome</h4>\n            <p>欢迎回来， <strong>{{.User.Nick}}</strong></p>\n        </div>\n        <div class=\"quick-link\">\n            <h4>快速链接</h4>\n            <ul>\n                <li><a href=\"/admin/article/write/\">撰写文章</a></li>\n                <li><a href=\"/admin/page/write/\">添加页面</a></li>\n                <li><a href=\"/admin/comments/\">查看和审核评论</a></li>\n                <li><a href=\"/admin/setting/\">修改配置</a></li>\n                <li><a href=\"/admin/profile/\">更新个人资料</a></li>\n            </ul>\n        </div>\n    </div>\n    <div class=\"grid-1-2 left\">\n        <div class=\"activity\">\n            <h4>最新活动</h4>{{range .Messages}}\n            <div class=\"msg relative {{.Type}}\">\n                <span class=\"time\">{{DateInt64 .CreateTime \"MM.DD HH:mm\"}}</span>\n                <div class=\"data\">{{Html .Data}}</div>\n                <a class=\"read absolute\" href=\"/admin/message/read?id={{.Id}}\" rel=\"{{.Id}}\">隐藏</a>\n            </div>{{end}}{{if lt (len .Messages) 1}}\n            <p>没有新的活动信息</p>\n            {{end}}\n        </div>\n    </div>\n    <div class=\"grid-1-4 right\">\n        <div class=\"stats\">\n            <h4>数据统计</h4>\n            <p>已经发布文章 <span class=\"lbl lbl-red\">{{.Statis.Articles}}</span> 篇，\n            页面 <span class=\"lbl lbl-red\">{{.Statis.Pages}}</span> 个， <br/>\n            收到评论 <span class=\"lbl lbl-blue\">{{.Statis.Comments}}</span> 次，\n            上传 <span class=\"lbl lbl-green\">{{.Statis.Files}}</span> 个附件，<br/>\n            评论者 <span class=\"lbl lbl-green\">{{.Statis.Readers}}</span> 人</p>\n            <p>当前程序版本：<strong>{{.Statis.Version}}</strong></p>\n        </div>\n        <div class=\"office\">\n            <h4>官方消息</h4>\n            <p>还没有消息</p>\n        </div>\n    </div>\n</div>\n<script>\n    $(document).ready(function(){\n       $(\".read\").on(\"click\",function(){\n           var $this = $(this);\n           $.post($this.attr(\"href\"),function(json){\n              if(json.res){\n                  $this.parent().remove();\n              }\n           });\n           return false;\n       });\n    });\n</script>"
  },
  {
    "path": "view/admin/login.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\"/>\n    <title>登录 - Fxh.Go</title>\n    <link rel=\"stylesheet\" href=\"/static/css/common.css\"/>\n    <style>\n        #login-form{\n            width: 280px;\n            margin: 80px auto;\n        }\n        #login-form h1{\n            margin-bottom: 12px;\n        }\n    </style>\n</head>\n<body>\n<form id=\"login-form\" class=\"form form-vertical\" action=\"#\" method=\"post\" name=\"login-form\">\n    <h1>登录 - Fxh.Go</h1>\n    <p class=\"field\">\n        <label for=\"user\">用户名</label>\n        <input class=\"ipt\" id=\"user\" type=\"text\" required=\"required\" name=\"user\"/>\n        <span class=\"invalid lbl lbl-red hide\" id=\"user-invalid\">用户名为字母+数字，长度4-20个字符</span>\n    </p>\n    <p class=\"field\">\n        <label for=\"password\">用户密码</label>\n        <input class=\"ipt\" id=\"password\" type=\"password\" required=\"required\" name=\"password\"/>\n        <span class=\"invalid lbl lbl-red hide\" id=\"password-invalid\">密码长度4-20个字符</span>\n    </p>\n    <button class=\"btn btn-blue\">登 录</button>\n    <span class=\"tip\">默认记住登陆3天</span>\n</form>\n<script src=\"http://libs.baidu.com/jquery/1.8.3/jquery.min.js\"></script>\n<script src=\"/static/lib/validate.min.js\"></script>\n<script src=\"/static/lib/jquery.form.min.js\"></script>\n<script>\n    $(function () {\n        new FormValidator(\"login-form\", [\n            {\"name\": \"user\", \"rules\": \"alpha_numeric|min_length[4]|max_length[20]\"},\n            {\"name\": \"password\", \"rules\": \"required|min_length[4]|max_length[20]\"}\n        ], function (errors, e) {\n            e.preventDefault();\n            $('.invalid').hide();\n            if (errors.length) {\n                $(\"#\" + errors[0].id + \"-invalid\").removeClass(\"hide\").show();\n                return;\n            }\n            $('#login-form').ajaxSubmit({\n                dataType: \"json\",\n                success: function (json) {\n                    if (!json.res) {\n                        alert(\"登录错误，请检查用户或密码\");\n                    } else {\n                        window.location.href = \"/admin/\";\n                    }\n                }\n            });\n        })\n    });\n</script>\n</body>\n</html>"
  },
  {
    "path": "view/admin/pages.html",
    "content": "<ul id=\"article-list\" class=\"container960 admin\">\n    <li>\n        <a class=\"lbl lbl-blue\" href=\"/admin/page/write/\">添加页面</a>\n    </li>{{range .Pages}}\n    <li>\n        <span class=\"time\">{{DateInt64 .CreateTime \"MM.DD\"}}</span><h4 class=\"inline-block title\"><a href=\"{{.Link}}\" target=\"_blank\">{{.Title}}</a></h4>{{if ne .Status \"publish\"}}\n        <span class=\"lbl status\">草稿</span>{{end}}\n        <span class=\"slug\">{{.Slug}}</span>{{if eq .IsComment false}}\n        <span class=\"is-comment\">关评</span>{{end}}\n        <span class=\"count\">{{.CommentNum}} / {{.Hits}}</span>\n        <a class=\"edit lbl lbl-green\" href=\"/admin/page/{{.Id}}/\" rel=\"{{.Id}}\">编辑</a>\n        <a class=\"del lbl lbl-red\" href=\"/admin/page/{{.Id}}/\" rel=\"{{.Id}}\">删除</a>\n    </li>{{end}}\n</ul>\n<ul id=\"article-pager\" class=\"pager container960\">{{range .Pager.PageSlice}}\n    <li class=\"item{{if eq $.Pager.Current .}} current{{end}}\"><a href=\"/admin/pages/?page={{.}}\">{{.}}</a></li>{{end}}\n</ul>\n<script>\n    $(\".del\").on(\"click\",function(e){\n        e.preventDefault();\n        if(confirm(\"删除页面将使相关内容失效！确认？\")){\n            var id = $(this).attr(\"rel\");\n            $.ajax({\n                \"url\":\"/admin/page/\"+id+\"/\",\n                \"type\":\"delete\",\n                \"success\":function(json){\n                    if(json.res){\n                        alert(\"已删除\");\n                        window.location.reload();\n                    }else{\n                        alert(json.msg);\n                    }\n                }\n            })\n        }\n    });\n</script>"
  },
  {
    "path": "view/admin/password.html",
    "content": "<form id=\"password\" class=\"form form-align clear\" action=\"#\" name=\"password-form\" method=\"post\">\n    <p class=\"field\">\n        <label for=\"old\">旧密码</label>\n        <input id=\"old\" type=\"password\" name=\"old\" required=\"required\" class=\"ipt\"/>\n        <span class=\"tip\">验证旧密码</span><br/>\n        <span class=\"invalid lbl lbl-red hide\" id=\"old-invalid\">密码长度4-20个字符</span>\n    </p>\n    <p class=\"field\">\n        <label for=\"new\">新密码</label>\n        <input id=\"new\" type=\"password\" name=\"new\" required=\"required\" class=\"ipt\"/><br/>\n        <span class=\"invalid lbl lbl-red hide\" id=\"new-invalid\">密码长度4-20个字符</span>\n    </p>\n    <p class=\"field\">\n        <label for=\"confirm\">确认密码</label>\n        <input id=\"confirm\" type=\"password\" name=\"confirm\" required=\"required\" class=\"ipt\"/><br/>\n        <span class=\"invalid lbl lbl-red hide\" id=\"confirm-invalid\">确认密码不匹配</span>\n    </p>\n    <p class=\"field\">\n        <label>&nbsp;</label>\n        <button class=\"btn btn-blue\">保存修改</button>\n    </p>\n</form>\n<script>\n    $(function(){\n        new FormValidator(\"password-form\",[\n            {\"name\":\"old\",\"rules\":\"min_length[2]|max_length[20]\"},\n            {\"name\":\"new\",\"rules\":\"min_length[2]|max_length[20]\"},\n            {\"name\":\"confirm\",\"rules\":\"required|matches[new]\"}\n        ],function(errors,e){\n            e.preventDefault();\n            $('.invalid').hide();\n            if(errors.length){\n                $(\"#\"+errors[0].id+\"-invalid\").removeClass(\"hide\").show();\n                return;\n            }\n            $('#password').ajaxSubmit(function(json){\n                if(!json.res){\n                    alert(json.msg);\n                }else{\n                    alert(\"已保存\");\n                }\n            });\n        })\n    });\n</script>"
  },
  {
    "path": "view/admin/plugin.html",
    "content": "<ul id=\"plugin-list\" class=\"container960 admin\">{{range .Plugins}}\n    <li class=\"clear\">{{if .IsActive}}\n        <span class=\"left lbl active lbl-green\">&nbsp;</span>{{end}}\n        <span class=\"name left\">{{.Name}}</span>\n        <span class=\"version left\">{{.Version}}</span>{{if .HasSetting}}\n        <a class=\"setting left\" href=\"/admin/plugins/{{.Key}}/\">选项</a>{{end}}{{if .IsActive}}\n        <a class=\"deactivate lbl lbl-red right\" href=\"#\" rel=\"{{.Key}}\">封印</a>{{else}}\n        <a class=\"activate lbl lbl-blue right\" href=\"#\" rel=\"{{.Key}}\">激活</a>{{end}}\n        <p class=\"desc left\">{{.Desc}}</p>\n    </li>{{end}}\n</ul>\n<script>\n    $(function () {\n        $(\".deactivate\").on(\"click\", function () {\n            var $this = $(this);\n            var p = $this.attr(\"rel\");\n            $.post(\"\", {\n                \"action\": \"deactivate\",\n                \"plugin\": p\n            }, function (json) {\n                if (json.res) {\n                    $this.off(\"click\").text(\"下次激活\");\n                } else {\n                    alert(\"封印失败\");\n                }\n            })\n        });\n        $(\".activate\").on(\"click\", function () {\n            var $this = $(this);\n            var p = $this.attr(\"rel\");\n            $.post(\"\", {\n                \"action\": \"activate\",\n                \"plugin\": p\n            }, function (json) {\n                if (json.res) {\n                    $this.off(\"click\").text(\"下次封印\");\n                } else {\n                    alert(\"激活失败\");\n                }\n            })\n        })\n    });\n</script>"
  },
  {
    "path": "view/admin/plugin_setting.html",
    "content": "<form id=\"plugin-setting-form\" class=\"form container960 admin\" action=\"#\" method=\"post\">\n    {{Html .Form}}\n</form>\n<script>\n    $(document).ready(function(){\n        $('#plugin-setting-form').ajaxForm(function(json){\n            alert(json.res ? \"已保存\":\"保存失败\");\n        })\n    })\n</script>"
  },
  {
    "path": "view/admin/profile.html",
    "content": "<form id=\"profile\" class=\"admin form clear form-align\" action=\"#\" method=\"post\" name=\"profile-form\">\n    <div class=\"avatar grid-1-4 left text-center\">\n        <img src=\"{{.User.Avatar}}\" alt=\"{{.User.Nick}}\" class=\"field\"/>\n        <span class=\"tip field inline-block\">头像由 <a href=\"http://gravatar.com/\" target=\"_blank\" rel=\"no-follow\">Gravatar</a> 提供</span>\n        <p class=\"field\">\n            <a class=\"btn btn-red inline-block\" href=\"/admin/password/\">修改密码</a>\n        </p>\n    </div>\n    <div class=\"info right grid-3-4\">\n        <p class=\"field\">\n            <label for=\"user\">登录名</label>\n            <input id=\"user\" type=\"text\" name=\"user\" value=\"{{.User.Name}}\" required=\"required\" class=\"ipt\"/>\n            <span class=\"tip\">登录的用户名</span><br/>\n            <span class=\"invalid lbl lbl-red hide\" id=\"user-invalid\">用户名为字母+数字，长度4-20个字符</span>\n        </p>\n        <p class=\"field\">\n            <label for=\"nick\">昵称</label>\n            <input id=\"nick\" type=\"text\" name=\"nick\" value=\"{{.User.Nick}}\" required=\"required\" class=\"ipt\"/>\n            <span class=\"tip\">显示在前台的称呼</span>\n            <br/><span class=\"invalid lbl lbl-red hide\" id=\"nick-invalid\">昵称长度2-20个字符</span>\n        </p>\n        <p class=\"field\">\n            <label for=\"email\">邮箱</label>\n            <input id=\"email\" type=\"email\" name=\"email\" value=\"{{.User.Email}}\" required=\"required\" class=\"ipt\"/>\n            <span class=\"tip\">联系邮箱，十分重要！</span>\n            <br/><span class=\"invalid lbl lbl-red hide\" id=\"email-invalid\">邮箱格式错误</span>\n        </p>\n        <p class=\"field\">\n            <label for=\"url\">网址</label>\n            <input id=\"url\" type=\"url\" name=\"url\" value=\"{{.User.Url}}\" class=\"ipt\"/>\n            <br/><span class=\"invalid lbl lbl-red hide\" id=\"url-invalid\">网址格式错误</span>\n        </p>\n        <p class=\"field\">\n            <textarea class=\"ipt bio\" name=\"bio\" id=\"bio\">{{.User.Bio}}</textarea>\n        </p>\n        <p class=\"field\">\n            <label>&nbsp;</label>\n            <button class=\"btn btn-blue\">保存修改</button>\n        </p>\n    </div>\n</form>\n<script>\n    $(function(){\n        new FormValidator(\"profile-form\",[\n            {\"name\":\"user\",\"rules\":\"alpha_numeric|min_length[4]|max_length[20]\"},\n            {\"name\":\"nick\",\"rules\":\"min_length[2]|max_length[20]\"},\n            {\"name\":\"email\",\"rules\":\"valid_email\"},\n            {\"name\":\"url\",\"rules\":\"valid_url\"}\n        ],function(errors,e){\n            e.preventDefault();\n            $('.invalid').hide();\n            if(errors.length){\n                $(\"#\"+errors[0].id+\"-invalid\").removeClass(\"hide\").show();\n                return;\n            }\n            $('#profile').ajaxSubmit(function(json){\n                if(!json.res){\n                    alert(json.msg);\n                }else{\n                    alert(\"已保存\");\n                }\n            });\n        })\n    });\n</script>"
  },
  {
    "path": "view/admin/setting.html",
    "content": "<ul id=\"setting-nav\" class=\"container text-center\">\n    <li><a href=\"#general\">基本</a></li>\n    <li><a href=\"#content\">内容</a></li>\n    <li><a href=\"#nav\">导航</a></li>\n    <li><a href=\"#custom\">自定义</a></li>\n</ul>\n<div id=\"setting-panels\" class=\"container\">\n    <form id=\"setting-form\" class=\"setting-form form form-align setting-panel\" action=\"/admin/setting/\" method=\"post\">\n        <p class=\"item\">\n            <label for=\"site-url\">站点地址</label>\n            <input id=\"site-url\" class=\"ipt\" type=\"url\" name=\"site_url\" required=\"required\" value=\"{{Setting `site_url`}}\"/>\n        </p>\n        <p class=\"item\">\n            <label for=\"site-title\">站点主标题</label>\n            <input id=\"site-title\" class=\"ipt\" type=\"text\" name=\"site_title\" required=\"required\" value=\"{{Setting `site_title`}}\"/>\n        </p>\n        <p class=\"item\">\n            <label for=\"site-sub-title\">站点副标题</label>\n            <input id=\"site-sub-title\" class=\"ipt\" type=\"text\" name=\"site_sub_title\" required=\"required\" value=\"{{Setting `site_sub_title`}}\"/>\n        </p>\n        <p class=\"item\">\n            <label for=\"site-keywords\">Meta关键字</label>\n            <input id=\"site-keywords\" class=\"ipt\" type=\"text\" name=\"site_keywords\" value=\"{{Setting `site_keywords`}}\"/>\n        </p>\n        <p class=\"item\">\n            <label for=\"site-desc\">Meta站点介绍</label>\n            <input id=\"site-desc\" class=\"ipt\" type=\"text\" name=\"site_description\" value=\"{{Setting `site_description`}}\"/>\n        </p>\n        <p>\n            <label>&nbsp;</label>\n            <button class=\"btn btn-blue\">保存</button>\n        </p>\n    </form>\n    <form id=\"setting-content-form\" class=\"setting-form form form-align setting-panel\" action=\"/admin/setting/\" method=\"post\">\n        <p class=\"item\">\n            <label for=\"article-size\">单页文章列表数</label>\n            <input id=\"article-size\" class=\"ipt\" type=\"number\" name=\"article_size\" value=\"{{Setting `article_size`}}\" max=\"10\" min=\"3\" required=\"required\"/>\n        </p>\n        <p class=\"item\">\n            <label for=\"popular-size\">热评文章列表数</label>\n            <input id=\"popular-size\" class=\"ipt\" type=\"number\" name=\"popular_size\" value=\"{{Setting `popular_size`}}\" max=\"10\" min=\"3\"  required=\"required\"/>\n        </p>\n        <p class=\"item\">\n            <label for=\"recent-comment-size\">最近评论列表数</label>\n            <input id=\"recent-comment-size\" class=\"ipt\" type=\"number\" name=\"recent_comment_size\" value=\"{{Setting `recent_comment_size`}}\" max=\"10\" min=\"3\" required=\"required\"/>\n        </p>\n        <p class=\"item\">\n            <label for=\"go-markdown\">Go渲染Markdown</label>\n            <input id=\"go-markdown\" class=\"ipt\" type=\"text\" name=\"enable_go_markdown\" value=\"{{Setting `enable_go_markdown`}}\"/>\n            <span class=\"tip block\">默认关闭，使用前端marked.js渲染，填true时开启</span>\n            <input type=\"hidden\" name=\"enable_go_markdown_def\" value=\"false\"/>\n        </p>\n        <p>\n            <label>&nbsp;</label>\n            <button class=\"btn btn-blue\">保存</button>\n        </p>\n    </form>\n    <form id=\"setting-nav-form\" class=\"setting-form form form-align setting-panel\" action=\"/admin/setting/nav/\" method=\"post\">{{range .Navigators}}\n        <p class=\"item\">\n            <span class=\"label\">排序</span><input class=\"ipt order\" type=\"number\" name=\"order\" value=\"{{.Order}}\"/>&nbsp;&nbsp;&nbsp;&nbsp;\n            <span class=\"label\">文本</span><input class=\"ipt text\" type=\"text\" name=\"text\" value=\"{{.Text}}\" required=\"required\"/>&nbsp;&nbsp;&nbsp;&nbsp;\n            <span class=\"label\">标题</span><input class=\"ipt title\" type=\"text\" name=\"title\" value=\"{{.Title}}\"/>&nbsp;&nbsp;&nbsp;&nbsp;\n            <span class=\"label\">链接</span><input class=\"ipt link\" type=\"text\" name=\"link\" value=\"{{.Link}}\" required=\"required\"/>&nbsp;&nbsp;&nbsp;&nbsp;\n            <a class=\"del\" href=\"#\">删除</a>\n        </p>{{end}}\n        <p>\n            <button class=\"btn btn-blue\">保存</button>&nbsp;&nbsp;&nbsp;&nbsp;\n            <a class=\"lbl lbl-green add\" href=\"#\" rel=\"#nav-item\">添加一项</a>\n        </p>\n        <script type=\"text/template\" id=\"nav-item\">\n            <p class=\"item\">\n                <span class=\"label\">排序</span><input class=\"ipt order\" type=\"number\" name=\"order\" value=\"1\"/>&nbsp;&nbsp;&nbsp;&nbsp;\n                <span class=\"label\">文本</span><input class=\"ipt text\" type=\"text\" name=\"text\" value=\"\" required=\"required\"/>&nbsp;&nbsp;&nbsp;&nbsp;\n                <span class=\"label\">标题</span><input class=\"ipt title\" type=\"text\" name=\"title\" value=\"\"/>&nbsp;&nbsp;&nbsp;&nbsp;\n                <span class=\"label\">链接</span><input class=\"ipt link\" type=\"text\" name=\"link\" value=\"\" required=\"required\"/>&nbsp;&nbsp;&nbsp;&nbsp;\n                <a class=\"del\" href=\"#\">删除</a>\n            </p>\n        </script>\n    </form>\n    <form id=\"setting-custom-form\" class=\"setting-form form form-align setting-panel\" action=\"/admin/setting/custom/\" method=\"post\">{{range $k,$v := .Custom}}\n        <p class=\"item\">\n            <input class=\"ipt key\" type=\"text\" name=\"key\" value=\"{{$k}}\"/>&nbsp;&nbsp;&nbsp;&nbsp;\n            <input name=\"value\" class=\"ipt value\" type=\"text\" value=\"{{$v}}\"/>\n            <a class=\"del\" href=\"#\">删除</a>\n        </p>{{end}}\n        <p>\n            <button class=\"btn btn-blue\">保存</button>&nbsp;&nbsp;&nbsp;&nbsp;\n            <a class=\"lbl lbl-green add\" href=\"#\" rel=\"#custom-item\">添加一项</a>\n            <span class=\"tip block\">使用函数自定义配置，需要加前缀\"c_\"，如GetSetting(\"c_key\")</span>\n        </p>\n        <script type=\"text/template\" id=\"custom-item\">\n            <p class=\"item\">\n                <input class=\"ipt key\" type=\"text\" name=\"key\" placeholder=\"字段名\"/>&nbsp;&nbsp;&nbsp;&nbsp;\n                <input name=\"value\" class=\"ipt value\" type=\"text\" placeholder=\"字段值\"/>\n                <a class=\"del\" href=\"#\">删除</a>\n            </p>\n        </script>\n    </form>\n</div>\n<script src=\"http://libs.baidu.com/jquerytools/1.2.7/jquery.tools.min.js\"></script>\n<script>\n    $(function () {\n        $('#setting-nav').tabs(\".setting-panel\");\n        $('.setting-form').ajaxForm(function (json) {\n            alert(json.res ? \"已保存\" : json.msg);\n        }).on(\"click\",\".add\",function(e){\n            e.preventDefault();\n            $(this).parent().parent().prepend($($(this).attr(\"rel\")).html());\n        }).on(\"click\",\".del\",function(e){\n            e.preventDefault();\n            if(confirm(\"要删除这项？\")){\n                $(this).parent().remove();\n            }\n        })\n    })\n</script>"
  },
  {
    "path": "view/admin/write_article.html",
    "content": "<style>\n    @import \"/static/css/codemirror.css\";\n    @import \"/static/css/highlight.css\";\n</style>\n<form id=\"article-form\" class=\"form clear container\" action=\"#\" method=\"post\">\n    <div class=\"left grid-1-2\">\n        <input class=\"ipt title\" id=\"title\" type=\"text\" required=\"required\" name=\"title\" placeholder=\"文章标题\"/>\n        <textarea name=\"content\" id=\"content\" class=\"ipt\">撰写文章内容，支持`markdown`语法高亮</textarea>\n    </div>\n    <div class=\"left grid-1-2\">\n        <div class=\"preview markdown\"></div>\n    </div>\n    <div class=\"form-vertical left\">\n        <button class=\"btn btn-green left\" type=\"button\" id=\"attach-show\">添加附件</button>\n        <p class=\"item\">\n            <span for=\"slug\">固定链接</span>&nbsp;&nbsp;&nbsp;\n            <input id=\"slug\" class=\"ipt\" type=\"text\" name=\"slug\" required=\"required\" placeholder=\"文章的唯一链接\"/>\n        </p>\n        <p class=\"item\">\n            <span>标签</span>&nbsp;&nbsp;\n            <input id=\"tag\" class=\"ipt\" type=\"text\" name=\"tag\" placeholder=\"文章的标签\"/>\n        </p>\n        <p class=\"item\">\n            <span>保存状态</span>&nbsp;&nbsp;\n            <select name=\"status\" id=\"status\">\n                <option value=\"publish\">公开</option>\n                <option value=\"draft\">草稿</option>\n            </select>\n        </p>\n        <p class=\"item\">\n            <span>允许评论</span>&nbsp;&nbsp;\n            <select name=\"comment\" id=\"is-comment\">\n                <option value=\"1\">允许</option>\n                <option value=\"0\">关闭</option>\n            </select>\n        </p>\n    </div>\n    <p class=\"submit text-right\" id=\"article-submit\">\n        <span class=\"invalid lbl lbl-red hide\" id=\"slug-invalid\">固定链接由字母，数字和-组成</span>\n        <button class=\"btn btn-blue\">保存文章</button>\n    </p>\n</form>\n<form class=\"form hide\" id=\"attach-form\" action=\"/admin/files/upload/\" enctype=\"multipart/form-data\" method=\"post\">\n    <input id=\"attach-upload\" type=\"file\" name=\"file\"/>\n</form>\n<script src=\"/static/lib/codemirror.min.js\"></script>\n<script src=\"/static/lib/codemirror-mode.min.js\"></script>\n<script src=\"/static/lib/marked.min.js\"></script>\n<script src=\"/static/lib/highlight.min.js\"></script>\n<script src=\"/static/js/upload.js\"></script>\n<script>\n    $(function () {\n        var editor = CodeMirror.fromTextArea(document.getElementById(\"content\"), {\n            mode: 'markdown',\n            lineNumbers: true,\n            theme: \"default\",\n            extraKeys: {\"Enter\": \"newlineAndIndentContinueMarkdownList\"}\n        });\n        editor.on(\"change\", function () {\n            var str = editor.getValue();\n            $('.preview').html(marked(str)).find(\"pre code\").each(function (i, e) {\n                hljs.highlightBlock(e);\n            });\n        });\n        new FormValidator(\"article-form\", [\n            {\"name\": \"slug\", \"rules\": \"alpha_dash\"}\n        ],function (errors, e) {\n            e.preventDefault();\n            $('.invalid').hide();\n            if (errors.length) {\n                $(\"#\" + errors[0].id + \"-invalid\").removeClass(\"hide\").show();\n                return;\n            }\n            $('#article-form').ajaxSubmit(function (json) {\n                if (json.res) {\n                    alert(\"已保存\");\n                    window.location.href = \"/admin/articles/\";\n                } else {\n                    alert(json.msg);\n                }\n            });\n        });\n        initUpload(\"#article-submit\");\n    });\n</script>"
  },
  {
    "path": "view/admin/write_page.html",
    "content": "<style>\n    @import \"/static/css/codemirror.css\";\n    @import \"/static/css/highlight.css\";\n</style>\n<form id=\"article-form\" class=\"form clear container\" action=\"#\" method=\"post\">\n    <div class=\"left grid-1-2\">\n        <input class=\"ipt title\" id=\"title\" type=\"text\" required=\"required\" name=\"title\" placeholder=\"页面标题\"/>\n        <textarea name=\"content\" id=\"content\" class=\"ipt\">撰写页面内容，支持`markdown`语法高亮</textarea>\n    </div>\n    <div class=\"left grid-1-2\">\n        <div class=\"preview markdown\"></div>\n    </div>\n    <div class=\"form-vertical left\">\n        <button class=\"btn btn-green left\" type=\"button\" id=\"attach-show\">添加附件</button>\n        <p class=\"item\">\n            <span for=\"slug\">固定链接</span>&nbsp;&nbsp;&nbsp;\n            <input id=\"slug\" class=\"ipt\" type=\"text\" name=\"slug\" required=\"required\" placeholder=\"页面的唯一链接\"/>\n        </p>\n        <p class=\"item\">\n            <span>保存状态</span>&nbsp;&nbsp;\n            <select name=\"status\" id=\"status\">\n                <option value=\"publish\">公开</option>\n                <option value=\"draft\">草稿</option>\n            </select>\n        </p>\n        <p class=\"item\">\n            <span>允许评论</span>&nbsp;&nbsp;\n            <select name=\"comment\" id=\"is-comment\">\n                <option value=\"1\">允许</option>\n                <option value=\"0\">关闭</option>\n            </select>\n        </p>\n        <p class=\"item\">\n            <span>置顶链接</span>&nbsp;&nbsp;\n            <select name=\"link\" id=\"is-link\">\n                <option value=\"0\">关闭</option>\n                <option value=\"1\">允许</option>\n            </select>\n        </p>\n    </div>\n    <p class=\"submit text-right\" id=\"article-submit\">\n        <span class=\"invalid lbl lbl-red hide\" id=\"slug-invalid\">固定链接由字母，数字和-组成</span>\n        <button class=\"btn btn-blue\">保存文章</button>\n    </p>\n</form>\n<form class=\"form hide\" id=\"attach-form\" action=\"/admin/files/upload/\" enctype=\"multipart/form-data\" method=\"post\">\n    <input id=\"attach-upload\" type=\"file\" name=\"file\"/>\n</form>\n<script src=\"/static/lib/codemirror.min.js\"></script>\n<script src=\"/static/lib/codemirror-mode.min.js\"></script>\n<script src=\"/static/lib/marked.min.js\"></script>\n<script src=\"/static/lib/highlight.min.js\"></script>\n<script src=\"/static/js/upload.js\"></script>\n<script>\n    $(function () {\n        var editor = CodeMirror.fromTextArea(document.getElementById(\"content\"), {\n            mode: 'markdown',\n            lineNumbers: true,\n            theme: \"default\",\n            extraKeys: {\"Enter\": \"newlineAndIndentContinueMarkdownList\"}\n        });\n        editor.on(\"change\", function () {\n            var str = editor.getValue();\n            $('.preview').html(marked(str)).find(\"pre code\").each(function (i, e) {\n                hljs.highlightBlock(e);\n            });\n        });\n        new FormValidator(\"article-form\", [\n            {\"name\": \"slug\", \"rules\": \"alpha_dash\"}\n        ],function (errors, e) {\n            e.preventDefault();\n            $('.invalid').hide();\n            if (errors.length) {\n                $(\"#\" + errors[0].id + \"-invalid\").removeClass(\"hide\").show();\n                return;\n            }\n            $('#article-form').ajaxSubmit(function (json) {\n                if (json.res) {\n                    alert(\"已保存\");\n                    window.location.href = \"/admin/pages/\";\n                } else {\n                    alert(json.msg);\n                }\n            });\n        });\n        initUpload(\"#article-submit\");\n    });\n</script>"
  },
  {
    "path": "view/default/article.html",
    "content": "<div id=\"article-container\" class=\"clear\">\n    <article class=\"clear {{.Article.Status}}\" id=\"article-{{.Article.Id}}\">{{with .Article}}\n        <h3 class=\"title\"><a href=\"{{.Link}}\" title=\"{{.Title}}\">{{.Title}}</a></h3>\n        <section class=\"content markdown\">{{Html .Content}}</section>\n        <p class=\"info clear\">{{if .User}}\n            <span class=\"author inline-block\"><i class=\"fa fa-user\"></i>{{.User.Nick}}</span>{{end}}\n            <span class=\"time inline-block\"><i class=\"fa fa-clock-o\"></i>{{DateInt64 .CreateTime \"MM.DD\"}}</span>{{if .TagString}}\n            <span class=\"tag inline-block\"><i class=\"fa fa-tags\"></i>{{range .GetTags}}<a href=\"{{.Link}}\">{{.Name}}</a>{{end}}</span>{{end}}\n            <span class=\"views inline-block right\">阅读&nbsp;&nbsp;<span>{{.Hits}}</span>&nbsp;&nbsp;次</span>\n        </p>{{end}}\n    </article>\n    {{Html .CommentHtml}}\n</div>"
  },
  {
    "path": "view/default/comment.html",
    "content": "<div id=\"comment\">\n    <div id=\"comment-list\">{{range .Comments}}{{if .IsValid}}\n        <div class=\"comment clear\" id=\"comment-{{.Id}}\">\n            <img class=\"c-avatar left\" src=\"{{.Avatar}}\" alt=\"{{.Author}}\"/>\n            <div class=\"c-section left\">\n                <div class=\"c-meta\">\n                    <a class=\"lbl lbl-blue c-author{{if .IsAdmin}} admin{{end}}\" href=\"{{.Url}}\" target=\"_blank\">{{.Author}}{{if .IsAdmin}}&nbsp;&nbsp;(admin){{end}}</a>\n                    <span class=\"c-time\"><i class=\"fa fa-clock-o\"></i>{{DateInt64 .CreateTime \"MM.DD HH:mm\"}}</span>\n                    <a class=\"c-reply\" href=\"#\" rel=\"{{.Id}}\"><i class=\"fa fa-quote-right\"></i></a>\n                </div>\n                <section class=\"c-content\">{{Html .Content}}</section>{{if .ParentMd}}\n                <div class=\"c-p-md markdown\">{{Html .ParentMd}}</div>{{end}}\n            </div>\n        </div>{{end}}{{end}}\n    </div>\n    <div id=\"comment-show\" class=\"text-center\">{{if .Content.IsComment}}\n        <button class=\"btn btn-green enable\">发表评论</button>{{else}}\n        <button class=\"btn btn-red\">本文关闭了评论</button>{{end}}\n    </div>{{if .Content.IsComment}}\n    <form id=\"comment-form\" class=\"hide clear text-center form\" action=\"/comment/{{.Content.Id}}/\" method=\"post\">\n        <div class=\"c-info left text-right\">\n            <p class=\"item c-avatar-field\">\n                <img class=\"c-avatar null\" src=\"/static/img/site.png\" alt=\"\" id=\"comment-avatar\"/>\n                <a class=\"not-me block\" href=\"#\">不是我?</a>\n            </p>\n            <div class=\"c-info-fields hide\">\n                <p class=\"item\"><input class=\"ipt\" type=\"text\" name=\"user\" required=\"required\" placeholder=\"称呼\" id=\"comment-author\"/></p>\n                <p class=\"item\"><input class=\"ipt\" type=\"email\" name=\"email\" required=\"required\" placeholder=\"邮箱\" id=\"comment-email\"/> </p>\n                <p class=\"item\"><input class=\"ipt\" type=\"url\" name=\"url\" placeholder=\"网址\" id=\"comment-url\"/></p>\n                <input id=\"comment-parent\" type=\"hidden\" value=\"0\" name=\"pid\"/>\n            </div>\n        </div>\n        <div class=\"c-content text-left right\">\n            <textarea class=\"ipt\" name=\"content\" id=\"comment-content\" required=\"required\"></textarea>\n            <button class=\"btn btn-blue\">发表评论</button>\n            <button class=\"lbl lbl-green cancel-reply\" type=\"button\">取消回复</button>\n        </div>\n    </form>{{end}}\n    <script type=\"text/template\" id=\"comment-tpl\">\n        <div class=\"comment clear\">\n            <img class=\"c-avatar left\" src=\"\" alt=\"\"/>\n            <div class=\"c-section left\">\n                <div class=\"c-meta\">\n                    <a class=\"lbl lbl-blue c-author\" href=\"\" target=\"_blank\"></a>\n                    <span class=\"c-time\"><i class=\"fa fa-clock-o\"></i>Now</span>\n                    <a class=\"c-reply\" href=\"#\" rel=\"\"><i class=\"fa fa-quote-right\"></i></a>\n                    <span class=\"c-check\"><i class=\"fa fa-exclamation-triangle\"></i>审核中，刷新后隐藏</span>\n                </div>\n                <section class=\"c-content\"></section>\n                <div class=\"c-p-md markdown\"></div>\n            </div>\n        </div>\n    </script>\n</div>"
  },
  {
    "path": "view/default/error/error.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\"/>\n    <title>错误提示</title>\n    <link rel=\"stylesheet\" href=\"/static/css/common.css\"/>\n    <style>body{margin: 40px 100px}</style>\n</head>\n<body>\n<h2>您访问的页面正在打瞌睡</h2><br/>\n<p>程序员正在努力唤醒，请稍候访问...</p>\n<p><a href=\"/\">返回首页</a></p>\n</body>\n</html>"
  },
  {
    "path": "view/default/error/notfound.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\"/>\n    <title>错误提示</title>\n    <link rel=\"stylesheet\" href=\"/static/css/common.css\"/>\n    <style>body{margin: 40px 100px}</style>\n</head>\n<body>\n<h2>您访问的页面离家出走</h2><br/>\n<p>程序员正在四处寻找，请稍候访问...</p>\n<p><a href=\"/\">返回首页</a></p>\n</body>\n</html>"
  },
  {
    "path": "view/default/home.layout",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\"/>\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\"/>\n    <title>{{if .Title}}{{.Title}} - {{end}}{{Setting \"site_title\"}}</title>\n    <meta name=\"keywords\" content=\"{{Setting `site_keywords`}}\"/>\n    <meta name=\"description\" content=\"{{Setting `site_description`}}\"/>\n    <meta name=\"generator\" content=\"FxhGo Blog\" />\n    <link rel=\"stylesheet\" href=\"/static/css/style.css\"/>\n    <link rel=\"stylesheet\" href=\"http://libs.baidu.com/fontawesome/4.0.3/css/font-awesome.min.css\"/>\n    <link rel=\"alternate\" type=\"application/rss+xml\" title=\"{{Setting `site_title`}} - RSS 2.0\" href=\"/feed/\"/>\n    <script src=\"http://libs.baidu.com/jquery/1.8.3/jquery.min.js\"></script>\n    <script src=\"/static/lib/jquery.form.min.js\"></script>\n    <script src=\"/static/lib/marked.min.js\"></script>\n</head>\n<body>\n<header id=\"header\" class=\"clear\">\n    <div class=\"container960 text-center\">\n        <img src=\"{{Setting `c_home_avatar`}}\" alt=\"site\" id=\"header-img\"/>\n        <h1 id=\"header-h\"><a href=\"/\">{{Setting \"site_title\"}}</a></h1>\n        <h4 id=\"header-sub\">{{Setting \"site_sub_title\"}}</h4>\n    </div>\n</header>\n<nav id=\"nav\" class=\"clear text-center\">\n    <ul>{{range Navigator}}\n        <li class=\"inline-block\"><a href=\"{{.Link}}\" title=\"{{.Title}}\">{{.Text}}</a></li>{{end}}\n    </ul>\n</nav>\n<div id=\"main\" class=\"container960\">\n    {@Content}\n</div>\n<footer id=\"footer\" class=\"text-center\">\n    <p>\n        <a class=\"weibo\" href=\"{{Setting `c_footer_weibo`}}\" target=\"_blank\"><i class=\"fa fa-weibo\"></i>Weibo</a>\n        <a class=\"git\" href=\"{{Setting `c_footer_github`}}\" target=\"_blank\"><i class=\"fa fa-github\"></i>GitHub</a>\n        <a class=\"email\" href=\"{{Setting `c_footer_email`}}\" target=\"_blank\"><i class=\"fa fa-envelope\"></i>Email</a>\n        <a class=\"rss\" href=\"/feed/\" target=\"_blank\"><i class=\"fa fa-rss\"></i>RSS</a>{{Setting `c_footer_ga` | Html}}\n    </p>\n    <span>Go © 2014 All rights reserved. Proudly Powered by <a href=\"https://github.com/fuxiaohei/GoBlog\" target=\"_blank\">Fxh.Go</a>.</span>\n    <a id=\"go-top\" href=\"#\" class=\"lbl hide lbl-blue\" title=\"回到顶部\"><i class=\"fa fa-arrow-up fa-lg\"></i></a>\n</footer>\n<script src=\"/static/js/home.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "view/default/index.html",
    "content": "<div id=\"article-container\" class=\"clear\">{{if .Tag}}\n    <div class=\"tag-banner\">标签：{{.Tag}}</div>{{end}}{{range .Articles}}\n    <article class=\"clear {{.Status}}\" id=\"article-{{.Id}}\">\n        <div class=\"meta left text-center\">{{if gt .CommentNum 0}}\n            <p class=\"lbl lbl-red comments\"><a href=\"{{.Link}}#comment\"><i class=\"fa fa-comments\"></i><strong>{{.CommentNum}} ℃</strong></a></p>{{end}}\n            <p class=\"lbl lbl-green views\"><i class=\"fa fa-eye\"></i><strong>{{.Hits}} ℉</strong></p>\n            <p class=\"lbl lbl-gray time\"><i class=\"fa fa-clock-o\"></i><strong>{{DateInt64 .CreateTime \"MM.DD\"}}</strong></p>\n        </div>\n        <div class=\"main\">\n            <h3 class=\"title\"><a href=\"{{.Link}}\" title=\"{{.Title}}\">{{.Title}}</a></h3>\n            <section class=\"content markdown\">{{Html .Summary}}</section>\n            <p class=\"info clear\">{{if .User}}\n                <span class=\"author inline-block\"><i class=\"fa fa-user\"></i>{{.User.Nick}}</span>{{end}}{{if .TagString}}\n                <span class=\"tag inline-block\"><i class=\"fa fa-tags\"></i>标签：{{range .GetTags}}<a href=\"{{.Link}}\">{{.Name}}</a>{{end}}</span>{{end}}\n                <a class=\"inline-block read right\" href=\"{{.Link}}\"><i class=\"fa fa-search\"></i>继续阅读</a>\n            </p>\n        </div>\n    </article>{{end}}\n    <div class=\"pager text-center\">{{range .Pager.PageSlice}}\n        <a href=\"/p/{{.}}/\" class=\"item{{if eq $.Pager.Current .}} current{{end}}\">{{.}}</a>{{end}}\n    </div>\n</div>"
  },
  {
    "path": "view/default/page.html",
    "content": "<div id=\"article-container\" class=\"clear\">\n    <article class=\"clear\" id=\"article-Id\">{{with .Page}}\n        <h3 class=\"title\"><a href=\"{{.Link}}\" title=\"{{.Title}}\">{{.Title}}</a></h3>\n        <section class=\"content markdown\">{{Html .Content}}</section>\n        <p class=\"info clear\">{{if .User}}\n            <span class=\"author inline-block\"><i class=\"fa fa-user\"></i>{{.User.Nick}}</span>{{end}}\n            <span class=\"time inline-block\"><i class=\"fa fa-clock-o\"></i>{{DateInt64 .CreateTime \"MM.DD\"}}</span>\n            <span class=\"views inline-block right\">阅读&nbsp;&nbsp;<span>{{.Hits}}</span>&nbsp;&nbsp;次</span>\n        </p>{{end}}\n    </article>\n</div>"
  },
  {
    "path": "view/ling/article.html",
    "content": "<div id=\"article-container\" class=\"clear\">\n    <article class=\"clear article-single relative {{.Article.Status}}\" id=\"article-{{.Article.Id}}\">{{with .Article}}\n        <div class=\"meta absolute text-center\">\n            <p class=\"lbl lbl-green views absolute\">{{.Hits}}</p>\n        </div>\n        <div class=\"main\">\n            <h3 class=\"title\"><a href=\"{{.Link}}\" title=\"{{.Title}}\">{{.Title}}</a></h3>\n            <p class=\"time-info\">{{if .User}}<strong>{{.User.Nick}}</strong>&nbsp;&nbsp;&nbsp;{{end}}发表于&nbsp;&nbsp;&nbsp;{{DateInt64 .CreateTime \"YYYY 年 MM 月 DD 日\"}}</p>\n            <section class=\"content markdown\">{{Html .Content}}</section>\n            <p class=\"info clear\">\n                <span class=\"tag inline-block\">标签：{{.TagString}}</span>\n            </p>\n        </div>{{end}}\n    </article>\n    {{Html .CommentHtml}}\n</div>"
  },
  {
    "path": "view/ling/comment.html",
    "content": "<div id=\"comment\" class=\"relative\">\n    <h4 id=\"comment-title\">文章评论</h4>\n    <div class=\"meta absolute text-center\">\n        <p class=\"lbl lbl-red comments\"><a href=\"{{.Link}}#comment\">{{.Content.CommentNum}}</a></p>\n    </div>\n    <div id=\"comment-list\">{{range .Comments}}{{if .IsValid}}\n        <div class=\"comment clear\" id=\"comment-{{.Id}}\">\n            <img class=\"c-avatar left\" src=\"{{.Avatar}}\" alt=\"{{.Author}}\"/>\n            <div class=\"c-section\">\n                <div class=\"c-meta clear\">\n                    <a class=\"c-reply lbl right\" href=\"#\" rel=\"{{.Id}}\">回复</a>\n                    <p><a class=\"c-author{{if .IsAdmin}} admin{{end}}\" href=\"{{.Url}}\" target=\"_blank\">{{.Author}}{{if .IsAdmin}}&nbsp;&nbsp;(admin){{end}}</a></p>\n                    <p><span class=\"c-time\">{{DateInt64 .CreateTime \"MM 月 DD 日 HH 时 mm 分\"}}</span></p>\n                </div>\n                <section class=\"c-content\">{{Html .Content}}</section>{{if .ParentMd}}\n                <div class=\"c-p-md markdown\">{{Html .ParentMd}}</div>{{end}}\n            </div>\n        </div>{{end}}{{end}}\n    </div>\n    <div id=\"comment-show\" class=\"text-center\">{{if .Content.IsComment}}\n        <button class=\"btn btn-green enable\">发表评论</button>{{else}}\n        <button class=\"btn btn-red\">本文关闭了评论</button>{{end}}\n    </div>{{if .Content.IsComment}}\n    <form id=\"comment-form\" class=\"hide clear text-center form\" action=\"/comment/{{.Content.Id}}/\" method=\"post\">\n        <div class=\"c-info left text-right\">\n            <p class=\"item c-avatar-field\">\n                <img class=\"c-avatar null\" src=\"/static/img/site.png\" alt=\"\" id=\"comment-avatar\"/>\n                <a class=\"not-me block\" href=\"#\">不是我?</a>\n            </p>\n            <div class=\"c-info-fields hide\">\n                <p class=\"item\"><input class=\"ipt\" type=\"text\" name=\"user\" required=\"required\" placeholder=\"称呼\" id=\"comment-author\"/></p>\n                <p class=\"item\"><input class=\"ipt\" type=\"email\" name=\"email\" required=\"required\" placeholder=\"邮箱\" id=\"comment-email\"/> </p>\n                <p class=\"item\"><input class=\"ipt\" type=\"url\" name=\"url\" placeholder=\"网址\" id=\"comment-url\"/></p>\n                <input id=\"comment-parent\" type=\"hidden\" value=\"0\" name=\"pid\"/>\n            </div>\n        </div>\n        <div class=\"c-content text-left right\">\n            <textarea class=\"ipt\" name=\"content\" id=\"comment-content\" required=\"required\"></textarea>\n            <button class=\"btn btn-blue\">发表评论</button>\n            <button class=\"lbl lbl-green cancel-reply\" type=\"button\">取消回复</button>\n        </div>\n    </form>{{end}}\n    <script type=\"text/template\" id=\"comment-tpl\">\n        <div class=\"comment clear\">\n            <img class=\"c-avatar left\" src=\"{{.Avatar}}\" alt=\"\"/>\n            <div class=\"c-section\">\n                <div class=\"c-meta clear\">\n                    <a class=\"c-reply lbl right\" href=\"#\" rel=\"\">回复</a>\n                    <p><a class=\"c-author \" href=\"{{.Url}}\" target=\"_blank\"></a></p>\n                    <p>\n                        <span class=\"c-time\">Now</span>\n                        <span class=\"c-check\">审核中，刷新后隐藏</span>\n                    </p>\n                </div>\n                <section class=\"c-content\"></section>\n                <div class=\"c-p-md markdown\"></div>\n            </div>\n        </div>\n    </script>\n</div>"
  },
  {
    "path": "view/ling/error/error.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\"/>\n    <title>错误提示</title>\n    <link rel=\"stylesheet\" href=\"/static/css/common.css\"/>\n    <style>body{margin: 40px 100px}</style>\n</head>\n<body>\n<h2>您访问的页面正在打瞌睡</h2><br/>\n<p>程序员正在努力唤醒，请稍候访问...</p>\n<p><a href=\"/\">返回首页</a></p>\n</body>\n</html>"
  },
  {
    "path": "view/ling/error/notfound.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\"/>\n    <title>错误提示</title>\n    <link rel=\"stylesheet\" href=\"/static/css/common.css\"/>\n    <style>body{margin: 40px 100px}</style>\n</head>\n<body>\n<h2>您访问的页面离家出走</h2><br/>\n<p>程序员正在四处寻找，请稍候访问...</p>\n<p><a href=\"/\">返回首页</a></p>\n</body>\n</html>"
  },
  {
    "path": "view/ling/home.layout",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\"/>\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\"/>\n    <title>{{if .Title}}{{.Title}} - {{end}}{{Setting \"site_title\"}}</title>\n    <meta name=\"keywords\" content=\"{{Setting `site_keywords`}}\"/>\n    <meta name=\"description\" content=\"{{Setting `site_description`}}\"/>\n    <meta name=\"generator\" content=\"FxhGo Blog\" />\n    <link rel=\"stylesheet\" href=\"/static/css/ling.css\"/>\n    <link rel=\"stylesheet\" href=\"http://libs.baidu.com/fontawesome/4.0.3/css/font-awesome.min.css\"/>\n    <link rel=\"alternate\" type=\"application/rss+xml\" title=\"{{Setting `site_title`}} - RSS 2.0\" href=\"/feed/\"/>\n    <script src=\"http://libs.baidu.com/jquery/1.8.3/jquery.min.js\"></script>\n    <script src=\"/static/lib/jquery.form.min.js\"></script>\n    <script src=\"/static/lib/marked.min.js\"></script>\n</head>\n<body>\n<header id=\"header\" class=\"clear\">\n    <div class=\"container960\">\n        <img src=\"{{Setting `c_home_avatar`}}\" alt=\"site\" id=\"header-img\" class=\"left\"/>\n        <h1 id=\"header-h\" class=\"left\"><a href=\"/\">{{Setting \"site_title\"}}</a></h1>\n        <h4 id=\"header-sub\" class=\"left\">{{Setting \"site_sub_title\"}}</h4>\n        <nav id=\"nav\" class=\"right\">\n            <ul>{{range Navigator}}\n                <li class=\"inline-block\"><a href=\"{{.Link}}\" title=\"{{.Title}}\">{{.Text}}</a></li>{{end}}\n            </ul>\n        </nav>\n    </div>\n</header>\n<div id=\"main\" class=\"container960\">\n    {@Content}\n</div>\n<footer id=\"footer\" class=\"text-center\">\n    <div class=\"container960 clear\">\n        <span class=\"left\">Go © 2014 All rights reserved.</span>\n        <span class=\"right\"><a href=\"/feed/\">RSS</a> . Proudly Powered by <a href=\"https://github.com/fuxiaohei/GoBlog\" target=\"_blank\">Fxh.Go</a>.</span>\n    </div>\n    <a id=\"go-top\" href=\"#\" class=\"lbl hide lbl-blue\" title=\"回到顶部\"><i class=\"fa fa-arrow-up fa-lg\"></i></a>\n    {{Setting `c_footer_ga` | Html}}\n</footer>\n<script src=\"/static/js/home.js\"></script>\n</body>\n</html>\n{{Html \"<!-- thanks for theme Lingonberry(http://www.andersnoren.se/) for WordPress-->\"}}"
  },
  {
    "path": "view/ling/index.html",
    "content": "<div id=\"article-container\" class=\"clear\">{{range .Articles}}\n    <article class=\"clear {{.Status}}\" id=\"article-{{.Id}}\">\n        <div class=\"meta left text-center relative\">\n            <p class=\"lbl lbl-red comments\"><a href=\"{{.Link}}#comment\">{{.CommentNum}}</a></p>\n            <p class=\"lbl lbl-green views absolute\">{{.Hits}}</p>\n        </div>\n        <div class=\"main relative\">\n            <h3 class=\"title\"><a href=\"{{.Link}}\" title=\"{{.Title}}\">{{.Title}}</a></h3>\n            <p class=\"time-info\">{{if .User}}<strong>{{.User.Nick}}</strong>&nbsp;&nbsp;&nbsp;{{end}}发表于&nbsp;&nbsp;&nbsp;{{DateInt64 .CreateTime \"YYYY 年 MM 月 DD 日\"}}</p>\n            <section class=\"content markdown\">{{Html .Summary}}</section>\n            <p class=\"info clear\">\n                <span class=\"tag inline-block\">标签：{{range .GetTags}}<a href=\"{{.Link}}\">{{.Name}}</a>{{end}}</span>\n                <a class=\"inline-block read right\" href=\"{{.Link}}\">继续阅读</a>\n            </p>\n        </div>\n    </article>{{end}}\n    <div class=\"pager text-center\" id=\"article-pager\">\n        {{if .Pager.IsNext}}<a href=\"/p/{{.Pager.Next}}/\" class=\"item left\">较旧的文章</a>{{end}}\n        {{if .Pager.IsPrev}}<a href=\"/p/{{.Pager.Prev}}/\" class=\"item right\">较新的文章</a>{{end}}\n    </div>\n</div>"
  },
  {
    "path": "view/ling/page.html",
    "content": "<div id=\"article-container\" class=\"clear\">\n    <article class=\"clear article-single relative\" id=\"article-{{.Page.Id}}\">{{with .Page}}\n        <div class=\"meta absolute text-center\">\n            <p class=\"lbl lbl-green views absolute\">{{.Hits}}</p>\n        </div>\n        <div class=\"main\">\n            <h3 class=\"title\"><a href=\"{{.Link}}\" title=\"{{.Title}}\">{{.Title}}</a></h3>\n            <p class=\"time-info\">{{if .User}}<strong>{{.User.Nick}}</strong>&nbsp;&nbsp;&nbsp;{{end}}发表于&nbsp;&nbsp;&nbsp;{{DateInt64 .CreateTime \"YYYY 年 MM 月 DD 日\"}}</p>\n            <section class=\"content markdown\">{{Html .Content}}</section>\n        </div>{{end}}\n    </article>\n</div>"
  },
  {
    "path": "view/rss.xml",
    "content": "{{Html `<?xml version=\"1.0\" encoding=\"UTF-8\"?>`}}\n<rss version=\"2.0\">\n    <channel>\n        <title>{{.Title}}</title>\n        <link>{{.Link}}/</link>\n        <description>{{.Desc}}</description>\n        <pubDate>{{.Created}}</pubDate>{{range .Articles}}\n        <item>\n            <title>{{.Title}}</title>\n            <link>{{.Link}}</link>\n            <description>{{.Desc}}</description>\n            <author>{{.Author}}</author>\n            <pubDate>{{.Created}}</pubDate>\n        </item>{{end}}\n    </channel>\n</rss>"
  },
  {
    "path": "view/saber/article.html",
    "content": "<div id=\"article-container\" class=\"clear container960\">\n    <article class=\"clear article-single relative {{.Article.Status}}\" id=\"article-{{.Article.Id}}\">{{with .Article}}\n        <div class=\"main clear\">\n            <span class=\"inline-block lbl lbl-green views right text-center\">{{.Hits}}</span>\n            <h3 class=\"title\"><a href=\"{{.Link}}\" title=\"{{.Title}}\">{{.Title}}</a></h3>\n            <section class=\"content markdown\">{{Html .Content}}</section>\n            <p class=\"info clear\">\n                <span class=\"time-info\">{{if .User}}<strong>{{.User.Nick}}</strong>&nbsp;&nbsp;&nbsp;{{end}}发表于&nbsp;&nbsp;&nbsp;{{DateInt64 .CreateTime \"YYYY 年 MM 月 DD 日\"}}</span>\n                <span class=\"tag\">标签：{{range .GetTags}}<a href=\"{{.Link}}\">{{.Name}}</a>{{end}}</span>\n            </p>\n        </div>{{end}}\n    </article>\n    {{Html .CommentHtml}}\n</div>"
  },
  {
    "path": "view/saber/comment.html",
    "content": "<div id=\"comment\" class=\"relative clear\">\n    <span class=\"right lbl lbl-red comments\"><a href=\"{{.Link}}#comment\">{{.Content.CommentNum}}</a></span>\n    <h4 id=\"comment-title\">文章评论</h4>\n    <div id=\"comment-list\">{{range .Comments}}{{if .IsValid}}\n        <div class=\"comment clear\" id=\"comment-{{.Id}}\">\n            <img class=\"c-avatar left\" src=\"{{.Avatar}}\" alt=\"{{.Author}}\"/>\n            <div class=\"c-section\">\n                <div class=\"c-meta clear\">\n                    <a class=\"c-reply lbl right\" href=\"#\" rel=\"{{.Id}}\">回复</a>\n                    <p><a class=\"c-author{{if .IsAdmin}} admin{{end}}\" href=\"{{.Url}}\" target=\"_blank\">{{.Author}}{{if .IsAdmin}}&nbsp;&nbsp;(admin){{end}}</a></p>\n                    <p><span class=\"c-time\">{{DateInt64 .CreateTime \"MM 月 DD 日 HH 时 mm 分\"}}</span></p>\n                </div>\n                <section class=\"c-content\">{{Html .Content}}</section>{{if .ParentMd}}\n                <div class=\"c-p-md markdown\">{{Html .ParentMd}}</div>{{end}}\n            </div>\n        </div>{{end}}{{end}}\n    </div>\n    <div id=\"comment-show\" class=\"text-center\">{{if .Content.IsComment}}\n        <button class=\"btn btn-green enable\">发表评论</button>{{else}}\n        <button class=\"btn btn-red\">本文关闭了评论</button>{{end}}\n    </div>{{if .Content.IsComment}}\n    <form id=\"comment-form\" class=\"hide clear text-center form\" action=\"/comment/{{.Content.Id}}/\" method=\"post\">\n        <div class=\"c-info left text-right\">\n            <p class=\"item c-avatar-field\">\n                <img class=\"c-avatar null\" src=\"/static/img/site.png\" alt=\"\" id=\"comment-avatar\"/>\n                <a class=\"not-me block\" href=\"#\">不是我?</a>\n            </p>\n            <div class=\"c-info-fields hide\">\n                <p class=\"item\"><input class=\"ipt\" type=\"text\" name=\"user\" required=\"required\" placeholder=\"称呼\" id=\"comment-author\"/></p>\n                <p class=\"item\"><input class=\"ipt\" type=\"email\" name=\"email\" required=\"required\" placeholder=\"邮箱\" id=\"comment-email\"/> </p>\n                <p class=\"item\"><input class=\"ipt\" type=\"url\" name=\"url\" placeholder=\"网址\" id=\"comment-url\"/></p>\n                <input id=\"comment-parent\" type=\"hidden\" value=\"0\" name=\"pid\"/>\n            </div>\n        </div>\n        <div class=\"c-content text-left right\">\n            <textarea class=\"ipt\" name=\"content\" id=\"comment-content\" required=\"required\"></textarea>\n            <button class=\"btn btn-blue\">发表评论</button>\n            <button class=\"lbl lbl-green cancel-reply\" type=\"button\">取消回复</button>\n        </div>\n    </form>{{end}}\n    <script type=\"text/template\" id=\"comment-tpl\">\n        <div class=\"comment clear\">\n            <img class=\"c-avatar left\" src=\"{{.Avatar}}\" alt=\"\"/>\n            <div class=\"c-section\">\n                <div class=\"c-meta clear\">\n                    <a class=\"c-reply lbl right\" href=\"#\" rel=\"\">回复</a>\n                    <p><a class=\"c-author \" href=\"{{.Url}}\" target=\"_blank\"></a></p>\n                    <p>\n                        <span class=\"c-time\">Now</span>\n                        <span class=\"c-check\">审核中，刷新后隐藏</span>\n                    </p>\n                </div>\n                <section class=\"c-content\"></section>\n                <div class=\"c-p-md markdown\"></div>\n            </div>\n        </div>\n    </script>\n</div>"
  },
  {
    "path": "view/saber/error/error.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\"/>\n    <title>错误提示</title>\n    <link rel=\"stylesheet\" href=\"/static/css/common.css\"/>\n    <style>body{margin: 40px 100px}</style>\n</head>\n<body>\n<h2>您访问的页面正在打瞌睡</h2><br/>\n<p>程序员正在努力唤醒，请稍候访问...</p>\n<p><a href=\"/\">返回首页</a></p>\n</body>\n</html>"
  },
  {
    "path": "view/saber/error/notfound.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\"/>\n    <title>错误提示</title>\n    <link rel=\"stylesheet\" href=\"/static/css/common.css\"/>\n    <style>body{margin: 40px 100px}</style>\n</head>\n<body>\n<h2>您访问的页面离家出走</h2><br/>\n<p>程序员正在四处寻找，请稍候访问...</p>\n<p><a href=\"/\">返回首页</a></p>\n</body>\n</html>"
  },
  {
    "path": "view/saber/home.layout",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\"/>\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\"/>\n    <title>{{if .Title}}{{.Title}} - {{end}}{{Setting \"site_title\"}}</title>\n    <meta name=\"keywords\" content=\"{{Setting `site_keywords`}}\"/>\n    <meta name=\"description\" content=\"{{Setting `site_description`}}\"/>\n    <meta name=\"generator\" content=\"FxhGo Blog\" />\n    <link rel=\"stylesheet\" href=\"/static/css/saber.css\"/>\n    <link rel=\"alternate\" type=\"application/rss+xml\" title=\"{{Setting `site_title`}} - RSS 2.0\" href=\"/feed/\"/>\n    <script src=\"http://libs.baidu.com/jquery/1.8.3/jquery.min.js\"></script>\n    <script src=\"/static/lib/jquery.form.min.js\"></script>\n    <script src=\"/static/lib/marked.min.js\"></script>\n</head>\n<body>\n<header id=\"header\">\n    <div class=\"container clear\">\n        <img src=\"{{Setting `c_home_avatar`}}\" alt=\"site\" id=\"header-img\" class=\"left\"/>\n        <h1 id=\"header-h\" class=\"left\"><a href=\"/\">{{Setting \"site_title\"}}</a></h1>\n        <h4 id=\"header-sub\" class=\"left\">{{Setting \"site_sub_title\"}}</h4>\n        <nav id=\"nav\" class=\"right\">\n            <ul>{{range Navigator}}\n                <li class=\"inline-block\"><a href=\"{{.Link}}\" title=\"{{.Title}}\">{{.Text}}</a></li>{{end}}\n            </ul>\n        </nav>\n    </div>\n</header>\n<div id=\"main\" class=\"container grid clear relative\">\n    {@Content}\n</div>\n<footer id=\"footer\" class=\"text-center\">\n    <div class=\"container clear\">\n        <span class=\"left\">Go © 2014 All rights reserved.</span>\n        <span class=\"right\">\n            <a href=\"{{Setting `c_footer_github`}}\" target=\"_blank\">GitHub</a>&nbsp;&nbsp;&nbsp;&nbsp;\n            <a href=\"/feed/\">Feed</a>&nbsp;&nbsp;&nbsp;&nbsp;\n            Proudly Powered by Fxh.Go.\n        </span>\n    </div>\n    <a id=\"go-top\" href=\"#\" class=\"lbl hide lbl-blue\" title=\"回到顶部\">Top</a>\n    {{Setting `c_footer_ga` | Html}}\n</footer>\n<script src=\"/static/js/home.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "view/saber/index.html",
    "content": "<div id=\"article-container\" class=\"clear grid-3-4 left\">{{if .Tag}}\n    <div class=\"tag-banner\">标签：{{.Tag}}</div>{{end}}{{range .Articles}}\n    <article class=\"clear {{.Status}}\" id=\"article-{{.Id}}\">\n        <div class=\"meta left text-center relative\">\n            <p class=\"lbl lbl-red comments\"><a href=\"{{.Link}}#comment\">{{.CommentNum}}</a></p>\n            <p class=\"lbl lbl-green views absolute\">{{.Hits}}</p>\n        </div>\n        <div class=\"main\">\n            <h3 class=\"title\"><a href=\"{{.Link}}\" title=\"{{.Title}}\">{{.Title}}</a></h3>\n            <section class=\"content markdown\">{{Html .Summary}}</section>\n            <p class=\"info clear\">\n                <span class=\"time-info\">{{if .User}}<strong>{{.User.Nick}}</strong>&nbsp;&nbsp;&nbsp;{{end}}发表于&nbsp;&nbsp;&nbsp;{{DateInt64 .CreateTime \"YYYY 年 MM 月 DD 日\"}}</span>\n                <span class=\"tag\">标签：{{range .GetTags}}<a href=\"{{.Link}}\">{{.Name}}</a>{{end}}</span>\n                <a class=\"inline-block read right\" href=\"{{.Link}}\">继续阅读</a>\n            </p>\n        </div>\n    </article>{{end}}\n    <div class=\"pager text-center\" id=\"article-pager\">\n        {{if .Pager.IsNext}}<a href=\"/p/{{.Pager.Next}}/\" class=\"item left\">较旧的文章</a>{{end}}\n        {{if .Pager.IsPrev}}<a href=\"/p/{{.Pager.Prev}}/\" class=\"item right\">较新的文章</a>{{end}}\n    </div>\n</div>\n{{Html .SidebarHtml}}"
  },
  {
    "path": "view/saber/page.html",
    "content": "<div id=\"article-container\" class=\"clear container960\">\n    <article class=\"clear article-single relative\" id=\"article-{{.Page.Id}}\">{{with .Page}}\n        <div class=\"main clear\">\n            <span class=\"inline-block lbl lbl-green views right text-center\">{{.Hits}}</span>\n            <h3 class=\"title\"><a href=\"{{.Link}}\" title=\"{{.Title}}\">{{.Title}}</a></h3>\n            <section class=\"content markdown\">{{Html .Content}}</section>\n            <p class=\"info clear\">\n                <span class=\"time-info\">{{if .User}}<strong>{{.User.Nick}}</strong>&nbsp;&nbsp;&nbsp;{{end}}发表于&nbsp;&nbsp;&nbsp;{{DateInt64 .CreateTime \"YYYY 年 MM 月 DD 日\"}}</span>\n            </p>\n        </div>{{end}}\n    </article>\n</div>"
  },
  {
    "path": "view/saber/sidebar.html",
    "content": "<div id=\"article-sidebar\" class=\"grid-1-5 right\">\n    <div class=\"sidebar\" id=\"pop-article-sidebar\">\n        <h5 class=\"title\">热评文章</h5>\n        <ul class=\"list\">{{range .Popular}}\n            <li>\n                <a href=\"{{.Link}}\" title=\"{{.Title}}\">{{.Title}}</a>\n                <span class=\"pop-num lbl\">{{.CommentNum}}</span>\n            </li>{{end}}\n        </ul>\n    </div>\n    <div class=\"sidebar\" id=\"recent-comment-sidebar\">\n        <h5 class=\"title\">最新评论</h5>\n        <ul class=\"list\">{{range .RecentComment}}\n            <li>\n                <a class=\"author lbl lbl-blue\" href=\"{{.GetContent.Link}}#comment-{{.Id}}\">{{.Author}}</a>\n                <span class=\"content\">{{Html2str .Content}}</span>\n            </li>{{end}}\n        </ul>\n    </div>\n    <div class=\"sidebar\" id=\"tags-sidebar\">\n        <h5 class=\"title\">文章标签</h5>\n        <ul class=\"list\">{{range .Tags}}\n            <li class=\"inline-block\">\n                <a class=\"author lbl lbl-green\" href=\"{{.Link}}\">{{.Name}}</a>\n            </li>{{end}}\n        </ul>\n    </div>\n</div>"
  },
  {
    "path": "view/sitemap.xml",
    "content": "{{Html `<?xml version=\"1.0\" encoding=\"UTF-8\"?>`}}{{Html `<?xml-stylesheet type=\"text/xsl\" href=\"/static/css/sitemap.xsl\"?>`}}\n<urlset xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd\" xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n    <url>\n        <loc>{{.Link}}</loc>\n        <lastmod>{{.Created}}</lastmod>\n        <changefreq>daily</changefreq>\n        <priority>1.0</priority>\n    </url>{{range .Navigators}}\n    <url>\n        <loc>{{.Link}}</loc>\n        <lastmod>{{.Created}}</lastmod>\n        <changefreq>weekly</changefreq>\n        <priority>0.6</priority>\n    </url>{{end}}{{range .Articles}}\n    <url>\n        <loc>{{.Link}}</loc>\n        <lastmod>{{.Created}}</lastmod>\n        <changefreq>monthly</changefreq>\n        <priority>0.3</priority>\n    </url>{{end}}\n</urlset>"
  }
]