├── .gitignore ├── README.md ├── conf ├── app.conf ├── docTree.json ├── locale_en-US.ini └── locale_zh-CN.ini ├── controllers ├── controller.go ├── default.go └── docs.go ├── main.go ├── models ├── github.go ├── http.go ├── press.go └── product.go ├── static ├── css │ ├── admin.css │ ├── amazeui.css │ ├── amazeui.flat.css │ ├── amazeui.flat.min.css │ ├── amazeui.min.css │ ├── app.css │ └── index.css ├── favicon.ico ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ └── fontawesome-webfont.woff ├── images │ ├── InfoQ.jpg │ ├── bearychat.png │ ├── bowen.png │ ├── coding.png │ ├── csdn.png │ ├── daocloud.jpg │ ├── daocloud.png │ ├── dreamlab.png │ ├── fequan.jpg │ ├── gitcafe.png │ ├── gophercomplex1.jpg │ ├── gophercomplex2.jpg │ ├── gopherconf.png │ ├── huawei.png │ ├── imooc.png │ ├── jd.png │ ├── oschina.png │ ├── osforce.jpg │ ├── pusoft.jpg │ ├── pusoft1.jpg │ ├── pusoft2.jpg │ ├── pusoft_map.jpg │ ├── qiniu.jpg │ ├── segmentfault.png │ ├── techparty.jpg │ ├── tuling.jpg │ └── xd.png ├── img │ ├── chenmingda.png │ ├── gonghaohua.jpg │ ├── lisibao.jpg │ ├── liuqi.png │ ├── maquanyi.jpg │ ├── qleelulu.jpg │ ├── xushiwei.jpg │ └── zhouyang.jpg └── js │ ├── amazeui.js │ ├── amazeui.legacy.js │ ├── amazeui.legacy.min.js │ ├── amazeui.min.js │ ├── amazeui.widgets.helper.js │ ├── amazeui.widgets.helper.min.js │ ├── app.js │ ├── handlebars.min.js │ ├── jquery.min.js │ └── polyfill │ ├── rem.min.js │ └── respond.min.js └── views ├── base ├── footer.html └── header.html ├── detail.tpl ├── index.tpl ├── register.tpl ├── speaker.tpl ├── sponsors.tpl └── venue.tpl /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *~ 3 | .DS_Store 4 | *.tmp 5 | *.tmp 6 | *.pprof 7 | *.pdf 8 | 9 | /docs 10 | /tests 11 | website -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Gopher China Website 2 | =================== 3 | 4 | Gopher China Website 5 | 6 | -------------------------------------------------------------------------------- /conf/app.conf: -------------------------------------------------------------------------------- 1 | appname = website 2 | httpport = 8080 3 | runmode = dev 4 | 5 | 6 | [lang] 7 | types=en-US|zh-CN 8 | names=English|简体中文 9 | -------------------------------------------------------------------------------- /conf/docTree.json: -------------------------------------------------------------------------------- 1 | {"Tree":[{"Sha":"51473709537ae2a9b5342c9f2eff1fc3e7c2dc76","Path":"en-US/accommodation","Type":""},{"Sha":"1be9000125ff8f011ad246ac56ca5d02383760e7","Path":"en-US/images/chenmingda.png","Type":""},{"Sha":"88fc793c5105724ecb35347b04009a42c1ce693b","Path":"en-US/images/go.jpg","Type":""},{"Sha":"130d26e57274a3b4d600e44c98d4a032647458d2","Path":"en-US/images/gonghaohua.jpg","Type":""},{"Sha":"8dbe97e3180290accf9d49c3bb8b11639ce823c3","Path":"en-US/images/lisibao.jpg","Type":""},{"Sha":"fac54daa97dabd5b85a8191e610002c5a579c468","Path":"en-US/images/liuqi.png","Type":""},{"Sha":"adfd75aa20e709a4c0fd094b92a933c2f220bae8","Path":"en-US/images/maojian.jpg","Type":""},{"Sha":"3faef7d49392ef908c73761e8ee43ccb720eed83","Path":"en-US/images/maquanyi.jpg","Type":""},{"Sha":"7a6c39d25cd988548ddb95e917e2643d1dc60a70","Path":"en-US/images/qleelulu.jpg","Type":""},{"Sha":"494ce5157c460328780857ca1b88c59a01ad7a04","Path":"en-US/images/robert.jpeg","Type":""},{"Sha":"fe70f4e2a370b0c4213d3fa521cd4717c4a59207","Path":"en-US/images/wangyang.jpg","Type":""},{"Sha":"cdf63d4f2de23db6f654bcc4ca47c4a4a86dec9a","Path":"en-US/images/xiabin.jpg","Type":""},{"Sha":"b17b52a4cf5868dec1c757d6a3dccba468b510a5","Path":"en-US/images/xudaoli.jpg","Type":""},{"Sha":"9e6f61c82bc2bf6ea9ec8eb87feaab9acc8ae308","Path":"en-US/images/xushiwei.jpg","Type":""},{"Sha":"ba7cdd8352823e623f251e78a1bf839a3648fcf8","Path":"en-US/images/yuhen.jpg","Type":""},{"Sha":"a12cf783c59e26e8829eb59f5107a669f239ec54","Path":"en-US/images/yujun.jpg","Type":""},{"Sha":"3e90c26b9eae4a160960b12a1eaf1b9ba30d9a2f","Path":"en-US/images/zhangchengyuan.png","Type":""},{"Sha":"8ab03335f4a33ea213eabae1a2edc62c62d43571","Path":"en-US/images/zhouyang.jpg","Type":""},{"Sha":"4ab3647fe248f808f2285fcb7d15a0c6b74b5c34","Path":"en-US/travel","Type":""},{"Sha":"1b7d5e0ce1b12ad78060c84aadf535c28fae0a89","Path":"en-US/user/chenmingda","Type":""},{"Sha":"8bf61ccee740c3e1396553535a667d926c47575c","Path":"en-US/user/core","Type":""},{"Sha":"f7d86f80f81e6d9ade94c32fc5f50d3ce8c94127","Path":"en-US/user/gonghaohua","Type":""},{"Sha":"3c4d0e445e82d8d6857e2970d07830daf4c297fc","Path":"en-US/user/lisibao","Type":""},{"Sha":"599dc761fe2a83be1f4fc5acfeb3394960ec87c8","Path":"en-US/user/liuqi","Type":""},{"Sha":"04108c1b7f332754bb86545e8f2283f625a2e57b","Path":"en-US/user/maojian","Type":""},{"Sha":"8f4d7c497ebeb29f876888b32109f7c0d17840e1","Path":"en-US/user/maquanyi","Type":""},{"Sha":"b27e1ece5c5c2cd0ac475c9d7e98662094eed497","Path":"en-US/user/qleelulu","Type":""},{"Sha":"13c15fb7fad042fe668c3a154d6723aeeb4a98c9","Path":"en-US/user/robert","Type":""},{"Sha":"8000c3011558fff240b25f7096cdd61ffdb42711","Path":"en-US/user/wangyang","Type":""},{"Sha":"f6617d7688463101c3e95f1ba72c8572b6327ca6","Path":"en-US/user/xiabin","Type":""},{"Sha":"bf84b5454a9db45e55a9f54800df900c8184f9a3","Path":"en-US/user/xudaoli","Type":""},{"Sha":"ac1b2a4e7a8b5a7c7113d3515a15b5175acee1bb","Path":"en-US/user/xushiwei","Type":""},{"Sha":"ddce203cf99cb32349fb7b13aa1eb0af3273bac6","Path":"en-US/user/yuhen","Type":""},{"Sha":"0826eae155bdc50bd169fe7c7a305d08ab732af4","Path":"en-US/user/yujun","Type":""},{"Sha":"e4636cd67e14f051b650c45e73552b7a9221b76e","Path":"en-US/user/zhangchengyuan","Type":""},{"Sha":"4040e6496153a1013d0d60e1d5712dfa6a187275","Path":"en-US/user/zhouyang","Type":""},{"Sha":"6e8d9a8612bf158a956493909a028bae0dc73435","Path":"zh-CN/accommodation","Type":""},{"Sha":"1be9000125ff8f011ad246ac56ca5d02383760e7","Path":"zh-CN/images/chenmingda.png","Type":""},{"Sha":"88fc793c5105724ecb35347b04009a42c1ce693b","Path":"zh-CN/images/go.jpg","Type":""},{"Sha":"130d26e57274a3b4d600e44c98d4a032647458d2","Path":"zh-CN/images/gonghaohua.jpg","Type":""},{"Sha":"8dbe97e3180290accf9d49c3bb8b11639ce823c3","Path":"zh-CN/images/lisibao.jpg","Type":""},{"Sha":"fac54daa97dabd5b85a8191e610002c5a579c468","Path":"zh-CN/images/liuqi.png","Type":""},{"Sha":"adfd75aa20e709a4c0fd094b92a933c2f220bae8","Path":"zh-CN/images/maojian.jpg","Type":""},{"Sha":"3faef7d49392ef908c73761e8ee43ccb720eed83","Path":"zh-CN/images/maquanyi.jpg","Type":""},{"Sha":"7a6c39d25cd988548ddb95e917e2643d1dc60a70","Path":"zh-CN/images/qleelulu.jpg","Type":""},{"Sha":"494ce5157c460328780857ca1b88c59a01ad7a04","Path":"zh-CN/images/robert.jpeg","Type":""},{"Sha":"fe70f4e2a370b0c4213d3fa521cd4717c4a59207","Path":"zh-CN/images/wangyang.jpg","Type":""},{"Sha":"cdf63d4f2de23db6f654bcc4ca47c4a4a86dec9a","Path":"zh-CN/images/xiabin.jpg","Type":""},{"Sha":"b17b52a4cf5868dec1c757d6a3dccba468b510a5","Path":"zh-CN/images/xudaoli.jpg","Type":""},{"Sha":"9e6f61c82bc2bf6ea9ec8eb87feaab9acc8ae308","Path":"zh-CN/images/xushiwei.jpg","Type":""},{"Sha":"ba7cdd8352823e623f251e78a1bf839a3648fcf8","Path":"zh-CN/images/yuhen.jpg","Type":""},{"Sha":"a12cf783c59e26e8829eb59f5107a669f239ec54","Path":"zh-CN/images/yujun.jpg","Type":""},{"Sha":"3e90c26b9eae4a160960b12a1eaf1b9ba30d9a2f","Path":"zh-CN/images/zhangchengyuan.png","Type":""},{"Sha":"8ab03335f4a33ea213eabae1a2edc62c62d43571","Path":"zh-CN/images/zhouyang.jpg","Type":""},{"Sha":"8d89079ca22b52c59fae3e5915c11598c829cae4","Path":"zh-CN/travel","Type":""},{"Sha":"1b7d5e0ce1b12ad78060c84aadf535c28fae0a89","Path":"zh-CN/user/chenmingda","Type":""},{"Sha":"8bf61ccee740c3e1396553535a667d926c47575c","Path":"zh-CN/user/core","Type":""},{"Sha":"f7d86f80f81e6d9ade94c32fc5f50d3ce8c94127","Path":"zh-CN/user/gonghaohua","Type":""},{"Sha":"3c4d0e445e82d8d6857e2970d07830daf4c297fc","Path":"zh-CN/user/lisibao","Type":""},{"Sha":"599dc761fe2a83be1f4fc5acfeb3394960ec87c8","Path":"zh-CN/user/liuqi","Type":""},{"Sha":"8abda267248aa0e5d751dcf480702c62e0bbaa91","Path":"zh-CN/user/maojian","Type":""},{"Sha":"11497c9801656c1c9c29e174a61da178a4e6251a","Path":"zh-CN/user/maquanyi","Type":""},{"Sha":"b27e1ece5c5c2cd0ac475c9d7e98662094eed497","Path":"zh-CN/user/qleelulu","Type":""},{"Sha":"13c15fb7fad042fe668c3a154d6723aeeb4a98c9","Path":"zh-CN/user/robert","Type":""},{"Sha":"8000c3011558fff240b25f7096cdd61ffdb42711","Path":"zh-CN/user/wangyang","Type":""},{"Sha":"f6617d7688463101c3e95f1ba72c8572b6327ca6","Path":"zh-CN/user/xiabin","Type":""},{"Sha":"bf84b5454a9db45e55a9f54800df900c8184f9a3","Path":"zh-CN/user/xudaoli","Type":""},{"Sha":"ac1b2a4e7a8b5a7c7113d3515a15b5175acee1bb","Path":"zh-CN/user/xushiwei","Type":""},{"Sha":"373f978531cbce5cad22e94466648b33409ed4d4","Path":"zh-CN/user/yuhen","Type":""},{"Sha":"0826eae155bdc50bd169fe7c7a305d08ab732af4","Path":"zh-CN/user/yujun","Type":""},{"Sha":"e4636cd67e14f051b650c45e73552b7a9221b76e","Path":"zh-CN/user/zhangchengyuan","Type":""},{"Sha":"4040e6496153a1013d0d60e1d5712dfa6a187275","Path":"zh-CN/user/zhouyang","Type":""}]} 2 | -------------------------------------------------------------------------------- /conf/locale_en-US.ini: -------------------------------------------------------------------------------- 1 | zh-CN = 简体中文 2 | en-US = English 3 | 4 | home = Home 5 | speaker = Speaker 6 | register = Register 7 | venue = Venue 8 | venuemap = Venue Map 9 | travel = Router Navigation 10 | accommodation = Hotel & Food 11 | sponsor = Sponsor 12 | supporters = Supporters 13 | -------------------------------------------------------------------------------- /conf/locale_zh-CN.ini: -------------------------------------------------------------------------------- 1 | zh-CN = 简体中文 2 | en-US = English 3 | 4 | home = 首页 5 | speaker = 分享嘉宾 6 | register = 注册报名 7 | venue = 会场相关 8 | venuemap = 会场信息 9 | travel = 参会路线 10 | accommodation = 食宿 11 | sponsor = 赞助商 12 | supporters = 合作媒体 13 | -------------------------------------------------------------------------------- /controllers/controller.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "strings" 5 | "time" 6 | 7 | "github.com/astaxie/beego" 8 | "github.com/astaxie/beego/config" 9 | "github.com/beego/i18n" 10 | ) 11 | 12 | type baseController struct { 13 | beego.Controller 14 | i18n.Locale 15 | } 16 | 17 | var ( 18 | AppVer string 19 | IsPro bool 20 | ) 21 | 22 | var langTypes []*langType // Languages are supported. 23 | 24 | // langType represents a language type. 25 | type langType struct { 26 | Lang, Name string 27 | } 28 | 29 | // Prepare implemented Prepare method for baseController. 30 | func (this *baseController) Prepare() { 31 | // Setting properties. 32 | this.Data["AppVer"] = AppVer 33 | this.Data["IsPro"] = IsPro 34 | 35 | this.Data["PageStartTime"] = time.Now() 36 | 37 | // Redirect to make URL clean. 38 | if this.setLangVer() { 39 | i := strings.Index(this.Ctx.Request.RequestURI, "?") 40 | this.Redirect(this.Ctx.Request.RequestURI[:i], 302) 41 | return 42 | } 43 | } 44 | 45 | // setLangVer sets site language version. 46 | func (this *baseController) setLangVer() bool { 47 | isNeedRedir := false 48 | hasCookie := false 49 | 50 | // 1. Check URL arguments. 51 | lang := this.Input().Get("lang") 52 | 53 | // 2. Get language information from cookies. 54 | if len(lang) == 0 { 55 | lang = this.Ctx.GetCookie("lang") 56 | hasCookie = true 57 | } else { 58 | isNeedRedir = true 59 | } 60 | 61 | // Check again in case someone modify by purpose. 62 | if !i18n.IsExist(lang) { 63 | lang = "" 64 | isNeedRedir = false 65 | hasCookie = false 66 | } 67 | 68 | // 3. Get language information from 'Accept-Language'. 69 | if len(lang) == 0 { 70 | al := this.Ctx.Request.Header.Get("Accept-Language") 71 | if len(al) > 4 { 72 | al = al[:5] // Only compare first 5 letters. 73 | if i18n.IsExist(al) { 74 | lang = al 75 | } 76 | } 77 | } 78 | 79 | // 4. Default language is (Chinese) English. 80 | if len(lang) == 0 { 81 | lang = "zh-CN" //"en-US" 82 | isNeedRedir = false 83 | } 84 | 85 | curLang := langType{ 86 | Lang: lang, 87 | } 88 | 89 | // Save language information in cookies. 90 | if !hasCookie { 91 | this.Ctx.SetCookie("lang", curLang.Lang, 1<<31-1, "/") 92 | } 93 | 94 | restLangs := make([]*langType, 0, len(langTypes)-1) 95 | for _, v := range langTypes { 96 | restLangs = append(restLangs, v) 97 | } 98 | 99 | // Set language properties. 100 | this.Lang = lang 101 | this.Data["Lang"] = curLang.Lang 102 | this.Data["CurLang"] = curLang.Name 103 | this.Data["RestLangs"] = restLangs 104 | return isNeedRedir 105 | } 106 | 107 | func InitNav() { 108 | nav, err := config.NewConfig("json", "conf/nav.json") 109 | if err != nil { 110 | beego.Error(err) 111 | } 112 | diy, err := nav.DIY("nav") 113 | beego.Info(diy) 114 | } 115 | 116 | func InitLocales() { 117 | // Initialized language type list. 118 | langs := strings.Split(beego.AppConfig.String("lang::types"), "|") 119 | names := strings.Split(beego.AppConfig.String("lang::names"), "|") 120 | langTypes = make([]*langType, 0, len(langs)) 121 | for i, v := range langs { 122 | langTypes = append(langTypes, &langType{ 123 | Lang: v, 124 | Name: names[i], 125 | }) 126 | } 127 | for _, lang := range langs { 128 | beego.Trace("Loading language: " + lang) 129 | if err := i18n.SetMessage(lang, "conf/"+"locale_"+lang+".ini"); err != nil { 130 | beego.Error("Fail to set message file: " + err.Error()) 131 | return 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /controllers/default.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/gopherchina/website/models" 7 | ) 8 | 9 | type MainController struct { 10 | baseController 11 | } 12 | 13 | func (this *MainController) Get() { 14 | name := this.Ctx.Input.Param(":name") 15 | if name == "" { 16 | this.Data["Title"] = "GopherChina" 17 | this.Data["indexActive"] = true 18 | this.TplNames = "index.tpl" 19 | } else if name == "speaker" { 20 | this.Data["Title"] = "分享嘉宾 - GopherChina" 21 | this.Data["userActive"] = true 22 | this.TplNames = "speaker.tpl" 23 | } else if name == "venue" { 24 | this.Data["Title"] = "会场信息 - GopherChina" 25 | this.TplNames = "venue.tpl" 26 | } else if name == "register" { 27 | this.Data["regActive"] = true 28 | this.Data["Title"] = "注册报名 - GopherChina" 29 | this.TplNames = "register.tpl" 30 | } else { 31 | df := models.GetDoc(name, this.Lang) 32 | this.Data[fmt.Sprintf("%sActive", name)] = true 33 | this.Data["Section"] = name 34 | this.Data["Title"] = df.Title + " - GopherChina" 35 | this.Data["title"] = df.Title 36 | this.Data["Data"] = string(df.Data) 37 | this.TplNames = "detail.tpl" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /controllers/docs.go: -------------------------------------------------------------------------------- 1 | package controllers 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | 8 | "github.com/gopherchina/website/models" 9 | 10 | "github.com/astaxie/beego/context" 11 | "github.com/beego/i18n" 12 | ) 13 | 14 | type DocsController struct { 15 | baseController 16 | } 17 | 18 | // Get implemented Get method for DocsController. 19 | func (this *DocsController) Get() { 20 | name := this.Ctx.Input.Param(":name") 21 | id := this.Ctx.Input.Param(":id") 22 | if name == "" { 23 | this.Data["indexActive"] = true 24 | this.Data["Title"] = "GopherChina" 25 | this.TplNames = "index.tpl" 26 | } else { 27 | filename := name 28 | if id != "" { 29 | filename = name + "/" + id 30 | } 31 | df := models.GetDoc(filename, this.Lang) 32 | if df == nil { 33 | this.Abort("404") 34 | } 35 | this.Data[fmt.Sprintf("%sActive", name)] = true 36 | this.Data["Section"] = name 37 | 38 | this.Data["Title"] = df.Title + " - GopherChina" 39 | this.Data["title"] = df.Title 40 | this.Data["Data"] = string(df.Data) 41 | this.TplNames = "detail.tpl" 42 | } 43 | } 44 | 45 | func DocsStatic(ctx *context.Context) { 46 | if uri := ctx.Input.Params[":all"]; len(uri) > 0 { 47 | lang := ctx.GetCookie("lang") 48 | if !i18n.IsExist(lang) { 49 | lang = "en-US" 50 | } 51 | 52 | f, err := os.Open("docs/" + lang + "/" + "images/" + uri) 53 | if err != nil { 54 | ctx.WriteString(err.Error()) 55 | return 56 | } 57 | defer f.Close() 58 | 59 | _, err = io.Copy(ctx.ResponseWriter, f) 60 | if err != nil { 61 | ctx.WriteString(err.Error()) 62 | return 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/gopherchina/website/controllers" 5 | "github.com/gopherchina/website/models" 6 | 7 | "github.com/astaxie/beego" 8 | "github.com/beego/i18n" 9 | ) 10 | 11 | func main() { 12 | 13 | beego.Router("/", &controllers.MainController{}) 14 | beego.Router("/:name", &controllers.MainController{}) 15 | beego.Router("/:name/:id", &controllers.DocsController{}) 16 | beego.InsertFilter("/images/:all", beego.BeforeRouter, controllers.DocsStatic) 17 | controllers.InitLocales() 18 | models.InitModels() 19 | beego.AddFuncMap("i18n", i18n.Tr) 20 | beego.Run() 21 | } 22 | -------------------------------------------------------------------------------- /models/github.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Beego Web authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | // Package models is for loading and updating documentation files. 16 | package models 17 | 18 | import ( 19 | "encoding/json" 20 | "errors" 21 | "os" 22 | "path" 23 | "strconv" 24 | "strings" 25 | "sync" 26 | "time" 27 | 28 | "github.com/astaxie/beego" 29 | "github.com/astaxie/beego/toolbox" 30 | "github.com/astaxie/beego/utils" 31 | "github.com/slene/blackfriday" 32 | ) 33 | 34 | var docs = make(map[string]*DocRoot) 35 | 36 | type oldDocNode struct { 37 | Sha string 38 | Path string 39 | Type string 40 | } 41 | 42 | // docTree descriables a documentation file structure tree. 43 | var docTree struct { 44 | Tree []oldDocNode 45 | } 46 | 47 | var blogTree struct { 48 | Tree []oldDocNode 49 | } 50 | 51 | var productTree struct { 52 | Tree []oldDocNode 53 | } 54 | 55 | type docFile struct { 56 | Title string 57 | Data []byte 58 | } 59 | 60 | var ( 61 | docLock *sync.RWMutex 62 | blogLock *sync.RWMutex 63 | docMap map[string]*docFile 64 | blogMap map[string]*docFile 65 | ) 66 | 67 | var githubCred string 68 | 69 | func setGithubCredentials(id, secret string) { 70 | githubCred = "client_id=" + id + "&client_secret=" + secret 71 | } 72 | 73 | func GetDocByLocale(lang string) *DocRoot { 74 | return docs[lang] 75 | } 76 | 77 | func InitModels() { 78 | 79 | setGithubCredentials(beego.AppConfig.String("github::client_id"), 80 | beego.AppConfig.String("github::client_secret")) 81 | 82 | docLock = new(sync.RWMutex) 83 | blogLock = new(sync.RWMutex) 84 | 85 | parseDocs() 86 | initMaps() 87 | //initProuctCase() 88 | 89 | updateTask := toolbox.NewTask("check file update", "0 */5 * * * *", checkFileUpdates) 90 | 91 | if needCheckUpdate() { 92 | if err := updateTask.Run(); err != nil { 93 | beego.Error(err) 94 | } 95 | 96 | beego.AppConfig.Set("app::update_check_time", strconv.Itoa(int(time.Now().Unix()))) 97 | } 98 | 99 | // ATTENTION: you'd better comment following code when developing. 100 | toolbox.AddTask("check file update", updateTask) 101 | toolbox.StartTask() 102 | } 103 | 104 | func parseDocs() { 105 | root, err := ParseDocs("docs/zh-CN") 106 | if err != nil { 107 | beego.Error(err) 108 | } 109 | 110 | if root != nil { 111 | docs["zh-CN"] = root 112 | } 113 | 114 | root, err = ParseDocs("docs/en-US") 115 | if err != nil { 116 | beego.Error(err) 117 | } 118 | 119 | if root != nil { 120 | docs["en-US"] = root 121 | } 122 | } 123 | 124 | func needCheckUpdate() bool { 125 | // Does not have record for check update. 126 | stamp, err := beego.AppConfig.Int64("app::update_check_time") 127 | if err != nil { 128 | return true 129 | } 130 | 131 | if !utils.FileExists("conf/docTree.json") || !utils.FileExists("conf/blogTree.json") || 132 | !utils.FileExists("conf/productTree.json") { 133 | return true 134 | } 135 | 136 | return time.Unix(stamp, 0).Add(5 * time.Minute).Before(time.Now()) 137 | } 138 | 139 | func initDocMap() { 140 | // Documentation names. 141 | docNames := make([]string, 0, 20) 142 | docNames = append(docNames, strings.Split( 143 | beego.AppConfig.String("app::doc_names"), "|")...) 144 | 145 | isConfExist := utils.FileExists("conf/docTree.json") 146 | if isConfExist { 147 | f, err := os.Open("conf/docTree.json") 148 | if err != nil { 149 | beego.Error("models.initDocMap -> load data:", err.Error()) 150 | return 151 | } 152 | defer f.Close() 153 | 154 | d := json.NewDecoder(f) 155 | if err = d.Decode(&docTree); err != nil { 156 | beego.Error("models.initDocMap -> decode data:", err.Error()) 157 | return 158 | } 159 | } else { 160 | // Generate 'docTree'. 161 | for _, v := range docNames { 162 | docTree.Tree = append(docTree.Tree, oldDocNode{Path: v}) 163 | } 164 | } 165 | 166 | docLock.Lock() 167 | defer docLock.Unlock() 168 | 169 | docMap = make(map[string]*docFile) 170 | langs := strings.Split(beego.AppConfig.String("lang::types"), "|") 171 | 172 | os.Mkdir("docs", os.ModePerm) 173 | for _, l := range langs { 174 | os.Mkdir("docs/"+l, os.ModePerm) 175 | for _, v := range docTree.Tree { 176 | var fullName string 177 | if isConfExist { 178 | fullName = v.Path 179 | } else { 180 | fullName = l + "/" + v.Path 181 | } 182 | docMap[fullName] = getFile("docs/" + fullName) 183 | } 184 | } 185 | } 186 | 187 | func initMaps() { 188 | initDocMap() 189 | } 190 | 191 | // loadFile returns []byte of file data by given path. 192 | func loadFile(filePath string) ([]byte, error) { 193 | f, err := os.Open(filePath) 194 | if err != nil { 195 | return []byte(""), errors.New("Fail to open file: " + err.Error()) 196 | } 197 | 198 | fi, err := f.Stat() 199 | if err != nil { 200 | return []byte(""), errors.New("Fail to get file information: " + err.Error()) 201 | } 202 | 203 | d := make([]byte, fi.Size()) 204 | f.Read(d) 205 | return d, nil 206 | } 207 | 208 | func markdown(raw []byte) []byte { 209 | htmlFlags := 0 210 | htmlFlags |= blackfriday.HTML_USE_XHTML 211 | htmlFlags |= blackfriday.HTML_USE_SMARTYPANTS 212 | htmlFlags |= blackfriday.HTML_SMARTYPANTS_FRACTIONS 213 | htmlFlags |= blackfriday.HTML_SMARTYPANTS_LATEX_DASHES 214 | htmlFlags |= blackfriday.HTML_GITHUB_BLOCKCODE 215 | htmlFlags |= blackfriday.HTML_OMIT_CONTENTS 216 | htmlFlags |= blackfriday.HTML_COMPLETE_PAGE 217 | renderer := blackfriday.HtmlRenderer(htmlFlags, "", "") 218 | 219 | // set up the parser 220 | extensions := 0 221 | extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS 222 | extensions |= blackfriday.EXTENSION_TABLES 223 | extensions |= blackfriday.EXTENSION_FENCED_CODE 224 | extensions |= blackfriday.EXTENSION_AUTOLINK 225 | extensions |= blackfriday.EXTENSION_STRIKETHROUGH 226 | extensions |= blackfriday.EXTENSION_HARD_LINE_BREAK 227 | extensions |= blackfriday.EXTENSION_SPACE_HEADERS 228 | extensions |= blackfriday.EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK 229 | 230 | body := blackfriday.Markdown(raw, renderer, extensions) 231 | return body 232 | } 233 | 234 | func getFile(filePath string) *docFile { 235 | if strings.Contains(filePath, "images") { 236 | return nil 237 | } 238 | df := &docFile{} 239 | p, err := loadFile(filePath + ".md") 240 | if err != nil { 241 | beego.Error("models.getFile -> ", err) 242 | return nil 243 | } 244 | 245 | // Parse and render. 246 | s := string(p) 247 | i := strings.Index(s, "\n") 248 | if i > -1 { 249 | // Has title. 250 | df.Title = strings.TrimSpace( 251 | strings.Replace(s[:i+1], "#", "", -1)) 252 | if len(s) >= i+2 { 253 | df.Data = []byte(strings.TrimSpace(s[i+2:])) 254 | } 255 | } else { 256 | df.Data = p 257 | } 258 | df.Data = markdown(df.Data) 259 | return df 260 | } 261 | 262 | // GetDoc returns 'docFile' by given name and language version. 263 | func GetDoc(fullName, lang string) *docFile { 264 | filePath := "docs/" + lang + "/" + fullName 265 | 266 | if beego.RunMode == "dev" { 267 | return getFile(filePath) 268 | } 269 | 270 | docLock.RLock() 271 | defer docLock.RUnlock() 272 | return docMap[lang+"/"+fullName] 273 | } 274 | 275 | var checkTicker *time.Ticker 276 | 277 | func checkTickerTimer(checkChan <-chan time.Time) { 278 | for { 279 | <-checkChan 280 | checkFileUpdates() 281 | } 282 | } 283 | 284 | type rawFile struct { 285 | name string 286 | rawURL string 287 | data []byte 288 | } 289 | 290 | func (rf *rawFile) Name() string { 291 | return rf.name 292 | } 293 | 294 | func (rf *rawFile) RawUrl() string { 295 | return rf.rawURL 296 | } 297 | 298 | func (rf *rawFile) Data() []byte { 299 | return rf.data 300 | } 301 | 302 | func (rf *rawFile) SetData(p []byte) { 303 | rf.data = p 304 | } 305 | 306 | func checkFileUpdates() error { 307 | beego.Trace("Checking file updates") 308 | 309 | type tree struct { 310 | ApiUrl, RawUrl, TreeName, Prefix string 311 | } 312 | 313 | var trees = []*tree{ 314 | { 315 | ApiUrl: "https://api.github.com/repos/gopherchina/docs/git/trees/master?recursive=1&" + githubCred, 316 | RawUrl: "https://raw.github.com/gopherchina/docs/master/", 317 | TreeName: "conf/docTree.json", 318 | Prefix: "docs/", 319 | }, 320 | } 321 | 322 | for _, tree := range trees { 323 | var tmpTree struct { 324 | Tree []*oldDocNode 325 | } 326 | err := getHttpJson(tree.ApiUrl, &tmpTree) 327 | if err != nil { 328 | return errors.New("models.checkFileUpdates -> get trees: " + err.Error()) 329 | } 330 | 331 | var saveTree struct { 332 | Tree []*oldDocNode 333 | } 334 | saveTree.Tree = make([]*oldDocNode, 0, len(tmpTree.Tree)) 335 | 336 | // Compare SHA. 337 | files := make([]*rawFile, 0, len(tmpTree.Tree)) 338 | for _, node := range tmpTree.Tree { 339 | // Skip non-md files and "README.md". 340 | if node.Type != "blob" || (!strings.HasSuffix(node.Path, ".md") && 341 | !strings.Contains(node.Path, "images") && 342 | !strings.HasSuffix(node.Path, ".json")) || 343 | strings.HasPrefix(strings.ToLower(node.Path), "readme") { 344 | continue 345 | } 346 | 347 | name := strings.TrimSuffix(node.Path, ".md") 348 | 349 | if checkSHA(name, node.Sha, tree.Prefix) { 350 | beego.Info("Need to update:", name) 351 | files = append(files, &rawFile{ 352 | name: name, 353 | rawURL: tree.RawUrl + node.Path, 354 | }) 355 | } 356 | 357 | saveTree.Tree = append(saveTree.Tree, &oldDocNode{ 358 | Path: name, 359 | Sha: node.Sha, 360 | }) 361 | // For save purpose, reset name. 362 | node.Path = name + ".md" 363 | } 364 | 365 | // Fetch files. 366 | if err := getFiles(files); err != nil { 367 | return errors.New("models.checkFileUpdates -> fetch files: " + err.Error()) 368 | //beego.Info(err) 369 | } 370 | 371 | // Update data. 372 | for _, f := range files { 373 | os.MkdirAll(path.Join(tree.Prefix, path.Dir(f.name)), os.ModePerm) 374 | suf := ".md" 375 | if strings.Contains(f.name, "images") || 376 | strings.HasSuffix(f.name, ".json") { 377 | suf = "" 378 | } 379 | fw, err := os.Create(tree.Prefix + f.name + suf) 380 | if err != nil { 381 | beego.Error("models.checkFileUpdates -> open file:", err.Error()) 382 | continue 383 | } 384 | 385 | _, err = fw.Write(f.data) 386 | fw.Close() 387 | if err != nil { 388 | beego.Error("models.checkFileUpdates -> write data:", err.Error()) 389 | continue 390 | } 391 | } 392 | 393 | // Save documentation information. 394 | f, err := os.Create(tree.TreeName) 395 | if err != nil { 396 | return errors.New("models.checkFileUpdates -> save data: " + err.Error()) 397 | } 398 | 399 | e := json.NewEncoder(f) 400 | err = e.Encode(&saveTree) 401 | if err != nil { 402 | return errors.New("models.checkFileUpdates -> encode data: " + err.Error()) 403 | } 404 | f.Close() 405 | } 406 | 407 | beego.Trace("Finish check file updates") 408 | parseDocs() 409 | initMaps() 410 | return nil 411 | } 412 | 413 | // checkSHA returns true if the documentation file need to update. 414 | func checkSHA(name, sha, prefix string) bool { 415 | var tree struct { 416 | Tree []oldDocNode 417 | } 418 | 419 | switch prefix { 420 | case "docs/": 421 | tree = docTree 422 | case "blog/": 423 | tree = blogTree 424 | default: 425 | tree = productTree 426 | } 427 | 428 | for _, v := range tree.Tree { 429 | if v.Path == name { 430 | // Found. 431 | if v.Sha != sha { 432 | // Need to update. 433 | return true 434 | } 435 | return false 436 | } 437 | } 438 | // Not found. 439 | return true 440 | } 441 | -------------------------------------------------------------------------------- /models/http.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Gary Burd 2 | // Copyright 2013 Beego Web authors 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 5 | // not use this file except in compliance with the License. You may obtain 6 | // a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | // License for the specific language governing permissions and limitations 14 | // under the License. 15 | 16 | package models 17 | 18 | import ( 19 | "encoding/json" 20 | "errors" 21 | "io/ioutil" 22 | "net" 23 | "net/http" 24 | "time" 25 | 26 | "github.com/astaxie/beego" 27 | ) 28 | 29 | var userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36" 30 | 31 | var ( 32 | dialTimeout = 5 * time.Second //flag.Duration("dial_timeout", 10*time.Second, "Timeout for dialing an HTTP connection.") 33 | requestTimeout = 120 * time.Second //flag.Duration("request_timeout", 20*time.Second, "Time out for roundtripping an HTTP request.") 34 | ) 35 | 36 | func timeoutDial(network, addr string) (net.Conn, error) { 37 | return net.DialTimeout(network, addr, dialTimeout) 38 | } 39 | 40 | type transport struct { 41 | t http.Transport 42 | } 43 | 44 | func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) { 45 | timer := time.AfterFunc(requestTimeout, func() { 46 | t.t.CancelRequest(req) 47 | beego.Warn("Canceled request for %s", req.URL) 48 | }) 49 | defer timer.Stop() 50 | resp, err := t.t.RoundTrip(req) 51 | return resp, err 52 | } 53 | 54 | var ( 55 | httpTransport = &transport{t: http.Transport{Dial: timeoutDial, ResponseHeaderTimeout: requestTimeout / 2}} 56 | httpClient = &http.Client{Transport: httpTransport} 57 | ) 58 | 59 | func getHttpJson(url string, v interface{}) error { 60 | req, err := http.NewRequest("GET", url, nil) 61 | if err != nil { 62 | return err 63 | } 64 | req.Header.Set("User-Agent", userAgent) 65 | 66 | resp, err := httpClient.Do(req) 67 | if err != nil { 68 | return err 69 | } 70 | defer resp.Body.Close() 71 | if resp.StatusCode == 200 { 72 | err = json.NewDecoder(resp.Body).Decode(v) 73 | if _, ok := err.(*json.SyntaxError); ok { 74 | return errors.New("JSON syntax error at " + url) 75 | } 76 | return nil 77 | } 78 | return errors.New("can't get infomation") 79 | } 80 | 81 | func getFiles(files []*rawFile) error { 82 | ch := make(chan error, len(files)) 83 | for i := range files { 84 | go func(i int) { 85 | req, err := http.NewRequest("GET", files[i].rawURL, nil) 86 | if err != nil { 87 | ch <- err 88 | return 89 | } 90 | req.Header.Set("User-Agent", userAgent) 91 | resp, err := httpClient.Do(req) 92 | if err != nil { 93 | ch <- err 94 | return 95 | } 96 | time.Sleep(500) 97 | defer resp.Body.Close() 98 | if resp.StatusCode == 200 { 99 | p, err := ioutil.ReadAll(resp.Body) 100 | if err != nil { 101 | ch <- err 102 | return 103 | } 104 | files[i].data = p 105 | } 106 | ch <- nil 107 | }(i) 108 | } 109 | for _ = range files { 110 | if err := <-ch; err != nil { 111 | return err 112 | } 113 | } 114 | return nil 115 | } 116 | -------------------------------------------------------------------------------- /models/press.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Beego Web authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | package models 16 | 17 | import ( 18 | "bufio" 19 | "bytes" 20 | "fmt" 21 | "io" 22 | "io/ioutil" 23 | "os" 24 | "path/filepath" 25 | "sort" 26 | "strconv" 27 | "strings" 28 | "time" 29 | 30 | "github.com/astaxie/beego" 31 | ) 32 | 33 | type DocList []*DocNode 34 | 35 | func (s DocList) Len() int { return len(s) } 36 | func (s DocList) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 37 | func (s DocList) Less(i, j int) bool { return s[i].Sort < s[j].Sort } 38 | 39 | type DocNode struct { 40 | root bool 41 | IsDir bool 42 | Path string 43 | RelPath string 44 | FileRelPath string 45 | FilePath string 46 | Date time.Time 47 | Name string 48 | Sort int 49 | Link string 50 | Docs DocList 51 | dirs map[string]*DocNode 52 | Root *DocRoot 53 | Parent *DocNode 54 | } 55 | 56 | func (d *DocNode) SortDocs() { 57 | sort.Sort(d.Docs) 58 | } 59 | 60 | func (d *DocNode) HasContent() bool { 61 | return len(d.FilePath) > 0 62 | } 63 | 64 | func (d *DocNode) GetContent() string { 65 | if !d.HasContent() { 66 | return "" 67 | } 68 | 69 | body, err := ioutil.ReadFile(d.FilePath) 70 | if err != nil { 71 | return "" 72 | } 73 | 74 | if i := bytes.Index(body, []byte("---")); i != -1 { 75 | body = body[i+3:] 76 | if i = bytes.Index(body, []byte("---")); i != -1 { 77 | body = body[i+3:] 78 | i = 0 79 | m := 0 80 | mFor: 81 | for { 82 | if len(body) > 0 { 83 | if body[0] == ' ' || body[0] == '\n' { 84 | if body[0] == '\n' { 85 | m += 1 86 | } 87 | if m == 2 { 88 | break mFor 89 | } 90 | } else { 91 | break mFor 92 | } 93 | body = body[1:] 94 | } else { 95 | break mFor 96 | } 97 | } 98 | 99 | return string(markdown(body)) 100 | } 101 | } 102 | 103 | return "" 104 | } 105 | 106 | type DocRoot struct { 107 | Wd string 108 | Path string 109 | Doc *DocNode 110 | links map[string]*DocNode 111 | } 112 | 113 | func (d *DocRoot) GetNodeByLink(link string) (*DocNode, bool) { 114 | n, ok := d.links[link] 115 | return n, ok 116 | } 117 | 118 | func (d *DocRoot) walkParse() error { 119 | var err error 120 | if d.Path, err = filepath.Abs(d.Path); err != nil { 121 | return err 122 | } 123 | 124 | defer func() { 125 | if err == nil { 126 | d.sortAll(d.Doc) 127 | } 128 | }() 129 | 130 | err = filepath.Walk(d.Path, d.walk) 131 | return err 132 | } 133 | 134 | func (d *DocRoot) sortAll(node *DocNode) { 135 | for _, n := range node.Docs { 136 | if n.IsDir { 137 | d.sortAll(n) 138 | } 139 | } 140 | node.SortDocs() 141 | } 142 | 143 | func (d *DocRoot) makeDirNode(path string) error { 144 | relPath, _ := filepath.Rel(d.Path, path) 145 | 146 | var docDir *DocNode 147 | 148 | if d.Doc == nil { 149 | d.Doc = new(DocNode) 150 | d.Doc.dirs = make(map[string]*DocNode) 151 | docDir = d.Doc 152 | 153 | } else { 154 | list := strings.Split(relPath, string(filepath.Separator)) 155 | node := d.Doc 156 | for _, p := range list { 157 | if n, ok := node.dirs[p]; ok { 158 | node = n 159 | } else { 160 | n = new(DocNode) 161 | n.dirs = make(map[string]*DocNode) 162 | n.Parent = node 163 | node.Docs = append(node.Docs, n) 164 | node.dirs[p] = n 165 | node = n 166 | } 167 | } 168 | 169 | docDir = node 170 | } 171 | 172 | docDir.Root = d 173 | docDir.Path = path 174 | docDir.RelPath = relPath 175 | docDir.IsDir = true 176 | 177 | return nil 178 | } 179 | 180 | func (d *DocRoot) getDirNode(path string) *DocNode { 181 | node := d.Doc 182 | list := strings.Split(path, string(filepath.Separator)) 183 | for _, p := range list { 184 | if n, ok := node.dirs[p]; ok { 185 | node = n 186 | } 187 | } 188 | return node 189 | } 190 | 191 | func (d *DocRoot) makeFileNode(path string) error { 192 | file, err := os.Open(path) 193 | if err != nil { 194 | return err 195 | } 196 | defer file.Close() 197 | 198 | relPath, _ := filepath.Rel(d.Path, path) 199 | relPath = strings.Replace(relPath, "\\", "/", -1) 200 | 201 | docDir := d.getDirNode(filepath.Dir(relPath)) 202 | 203 | var bingo bool 204 | var doc *DocNode 205 | rd := bufio.NewReader(file) 206 | no := 0 207 | for { 208 | line, _, err := rd.ReadLine() 209 | if err == io.EOF { 210 | break 211 | } 212 | 213 | if no > 3 && !bingo { 214 | break 215 | } 216 | 217 | if no > 20 && bingo { 218 | return fmt.Errorf("document %s not contained ended tag `---`", path) 219 | } 220 | 221 | data := string(bytes.TrimSpace(line)) 222 | 223 | if len(data) == 3 && data == "---" { 224 | 225 | if bingo { 226 | if doc.root { 227 | if len(docDir.FilePath) > 0 { 228 | return fmt.Errorf("node %s has a document %s, can not replicate by %s", 229 | docDir.Path, docDir.FilePath, path) 230 | } 231 | 232 | docDir.Name = doc.Name 233 | docDir.Date = doc.Date 234 | docDir.Link = doc.Link 235 | docDir.Sort = doc.Sort 236 | 237 | mFor: 238 | for { 239 | l, _, er := rd.ReadLine() 240 | if er != nil { 241 | break mFor 242 | } 243 | if len(bytes.TrimSpace(l)) > 0 { 244 | docDir.FilePath = path 245 | break mFor 246 | } 247 | } 248 | 249 | if len(docDir.Link) == 0 { 250 | docDir.Link = docDir.RelPath + "/" 251 | } 252 | 253 | docDir.FileRelPath = relPath 254 | 255 | doc = docDir 256 | } else { 257 | doc.RelPath = relPath 258 | doc.FilePath = path 259 | if len(doc.Link) == 0 { 260 | doc.Link = doc.RelPath 261 | // doc.Link = strings.TrimSuffix(doc.RelPath, filepath.Ext(doc.RelPath)) 262 | } 263 | 264 | docDir.Docs = append(docDir.Docs, doc) 265 | } 266 | 267 | if dc, ok := d.links[doc.Link]; ok { 268 | return fmt.Errorf("document %s's link %s is already used by %s", path, doc.Link, dc.Path) 269 | } 270 | 271 | d.links[doc.Link] = doc 272 | 273 | break 274 | } 275 | 276 | doc = new(DocNode) 277 | doc.Path = path 278 | doc.Root = d 279 | doc.Parent = docDir 280 | 281 | bingo = true 282 | } 283 | 284 | if bingo { 285 | parts := strings.SplitN(data, ":", 2) 286 | if len(parts) == 2 { 287 | name := strings.TrimSpace(parts[0]) 288 | value := strings.TrimSpace(parts[1]) 289 | switch name { 290 | case "root": 291 | doc.root, _ = strconv.ParseBool(value) 292 | case "name": 293 | doc.Name = value 294 | case "date": 295 | doc.Date, err = beego.DateParse(value, "Y-m-d H:i") 296 | if err != nil { 297 | return err 298 | } 299 | case "link": 300 | doc.Link = value 301 | case "sort": 302 | n, _ := strconv.ParseInt(value, 10, 64) 303 | doc.Sort = int(n) 304 | } 305 | } 306 | } 307 | } 308 | 309 | return nil 310 | } 311 | 312 | func (d *DocRoot) walk(path string, info os.FileInfo, err error) error { 313 | if err != nil { 314 | return filepath.SkipDir 315 | } 316 | 317 | if !info.IsDir() && info.Size() == 0 { 318 | return nil 319 | } 320 | 321 | if info.IsDir() { 322 | if err := d.makeDirNode(path); err != nil { 323 | return err 324 | } 325 | } else { 326 | return d.makeFileNode(path) 327 | } 328 | 329 | return nil 330 | } 331 | 332 | func ParseDocs(path string) (*DocRoot, error) { 333 | root := new(DocRoot) 334 | root.Path = path 335 | root.links = make(map[string]*DocNode) 336 | 337 | if err := root.walkParse(); err == nil { 338 | return root, err 339 | } else { 340 | return nil, err 341 | } 342 | } 343 | -------------------------------------------------------------------------------- /models/product.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "encoding/json" 5 | "os" 6 | 7 | "github.com/astaxie/beego" 8 | "github.com/astaxie/beego/utils" 9 | ) 10 | 11 | type products struct { 12 | Projects []*Project 13 | } 14 | 15 | type Project struct { 16 | Name string 17 | Thumb string 18 | Desc string 19 | Url string 20 | Src string 21 | Submitter string 22 | Date string 23 | } 24 | 25 | var Products = new(products) 26 | 27 | func initProuctCase() { 28 | if !utils.FileExists("conf/productTree.json") { 29 | beego.Error("models.initBlogMap -> conf/productTree.json does not exist") 30 | return 31 | } 32 | 33 | f, err := os.Open("conf/productTree.json") 34 | if err != nil { 35 | beego.Error("models.initBlogMap -> load data:", err.Error()) 36 | return 37 | } 38 | defer f.Close() 39 | 40 | d := json.NewDecoder(f) 41 | err = d.Decode(&productTree) 42 | if err != nil { 43 | beego.Error("models.initBlogMap -> decode data:", err.Error()) 44 | return 45 | } 46 | 47 | fileName := "products/projects.json" 48 | 49 | aProducts := *Products 50 | 51 | var file *os.File 52 | 53 | if file, err = os.Open(fileName); err != nil { 54 | beego.Error("open %s, %s", fileName, err.Error()) 55 | return 56 | } 57 | 58 | d = json.NewDecoder(file) 59 | if err = d.Decode(&aProducts); err != nil { 60 | beego.Error("open %s, %s", fileName, err.Error()) 61 | return 62 | } 63 | 64 | for i, j := 0, len(aProducts.Projects)-1; i < j; i, j = i+1, j-1 { 65 | aProducts.Projects[i], aProducts.Projects[j] = aProducts.Projects[j], aProducts.Projects[i] 66 | } 67 | 68 | *Products = aProducts 69 | } 70 | -------------------------------------------------------------------------------- /static/css/admin.css: -------------------------------------------------------------------------------- 1 | /** 2 | * admin.css 3 | */ 4 | 5 | ul { 6 | margin-top: 0; 7 | } 8 | 9 | .admin-icon-yellow { 10 | color: #ffbe40; 11 | } 12 | 13 | .admin-header { 14 | font-size: 1.4rem; 15 | margin-bottom: 0; 16 | } 17 | 18 | .admin-header-list a:hover :after { 19 | content: none; 20 | } 21 | 22 | .admin-main { 23 | background: #f3f3f3; 24 | } 25 | 26 | .admin-sidebar { 27 | width: 260px; 28 | min-height: 100%; 29 | float: left; 30 | border-right: 1px solid #cecece; 31 | } 32 | 33 | .admin-sidebar-list { 34 | margin-bottom: 0; 35 | } 36 | 37 | .admin-sidebar-list li a { 38 | color: #5c5c5c; 39 | padding-left: 24px; 40 | } 41 | 42 | .admin-sidebar-list li:first-child { 43 | border-top: none; 44 | } 45 | 46 | .admin-sidebar-sub { 47 | margin-top: 0; 48 | margin-bottom: 0; 49 | box-shadow: 0 16px 8px -15px #e2e2e2 inset; 50 | background: #ececec; 51 | padding-left: 24px; 52 | } 53 | 54 | .admin-sidebar-sub li:first-child { 55 | border-top: 1px solid #dedede; 56 | } 57 | 58 | .admin-sidebar-panel { 59 | margin: 10px; 60 | } 61 | 62 | .admin-content { 63 | width: auto; 64 | overflow: hidden; 65 | height: 100%; 66 | background: #fff; 67 | } 68 | 69 | .admin-content-list { 70 | border: 1px solid #e9ecf1; 71 | margin-top: 0; 72 | } 73 | 74 | .admin-content-list li { 75 | border: 1px solid #e9ecf1; 76 | border-width: 0 1px; 77 | margin-left: -1px; 78 | } 79 | 80 | .admin-content-list li:first-child { 81 | border-left: none; 82 | } 83 | 84 | .admin-content-list li:last-child { 85 | border-right: none; 86 | } 87 | 88 | .admin-content-table a { 89 | color: #535353; 90 | } 91 | .admin-content-file { 92 | margin-bottom: 0; 93 | color: #666; 94 | } 95 | 96 | .admin-content-file p { 97 | margin: 0 0 5px 0; 98 | font-size: 1.4rem; 99 | } 100 | 101 | .admin-content-file li { 102 | padding: 10px 0; 103 | } 104 | 105 | .admin-content-file li:first-child { 106 | border-top: none; 107 | } 108 | 109 | .admin-content-file li:last-child { 110 | border-bottom: none; 111 | } 112 | 113 | .admin-content-file li .am-progress { 114 | margin-bottom: 4px; 115 | } 116 | 117 | .admin-content-file li .am-progress-bar { 118 | line-height: 14px; 119 | } 120 | 121 | .admin-content-task { 122 | margin-bottom: 0; 123 | } 124 | 125 | .admin-content-task li { 126 | padding: 5px 0; 127 | border-color: #eee; 128 | } 129 | 130 | .admin-content-task li:first-child { 131 | border-top: none; 132 | } 133 | 134 | .admin-content-task li:last-child { 135 | border-bottom: none; 136 | } 137 | 138 | .admin-task-meta { 139 | font-size: 1.2rem; 140 | color: #999; 141 | } 142 | 143 | .admin-task-bd { 144 | font-size: 1.4rem; 145 | margin-bottom: 5px; 146 | } 147 | 148 | .admin-content-comment { 149 | margin-bottom: 0; 150 | } 151 | 152 | .admin-content-comment .am-comment-bd { 153 | font-size: 1.4rem; 154 | } 155 | 156 | .admin-content-pagination { 157 | margin-bottom: 0; 158 | } 159 | .admin-content-pagination li a { 160 | padding: 4px 8px; 161 | } 162 | 163 | /* 164 | * user.html css 165 | */ 166 | .user-info { 167 | margin-bottom: 15px; 168 | } 169 | 170 | .user-info .am-progress { 171 | margin-bottom: 4px; 172 | } 173 | 174 | .user-info p { 175 | margin: 5px; 176 | } 177 | 178 | .user-info-order { 179 | font-size: 1.4rem; 180 | } 181 | 182 | /* 183 | * errorLog.html css 184 | */ 185 | 186 | .error-log .am-pre-scrollable { 187 | max-height: 40rem; 188 | } 189 | 190 | /* 191 | * table.html css 192 | */ 193 | 194 | .table-main { 195 | font-size: 1.4rem; 196 | padding: .5rem; 197 | } 198 | 199 | .table-main button { 200 | background: #fff; 201 | } 202 | 203 | .table-check { 204 | width: 30px; 205 | } 206 | 207 | .table-id { 208 | width: 50px; 209 | } 210 | 211 | /* 212 | gallery.html css 213 | */ 214 | 215 | .gallery-list li { 216 | padding: 10px; 217 | } 218 | 219 | .gallery-list a { 220 | color: #666; 221 | } 222 | 223 | .gallery-list a:hover { 224 | color: #3bb4f2; 225 | } 226 | 227 | .gallery-title { 228 | margin-top: 6px; 229 | font-size: 1.4rem; 230 | } 231 | 232 | .gallery-desc { 233 | font-size: 1.2rem; 234 | margin-top: 4px; 235 | } 236 | 237 | /* 238 | 404.html css 239 | */ 240 | 241 | .page-404 { 242 | background: #fff; 243 | border: none; 244 | width: 200px; 245 | margin: 0 auto; 246 | } 247 | -------------------------------------------------------------------------------- /static/css/app.css: -------------------------------------------------------------------------------- 1 | /* Write your styles */ -------------------------------------------------------------------------------- /static/css/index.css: -------------------------------------------------------------------------------- 1 | .m120{width: 120px;} 2 | .detail-span span{margin: 0;padding: .8rem;} 3 | .get { 4 | background: #1E5B94; 5 | color: #fff; 6 | text-align: center; 7 | padding: 50px 0; 8 | } 9 | 10 | .get-title { 11 | font-size: 200%; 12 | } 13 | 14 | .get-btn { 15 | background: #fff; 16 | } 17 | .center{ text-align: center;} 18 | .detail { 19 | background: #fff; 20 | } 21 | 22 | .detail-h2 { 23 | text-align: center; 24 | font-size: 150%; 25 | margin: 40px 0; 26 | } 27 | 28 | .detail-h3 { 29 | color: #1f8dd6; 30 | } 31 | 32 | .detail-p { 33 | color: #7f8c8d; 34 | 35 | } 36 | .detail-span { 37 | color: #7f8c8d; 38 | } 39 | .detail-mb { 40 | margin-bottom: 30px; 41 | } 42 | .detail-mt { 43 | margin-top: 10px; 44 | } 45 | .hope { 46 | background: #0bb59b; 47 | padding: 50px 0; 48 | } 49 | 50 | .hope-img { 51 | text-align: center; 52 | } 53 | 54 | .hope-hr { 55 | border-color: #149C88; 56 | } 57 | 58 | .hope-title { 59 | font-size: 140%; 60 | } 61 | 62 | .about { 63 | background: #fff; 64 | padding: 40px 0; 65 | color: #7f8c8d; 66 | } 67 | 68 | .about-color { 69 | color: #34495e; 70 | } 71 | 72 | .about-title { 73 | font-size: 180%; 74 | padding: 30px 0 50px 0; 75 | text-align: center; 76 | } 77 | .partner{ 78 | padding:0 0 0 25px; 79 | /*border-right: 1px solid #E0E0E0;*/ 80 | } 81 | .partner img { 82 | width: 125px; 83 | height: auto; 84 | margin: 10px 50px 0px 0px; 85 | } 86 | 87 | .footer p { 88 | color: #7f8c8d; 89 | margin: 0; 90 | padding: 15px 0; 91 | text-align: center; 92 | background: #2d3e50; 93 | } -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/favicon.ico -------------------------------------------------------------------------------- /static/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /static/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /static/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /static/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /static/images/InfoQ.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/InfoQ.jpg -------------------------------------------------------------------------------- /static/images/bearychat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/bearychat.png -------------------------------------------------------------------------------- /static/images/bowen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/bowen.png -------------------------------------------------------------------------------- /static/images/coding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/coding.png -------------------------------------------------------------------------------- /static/images/csdn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/csdn.png -------------------------------------------------------------------------------- /static/images/daocloud.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/daocloud.jpg -------------------------------------------------------------------------------- /static/images/daocloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/daocloud.png -------------------------------------------------------------------------------- /static/images/dreamlab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/dreamlab.png -------------------------------------------------------------------------------- /static/images/fequan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/fequan.jpg -------------------------------------------------------------------------------- /static/images/gitcafe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/gitcafe.png -------------------------------------------------------------------------------- /static/images/gophercomplex1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/gophercomplex1.jpg -------------------------------------------------------------------------------- /static/images/gophercomplex2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/gophercomplex2.jpg -------------------------------------------------------------------------------- /static/images/gopherconf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/gopherconf.png -------------------------------------------------------------------------------- /static/images/huawei.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/huawei.png -------------------------------------------------------------------------------- /static/images/imooc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/imooc.png -------------------------------------------------------------------------------- /static/images/jd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/jd.png -------------------------------------------------------------------------------- /static/images/oschina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/oschina.png -------------------------------------------------------------------------------- /static/images/osforce.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/osforce.jpg -------------------------------------------------------------------------------- /static/images/pusoft.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/pusoft.jpg -------------------------------------------------------------------------------- /static/images/pusoft1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/pusoft1.jpg -------------------------------------------------------------------------------- /static/images/pusoft2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/pusoft2.jpg -------------------------------------------------------------------------------- /static/images/pusoft_map.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/pusoft_map.jpg -------------------------------------------------------------------------------- /static/images/qiniu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/qiniu.jpg -------------------------------------------------------------------------------- /static/images/segmentfault.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/segmentfault.png -------------------------------------------------------------------------------- /static/images/techparty.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/techparty.jpg -------------------------------------------------------------------------------- /static/images/tuling.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/tuling.jpg -------------------------------------------------------------------------------- /static/images/xd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/images/xd.png -------------------------------------------------------------------------------- /static/img/chenmingda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/img/chenmingda.png -------------------------------------------------------------------------------- /static/img/gonghaohua.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/img/gonghaohua.jpg -------------------------------------------------------------------------------- /static/img/lisibao.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/img/lisibao.jpg -------------------------------------------------------------------------------- /static/img/liuqi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/img/liuqi.png -------------------------------------------------------------------------------- /static/img/maquanyi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/img/maquanyi.jpg -------------------------------------------------------------------------------- /static/img/qleelulu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/img/qleelulu.jpg -------------------------------------------------------------------------------- /static/img/xushiwei.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/img/xushiwei.jpg -------------------------------------------------------------------------------- /static/img/zhouyang.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gopherchina/website/a17ef0e1b67a3c6c9fe5dfff2f24d634adb5ad92/static/img/zhouyang.jpg -------------------------------------------------------------------------------- /static/js/amazeui.widgets.helper.js: -------------------------------------------------------------------------------- 1 | /*! Amaze UI v2.1.0-beta1 ~ helper | by Amaze UI Team | (c) 2015 AllMobilize, Inc. | Licensed under MIT | 2015-01-04T05:01:12 UTC */ 2 | (function(undefined) { 3 | 'use strict'; 4 | 5 | var registerIfCondHelper = function(hbs) { 6 | hbs.registerHelper('ifCond', function(v1, operator, v2, options) { 7 | switch (operator) { 8 | case '==': 9 | return (v1 == v2) ? options.fn(this) : options.inverse(this); 10 | break; 11 | case '===': 12 | return (v1 === v2) ? options.fn(this) : options.inverse(this); 13 | break; 14 | case '<': 15 | return (v1 < v2) ? options.fn(this) : options.inverse(this); 16 | break; 17 | case '<=': 18 | return (v1 <= v2) ? options.fn(this) : options.inverse(this); 19 | break; 20 | case '>': 21 | return (v1 > v2) ? options.fn(this) : options.inverse(this); 22 | break; 23 | case '>=': 24 | return (v1 >= v2) ? options.fn(this) : options.inverse(this); 25 | break; 26 | default: 27 | return options.inverse(this); 28 | break; 29 | } 30 | return options.inverse(this); 31 | }); 32 | }; 33 | 34 | if (typeof module !== 'undefined' && module.exports) { 35 | module.exports = registerIfCondHelper; 36 | } 37 | 38 | this.Handlebars && registerIfCondHelper(this.Handlebars); 39 | }).call(this); 40 | 41 | (function(undefined){ 42 | 'use strict'; 43 | 44 | var registerAMUIPartials = function(hbs) { 45 | hbs.registerPartial('accordion', "{{#this}}\n
\n {{#each content}}\n
\n
\n {{{title}}}\n
\n
\n \n
\n {{{content}}}\n
\n
\n
\n {{/each}}\n
\n{{/this}}\n"); 46 | 47 | hbs.registerPartial('divider', "{{#this}}\n
\n{{/this}}\n"); 48 | 49 | hbs.registerPartial('duoshuo', "{{#this}}\n
\n
\n
\n
\n{{/this}}"); 50 | 51 | hbs.registerPartial('figure', "{{#this}}\n
\n {{#if content.link}}{{/if}}\n\n {{#if options.figcaptionPosition}}\n {{#ifCond options.figcaptionPosition '==' 'top'}}\n {{#if content.figcaption}}\n
\n {{content.figcaption}}\n
\n {{/if}}\n {{/ifCond}}\n {{/if}}\n\n {{#if content.img}}\n \"{{#if\n {{/if}}\n {{#if options.figcaptionPosition}}\n {{#ifCond options.figcaptionPosition '==' 'bottom'}}\n {{#if content.figcaption}}\n
\n {{content.figcaption}}\n
\n {{/if}}\n {{/ifCond}}\n {{else}}\n {{#if content.figcaption}}\n
\n {{content.figcaption}}\n
\n {{/if}}\n {{/if}}\n\n {{#if content.link}}
{{/if}}\n
\n{{/this}}\n"); 52 | 53 | hbs.registerPartial('footer', "{{#this}}\n \n\n \n{{/this}}\n"); 54 | 55 | hbs.registerPartial('gallery', "{{#this}}\n \n{{/this}}\n"); 56 | 57 | hbs.registerPartial('gotop', "{{#this}}\n
\n \n {{#if content.title}}\n {{content.title}}\n {{/if}}\n {{#if content.customIcon}}\n \n {{else}}\n {{#if content.icon}}\n \n {{else}}\n \n {{/if}}\n {{/if}}\n \n
\n{{/this}}"); 58 | 59 | hbs.registerPartial('header', "{{#this}}\n
\n {{#if content.left}}\n
\n {{#each content.left}}\n \n {{#if title}}\n \n {{title}}\n \n {{/if}}\n\n {{# if customIcon}}\n \"\"/\n {{else}}\n {{#if icon}}\n \n {{/if}}\n {{/if}}\n \n {{/each}}\n
\n {{/if}}\n\n {{#if content.title}}\n

\n {{#if content.link}}\n \n {{{content.title}}}\n \n {{else}}\n {{{content.title}}}\n {{/if}}\n

\n {{/if}}\n\n {{#if content.right}}\n
\n {{#each content.right}}\n \n {{#if title}}\n \n {{title}}\n \n {{/if}}\n\n {{# if customIcon}}\n \"\"/\n {{else}}\n {{#if icon}}\n \n {{/if}}\n {{/if}}\n \n {{/each}}\n
\n {{/if}}\n
\n{{/this}}"); 60 | 61 | hbs.registerPartial('intro', "{{#this }}\n
\n {{#if content.title}}\n
\n

{{{content.title}}}

\n {{#if content.more.link}}\n {{#ifCond options.position '==' 'top'}}\n {{content.more.title}}\n {{/ifCond}}\n {{/if}}\n
\n {{/if}}\n\n
\n {{#if content.left}}\n {{{content.left}}}
\n {{/if}}\n {{#if content.right}}\n {{{content.right}}}
\n {{/if}}\n \n {{#ifCond options.position '==' 'bottom'}}\n
\n {{content.more.title}}\n
\n {{/ifCond}}\n \n{{/this}}\n"); 62 | 63 | hbs.registerPartial('list_news', "{{#this}}\n
\n \n {{#if content.header.title}}\n
\n {{#if content.header.link}} \n \n

{{{content.header.title}}}

\n {{#ifCond content.header.morePosition '==' 'top'}}\n {{{content.header.moreText}}}\n {{/ifCond}}\n
\n {{else}} \n

{{{content.header.title}}}

\n {{/if}}\n
\n {{/if}}\n\n
\n \n
\n\n {{#ifCond content.header.morePosition '==' 'bottom'}}\n {{#if content.header.link}}\n
\n {{{content.header.moreText}}}\n
\n {{/if}}\n {{/ifCond}}\n
\n{{/this}}"); 64 | 65 | hbs.registerPartial('map', "{{#this}}\n
\n
\n
\n{{/this}}"); 66 | 67 | hbs.registerPartial('mechat', "{{#this}}\n
\n
\n
\n{{/this}}"); 68 | 69 | hbs.registerPartial('menu', "{{#this}}\n \n{{/this}}\n"); 70 | 71 | hbs.registerPartial('navbar', "{{#this}}\n
\n {{#if content}}\n \n {{/if}}\n
\n{{/this}}\n"); 72 | 73 | hbs.registerPartial('pagination', "{{#this}}\n \n{{/this}}"); 74 | 75 | hbs.registerPartial('paragraph', "{{#this}}\n
\n\n {{#if content}}\n {{{ content.content }}}\n {{/if}}\n
\n{{/this}}\n"); 76 | 77 | hbs.registerPartial('slider', "{{#this}}\n
\n \n
\n{{/this}}"); 78 | 79 | hbs.registerPartial('tabs', "{{#this}}\n
\n {{#if content}}\n \n
\n {{#each content}}\n
\n {{{content}}}\n
\n {{/each}}\n
\n {{/if}}\n
\n{{/this}}\n"); 80 | 81 | hbs.registerPartial('titlebar', "{{#this}}\n
\n {{#if content.title}}\n

\n {{#if content.link}}\n {{{content.title}}}\n {{else}}\n {{{content.title}}}\n {{/if}}\n

\n {{/if}}\n\n {{#if content.nav}}\n \n {{/if}}\n
\n{{/this}}"); 82 | 83 | }; 84 | 85 | if (typeof module !== 'undefined' && module.exports) { 86 | module.exports = registerAMUIPartials; 87 | } 88 | 89 | this.Handlebars && registerAMUIPartials(this.Handlebars); 90 | }).call(this); 91 | -------------------------------------------------------------------------------- /static/js/amazeui.widgets.helper.min.js: -------------------------------------------------------------------------------- 1 | /*! Amaze UI v2.1.0-beta1 ~ helper | by Amaze UI Team | (c) 2015 AllMobilize, Inc. | Licensed under MIT | 2015-01-04T05:01:12 UTC */ 2 | (function(){"use strict";var i=function(i){i.registerHelper("ifCond",function(i,n,t,a){switch(n){case"==":return i==t?a.fn(this):a.inverse(this);case"===":return i===t?a.fn(this):a.inverse(this);case"<":return t>i?a.fn(this):a.inverse(this);case"<=":return t>=i?a.fn(this):a.inverse(this);case">":return i>t?a.fn(this):a.inverse(this);case">=":return i>=t?a.fn(this):a.inverse(this);default:return a.inverse(this)}return a.inverse(this)})};"undefined"!=typeof module&&module.exports&&(module.exports=i),this.Handlebars&&i(this.Handlebars)}).call(this),function(){"use strict";var i=function(i){i.registerPartial("accordion",'{{#this}}\n
\n {{#each content}}\n
\n
\n {{{title}}}\n
\n
\n \n
\n {{{content}}}\n
\n
\n
\n {{/each}}\n
\n{{/this}}\n'),i.registerPartial("divider",'{{#this}}\n
\n{{/this}}\n'),i.registerPartial("duoshuo",'{{#this}}\n
\n
\n
\n
\n{{/this}}'),i.registerPartial("figure",'{{#this}}\n
\n {{#if content.link}}{{/if}}\n\n {{#if options.figcaptionPosition}}\n {{#ifCond options.figcaptionPosition \'==\' \'top\'}}\n {{#if content.figcaption}}\n
\n {{content.figcaption}}\n
\n {{/if}}\n {{/ifCond}}\n {{/if}}\n\n {{#if content.img}}\n {{#if content.imgAlt}}{{content.imgAlt}}{{else}}{{content.figcaption}}{{/if}}\n {{/if}}\n {{#if options.figcaptionPosition}}\n {{#ifCond options.figcaptionPosition \'==\' \'bottom\'}}\n {{#if content.figcaption}}\n
\n {{content.figcaption}}\n
\n {{/if}}\n {{/ifCond}}\n {{else}}\n {{#if content.figcaption}}\n
\n {{content.figcaption}}\n
\n {{/if}}\n {{/if}}\n\n {{#if content.link}}
{{/if}}\n
\n{{/this}}\n'),i.registerPartial("footer",'{{#this}}\n \n\n \n{{/this}}\n'),i.registerPartial("gallery",'{{#this}}\n \n{{/this}}\n'),i.registerPartial("gotop",'{{#this}}\n
\n \n {{#if content.title}}\n {{content.title}}\n {{/if}}\n {{#if content.customIcon}}\n \n {{else}}\n {{#if content.icon}}\n \n {{else}}\n \n {{/if}}\n {{/if}}\n \n
\n{{/this}}'),i.registerPartial("header",'{{#this}}\n
\n {{#if content.left}}\n
\n {{#each content.left}}\n \n {{#if title}}\n \n {{title}}\n \n {{/if}}\n\n {{# if customIcon}}\n \n {{else}}\n {{#if icon}}\n \n {{/if}}\n {{/if}}\n \n {{/each}}\n
\n {{/if}}\n\n {{#if content.title}}\n

\n {{#if content.link}}\n \n {{{content.title}}}\n \n {{else}}\n {{{content.title}}}\n {{/if}}\n

\n {{/if}}\n\n {{#if content.right}}\n
\n {{#each content.right}}\n \n {{#if title}}\n \n {{title}}\n \n {{/if}}\n\n {{# if customIcon}}\n \n {{else}}\n {{#if icon}}\n \n {{/if}}\n {{/if}}\n \n {{/each}}\n
\n {{/if}}\n
\n{{/this}}'),i.registerPartial("intro",'{{#this }}\n
\n {{#if content.title}}\n
\n

{{{content.title}}}

\n {{#if content.more.link}}\n {{#ifCond options.position \'==\' \'top\'}}\n {{content.more.title}}\n {{/ifCond}}\n {{/if}}\n
\n {{/if}}\n\n
\n {{#if content.left}}\n {{{content.left}}}
\n {{/if}}\n {{#if content.right}}\n {{{content.right}}}
\n {{/if}}\n \n {{#ifCond options.position \'==\' \'bottom\'}}\n
\n {{content.more.title}}\n
\n {{/ifCond}}\n \n{{/this}}\n'),i.registerPartial("list_news",'{{#this}}\n
\n \n {{#if content.header.title}}\n
\n {{#if content.header.link}} \n \n

{{{content.header.title}}}

\n {{#ifCond content.header.morePosition \'==\' \'top\'}}\n {{{content.header.moreText}}}\n {{/ifCond}}\n
\n {{else}} \n

{{{content.header.title}}}

\n {{/if}}\n
\n {{/if}}\n\n
\n \n
\n\n {{#ifCond content.header.morePosition \'==\' \'bottom\'}}\n {{#if content.header.link}}\n
\n {{{content.header.moreText}}}\n
\n {{/if}}\n {{/ifCond}}\n
\n{{/this}}'),i.registerPartial("map",'{{#this}}\n
\n
\n
\n{{/this}}'),i.registerPartial("mechat",'{{#this}}\n
\n
\n
\n{{/this}}'),i.registerPartial("menu",'{{#this}}\n \n{{/this}}\n'),i.registerPartial("navbar",'{{#this}}\n
\n {{#if content}}\n \n {{/if}}\n
\n{{/this}}\n'),i.registerPartial("pagination",'{{#this}}\n \n{{/this}}'),i.registerPartial("paragraph",'{{#this}}\n
\n\n {{#if content}}\n {{{ content.content }}}\n {{/if}}\n
\n{{/this}}\n'),i.registerPartial("slider",'{{#this}}\n
\n \n
\n{{/this}}'),i.registerPartial("tabs",'{{#this}}\n
\n {{#if content}}\n \n
\n {{#each content}}\n
\n {{{content}}}\n
\n {{/each}}\n
\n {{/if}}\n
\n{{/this}}\n'),i.registerPartial("titlebar",'{{#this}}\n
\n {{#if content.title}}\n

\n {{#if content.link}}\n {{{content.title}}}\n {{else}}\n {{{content.title}}}\n {{/if}}\n

\n {{/if}}\n\n {{#if content.nav}}\n \n {{/if}}\n
\n{{/this}}')};"undefined"!=typeof module&&module.exports&&(module.exports=i),this.Handlebars&&i(this.Handlebars)}.call(this); -------------------------------------------------------------------------------- /static/js/app.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 'use strict'; 3 | 4 | $(function() { 5 | var $fullText = $('.admin-fullText'); 6 | $('#admin-fullscreen').on('click', function() { 7 | $.AMUI.fullscreen.toggle(); 8 | }); 9 | 10 | $(document).on($.AMUI.fullscreen.raw.fullscreenchange, function() { 11 | $.AMUI.fullscreen.isFullscreen ? $fullText.text('关闭全屏') : $fullText.text('开启全屏'); 12 | }); 13 | }); 14 | })(jQuery); 15 | -------------------------------------------------------------------------------- /static/js/handlebars.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | 3 | handlebars v2.0.0 4 | 5 | Copyright (C) 2011-2014 by Yehuda Katz 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | 25 | @license 26 | */ 27 | !function(a,b){"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?module.exports=b():a.Handlebars=a.Handlebars||b()}(this,function(){var a=function(){"use strict";function a(a){this.string=a}var b;return a.prototype.toString=function(){return""+this.string},b=a}(),b=function(a){"use strict";function b(a){return i[a]}function c(a){for(var b=1;b":">",'"':""","'":"'","`":"`"},j=/[&<>"'`]/g,k=/[&<>"'`]/;g.extend=c;var l=Object.prototype.toString;g.toString=l;var m=function(a){return"function"==typeof a};m(/x/)&&(m=function(a){return"function"==typeof a&&"[object Function]"===l.call(a)});var m;g.isFunction=m;var n=Array.isArray||function(a){return a&&"object"==typeof a?"[object Array]"===l.call(a):!1};return g.isArray=n,g.escapeExpression=d,g.isEmpty=e,g.appendContextPath=f,g}(a),c=function(){"use strict";function a(a,b){var d;b&&b.firstLine&&(d=b.firstLine,a+=" - "+d+":"+b.firstColumn);for(var e=Error.prototype.constructor.call(this,a),f=0;f0?(c.ids&&(c.ids=[c.name]),a.helpers.each(b,c)):d(this);if(c.data&&c.ids){var g=q(c.data);g.contextPath=f.appendContextPath(c.data.contextPath,c.name),c={data:g}}return e(b,c)}),a.registerHelper("each",function(a,b){if(!b)throw new g("Must pass iterator to #each");var c,d,e=b.fn,h=b.inverse,i=0,j="";if(b.data&&b.ids&&(d=f.appendContextPath(b.data.contextPath,b.ids[0])+"."),l(a)&&(a=a.call(this)),b.data&&(c=q(b.data)),a&&"object"==typeof a)if(k(a))for(var m=a.length;m>i;i++)c&&(c.index=i,c.first=0===i,c.last=i===a.length-1,d&&(c.contextPath=d+i)),j+=e(a[i],{data:c});else for(var n in a)a.hasOwnProperty(n)&&(c&&(c.key=n,c.index=i,c.first=0===i,d&&(c.contextPath=d+n)),j+=e(a[n],{data:c}),i++);return 0===i&&(j=h(this)),j}),a.registerHelper("if",function(a,b){return l(a)&&(a=a.call(this)),!b.hash.includeZero&&!a||f.isEmpty(a)?b.inverse(this):b.fn(this)}),a.registerHelper("unless",function(b,c){return a.helpers["if"].call(this,b,{fn:c.inverse,inverse:c.fn,hash:c.hash})}),a.registerHelper("with",function(a,b){l(a)&&(a=a.call(this));var c=b.fn;if(f.isEmpty(a))return b.inverse(this);if(b.data&&b.ids){var d=q(b.data);d.contextPath=f.appendContextPath(b.data.contextPath,b.ids[0]),b={data:d}}return c(a,b)}),a.registerHelper("log",function(b,c){var d=c.data&&null!=c.data.level?parseInt(c.data.level,10):1;a.log(d,b)}),a.registerHelper("lookup",function(a,b){return a&&a[b]})}var e={},f=a,g=b,h="2.0.0";e.VERSION=h;var i=6;e.COMPILER_REVISION=i;var j={1:"<= 1.0.rc.2",2:"== 1.0.0-rc.3",3:"== 1.0.0-rc.4",4:"== 1.x.x",5:"== 2.0.0-alpha.x",6:">= 2.0.0-beta.1"};e.REVISION_CHANGES=j;var k=f.isArray,l=f.isFunction,m=f.toString,n="[object Object]";e.HandlebarsEnvironment=c,c.prototype={constructor:c,logger:o,log:p,registerHelper:function(a,b){if(m.call(a)===n){if(b)throw new g("Arg not supported with multiple helpers");f.extend(this.helpers,a)}else this.helpers[a]=b},unregisterHelper:function(a){delete this.helpers[a]},registerPartial:function(a,b){m.call(a)===n?f.extend(this.partials,a):this.partials[a]=b},unregisterPartial:function(a){delete this.partials[a]}};var o={methodMap:{0:"debug",1:"info",2:"warn",3:"error"},DEBUG:0,INFO:1,WARN:2,ERROR:3,level:3,log:function(a,b){if(o.level<=a){var c=o.methodMap[a];"undefined"!=typeof console&&console[c]&&console[c].call(console,b)}}};e.logger=o;var p=o.log;e.log=p;var q=function(a){var b=f.extend({},a);return b._parent=a,b};return e.createFrame=q,e}(b,c),e=function(a,b,c){"use strict";function d(a){var b=a&&a[0]||1,c=m;if(b!==c){if(c>b){var d=n[c],e=n[b];throw new l("Template was precompiled with an older version of Handlebars than the current runtime. Please update your precompiler to a newer version ("+d+") or downgrade your runtime to an older version ("+e+").")}throw new l("Template was precompiled with a newer version of Handlebars than the current runtime. Please update your runtime to a newer version ("+a[1]+").")}}function e(a,b){if(!b)throw new l("No environment passed to template");if(!a||!a.main)throw new l("Unknown template object: "+typeof a);b.VM.checkRevision(a.compiler);var c=function(c,d,e,f,g,h,i,j,m){g&&(f=k.extend({},f,g));var n=b.VM.invokePartial.call(this,c,e,f,h,i,j,m);if(null==n&&b.compile){var o={helpers:h,partials:i,data:j,depths:m};i[e]=b.compile(c,{data:void 0!==j,compat:a.compat},b),n=i[e](f,o)}if(null!=n){if(d){for(var p=n.split("\n"),q=0,r=p.length;r>q&&(p[q]||q+1!==r);q++)p[q]=d+p[q];n=p.join("\n")}return n}throw new l("The partial "+e+" could not be compiled when running in runtime-only mode")},d={lookup:function(a,b){for(var c=a.length,d=0;c>d;d++)if(a[d]&&null!=a[d][b])return a[d][b]},lambda:function(a,b){return"function"==typeof a?a.call(b):a},escapeExpression:k.escapeExpression,invokePartial:c,fn:function(b){return a[b]},programs:[],program:function(a,b,c){var d=this.programs[a],e=this.fn(a);return b||c?d=f(this,a,e,b,c):d||(d=this.programs[a]=f(this,a,e)),d},data:function(a,b){for(;a&&b--;)a=a._parent;return a},merge:function(a,b){var c=a||b;return a&&b&&a!==b&&(c=k.extend({},b,a)),c},noop:b.VM.noop,compilerInfo:a.compiler},e=function(b,c){c=c||{};var f=c.data;e._setup(c),!c.partial&&a.useData&&(f=i(b,f));var g;return a.useDepths&&(g=c.depths?[b].concat(c.depths):[b]),a.main.call(d,b,d.helpers,d.partials,f,g)};return e.isTop=!0,e._setup=function(c){c.partial?(d.helpers=c.helpers,d.partials=c.partials):(d.helpers=d.merge(c.helpers,b.helpers),a.usePartial&&(d.partials=d.merge(c.partials,b.partials)))},e._child=function(b,c,e){if(a.useDepths&&!e)throw new l("must pass parent depths");return f(d,b,a[b],c,e)},e}function f(a,b,c,d,e){var f=function(b,f){return f=f||{},c.call(a,b,a.helpers,a.partials,f.data||d,e&&[b].concat(e))};return f.program=b,f.depth=e?e.length:0,f}function g(a,b,c,d,e,f,g){var h={partial:!0,helpers:d,partials:e,data:f,depths:g};if(void 0===a)throw new l("The partial "+b+" could not be found");return a instanceof Function?a(c,h):void 0}function h(){return""}function i(a,b){return b&&"root"in b||(b=b?o(b):{},b.root=a),b}var j={},k=a,l=b,m=c.COMPILER_REVISION,n=c.REVISION_CHANGES,o=c.createFrame;return j.checkRevision=d,j.template=e,j.program=f,j.invokePartial=g,j.noop=h,j}(b,c,d),f=function(a,b,c,d,e){"use strict";var f,g=a,h=b,i=c,j=d,k=e,l=function(){var a=new g.HandlebarsEnvironment;return j.extend(a,g),a.SafeString=h,a.Exception=i,a.Utils=j,a.escapeExpression=j.escapeExpression,a.VM=k,a.template=function(b){return k.template(b,a)},a},m=l();return m.create=l,m["default"]=m,f=m}(d,a,c,b,e),g=function(a){"use strict";function b(a){a=a||{},this.firstLine=a.first_line,this.firstColumn=a.first_column,this.lastColumn=a.last_column,this.lastLine=a.last_line}var c,d=a,e={ProgramNode:function(a,c,d){b.call(this,d),this.type="program",this.statements=a,this.strip=c},MustacheNode:function(a,c,d,f,g){if(b.call(this,g),this.type="mustache",this.strip=f,null!=d&&d.charAt){var h=d.charAt(3)||d.charAt(2);this.escaped="{"!==h&&"&"!==h}else this.escaped=!!d;this.sexpr=a instanceof e.SexprNode?a:new e.SexprNode(a,c),this.id=this.sexpr.id,this.params=this.sexpr.params,this.hash=this.sexpr.hash,this.eligibleHelper=this.sexpr.eligibleHelper,this.isHelper=this.sexpr.isHelper},SexprNode:function(a,c,d){b.call(this,d),this.type="sexpr",this.hash=c;var e=this.id=a[0],f=this.params=a.slice(1);this.isHelper=!(!f.length&&!c),this.eligibleHelper=this.isHelper||e.isSimple},PartialNode:function(a,c,d,e,f){b.call(this,f),this.type="partial",this.partialName=a,this.context=c,this.hash=d,this.strip=e,this.strip.inlineStandalone=!0},BlockNode:function(a,c,d,e,f){b.call(this,f),this.type="block",this.mustache=a,this.program=c,this.inverse=d,this.strip=e,d&&!c&&(this.isInverse=!0)},RawBlockNode:function(a,c,f,g){if(b.call(this,g),a.sexpr.id.original!==f)throw new d(a.sexpr.id.original+" doesn't match "+f,this);c=new e.ContentNode(c,g),this.type="block",this.mustache=a,this.program=new e.ProgramNode([c],{},g)},ContentNode:function(a,c){b.call(this,c),this.type="content",this.original=this.string=a},HashNode:function(a,c){b.call(this,c),this.type="hash",this.pairs=a},IdNode:function(a,c){b.call(this,c),this.type="ID";for(var e="",f=[],g=0,h="",i=0,j=a.length;j>i;i++){var k=a[i].part;if(e+=(a[i].separator||"")+k,".."===k||"."===k||"this"===k){if(f.length>0)throw new d("Invalid path: "+e,this);".."===k?(g++,h+="../"):this.isScoped=!0}else f.push(k)}this.original=e,this.parts=f,this.string=f.join("."),this.depth=g,this.idName=h+this.string,this.isSimple=1===a.length&&!this.isScoped&&0===g,this.stringModeValue=this.string},PartialNameNode:function(a,c){b.call(this,c),this.type="PARTIAL_NAME",this.name=a.original},DataNode:function(a,c){b.call(this,c),this.type="DATA",this.id=a,this.stringModeValue=a.stringModeValue,this.idName="@"+a.stringModeValue},StringNode:function(a,c){b.call(this,c),this.type="STRING",this.original=this.string=this.stringModeValue=a},NumberNode:function(a,c){b.call(this,c),this.type="NUMBER",this.original=this.number=a,this.stringModeValue=Number(a)},BooleanNode:function(a,c){b.call(this,c),this.type="BOOLEAN",this.bool=a,this.stringModeValue="true"===a},CommentNode:function(a,c){b.call(this,c),this.type="comment",this.comment=a,this.strip={inlineStandalone:!0}}};return c=e}(c),h=function(){"use strict";var a,b=function(){function a(){this.yy={}}var b={trace:function(){},yy:{},symbols_:{error:2,root:3,program:4,EOF:5,program_repetition0:6,statement:7,mustache:8,block:9,rawBlock:10,partial:11,CONTENT:12,COMMENT:13,openRawBlock:14,END_RAW_BLOCK:15,OPEN_RAW_BLOCK:16,sexpr:17,CLOSE_RAW_BLOCK:18,openBlock:19,block_option0:20,closeBlock:21,openInverse:22,block_option1:23,OPEN_BLOCK:24,CLOSE:25,OPEN_INVERSE:26,inverseAndProgram:27,INVERSE:28,OPEN_ENDBLOCK:29,path:30,OPEN:31,OPEN_UNESCAPED:32,CLOSE_UNESCAPED:33,OPEN_PARTIAL:34,partialName:35,param:36,partial_option0:37,partial_option1:38,sexpr_repetition0:39,sexpr_option0:40,dataName:41,STRING:42,NUMBER:43,BOOLEAN:44,OPEN_SEXPR:45,CLOSE_SEXPR:46,hash:47,hash_repetition_plus0:48,hashSegment:49,ID:50,EQUALS:51,DATA:52,pathSegments:53,SEP:54,$accept:0,$end:1},terminals_:{2:"error",5:"EOF",12:"CONTENT",13:"COMMENT",15:"END_RAW_BLOCK",16:"OPEN_RAW_BLOCK",18:"CLOSE_RAW_BLOCK",24:"OPEN_BLOCK",25:"CLOSE",26:"OPEN_INVERSE",28:"INVERSE",29:"OPEN_ENDBLOCK",31:"OPEN",32:"OPEN_UNESCAPED",33:"CLOSE_UNESCAPED",34:"OPEN_PARTIAL",42:"STRING",43:"NUMBER",44:"BOOLEAN",45:"OPEN_SEXPR",46:"CLOSE_SEXPR",50:"ID",51:"EQUALS",52:"DATA",54:"SEP"},productions_:[0,[3,2],[4,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[10,3],[14,3],[9,4],[9,4],[19,3],[22,3],[27,2],[21,3],[8,3],[8,3],[11,5],[11,4],[17,3],[17,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,3],[47,1],[49,3],[35,1],[35,1],[35,1],[41,2],[30,1],[53,3],[53,1],[6,0],[6,2],[20,0],[20,1],[23,0],[23,1],[37,0],[37,1],[38,0],[38,1],[39,0],[39,2],[40,0],[40,1],[48,1],[48,2]],performAction:function(a,b,c,d,e,f){var g=f.length-1;switch(e){case 1:return d.prepareProgram(f[g-1].statements,!0),f[g-1];case 2:this.$=new d.ProgramNode(d.prepareProgram(f[g]),{},this._$);break;case 3:this.$=f[g];break;case 4:this.$=f[g];break;case 5:this.$=f[g];break;case 6:this.$=f[g];break;case 7:this.$=new d.ContentNode(f[g],this._$);break;case 8:this.$=new d.CommentNode(f[g],this._$);break;case 9:this.$=new d.RawBlockNode(f[g-2],f[g-1],f[g],this._$);break;case 10:this.$=new d.MustacheNode(f[g-1],null,"","",this._$);break;case 11:this.$=d.prepareBlock(f[g-3],f[g-2],f[g-1],f[g],!1,this._$);break;case 12:this.$=d.prepareBlock(f[g-3],f[g-2],f[g-1],f[g],!0,this._$);break;case 13:this.$=new d.MustacheNode(f[g-1],null,f[g-2],d.stripFlags(f[g-2],f[g]),this._$);break;case 14:this.$=new d.MustacheNode(f[g-1],null,f[g-2],d.stripFlags(f[g-2],f[g]),this._$);break;case 15:this.$={strip:d.stripFlags(f[g-1],f[g-1]),program:f[g]};break;case 16:this.$={path:f[g-1],strip:d.stripFlags(f[g-2],f[g])};break;case 17:this.$=new d.MustacheNode(f[g-1],null,f[g-2],d.stripFlags(f[g-2],f[g]),this._$);break;case 18:this.$=new d.MustacheNode(f[g-1],null,f[g-2],d.stripFlags(f[g-2],f[g]),this._$);break;case 19:this.$=new d.PartialNode(f[g-3],f[g-2],f[g-1],d.stripFlags(f[g-4],f[g]),this._$);break;case 20:this.$=new d.PartialNode(f[g-2],void 0,f[g-1],d.stripFlags(f[g-3],f[g]),this._$);break;case 21:this.$=new d.SexprNode([f[g-2]].concat(f[g-1]),f[g],this._$);break;case 22:this.$=new d.SexprNode([f[g]],null,this._$);break;case 23:this.$=f[g];break;case 24:this.$=new d.StringNode(f[g],this._$);break;case 25:this.$=new d.NumberNode(f[g],this._$);break;case 26:this.$=new d.BooleanNode(f[g],this._$);break;case 27:this.$=f[g];break;case 28:f[g-1].isHelper=!0,this.$=f[g-1];break;case 29:this.$=new d.HashNode(f[g],this._$);break;case 30:this.$=[f[g-2],f[g]];break;case 31:this.$=new d.PartialNameNode(f[g],this._$);break;case 32:this.$=new d.PartialNameNode(new d.StringNode(f[g],this._$),this._$);break;case 33:this.$=new d.PartialNameNode(new d.NumberNode(f[g],this._$));break;case 34:this.$=new d.DataNode(f[g],this._$);break;case 35:this.$=new d.IdNode(f[g],this._$);break;case 36:f[g-2].push({part:f[g],separator:f[g-1]}),this.$=f[g-2];break;case 37:this.$=[{part:f[g]}];break;case 38:this.$=[];break;case 39:f[g-1].push(f[g]);break;case 48:this.$=[];break;case 49:f[g-1].push(f[g]);break;case 52:this.$=[f[g]];break;case 53:f[g-1].push(f[g])}},table:[{3:1,4:2,5:[2,38],6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],31:[2,38],32:[2,38],34:[2,38]},{1:[3]},{5:[1,4]},{5:[2,2],7:5,8:6,9:7,10:8,11:9,12:[1,10],13:[1,11],14:16,16:[1,20],19:14,22:15,24:[1,18],26:[1,19],28:[2,2],29:[2,2],31:[1,12],32:[1,13],34:[1,17]},{1:[2,1]},{5:[2,39],12:[2,39],13:[2,39],16:[2,39],24:[2,39],26:[2,39],28:[2,39],29:[2,39],31:[2,39],32:[2,39],34:[2,39]},{5:[2,3],12:[2,3],13:[2,3],16:[2,3],24:[2,3],26:[2,3],28:[2,3],29:[2,3],31:[2,3],32:[2,3],34:[2,3]},{5:[2,4],12:[2,4],13:[2,4],16:[2,4],24:[2,4],26:[2,4],28:[2,4],29:[2,4],31:[2,4],32:[2,4],34:[2,4]},{5:[2,5],12:[2,5],13:[2,5],16:[2,5],24:[2,5],26:[2,5],28:[2,5],29:[2,5],31:[2,5],32:[2,5],34:[2,5]},{5:[2,6],12:[2,6],13:[2,6],16:[2,6],24:[2,6],26:[2,6],28:[2,6],29:[2,6],31:[2,6],32:[2,6],34:[2,6]},{5:[2,7],12:[2,7],13:[2,7],16:[2,7],24:[2,7],26:[2,7],28:[2,7],29:[2,7],31:[2,7],32:[2,7],34:[2,7]},{5:[2,8],12:[2,8],13:[2,8],16:[2,8],24:[2,8],26:[2,8],28:[2,8],29:[2,8],31:[2,8],32:[2,8],34:[2,8]},{17:21,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:27,30:22,41:23,50:[1,26],52:[1,25],53:24},{4:28,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{4:29,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{12:[1,30]},{30:32,35:31,42:[1,33],43:[1,34],50:[1,26],53:24},{17:35,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:36,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:37,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[1,38]},{18:[2,48],25:[2,48],33:[2,48],39:39,42:[2,48],43:[2,48],44:[2,48],45:[2,48],46:[2,48],50:[2,48],52:[2,48]},{18:[2,22],25:[2,22],33:[2,22],46:[2,22]},{18:[2,35],25:[2,35],33:[2,35],42:[2,35],43:[2,35],44:[2,35],45:[2,35],46:[2,35],50:[2,35],52:[2,35],54:[1,40]},{30:41,50:[1,26],53:24},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],52:[2,37],54:[2,37]},{33:[1,42]},{20:43,27:44,28:[1,45],29:[2,40]},{23:46,27:47,28:[1,45],29:[2,42]},{15:[1,48]},{25:[2,46],30:51,36:49,38:50,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],47:57,48:58,49:60,50:[1,59],52:[1,25],53:24},{25:[2,31],42:[2,31],43:[2,31],44:[2,31],45:[2,31],50:[2,31],52:[2,31]},{25:[2,32],42:[2,32],43:[2,32],44:[2,32],45:[2,32],50:[2,32],52:[2,32]},{25:[2,33],42:[2,33],43:[2,33],44:[2,33],45:[2,33],50:[2,33],52:[2,33]},{25:[1,61]},{25:[1,62]},{18:[1,63]},{5:[2,17],12:[2,17],13:[2,17],16:[2,17],24:[2,17],26:[2,17],28:[2,17],29:[2,17],31:[2,17],32:[2,17],34:[2,17]},{18:[2,50],25:[2,50],30:51,33:[2,50],36:65,40:64,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],46:[2,50],47:66,48:58,49:60,50:[1,59],52:[1,25],53:24},{50:[1,67]},{18:[2,34],25:[2,34],33:[2,34],42:[2,34],43:[2,34],44:[2,34],45:[2,34],46:[2,34],50:[2,34],52:[2,34]},{5:[2,18],12:[2,18],13:[2,18],16:[2,18],24:[2,18],26:[2,18],28:[2,18],29:[2,18],31:[2,18],32:[2,18],34:[2,18]},{21:68,29:[1,69]},{29:[2,41]},{4:70,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{21:71,29:[1,69]},{29:[2,43]},{5:[2,9],12:[2,9],13:[2,9],16:[2,9],24:[2,9],26:[2,9],28:[2,9],29:[2,9],31:[2,9],32:[2,9],34:[2,9]},{25:[2,44],37:72,47:73,48:58,49:60,50:[1,74]},{25:[1,75]},{18:[2,23],25:[2,23],33:[2,23],42:[2,23],43:[2,23],44:[2,23],45:[2,23],46:[2,23],50:[2,23],52:[2,23]},{18:[2,24],25:[2,24],33:[2,24],42:[2,24],43:[2,24],44:[2,24],45:[2,24],46:[2,24],50:[2,24],52:[2,24]},{18:[2,25],25:[2,25],33:[2,25],42:[2,25],43:[2,25],44:[2,25],45:[2,25],46:[2,25],50:[2,25],52:[2,25]},{18:[2,26],25:[2,26],33:[2,26],42:[2,26],43:[2,26],44:[2,26],45:[2,26],46:[2,26],50:[2,26],52:[2,26]},{18:[2,27],25:[2,27],33:[2,27],42:[2,27],43:[2,27],44:[2,27],45:[2,27],46:[2,27],50:[2,27],52:[2,27]},{17:76,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[2,47]},{18:[2,29],25:[2,29],33:[2,29],46:[2,29],49:77,50:[1,74]},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],51:[1,78],52:[2,37],54:[2,37]},{18:[2,52],25:[2,52],33:[2,52],46:[2,52],50:[2,52]},{12:[2,13],13:[2,13],16:[2,13],24:[2,13],26:[2,13],28:[2,13],29:[2,13],31:[2,13],32:[2,13],34:[2,13]},{12:[2,14],13:[2,14],16:[2,14],24:[2,14],26:[2,14],28:[2,14],29:[2,14],31:[2,14],32:[2,14],34:[2,14]},{12:[2,10]},{18:[2,21],25:[2,21],33:[2,21],46:[2,21]},{18:[2,49],25:[2,49],33:[2,49],42:[2,49],43:[2,49],44:[2,49],45:[2,49],46:[2,49],50:[2,49],52:[2,49]},{18:[2,51],25:[2,51],33:[2,51],46:[2,51]},{18:[2,36],25:[2,36],33:[2,36],42:[2,36],43:[2,36],44:[2,36],45:[2,36],46:[2,36],50:[2,36],52:[2,36],54:[2,36]},{5:[2,11],12:[2,11],13:[2,11],16:[2,11],24:[2,11],26:[2,11],28:[2,11],29:[2,11],31:[2,11],32:[2,11],34:[2,11]},{30:79,50:[1,26],53:24},{29:[2,15]},{5:[2,12],12:[2,12],13:[2,12],16:[2,12],24:[2,12],26:[2,12],28:[2,12],29:[2,12],31:[2,12],32:[2,12],34:[2,12]},{25:[1,80]},{25:[2,45]},{51:[1,78]},{5:[2,20],12:[2,20],13:[2,20],16:[2,20],24:[2,20],26:[2,20],28:[2,20],29:[2,20],31:[2,20],32:[2,20],34:[2,20]},{46:[1,81]},{18:[2,53],25:[2,53],33:[2,53],46:[2,53],50:[2,53]},{30:51,36:82,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],50:[1,26],52:[1,25],53:24},{25:[1,83]},{5:[2,19],12:[2,19],13:[2,19],16:[2,19],24:[2,19],26:[2,19],28:[2,19],29:[2,19],31:[2,19],32:[2,19],34:[2,19]},{18:[2,28],25:[2,28],33:[2,28],42:[2,28],43:[2,28],44:[2,28],45:[2,28],46:[2,28],50:[2,28],52:[2,28]},{18:[2,30],25:[2,30],33:[2,30],46:[2,30],50:[2,30]},{5:[2,16],12:[2,16],13:[2,16],16:[2,16],24:[2,16],26:[2,16],28:[2,16],29:[2,16],31:[2,16],32:[2,16],34:[2,16]}],defaultActions:{4:[2,1],44:[2,41],47:[2,43],57:[2,47],63:[2,10],70:[2,15],73:[2,45]},parseError:function(a){throw new Error(a)},parse:function(a){function b(){var a;return a=c.lexer.lex()||1,"number"!=typeof a&&(a=c.symbols_[a]||a),a}var c=this,d=[0],e=[null],f=[],g=this.table,h="",i=0,j=0,k=0;this.lexer.setInput(a),this.lexer.yy=this.yy,this.yy.lexer=this.lexer,this.yy.parser=this,"undefined"==typeof this.lexer.yylloc&&(this.lexer.yylloc={});var l=this.lexer.yylloc;f.push(l);var m=this.lexer.options&&this.lexer.options.ranges;"function"==typeof this.yy.parseError&&(this.parseError=this.yy.parseError);for(var n,o,p,q,r,s,t,u,v,w={};;){if(p=d[d.length-1],this.defaultActions[p]?q=this.defaultActions[p]:((null===n||"undefined"==typeof n)&&(n=b()),q=g[p]&&g[p][n]),"undefined"==typeof q||!q.length||!q[0]){var x="";if(!k){v=[];for(s in g[p])this.terminals_[s]&&s>2&&v.push("'"+this.terminals_[s]+"'");x=this.lexer.showPosition?"Parse error on line "+(i+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+v.join(", ")+", got '"+(this.terminals_[n]||n)+"'":"Parse error on line "+(i+1)+": Unexpected "+(1==n?"end of input":"'"+(this.terminals_[n]||n)+"'"),this.parseError(x,{text:this.lexer.match,token:this.terminals_[n]||n,line:this.lexer.yylineno,loc:l,expected:v})}}if(q[0]instanceof Array&&q.length>1)throw new Error("Parse Error: multiple actions possible at state: "+p+", token: "+n);switch(q[0]){case 1:d.push(n),e.push(this.lexer.yytext),f.push(this.lexer.yylloc),d.push(q[1]),n=null,o?(n=o,o=null):(j=this.lexer.yyleng,h=this.lexer.yytext,i=this.lexer.yylineno,l=this.lexer.yylloc,k>0&&k--);break;case 2:if(t=this.productions_[q[1]][1],w.$=e[e.length-t],w._$={first_line:f[f.length-(t||1)].first_line,last_line:f[f.length-1].last_line,first_column:f[f.length-(t||1)].first_column,last_column:f[f.length-1].last_column},m&&(w._$.range=[f[f.length-(t||1)].range[0],f[f.length-1].range[1]]),r=this.performAction.call(w,h,j,i,this.yy,q[1],e,f),"undefined"!=typeof r)return r;t&&(d=d.slice(0,-1*t*2),e=e.slice(0,-1*t),f=f.slice(0,-1*t)),d.push(this.productions_[q[1]][0]),e.push(w.$),f.push(w._$),u=g[d[d.length-2]][d[d.length-1]],d.push(u);break;case 3:return!0}}return!0}},c=function(){var a={EOF:1,parseError:function(a,b){if(!this.yy.parser)throw new Error(a);this.yy.parser.parseError(a,b)},setInput:function(a){return this._input=a,this._more=this._less=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var a=this._input[0];this.yytext+=a,this.yyleng++,this.offset++,this.match+=a,this.matched+=a;var b=a.match(/(?:\r\n?|\n).*/g);return b?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),a},unput:function(a){var b=a.length,c=a.split(/(?:\r\n?|\n)/g);this._input=a+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-b-1),this.offset-=b;var d=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),c.length-1&&(this.yylineno-=c.length-1);var e=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:c?(c.length===d.length?this.yylloc.first_column:0)+d[d.length-c.length].length-c[0].length:this.yylloc.first_column-b},this.options.ranges&&(this.yylloc.range=[e[0],e[0]+this.yyleng-b]),this},more:function(){return this._more=!0,this},less:function(a){this.unput(this.match.slice(a))},pastInput:function(){var a=this.matched.substr(0,this.matched.length-this.match.length);return(a.length>20?"...":"")+a.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var a=this.match;return a.length<20&&(a+=this._input.substr(0,20-a.length)),(a.substr(0,20)+(a.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var a=this.pastInput(),b=new Array(a.length+1).join("-");return a+this.upcomingInput()+"\n"+b+"^"},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var a,b,c,d,e;this._more||(this.yytext="",this.match="");for(var f=this._currentRules(),g=0;gb[0].length)||(b=c,d=g,this.options.flex));g++);return b?(e=b[0].match(/(?:\r\n?|\n).*/g),e&&(this.yylineno+=e.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:e?e[e.length-1].length-e[e.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+b[0].length},this.yytext+=b[0],this.match+=b[0],this.matches=b,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._input=this._input.slice(b[0].length),this.matched+=b[0],a=this.performAction.call(this,this.yy,this,f[d],this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a?a:void 0):""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var a=this.next();return"undefined"!=typeof a?a:this.lex()},begin:function(a){this.conditionStack.push(a)},popState:function(){return this.conditionStack.pop()},_currentRules:function(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function(a){this.begin(a)}};return a.options={},a.performAction=function(a,b,c,d){function e(a,c){return b.yytext=b.yytext.substr(a,b.yyleng-c)}switch(c){case 0:if("\\\\"===b.yytext.slice(-2)?(e(0,1),this.begin("mu")):"\\"===b.yytext.slice(-1)?(e(0,1),this.begin("emu")):this.begin("mu"),b.yytext)return 12;break;case 1:return 12;case 2:return this.popState(),12;case 3:return b.yytext=b.yytext.substr(5,b.yyleng-9),this.popState(),15;case 4:return 12;case 5:return e(0,4),this.popState(),13;case 6:return 45;case 7:return 46;case 8:return 16;case 9:return this.popState(),this.begin("raw"),18;case 10:return 34;case 11:return 24;case 12:return 29;case 13:return this.popState(),28;case 14:return this.popState(),28;case 15:return 26;case 16:return 26;case 17:return 32;case 18:return 31;case 19:this.popState(),this.begin("com");break;case 20:return e(3,5),this.popState(),13;case 21:return 31;case 22:return 51;case 23:return 50;case 24:return 50;case 25:return 54;case 26:break;case 27:return this.popState(),33;case 28:return this.popState(),25;case 29:return b.yytext=e(1,2).replace(/\\"/g,'"'),42;case 30:return b.yytext=e(1,2).replace(/\\'/g,"'"),42;case 31:return 52;case 32:return 44;case 33:return 44;case 34:return 43;case 35:return 50;case 36:return b.yytext=e(1,2),50;case 37:return"INVALID";case 38:return 5}},a.rules=[/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]*?(?=(\{\{\{\{\/)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/],a.conditions={mu:{rules:[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],inclusive:!1},emu:{rules:[2],inclusive:!1},com:{rules:[5],inclusive:!1},raw:{rules:[3,4],inclusive:!1},INITIAL:{rules:[0,1,38],inclusive:!0}},a}();return b.lexer=c,a.prototype=b,b.Parser=a,new a}();return a=b}(),i=function(a){"use strict";function b(a,b){return{left:"~"===a.charAt(2),right:"~"===b.charAt(b.length-3)}}function c(a,b,c,d,i,k){if(a.sexpr.id.original!==d.path.original)throw new j(a.sexpr.id.original+" doesn't match "+d.path.original,a);var l=c&&c.program,m={left:a.strip.left,right:d.strip.right,openStandalone:f(b.statements),closeStandalone:e((l||b).statements)};if(a.strip.right&&g(b.statements,null,!0),l){var n=c.strip;n.left&&h(b.statements,null,!0),n.right&&g(l.statements,null,!0),d.strip.left&&h(l.statements,null,!0),e(b.statements)&&f(l.statements)&&(h(b.statements),g(l.statements))}else d.strip.left&&h(b.statements,null,!0);return i?new this.BlockNode(a,l,b,m,k):new this.BlockNode(a,b,l,m,k)}function d(a,b){for(var c=0,d=a.length;d>c;c++){var i=a[c],j=i.strip;if(j){var k=e(a,c,b,"partial"===i.type),l=f(a,c,b),m=j.openStandalone&&k,n=j.closeStandalone&&l,o=j.inlineStandalone&&k&&l;j.right&&g(a,c,!0),j.left&&h(a,c,!0),o&&(g(a,c),h(a,c)&&"partial"===i.type&&(i.indent=/([ \t]+$)/.exec(a[c-1].original)?RegExp.$1:"")),m&&(g((i.program||i.inverse).statements),h(a,c)),n&&(g(a,c),h((i.inverse||i.program).statements))}}return a}function e(a,b,c){void 0===b&&(b=a.length);var d=a[b-1],e=a[b-2];return d?"content"===d.type?(e||!c?/\r?\n\s*?$/:/(^|\r?\n)\s*?$/).test(d.original):void 0:c}function f(a,b,c){void 0===b&&(b=-1);var d=a[b+1],e=a[b+2];return d?"content"===d.type?(e||!c?/^\s*?\r?\n/:/^\s*?(\r?\n|$)/).test(d.original):void 0:c}function g(a,b,c){var d=a[null==b?0:b+1];if(d&&"content"===d.type&&(c||!d.rightStripped)){var e=d.string;d.string=d.string.replace(c?/^\s+/:/^[ \t]*\r?\n?/,""),d.rightStripped=d.string!==e}}function h(a,b,c){var d=a[null==b?a.length-1:b-1];if(d&&"content"===d.type&&(c||!d.leftStripped)){var e=d.string;return d.string=d.string.replace(c?/\s+$/:/[ \t]+$/,""),d.leftStripped=d.string!==e,d.leftStripped}}var i={},j=a;return i.stripFlags=b,i.prepareBlock=c,i.prepareProgram=d,i}(c),j=function(a,b,c,d){"use strict";function e(a){return a.constructor===h.ProgramNode?a:(g.yy=k,g.parse(a))}var f={},g=a,h=b,i=c,j=d.extend;f.parser=g;var k={};return j(k,i,h),f.parse=e,f}(h,g,i,b),k=function(a,b){"use strict";function c(){}function d(a,b,c){if(null==a||"string"!=typeof a&&a.constructor!==c.AST.ProgramNode)throw new h("You must pass a string or Handlebars AST to Handlebars.precompile. You passed "+a);b=b||{},"data"in b||(b.data=!0),b.compat&&(b.useDepths=!0);var d=c.parse(a),e=(new c.Compiler).compile(d,b);return(new c.JavaScriptCompiler).compile(e,b)}function e(a,b,c){function d(){var d=c.parse(a),e=(new c.Compiler).compile(d,b),f=(new c.JavaScriptCompiler).compile(e,b,void 0,!0);return c.template(f)}if(null==a||"string"!=typeof a&&a.constructor!==c.AST.ProgramNode)throw new h("You must pass a string or Handlebars AST to Handlebars.compile. You passed "+a);b=b||{},"data"in b||(b.data=!0),b.compat&&(b.useDepths=!0);var e,f=function(a,b){return e||(e=d()),e.call(this,a,b)};return f._setup=function(a){return e||(e=d()),e._setup(a)},f._child=function(a,b,c){return e||(e=d()),e._child(a,b,c)},f}function f(a,b){if(a===b)return!0;if(i(a)&&i(b)&&a.length===b.length){for(var c=0;cc;c++){var d=this.opcodes[c],e=a.opcodes[c];if(d.opcode!==e.opcode||!f(d.args,e.args))return!1}for(b=this.children.length,c=0;b>c;c++)if(!this.children[c].equals(a.children[c]))return!1;return!0},guid:0,compile:function(a,b){this.opcodes=[],this.children=[],this.depths={list:[]},this.options=b,this.stringParams=b.stringParams,this.trackIds=b.trackIds;var c=this.options.knownHelpers;if(this.options.knownHelpers={helperMissing:!0,blockHelperMissing:!0,each:!0,"if":!0,unless:!0,"with":!0,log:!0,lookup:!0},c)for(var d in c)this.options.knownHelpers[d]=c[d];return this.accept(a)},accept:function(a){return this[a.type](a)},program:function(a){for(var b=a.statements,c=0,d=b.length;d>c;c++)this.accept(b[c]);return this.isSimple=1===d,this.depths.list=this.depths.list.sort(function(a,b){return a-b}),this},compileProgram:function(a){var b,c=(new this.compiler).compile(a,this.options),d=this.guid++; 28 | this.usePartial=this.usePartial||c.usePartial,this.children[d]=c;for(var e=0,f=c.depths.list.length;f>e;e++)b=c.depths.list[e],2>b||this.addDepth(b-1);return d},block:function(a){var b=a.mustache,c=a.program,d=a.inverse;c&&(c=this.compileProgram(c)),d&&(d=this.compileProgram(d));var e=b.sexpr,f=this.classifySexpr(e);"helper"===f?this.helperSexpr(e,c,d):"simple"===f?(this.simpleSexpr(e),this.opcode("pushProgram",c),this.opcode("pushProgram",d),this.opcode("emptyHash"),this.opcode("blockValue",e.id.original)):(this.ambiguousSexpr(e,c,d),this.opcode("pushProgram",c),this.opcode("pushProgram",d),this.opcode("emptyHash"),this.opcode("ambiguousBlockValue")),this.opcode("append")},hash:function(a){var b,c,d=a.pairs;for(this.opcode("pushHash"),b=0,c=d.length;c>b;b++)this.pushParam(d[b][1]);for(;b--;)this.opcode("assignToHash",d[b][0]);this.opcode("popHash")},partial:function(a){var b=a.partialName;this.usePartial=!0,a.hash?this.accept(a.hash):this.opcode("push","undefined"),a.context?this.accept(a.context):(this.opcode("getContext",0),this.opcode("pushContext")),this.opcode("invokePartial",b.name,a.indent||""),this.opcode("append")},content:function(a){a.string&&this.opcode("appendContent",a.string)},mustache:function(a){this.sexpr(a.sexpr),a.escaped&&!this.options.noEscape?this.opcode("appendEscaped"):this.opcode("append")},ambiguousSexpr:function(a,b,c){var d=a.id,e=d.parts[0],f=null!=b||null!=c;this.opcode("getContext",d.depth),this.opcode("pushProgram",b),this.opcode("pushProgram",c),this.ID(d),this.opcode("invokeAmbiguous",e,f)},simpleSexpr:function(a){var b=a.id;"DATA"===b.type?this.DATA(b):b.parts.length?this.ID(b):(this.addDepth(b.depth),this.opcode("getContext",b.depth),this.opcode("pushContext")),this.opcode("resolvePossibleLambda")},helperSexpr:function(a,b,c){var d=this.setupFullMustacheParams(a,b,c),e=a.id,f=e.parts[0];if(this.options.knownHelpers[f])this.opcode("invokeKnownHelper",d.length,f);else{if(this.options.knownHelpersOnly)throw new h("You specified knownHelpersOnly, but used the unknown helper "+f,a);e.falsy=!0,this.ID(e),this.opcode("invokeHelper",d.length,e.original,e.isSimple)}},sexpr:function(a){var b=this.classifySexpr(a);"simple"===b?this.simpleSexpr(a):"helper"===b?this.helperSexpr(a):this.ambiguousSexpr(a)},ID:function(a){this.addDepth(a.depth),this.opcode("getContext",a.depth);var b=a.parts[0];b?this.opcode("lookupOnContext",a.parts,a.falsy,a.isScoped):this.opcode("pushContext")},DATA:function(a){this.options.data=!0,this.opcode("lookupData",a.id.depth,a.id.parts)},STRING:function(a){this.opcode("pushString",a.string)},NUMBER:function(a){this.opcode("pushLiteral",a.number)},BOOLEAN:function(a){this.opcode("pushLiteral",a.bool)},comment:function(){},opcode:function(a){this.opcodes.push({opcode:a,args:j.call(arguments,1)})},addDepth:function(a){0!==a&&(this.depths[a]||(this.depths[a]=!0,this.depths.list.push(a)))},classifySexpr:function(a){var b=a.isHelper,c=a.eligibleHelper,d=this.options;if(c&&!b){var e=a.id.parts[0];d.knownHelpers[e]?b=!0:d.knownHelpersOnly&&(c=!1)}return b?"helper":c?"ambiguous":"simple"},pushParams:function(a){for(var b=0,c=a.length;c>b;b++)this.pushParam(a[b])},pushParam:function(a){this.stringParams?(a.depth&&this.addDepth(a.depth),this.opcode("getContext",a.depth||0),this.opcode("pushStringParam",a.stringModeValue,a.type),"sexpr"===a.type&&this.sexpr(a)):(this.trackIds&&this.opcode("pushId",a.type,a.idName||a.stringModeValue),this.accept(a))},setupFullMustacheParams:function(a,b,c){var d=a.params;return this.pushParams(d),this.opcode("pushProgram",b),this.opcode("pushProgram",c),a.hash?this.hash(a.hash):this.opcode("emptyHash"),d}},g.precompile=d,g.compile=e,g}(c,b),l=function(a,b){"use strict";function c(a){this.value=a}function d(){}var e,f=a.COMPILER_REVISION,g=a.REVISION_CHANGES,h=b;d.prototype={nameLookup:function(a,b){return d.isValidJavaScriptVariableName(b)?a+"."+b:a+"['"+b+"']"},depthedLookup:function(a){return this.aliases.lookup="this.lookup",'lookup(depths, "'+a+'")'},compilerInfo:function(){var a=f,b=g[a];return[a,b]},appendToBuffer:function(a){return this.environment.isSimple?"return "+a+";":{appendToBuffer:!0,content:a,toString:function(){return"buffer += "+a+";"}}},initializeBuffer:function(){return this.quotedString("")},namespace:"Handlebars",compile:function(a,b,c,d){this.environment=a,this.options=b,this.stringParams=this.options.stringParams,this.trackIds=this.options.trackIds,this.precompile=!d,this.name=this.environment.name,this.isChild=!!c,this.context=c||{programs:[],environments:[]},this.preamble(),this.stackSlot=0,this.stackVars=[],this.aliases={},this.registers={list:[]},this.hashes=[],this.compileStack=[],this.inlineStack=[],this.compileChildren(a,b),this.useDepths=this.useDepths||a.depths.list.length||this.options.compat;var e,f,g,i=a.opcodes;for(f=0,g=i.length;g>f;f++)e=i[f],this[e.opcode].apply(this,e.args);if(this.pushSource(""),this.stackSlot||this.inlineStack.length||this.compileStack.length)throw new h("Compile completed with content left on stack");var j=this.createFunctionContext(d);if(this.isChild)return j;var k={compiler:this.compilerInfo(),main:j},l=this.context.programs;for(f=0,g=l.length;g>f;f++)l[f]&&(k[f]=l[f]);return this.environment.usePartial&&(k.usePartial=!0),this.options.data&&(k.useData=!0),this.useDepths&&(k.useDepths=!0),this.options.compat&&(k.compat=!0),d||(k.compiler=JSON.stringify(k.compiler),k=this.objectLiteral(k)),k},preamble:function(){this.lastContext=0,this.source=[]},createFunctionContext:function(a){var b="",c=this.stackVars.concat(this.registers.list);c.length>0&&(b+=", "+c.join(", "));for(var d in this.aliases)this.aliases.hasOwnProperty(d)&&(b+=", "+d+"="+this.aliases[d]);var e=["depth0","helpers","partials","data"];this.useDepths&&e.push("depths");var f=this.mergeSource(b);return a?(e.push(f),Function.apply(this,e)):"function("+e.join(",")+") {\n "+f+"}"},mergeSource:function(a){for(var b,c,d="",e=!this.forceBuffer,f=0,g=this.source.length;g>f;f++){var h=this.source[f];h.appendToBuffer?b=b?b+"\n + "+h.content:h.content:(b&&(d?d+="buffer += "+b+";\n ":(c=!0,d=b+";\n "),b=void 0),d+=h+"\n ",this.environment.isSimple||(e=!1))}return e?(b||!d)&&(d+="return "+(b||'""')+";\n"):(a+=", buffer = "+(c?"":this.initializeBuffer()),d+=b?"return buffer + "+b+";\n":"return buffer;\n"),a&&(d="var "+a.substring(2)+(c?"":";\n ")+d),d},blockValue:function(a){this.aliases.blockHelperMissing="helpers.blockHelperMissing";var b=[this.contextName(0)];this.setupParams(a,0,b);var c=this.popStack();b.splice(1,0,c),this.push("blockHelperMissing.call("+b.join(", ")+")")},ambiguousBlockValue:function(){this.aliases.blockHelperMissing="helpers.blockHelperMissing";var a=[this.contextName(0)];this.setupParams("",0,a,!0),this.flushInline();var b=this.topStack();a.splice(1,0,b),this.pushSource("if (!"+this.lastHelper+") { "+b+" = blockHelperMissing.call("+a.join(", ")+"); }")},appendContent:function(a){this.pendingContent&&(a=this.pendingContent+a),this.pendingContent=a},append:function(){this.flushInline();var a=this.popStack();this.pushSource("if ("+a+" != null) { "+this.appendToBuffer(a)+" }"),this.environment.isSimple&&this.pushSource("else { "+this.appendToBuffer("''")+" }")},appendEscaped:function(){this.aliases.escapeExpression="this.escapeExpression",this.pushSource(this.appendToBuffer("escapeExpression("+this.popStack()+")"))},getContext:function(a){this.lastContext=a},pushContext:function(){this.pushStackLiteral(this.contextName(this.lastContext))},lookupOnContext:function(a,b,c){var d=0,e=a.length;for(c||!this.options.compat||this.lastContext?this.pushContext():this.push(this.depthedLookup(a[d++]));e>d;d++)this.replaceStack(function(c){var e=this.nameLookup(c,a[d],"context");return b?" && "+e:" != null ? "+e+" : "+c})},lookupData:function(a,b){a?this.pushStackLiteral("this.data(data, "+a+")"):this.pushStackLiteral("data");for(var c=b.length,d=0;c>d;d++)this.replaceStack(function(a){return" && "+this.nameLookup(a,b[d],"data")})},resolvePossibleLambda:function(){this.aliases.lambda="this.lambda",this.push("lambda("+this.popStack()+", "+this.contextName(0)+")")},pushStringParam:function(a,b){this.pushContext(),this.pushString(b),"sexpr"!==b&&("string"==typeof a?this.pushString(a):this.pushStackLiteral(a))},emptyHash:function(){this.pushStackLiteral("{}"),this.trackIds&&this.push("{}"),this.stringParams&&(this.push("{}"),this.push("{}"))},pushHash:function(){this.hash&&this.hashes.push(this.hash),this.hash={values:[],types:[],contexts:[],ids:[]}},popHash:function(){var a=this.hash;this.hash=this.hashes.pop(),this.trackIds&&this.push("{"+a.ids.join(",")+"}"),this.stringParams&&(this.push("{"+a.contexts.join(",")+"}"),this.push("{"+a.types.join(",")+"}")),this.push("{\n "+a.values.join(",\n ")+"\n }")},pushString:function(a){this.pushStackLiteral(this.quotedString(a))},push:function(a){return this.inlineStack.push(a),a},pushLiteral:function(a){this.pushStackLiteral(a)},pushProgram:function(a){null!=a?this.pushStackLiteral(this.programExpression(a)):this.pushStackLiteral(null)},invokeHelper:function(a,b,c){this.aliases.helperMissing="helpers.helperMissing";var d=this.popStack(),e=this.setupHelper(a,b),f=(c?e.name+" || ":"")+d+" || helperMissing";this.push("(("+f+").call("+e.callParams+"))")},invokeKnownHelper:function(a,b){var c=this.setupHelper(a,b);this.push(c.name+".call("+c.callParams+")")},invokeAmbiguous:function(a,b){this.aliases.functionType='"function"',this.aliases.helperMissing="helpers.helperMissing",this.useRegister("helper");var c=this.popStack();this.emptyHash();var d=this.setupHelper(0,a,b),e=this.lastHelper=this.nameLookup("helpers",a,"helper");this.push("((helper = (helper = "+e+" || "+c+") != null ? helper : helperMissing"+(d.paramsInit?"),("+d.paramsInit:"")+"),(typeof helper === functionType ? helper.call("+d.callParams+") : helper))")},invokePartial:function(a,b){var c=[this.nameLookup("partials",a,"partial"),"'"+b+"'","'"+a+"'",this.popStack(),this.popStack(),"helpers","partials"];this.options.data?c.push("data"):this.options.compat&&c.push("undefined"),this.options.compat&&c.push("depths"),this.push("this.invokePartial("+c.join(", ")+")")},assignToHash:function(a){var b,c,d,e=this.popStack();this.trackIds&&(d=this.popStack()),this.stringParams&&(c=this.popStack(),b=this.popStack());var f=this.hash;b&&f.contexts.push("'"+a+"': "+b),c&&f.types.push("'"+a+"': "+c),d&&f.ids.push("'"+a+"': "+d),f.values.push("'"+a+"': ("+e+")")},pushId:function(a,b){"ID"===a||"DATA"===a?this.pushString(b):"sexpr"===a?this.pushStackLiteral("true"):this.pushStackLiteral("null")},compiler:d,compileChildren:function(a,b){for(var c,d,e=a.children,f=0,g=e.length;g>f;f++){c=e[f],d=new this.compiler;var h=this.matchExistingProgram(c);null==h?(this.context.programs.push(""),h=this.context.programs.length,c.index=h,c.name="program"+h,this.context.programs[h]=d.compile(c,b,this.context,!this.precompile),this.context.environments[h]=c,this.useDepths=this.useDepths||d.useDepths):(c.index=h,c.name="program"+h)}},matchExistingProgram:function(a){for(var b=0,c=this.context.environments.length;c>b;b++){var d=this.context.environments[b];if(d&&d.equals(a))return b}},programExpression:function(a){var b=this.environment.children[a],c=(b.depths.list,this.useDepths),d=[b.index,"data"];return c&&d.push("depths"),"this.program("+d.join(", ")+")"},useRegister:function(a){this.registers[a]||(this.registers[a]=!0,this.registers.list.push(a))},pushStackLiteral:function(a){return this.push(new c(a))},pushSource:function(a){this.pendingContent&&(this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent))),this.pendingContent=void 0),a&&this.source.push(a)},pushStack:function(a){this.flushInline();var b=this.incrStack();return this.pushSource(b+" = "+a+";"),this.compileStack.push(b),b},replaceStack:function(a){{var b,d,e,f="";this.isInline()}if(!this.isInline())throw new h("replaceStack on non-inline");var g=this.popStack(!0);if(g instanceof c)f=b=g.value,e=!0;else{d=!this.stackSlot;var i=d?this.incrStack():this.topStackName();f="("+this.push(i)+" = "+g+")",b=this.topStack()}var j=a.call(this,b);e||this.popStack(),d&&this.stackSlot--,this.push("("+f+j+")")},incrStack:function(){return this.stackSlot++,this.stackSlot>this.stackVars.length&&this.stackVars.push("stack"+this.stackSlot),this.topStackName()},topStackName:function(){return"stack"+this.stackSlot},flushInline:function(){var a=this.inlineStack;if(a.length){this.inlineStack=[];for(var b=0,d=a.length;d>b;b++){var e=a[b];e instanceof c?this.compileStack.push(e):this.pushStack(e)}}},isInline:function(){return this.inlineStack.length},popStack:function(a){var b=this.isInline(),d=(b?this.inlineStack:this.compileStack).pop();if(!a&&d instanceof c)return d.value;if(!b){if(!this.stackSlot)throw new h("Invalid stack pop");this.stackSlot--}return d},topStack:function(){var a=this.isInline()?this.inlineStack:this.compileStack,b=a[a.length-1];return b instanceof c?b.value:b},contextName:function(a){return this.useDepths&&a?"depths["+a+"]":"depth"+a},quotedString:function(a){return'"'+a.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")+'"'},objectLiteral:function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(this.quotedString(c)+":"+a[c]);return"{"+b.join(",")+"}"},setupHelper:function(a,b,c){var d=[],e=this.setupParams(b,a,d,c),f=this.nameLookup("helpers",b,"helper");return{params:d,paramsInit:e,name:f,callParams:[this.contextName(0)].concat(d).join(", ")}},setupOptions:function(a,b,c){var d,e,f,g={},h=[],i=[],j=[];g.name=this.quotedString(a),g.hash=this.popStack(),this.trackIds&&(g.hashIds=this.popStack()),this.stringParams&&(g.hashTypes=this.popStack(),g.hashContexts=this.popStack()),e=this.popStack(),f=this.popStack(),(f||e)&&(f||(f="this.noop"),e||(e="this.noop"),g.fn=f,g.inverse=e);for(var k=b;k--;)d=this.popStack(),c[k]=d,this.trackIds&&(j[k]=this.popStack()),this.stringParams&&(i[k]=this.popStack(),h[k]=this.popStack());return this.trackIds&&(g.ids="["+j.join(",")+"]"),this.stringParams&&(g.types="["+i.join(",")+"]",g.contexts="["+h.join(",")+"]"),this.options.data&&(g.data="data"),g},setupParams:function(a,b,c,d){var e=this.objectLiteral(this.setupOptions(a,b,c));return d?(this.useRegister("options"),c.push("options"),"options="+e):(c.push(e),"")}};for(var i="break else new var case finally return void catch for switch while continue function this with default if throw delete in try do instanceof typeof abstract enum int short boolean export interface static byte extends long super char final native synchronized class float package throws const goto private transient debugger implements protected volatile double import public let yield".split(" "),j=d.RESERVED_WORDS={},k=0,l=i.length;l>k;k++)j[i[k]]=!0;return d.isValidJavaScriptVariableName=function(a){return!d.RESERVED_WORDS[a]&&/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(a)},e=d}(d,c),m=function(a,b,c,d,e){"use strict";var f,g=a,h=b,i=c.parser,j=c.parse,k=d.Compiler,l=d.compile,m=d.precompile,n=e,o=g.create,p=function(){var a=o();return a.compile=function(b,c){return l(b,c,a)},a.precompile=function(b,c){return m(b,c,a)},a.AST=h,a.Compiler=k,a.JavaScriptCompiler=n,a.Parser=i,a.parse=j,a};return g=p(),g.create=p,g["default"]=g,f=g}(f,g,j,k,l);return m}); -------------------------------------------------------------------------------- /static/js/polyfill/rem.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module: rem - v1.3.2 3 | * Description: A polyfill to parse CSS links and rewrite pixel equivalents into head for non supporting browsers 4 | * Date Built: 2014-07-02 5 | * Copyright (c) 2014 | Chuck Carpenter ,Lucas Serven ; 6 | **/ 7 | !function(a){"use strict";var b=function(){var a=document.createElement("div");return a.style.cssText="font-size: 1rem;",/rem/.test(a.style.fontSize)},c=function(){for(var a=document.getElementsByTagName("link"),b=[],c=0;c0?(r=[],q=[],n=[],d()):g()}},f=function(a,b){for(var c,d=k(a).replace(/\/\*[\s\S]*?\*\//g,""),e=/[\w\d\s\-\/\\\[\]:,.'"*()<>+~%#^$_=|@]+\{[\w\d\s\-\/\\%#:!;,.'"*()]+\d*\.?\d+rem[\w\d\s\-\/\\%#:!;,.'"*()]*\}/g,f=d.match(e),g=/\d*\.?\d+rem/g,h=d.match(g),i=/(.*\/)/,j=i.exec(b)[0],l=/@import (?:url\()?['"]?([^'\)"]*)['"]?\)?[^;]*/gm;null!==(c=l.exec(a));)n.push(j+c[1]);null!==f&&0!==f.length&&(o=o.concat(f),p=p.concat(h))},g=function(){for(var a=/[\w\d\s\-\/\\%#:,.'"*()]+\d*\.?\d+rem[\w\d\s\-\/\\%#:!,.'"*()]*[;}]/g,b=0;b #mq-test-1 { width: 42px; }',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){v(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},g=function(a){return a.replace(c.regex.minmaxwh,"").match(c.regex.other)};if(c.ajax=f,c.queue=d,c.unsupportedmq=g,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,comments:/\/\*[^*]*\*+([^/][^*]*\*+)*\//gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,maxw:/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,minmaxwh:/\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,other:/\([^\)]*\)/g},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var h,i,j,k=a.document,l=k.documentElement,m=[],n=[],o=[],p={},q=30,r=k.getElementsByTagName("head")[0]||l,s=k.getElementsByTagName("base")[0],t=r.getElementsByTagName("link"),u=function(){var a,b=k.createElement("div"),c=k.body,d=l.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=k.createElement("body"),c.style.background="none"),l.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&l.insertBefore(c,l.firstChild),a=b.offsetWidth,f?l.removeChild(c):c.removeChild(b),l.style.fontSize=d,e&&(c.style.fontSize=e),a=j=parseFloat(a)},v=function(b){var c="clientWidth",d=l[c],e="CSS1Compat"===k.compatMode&&d||k.body[c]||d,f={},g=t[t.length-1],p=(new Date).getTime();if(b&&h&&q>p-h)return a.clearTimeout(i),i=a.setTimeout(v,q),void 0;h=p;for(var s in m)if(m.hasOwnProperty(s)){var w=m[s],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?j||u():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?j||u():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(n[w.rules]))}for(var C in o)o.hasOwnProperty(C)&&o[C]&&o[C].parentNode===r&&r.removeChild(o[C]);o.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=k.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,r.insertBefore(E,g.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(k.createTextNode(F)),o.push(E)}},w=function(a,b,d){var e=a.replace(c.regex.comments,"").replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},i=!f&&d;b.length&&(b+="/"),i&&(f=1);for(var j=0;f>j;j++){var k,l,o,p;i?(k=d,n.push(h(a))):(k=e[j].match(c.regex.findStyles)&&RegExp.$1,n.push(RegExp.$2&&h(RegExp.$2))),o=k.split(","),p=o.length;for(var q=0;p>q;q++)l=o[q],g(l)||m.push({media:l.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:n.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}v()},x=function(){if(d.length){var b=d.shift();f(b.href,function(c){w(c,b.href,b.media),p[b.href]=!0,a.setTimeout(function(){x()},0)})}},y=function(){for(var b=0;b 3 |

© 2015 Gopher China组委会

4 | 5 | 6 | 13 | 14 | 15 | 16 | 17 | 18 | 31 | 32 | -------------------------------------------------------------------------------- /views/base/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{.Title}} 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |

20 | Gopher China 21 |

22 | 23 | 26 | 27 |
28 | 52 |
53 | 58 |
59 |
60 |
61 |
-------------------------------------------------------------------------------- /views/detail.tpl: -------------------------------------------------------------------------------- 1 | {{template "base/header.html" .}} 2 | 3 | 92 | 93 |
94 |
95 |
96 |
97 |
98 | {{str2html .Data}} 99 |
100 |
101 |
102 |
103 |
104 | 112 |
113 | 侧栏导航 114 |
115 |
116 | {{template "base/footer.html" .}} 117 | 141 | -------------------------------------------------------------------------------- /views/index.tpl: -------------------------------------------------------------------------------- 1 | {{template "base/header.html" .}} 2 | 3 |
4 |
5 |
6 | 7 |

Gopher China 2015 上海 大会 欢迎您!!

8 |

9 | 时间:2015年4月25-26日 地点:中国·上海市浦东软件大厦(浦软大厦) 10 |

11 | 12 |

13 | 上海市浦东新区博云路2号 14 |

15 |
16 |
17 |
18 | 19 |
20 |
21 |
22 |

23 |
24 |
25 | 26 |

27 | 28 | 会议日程 29 |

30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 |
日期时间日程安排
4月25日
周六
08:20-8:50入场报到
08:50-9:00大会介绍
09:00-10:00陈明达,厦门真有趣信息科技有限公司- Go 语言在游戏项目的应用情况汇报
10:05-11:05刘奇,豌豆莢- Go 在分布式系统开发中的应用
11:10-12:10许式伟,七牛- 七牛如何做HTTP服务测试
13:10-14:10马全一,DockerChina- 使用 Docker 构建企业持续集成服务
14:15-15:15周洋,奇虎360- Go 语言构建高并发分布式系统实践
15:30-16:30余军- 动态资源管理和容器技术在金融行业的架构探索和明天
16:35-17:35汪洋,华为- Go 语言在 NFV 场景下的应用研究
17:40-18:40郭峰,DaoCloud- Go 在持续交付中的实践
20:30-22:00Gopher酒会, 七牛
4月26日
周日
09:00-10:00Robert Griesemer- gofmt 的文化演变
10:05-11:05龚浩华,网宿科技- 基于Go实现的 P2P Cache服务器
11:10-12:10李四宝,杭州佑软科技- 在 P2P 网络构之上构建的应用生态----Leither
13:10-14:10雨痕- Go 1.4 runtime
14:15-15:15毛剑,猎豹移动- Go 在猎豹移动的应用
15:30-16:30夏彬,深之度- Go在深度桌面环境中的应用
16:35-17:35QLeelulu,广州舜飞- Go 在 RTB 实时竞价 DSP 广告系统中的应用
17:40-18:40张成远,京东- Docker 原理与应用实践
119 |
120 |
121 |

122 | 123 | 演讲嘉宾 124 |

125 |
126 |
127 | Robert Griesemer 128 |
Robert Griesemer
129 | Go 语言作者之一 130 |
131 |
132 |
133 |
134 | 许式伟 135 |
许式伟
136 | 七牛云存储CEO 137 |
138 |
139 |
140 |
141 | 马全一 142 |
马全一
143 | Dockercn创始人 144 |
145 |
146 |
147 |
148 | 陈明达 149 |
陈明达
150 | 厦门真有趣科技 151 |
152 |
153 |
154 |
155 | 周洋 156 |
周洋
157 | 奇虎360 158 |
159 |
160 |
161 |
162 | 刘奇 163 |
刘奇
164 | 豌豆荚 165 |
166 |
167 |
168 |
169 | 龚浩华 170 |
龚浩华
171 | 网宿科技 172 |
173 |
174 |
175 |
176 | QLeelulu 177 |
QLeelulu
178 | 广州舜飞 179 |
180 |
181 |
182 |
183 | 李四保 184 |
李四保
185 | 杭州佑软科技 186 |
187 |
188 |
189 |
190 | 余军 191 |
余军
192 | 上海富麦 193 |
194 |
195 |
196 |
197 | 雨痕 198 |
雨痕
199 | Go学习笔记 200 |
201 |
202 |
203 |
204 | 毛剑 205 |
毛剑
206 | 猎豹移动 207 |
208 |
209 |
210 |
211 | 汪洋 212 |
汪洋
213 | 华为 214 |
215 |
216 |
217 |
218 | 夏彬 219 |
夏彬
220 | 深之度 221 |
222 |
223 |
224 |
225 | 张成远 226 |
张成远
227 | 京东 228 |
229 |
230 |
231 |
232 | 郭峰 233 |
郭峰
234 | DaoCloud 235 |
236 |
237 |
238 | 239 | 240 |
241 |

242 | 243 | 赞助商 244 |

245 |
246 | 七牛 247 | 华为 248 | 京东 249 | 心动游戏 250 | coding 251 | DaoCloud 252 | DreamLab 253 | bearychat 254 | 图灵 255 | 博文 256 |
257 |
258 | 259 |
260 |

261 | 262 | 合作媒体 263 |

264 |
265 | oschina 266 | imooc 267 | techparty 268 | osforce 269 | fequan 270 | gitcafe 271 | segmentfault 272 | 273 |
274 |
275 |
276 |
277 |
278 |
279 | {{template "base/footer.html" .}} -------------------------------------------------------------------------------- /views/register.tpl: -------------------------------------------------------------------------------- 1 | {{template "base/header.html" .}} 2 | 9 |
10 |
11 |
12 |
13 |
14 |

15 | 大会报名 在线支付(支付宝) 获取电子门票报名成功 (门票不含发票) 持打印的电子门票现场签到(或凭彩信/短信) 领取大会入场券及礼品 (包午餐) 16 |

17 |
18 |
19 |
20 |
21 |
22 | 23 |
24 |
25 |
26 |
27 |
28 |
29 | 30 | {{template "base/footer.html" .}} 31 | -------------------------------------------------------------------------------- /views/speaker.tpl: -------------------------------------------------------------------------------- 1 | {{template "base/header.html" .}} 2 | 3 |
4 |
5 |
6 |

7 |

8 |
9 |
10 | Robert Griesemer 11 |
Robert Griesemer
12 | Go作者之一 13 |
14 |
15 |
16 |
17 | 许式伟 18 |
许式伟
19 | 七牛云存储CEO 20 |
21 |
22 |
23 |
24 | 马全一 25 |
马全一
26 | Dockercn创始人 27 |
28 |
29 |
30 |
31 | 陈明达 32 |
陈明达
33 | 厦门真有趣科技 34 |
35 |
36 |
37 |
38 | 周洋 39 |
周洋
40 | 奇虎360 41 |
42 |
43 |
44 |
45 | 刘奇 46 |
刘奇
47 | 豌豆荚 48 |
49 |
50 |
51 |
52 | 龚浩华 53 |
龚浩华
54 | 网宿科技 55 |
56 |
57 |
58 |
59 | QLeelulu 60 |
QLeelulu
61 | 广州舜飞 62 |
63 |
64 |
65 |
66 | 李四保 67 |
李四保
68 | 杭州佑软科技 69 |
70 |
71 |
72 |
73 | 余军 74 |
余军
75 | 上海富麦 76 |
77 |
78 |
79 |
80 | 雨痕 81 |
雨痕
82 | 雨痕 83 |
84 |
85 |
86 |
87 | 毛剑 88 |
毛剑
89 | 猎豹移动 90 |
91 |
92 |
93 |
94 | 汪洋 95 |
汪洋
96 | 华为 97 |
98 |
99 |
100 |
101 | 夏彬 102 |
夏彬
103 | 深之度 104 |
105 |
106 |
107 |
108 | 张成远 109 |
张成远
110 | 京东 111 |
112 |
113 |
114 |
115 | 郭峰 116 |
郭峰
117 | DaoCloud 118 |
119 |
120 |
121 |
122 |
123 | {{template "base/footer.html" .}} 124 | -------------------------------------------------------------------------------- /views/sponsors.tpl: -------------------------------------------------------------------------------- 1 | {{template "base/header.html" .}} 2 | {{template "base/footer.html" .}} 3 | -------------------------------------------------------------------------------- /views/venue.tpl: -------------------------------------------------------------------------------- 1 | {{template "base/header.html" .}} 2 | 9 |
10 |
11 |
12 |
13 |
14 |
15 | 16 |
17 |

浦软大厦

18 |
19 |
20 |
21 | 22 |
23 |
24 | 25 |
26 |

浦软大厦

27 |
28 |
29 |
30 |
31 |
32 | 33 |
34 |

地图位置

35 |
36 |
37 |
38 |

39 | 浦软大厦二层大会议厅 上海市浦东新区博云路2号 40 |

41 | 42 |
43 |
44 | 45 |
46 |

二楼会议室

47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | {{template "base/footer.html" .}} 55 | --------------------------------------------------------------------------------