commit 6bf84d8b541ce4ddb4d738979dccfaadb8346cc0 Author: Brian Buller Date: Sat Jan 27 11:58:40 2018 -0600 Initial Commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d08761a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Ignore the binary +songbook diff --git a/admin.go b/admin.go new file mode 100644 index 0000000..bb0366f --- /dev/null +++ b/admin.go @@ -0,0 +1,54 @@ +package main + +import ( + "fmt" + "net/http" + "strings" + + "github.com/gorilla/mux" +) + +func handleAdmin(w http.ResponseWriter, req *http.Request) { + page := initPageData(w, req) + w.Header().Set("Content-Type", "text/html; charset=utf-8") + vars := mux.Vars(req) + if !page.LoggedIn { + page.show("admin-login.html", w) + } else { + action := vars["action"] + switch action { + case "dologin": + handleAdminDoLogin(w, req) + case "dologout": + handleAdminDoLogout(w, req) + case "build": + default: + loadAndShowSongs(w, req, page) + } + + } +} + +func handleAdminDoLogin(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + username := req.FormValue("un") + password := req.FormValue("pw") + var success bool + if strings.TrimSpace(username) != "" && strings.TrimSpace(password) != "" { + } + page.session.setFlashMessage("Login Successful!", "success") + redirect("/admin", w, req) +} + +func handleAdminDoLogout(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + fmt.Fprint(w, "Admin Logout") +} + +func loadAndShowSongs(w http.ResponseWriter, req *http.Request, page *pageData) { + +} + +func buildSongbook(w http.ResponseWriter, req *http.Request, page *pageData) { + +} diff --git a/assets.go b/assets.go new file mode 100644 index 0000000..ab3f9de --- /dev/null +++ b/assets.go @@ -0,0 +1,1226 @@ +package main + +import ( + "bytes" + "compress/gzip" + "encoding/base64" + "io/ioutil" + "net/http" + "os" + "path" + "sync" + "time" +) + +type _escLocalFS struct{} + +var _escLocal _escLocalFS + +type _escStaticFS struct{} + +var _escStatic _escStaticFS + +type _escDirectory struct { + fs http.FileSystem + name string +} + +type _escFile struct { + compressed string + size int64 + modtime int64 + local string + isDir bool + + once sync.Once + data []byte + name string +} + +func (_escLocalFS) Open(name string) (http.File, error) { + f, present := _escData[path.Clean(name)] + if !present { + return nil, os.ErrNotExist + } + return os.Open(f.local) +} + +func (_escStaticFS) prepare(name string) (*_escFile, error) { + f, present := _escData[path.Clean(name)] + if !present { + return nil, os.ErrNotExist + } + var err error + f.once.Do(func() { + f.name = path.Base(name) + if f.size == 0 { + return + } + var gr *gzip.Reader + b64 := base64.NewDecoder(base64.StdEncoding, bytes.NewBufferString(f.compressed)) + gr, err = gzip.NewReader(b64) + if err != nil { + return + } + f.data, err = ioutil.ReadAll(gr) + }) + if err != nil { + return nil, err + } + return f, nil +} + +func (fs _escStaticFS) Open(name string) (http.File, error) { + f, err := fs.prepare(name) + if err != nil { + return nil, err + } + return f.File() +} + +func (dir _escDirectory) Open(name string) (http.File, error) { + return dir.fs.Open(dir.name + name) +} + +func (f *_escFile) File() (http.File, error) { + type httpFile struct { + *bytes.Reader + *_escFile + } + return &httpFile{ + Reader: bytes.NewReader(f.data), + _escFile: f, + }, nil +} + +func (f *_escFile) Close() error { + return nil +} + +func (f *_escFile) Readdir(count int) ([]os.FileInfo, error) { + return nil, nil +} + +func (f *_escFile) Stat() (os.FileInfo, error) { + return f, nil +} + +func (f *_escFile) Name() string { + return f.name +} + +func (f *_escFile) Size() int64 { + return f.size +} + +func (f *_escFile) Mode() os.FileMode { + return 0 +} + +func (f *_escFile) ModTime() time.Time { + return time.Unix(f.modtime, 0) +} + +func (f *_escFile) IsDir() bool { + return f.isDir +} + +func (f *_escFile) Sys() interface{} { + return f +} + +// FS returns a http.Filesystem for the embedded assets. If useLocal is true, +// the filesystem's contents are instead used. +func FS(useLocal bool) http.FileSystem { + if useLocal { + return _escLocal + } + return _escStatic +} + +// Dir returns a http.Filesystem for the embedded assets on a given prefix dir. +// If useLocal is true, the filesystem's contents are instead used. +func Dir(useLocal bool, name string) http.FileSystem { + if useLocal { + return _escDirectory{fs: _escLocal, name: name} + } + return _escDirectory{fs: _escStatic, name: name} +} + +// FSByte returns the named file from the embedded assets. If useLocal is +// true, the filesystem's contents are instead used. +func FSByte(useLocal bool, name string) ([]byte, error) { + if useLocal { + f, err := _escLocal.Open(name) + if err != nil { + return nil, err + } + b, err := ioutil.ReadAll(f) + f.Close() + return b, err + } + f, err := _escStatic.prepare(name) + if err != nil { + return nil, err + } + return f.data, nil +} + +// FSMustByte is the same as FSByte, but panics if name is not present. +func FSMustByte(useLocal bool, name string) []byte { + b, err := FSByte(useLocal, name) + if err != nil { + panic(err) + } + return b +} + +// FSString is the string version of FSByte. +func FSString(useLocal bool, name string) (string, error) { + b, err := FSByte(useLocal, name) + return string(b), err +} + +// FSMustString is the string version of FSMustByte. +func FSMustString(useLocal bool, name string) string { + return string(FSMustByte(useLocal, name)) +} + +var _escData = map[string]*_escFile{ + + "/songs/10000 Reasons.md": { + local: "songs/10000 Reasons.md", + size: 1042, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8RTzWoUQRC+11N8tyhE1HsQ9CAuBAQNBI9lpnam2Z6uoasnw769VT0bjPgAO7DsbnV/ +v93z8YM/+CFsWgxvvmQxQ5sE91qHt/TOH7pbqnyif5fwHfMZpmumv78etdqUFnxLhknzGYVnIfqZyoic +ToIiz1LxW45a5RXucJMztgv4l671NfrBFW0teNJZDOtyS4d2Y2An2zDw2T9bcYV93NIsaAoLzU7lwUbw +yKkQPU7cuoXZcQub3dLnMmB7GefkErs9uPa9NP/yQacLxm2S0jvw7SG6u6KrleP/b9xrTU8TUkHWZwGx +R7osWNYt6uAySqWODiDcw1iFGy57nVS4tpifUhmIvmoFu3BfG1WHEgHpgC359CSyQMtLLfTQW9HVgq72 +ywSPERl2Xrdw7LzXKiqOWcOkZ45LQ/0kA9qqlLFNEf3IKfc4ccAOGCpv5nJce0++u1+via2fu3tq0cbF +wF5NVLIXvVROJliLU/1X0tlJrbO2MBJRPNQcia7V0d37/p7/CQAA///Sg7ysEgQAAA== +`, + }, + + "/songs/All the Poor and Powerless.md": { + local: "songs/All the Poor and Powerless.md", + size: 543, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/7SRwU60QBCE7/MU/QJ//hfYmOxp92iiifE42S2c0aGbTPdIeHsbWFATPcqBQNXXU9Vw +LIUsge5FKkW++sOIWqAa/vkVDkPFXdioYaOGnTr6W7zZRdQWuwijTPuYpYx3KI3ZhYv08Bt32/Qby+hI +NHqWRrGCkvjw0wz/4u2py4ma+YWkWTi7hNJeY1qJEbfIOv3ob70TYjVdc+YMb2dg+0xJQh1QqPEo1dL0 +zUmtmudYIhbf1LsUdPbX/R+SK5QtnISEl6+ul4rYu0ZdlX7ZrJfGFjPrF8zgRzpksiJRFRoe55JnUFY6 +yTUc/i8//iMAAP//lVzd/B8CAAA= +`, + }, + + "/songs/Amazing Grace - My Chains are Gone.md": { + local: "songs/Amazing Grace - My Chains are Gone.md", + size: 861, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8yTwY4TMQyG73kK33rpwguskAqHthKcKKo4phPPJCITj+JMR+Xp+Z1lBXvgTk+t89v+ +/Ns9zP5nKhMdqx+YnujLgz5Fn4qSr0xHKeye8HHPS+UP7lU9mdqdZCPdmBu1yKSyluAu0TdSf+dAnrbK +bYiU0w+mmd2ZpKDJ5pWyaNvTbW1UUOS8m2ns6Ve83XIq4a9HUmbndhfL643RDk2aX6fYaH5QZF/xW2jE +F3co4bcMTxZRqpwTA6kTY5AhyaoUUnip9KL2y2LpF4wSZa3oO6aqjW6vyQ7eDH+8mcyb8+7OUHABZKOx +ghSqo4Af3b/6e5JKEeDVF5UZrsAHI+yeeBqzSKBTUsTr8ABpmoq6b4VLMKOz3HlP/o3tHfGz1NALL1Xm +pCg8WSWYgAZWbzOBmSMLdsPDWlndCe6nnC2uMXHGksCySG1JCuZwB1sNOtmK0sgEjJ74X81u644YwGMS +FYCHpCoZNL2y4mq6TteCs6o36M0YTAzqjzirzniNQgNKdC7cULVhsmx7dzWLbmy5WHylGXnv/hH9Lmt3 +5G30+X3/u/wKAAD//4TYMZFdAwAA +`, + }, + + "/songs/Angels We Have Heard on High.md": { + local: "songs/Angels We Have Heard on High.md", + size: 486, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/3yRQU/DMAyF7/kVvnEB8QcmEAzEJLjtsHO6PDUeaVw52Uov/HacFi5IUFWVGr9nf355 +yD1SoQNo5y/2gddAkmnHfXQ39rjNqLhz37oJFJsu/uhi0+0noKaZCufeXpIrKNUIGpPnXMwclt9Bzrm2 +E+JMijHN7vkYpVmszEonmeVcqFRdfO4lyaeydybHx9EAuNATSJzbR4wRGso1TXE2u1VO544TcO8OdmKN +fvejUSVJ7pvA14WoTz4UGUCVg2EU6mBFPkYjLCMr1j627gW5bbjY/+HaLs2EHlFjQsRA3pYvgNvxYKhS +QB1rjct4v6bacludPojNtFw75IBA79mc26hcVt430TXKjKkTzfTarH/zbG6X2/sKAAD//2dD+cLmAQAA +`, + }, + + "/songs/Be Thou My Vision.md": { + local: "songs/Be Thou My Vision.md", + size: 705, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/3RSQXITMRC86xXNXYQ7pDhwoOwiIVWJKzlrvWOvQCu5JK23dOMbfI+X0JJlyCV72pru +aXXPzBfBbgoL7guebbLBq/f81O0pymdFMFdwLjg3UCNMuAtxRDjU6iQmZvXdLMcpYxAY5yAusS1gFo1k +zlXC5ItOJe+64CDpUmWrxlAwmgLjR9YE3rKqVvPT+iNCRHIiJ/5rogX0lsTvpcq4xlTXGKy82DSGWTet +ay3HRfBC35/UFnKWiNXmibDIf14rVdd3jXjtPUah/6+GvqLGltyul4LvLOvZh3EV55rJKrl99UTwcqPU +o91PkgiwNMIHxvbMNhv/59fvBJlPuWYzNonur1sv2Ho+bLNh4NqwNnXjVlPSxwvtX4LgXdE42MjRVk99 +QVptOCV8a8M8YCPcCldJeMdsaYl9eKTS5lvcs93nEAtWnoG657K2YPd+6pyW4UcoSUM9YIh1L6+hp8W/ +U5tqp99OWH23h5UX0rYyyIEnpNVTtrykoW34uV/eAx4XRw67yblRtx/ajf4NAAD//0PP/l7BAgAA +`, + }, + + "/songs/Because He Lives (Maher).md": { + local: "songs/Because He Lives (Maher).md", + size: 851, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8STX0rDQBDG3/cU36NCxQsUwYLQQMUHTzDNTpro7kzZTRPy5jW8nidxNlSoxGcbyJ+d +P19+32yy4ZpOmbFl7LqBM26eqeV06+7scOtj4gdXYc+h44HRCfqW8aqyDKYus+BF+CJVQQdOtUZ2m2mu +OurICdpg22Xsg6p37jGyrFCurvr6+IygYCgrXCzcBWdZ519dO+4RJ2SVA970zKPCdqceYiQJLN6aljIV +RsrwTP7HyCHRwOd4Xfh5TmU7STxyS7GkW6bkEc3ehJpCKARSUqadNATrKmq5LyA00nRlo4tIZdiChmpr +16gp6fhH1ZNpTmjMLGzHDvayMrN30bHUtBp8LkihaxjOHppTf0rzR1F2uLWJ/avva454fT//Lt8BAAD/ +//qGNABTAwAA +`, + }, + + "/songs/Because He Lives.md": { + local: "songs/Because He Lives.md", + size: 1032, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/9STsW7cMBBEe37FprpGQfrYCBA3ORvukh+gxJXEhCKFXVIC/z5Dnm0YQX7AV+mo4ZvZ +IfXAky3KdGV69ger+Yyfud+Fv5kfyZFyzHT1SpriQHnlSpMNgR0Wt4GeWIveGeye7MaUE4V08EAr20A2 +OpqTLOB2ScCD66vO4wHisVTaKu1WHPDmeyTe9lxpEXswwRWG0rG7gEsG4p/28Ek6TD8Z826AvjTQI7JE +mu3UNm5JJJ3Df2SYgma20myWFBHxVfNIf2I6m3RNwfUQNJdchFtEB8Dcw51J8trfAunjMpinopnGf6wQ +8gqcnsy5jdKgZCnyOSaJNNqx3rgzc+i4XbzjXtTvVNEltQpR80PJqIZtZiHNPtzUOI+NrGoRGyf+an6t +yDatHi5vRRS8kWx9JGervo/4/JF6bLugiwSfNglCXmA/SdIbXiCUwfTV2S9r7iYXxZ+IG3ki5ulhtqOK +uzcchlBy6HW9NQ1dbSd1+ClfpL7wlPklJLhKaaYlJKmmH1RXvI77ke7m/Zf+rf8NAAD//8F07BkIBAAA +`, + }, + + "/songs/Behold Our God.md": { + local: "songs/Behold Our God.md", + size: 1236, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/7SUz27TQBDG7/MUkxMXEx6gFVJBNJUQ5IKEOG7ksXeRPYP2T43fnpmNWxUnEqhKckl2 +Z/b7fvvtKB/Iy9DivkTcSQtv9QO3vyK9hwfCkDB7wn6QOKN0dZGyi+nmRXWQR4pPVV9Gx+jJxQzwTTcK +By2n2h0YH/TLO25V4Sv9zpgFdW9skIUJpzAMZsAtwAImRzA767Ro57+4n5TyvOpo0JXspZKMc8oU57XI +ZqG25b1T3IhqVZddDKSu9y5k35XBuOw6urfFRUQxtwAGYDc2nSm0KpH1PsdkyN3ATkgNGDuJ9FirUUrv +kRSIg1LDd5c8tdZjWkmRqcGJ3kQNOrrAyW6QFOyfEeEFMsKLhPSXyOfA/VbPKkorExvWJKxRwZ0KHdaN +OiWxOrKgVL+FwPKbs7eml+MWOqpEQ+h9rjdxrPZ9YNbWWnqm2unkBimpqTNsvwA+PcuiO0jJ+ENKA3Rm +1yzPanyU8ciQiGrkSmGpH0jzPY30fx7m7joPg1d/mdc9jXLtfYOLZ/PkrXO+wb2HM4ibU5x1zHD7rv5z +/QkAAP//loKhKNQEAAA= +`, + }, + + "/songs/Better Is One Day.md": { + local: "songs/Better Is One Day.md", + size: 811, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/7yTwY7UMAyG734K3/ZSxAuskEAIqMSKy144ehu3iTaNR3HaqG+P3e4cgRPMYZo6f35/ +ttNP3BpXHBV/FMbPdMA7+8HjrfIH+CYds+ycD0yKP2WrGDrnnMqCt0wTDyARv0sN+DGvaYntgKcDVbZs +58qiSCUg71xwplSa4izVfQC+2CJyZVwPe1JtnkGpJZ0ThwF6ajGVK6exKJeJYUT11C9cmFrEFhk1UjBK +mS9pt32FfwnubXK0BUckfT2FI3Y7GVCZXwdo4osr6wvTZt7PgnMyocXQqnLwE+MSLVnqcQEa+9tEjFss +VaAD732Y7K/pHwRRNuW/GzxHcgYTG7wiZ+Xus/gPxT3dp+3Oc2aNONm2bG2AtxafBjntTvFVApwueks1 +tQfFTl6bS9drXjA+7AZN2jhcvP5ujGWASVa2JhgKLeRogqvfop5yxlCpo12k6mEf7e/i8Pj+/Bp+BQAA +//9O1fVlKwMAAA== +`, + }, + + "/songs/Blessed Be Your Name.md": { + local: "songs/Blessed Be Your Name.md", + size: 1085, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/+RUTYvbMBC961c89pLLlv6BpdCFHgz9uBSWHifWOBaRNUYfa/LvO+M4kIID7bk5KXqj +N++9kfwauRT2eGX8kpbxnSZ2H/TnXubMn9wNP254MrxLqCMjUvK6oIpQMEdONQwtureR81ZdamaaCmQA +HVvylHrGEGUBdokdPivlcQ9S1oTuMGEQJUK4SvBcOFdtTj27n6O004gOC8Wzwnn9a2VLiJ5zUtpHjb+8 +c75cO4d0MgSzodKq6w4xArXlhCP1yiyYM4XC2AQvpm2VQ/m8dumjFC6q8tl9lew1iKAcnQmJKHRx98Ha +SVNhMdnaTjg8UPrn/t8ePUXJQVrZ3O4yv91clJYOBWUMyaLwsiRIwn3FIjl6rXkitUPqs2q5tGiMT/8+ +2x9X1izkMWmEii+hjipkGDibiNtsq90tbTyTXoDtDshWtO/qP5us2TuFd8b6Numsi0VFPdj+dsHIpA9o +Vd+Pot4sBPNhDZ/35+VePq4fh98BAAD//8YBd/s9BAAA +`, + }, + + "/songs/Christ Is Risen.md": { + local: "songs/Christ Is Risen.md", + size: 937, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/6RT0YoUSwx9z1fkPt2XET9gFsVdWHdBXJAF2cea7nRXYXVlSFVPO2/+hr/nl3jSPeji +g4IODBTJSXJyTvomWqqN7yt/SFUKvcCPro4mr+idNC7KWoS7MI+xcSpc8TeZQip7ui819cItCuckrAMA +S7CeawyT0PXceEifWWdjOUvl+ahlRXemte6J3pSebUZM+S5NvERFqS7S82gSGmc9yQo6ZMQGNZ7rnm9N +JJ/5SedvX76e5HmS6LJPqmy+Dw+m0zqzl9DvmR4tTMecysjobR5tkQ/n7UE3OgmHJXySHXc/3ijbEk4X +XbHIz76jBZD8w1z6iGqTVcslYaKvG0ao+A8jr6Ws7D20SHKDYEHIeVW8ukPQiA+roJC4+PQDTImC+gLx +KsjkTO8hexdlWi2MkvPOfa+dDoPY/9XtWtAMsMNsPZbb3OlC4ai5dye4B4RwEVybSRlBy6MGWqi8VRNX +O+OinpxcF2frIh9NuxzSRPTAmwM7HIFAKOh4XrdosOq1pzdev6RPqWtqZwdsLS8a1ubCpXK5TUizp0dX +LgPtW77VnmOoGDpgrOuDbHGgc/k9lY3J3xOhBxQ4ARQXbeuFMN0JlA45neQ/fvYmunq5fo3fAwAA///q +E2nZqQMAAA== +`, + }, + + "/songs/Come As You Are.md": { + local: "songs/Come As You Are.md", + size: 1201, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/9RUTW/UMBC9z694t70E8QOokFYI1EOlSsCFozeZbEKdmdXY3ij/nrG3LeoKJCoukJtf +nj3vI84HXRj7hG9asDemN/7Qzcn4PbVXWjJ0RAqDcEqg0XTBOrHxmQ2blt2ZcWCWRu9wMH1gmThY5gGR +M4xTXyrnOAtdDh1nGepew8LWbx3oHmkWYevQV8KDMEeij37KhCkkiCKpma7IU8i45XBmQR9kl+HD4muo +dBc2DLrKRcKh2MCSXMRLPE1hYaJ9jO5XEYwfzXW4m8eMcrrwxtA77R5rkMFjebKAqeVBHuzOt4pmZFVn +G9EXRXwxayqWnXsF1hAfE3NfjlURRF9r+rvkA04epZr75LaI3tA72nu2wUXnSRNX6bWhlC1sPFwOS3OG +J1O35XCIrrLBOaTMDT1a8/Q0yBvMz4Owuqyto88VbAmzDMUpf1hBX6qHX1fwvzRwDVyvP9X8Z8HtnHy9 +pN93+F2352QXNZnl2OHnZTjU5ub4qs/772/Cv1nDzdv2V/oRAAD//yAhCEuxBAAA +`, + }, + + "/songs/Creed.md": { + local: "songs/Creed.md", + size: 1430, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/7xU22obPRC+n6eYu//GP32AhkIIbd3SQCB9AXk1uzvNrpSOJJt9+36SFztOoJT04AvL +c/y+OfnGRDz9jw9dPZq8o0+8k0llL6yBP0bPeRT+4PBtG7qeZh3GvPCtexDj2PNW3F4Cu+DPuvfO8shE +11AiyWdJJfHNaJoybTVxDNMClCHmjND7GDgW4y/RPNFW+OASdzF0onvxvFsag21EzP2jmuYN7aKFClQN +e7UBILfOFkDel74XQ1gJHmTuYsgK8DudXJbNKbuVTnuFW+XtxR1/7IpBd+R9bsNhdPksEvg3zYxqE88n +u5sJvfPqOcSjlUEVAh5GEDQaBgTArSkaeQHrbAXtQjnoNlUeNUG1akBrs8ZWqwsLcgSiJ9Ryha41jZHT +WjldFLhZizoVSuQldYLu1NnkyKNMU0MFTAXNoxpc3VITW0zCbnBacSG7Z6F19nTAaki1Js2JwQh1/IeC +j5ti9eERCEQvmMPNJBcLaA0h47fiB2k0vhftHhrrKjXm68BTDKk2ZJZK6i/P6o+NquZ/KtGFQD9xvMjy +Wyf5uou8hH9+iwhdFTdjsQ5n/xUeXZznEtZ2JKxPTpsW2kdcK9hJajNMyEj0AsDAz0y61tBLs+NJ+3V/ +AnTGWMj06pvlX1yEt//itkHm6k37E/4RAAD//1cAlSSWBQAA +`, + }, + + "/songs/Everything Is Grace.md": { + local: "songs/Everything Is Grace.md", + size: 998, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8yTQY7UMBBF9z5FHSDABUZIs0CoF7MbCbH0pCuxacdllSuJsuMaXI+TUGUHMQhm372y +2q/+//Xd/WlDPiTEPMOlwmf2I7p3+nEPhfGj+0orwzc6BtgDZpCAsBBnw0dasA6dCFRwgBtiqbAgJKKb +IWsBuwfPCJhpnYNzfaCgGg1NDw8EmgAtCFQhXt53pgpjniWc3ssBAT0LxAq7ZvhX+kvwYjI9mg3s/hjc +BfaYkp7TTQ3Z2GY8Ja9YC/Tz+w/VkbVvpoOTOoEQTD5qAPd0wJXWF7GvCvtY0T3ma8/cy9NQcyuvZ0+0 +4avOdpUxJFGez8o2iuPrzgKlqwnRfxYze0xxDnJqvkQR5Iy1nruOiSq2nIVYIuXeLeV0wPm6cMu032tp +z7wixF5W0XrsVkfy8NfNyL62wd1vFuIimqGCGKKy2TjNUdrg0+/fy+gzVH+4Z930DfeoD+AnrRREj+cL +MV5xKVamoUvMSj7Oqg1e1/Bzc2lkkzHoj/qdFPvwof2NfwUAAP//mM1gcuYDAAA= +`, + }, + + "/songs/Famous One.md": { + local: "songs/Famous One.md", + size: 966, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/9STwWrDMAyG734K3XrZ2AuUwcZoKQwGYzB2VGulNjhWke0Mv/1kB7JSCjuO5iQp0qdf +P8kGRy4J3iKZe33M+iT0aL64AApBdgSvLNZ8aDDMraytm99wK4QZfILKRSDiSGYXAUPow4SSnenjjnCi +mMDSISi77VjpimNg8Qq7W6IL5NCQz1Q52nPkDUh80nRg6Zu0bzUR2Kan1StlyKy5+fTZAU0kFfaN6sxu +NcJJ0Ccfj23QmBdKXoXwoOqz55g6Yx5ybdtsR1B6N2XL9krlT88u0v/yrSFHltjOTxnF7BIk53uenXA5 +urP7qVJr+MZ8cIth7/oOA1nY12ZZkdn10QseAqXFiT1hyX4o4UrlFj6x9UP/X38CAAD//9mEnQ7GAwAA +`, + }, + + "/songs/Forever Reign.md": { + local: "songs/Forever Reign.md", + size: 1261, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/9RUwY7UMAy95yvMaS6L+IEVEgdAgxZGQkgrjtnWbQJpXNnpjHrjc/guvgQ7Xdpc+ICd +y+jVfnn2s5MPxHhFhq8Yx+xe68/dz4xv3XdawDPCSNTfQYvcY8AMJSDjSSBTCTGPNQIxw4Ru5ya64sE1 +5C4Z+ihz8isMxOBTgkIg2LLiGEpDM7hrQu/5Z0YR6BIJikoezEBzo2eohoK/InSqzthXxWkFaXkz+q4h +VrgpauaAniGqHsd5Ttqq+/Pr97/UwktDNOTeX5UXK/Xmc49slF3qB61HvgILnIyqrTF6IevSFzhbhWNr +ytBaqcidM6yKe/QlaI+iBkuBWHQoUir5El7B+TQBLznbjNRpPUFd50ncfwPfrJTYBTWXhu17Hd1jVOt8 +uvlV4AkBMy1jcO7L8wJ0NM1am+yH4fTEZuSDDdCOsh5vxKm30det47p1e5OTfj6aNKTF+M1K4l7gZiVU +pvj14D1o8OAZcu80sVNDS1RHK21m6pKPU7Mu2MoZevaUNRkFc4fVvsn3Wnig1Czpx/ZWKHCXoa4WJtlI +CUvZ7sXLmcNLqfPzqtPyXLbB2kUBlwnI3iTI3p6gTyiL3EH9c+7+TX3T/gYAAP//H0Fuhu0EAAA= +`, + }, + + "/songs/Gifted Response.md": { + local: "songs/Gifted Response.md", + size: 596, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/3RSzYrjMAy++yl028tu9wXKQllY9j6FMke3UWwziWQkp6FvP5JDwxw6IRAjfz/6PnLO +RcHeCKmMDQcQ1MqkGH7ZE45V8E/4HvQvtowCK8ItEnGDG88IjeGdF7g+gBcBXglmlNLCBWEt07SBCoFx +gaKdeXSCgDKFk8J/hDSxlLGg+kU40fDEV17NcCfU4sKunOMdd3u1b8uFkp1gfmgzf140nJlhQKwwssBc +aFBHG8tyZqTBogovKXcrrkgwMEu4WEjss0gJJwU16b6VzzJr840y2goEURxmF6afDodD6MAVf1hy53WO +53vsMbyE8BcnvEpsuAM8/hOSJN5wb3Bl0VyqX/2EF8MvlnP8wE2iSiyK3kgX9z7ebJ+tJUrdC+8oU9Tm +ww3/2nN94RmOv/vv8hkAAP//ytPO01QCAAA= +`, + }, + + "/songs/Glory in the Highest.md": { + local: "songs/Glory in the Highest.md", + size: 1100, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/7RUS44TMRDd+xR1ACMuMEKaRTQgzYIFG5ZOutI2sl0t2z1R77gG1+MkvLJ7QoKEhARk +1a6f36ecpyhlow+ZPnmm92H2XJt5g595WAq/M59lJVeYGtLnUGqzpKFZ6MhnKXxXEJ3mn6VMWvT967c9 +zvm0lxbKLjEylUKmiPtaJcwhFyM1ocpsFEltrgCXl9po4lPUG3r7rHiNGbAxQsf7HfafB83j4kqjc5HU +6SCHC0KlLPQkkzXPiozk3LsuUuJkqQM7lp5xeaIkJYc8d6z2Jzm6BHCpPmT+ldmtVpJ5SKmBtP0zYgAG +EphOHCvTSdY4Eb9wwWcCa7YGaPRi9ck8KjoMOEAPD5wzqxavmte/BnR71+33f5tLr4y4MxpmqE3doKW4 +UMeKJZHcfVT/qu09dR0hVGVzgGgbLG0BhX3OUgSyhIR+167mYWF6k557WeEw5wHbDl/JYws4rl+cv48P +6OPN/LbD9Mfp2b1wjuNRAO/HHQxtSuwYwHaXqskV08LuhKXlTXC4qnKzrLrziFk6pOTyytFo6yVAurWS +Pgvbhy2RXeU9w/uy0HThGI15eNv/K34EAAD//7g9sPRMBAAA +`, + }, + + "/songs/Glory to God.md": { + local: "songs/Glory to God.md", + size: 847, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/7xTsW7rMAzc9RW3vcUP7weCB6RFGxQdW6DIKMe0rVYWA1GJ4X59SSUFkqVDh2SJyfOR +vCO9iZwXFMaGO/dXf261z/Tf3VHPmVBGwsw5dpi9YPIdNa49QQsfIHv+IIRiBVpyW03NdKY9hzSA+/ov +jduSVIrhDZaLyLl16pB4tswfZWcKQzK2lBBj4x5SGTMn6uBbPhJ8jNrByipzoCjwWkB8SEWwUzl8KI17 +I7xzSDbLBB1+JohynLuU3ODKgGvoUWUeKf+GcZ/JF86WrToHfyQ3EVrLjxDGE3Z8UF/32Qep1mUMhlYx +ky+7MZIIkp/Uc5M8Lej8Ig0uAudeGJGKxfPIkRBDT7YLjzb6z9MOesqmfH0Cy6hNZFSTzsZVJ21ltX+y +rrq37x3exrBXr4ekIuqENpWJ0sNSJWuVqxdXfTTk/Kx2WakfmPUtuc38q3/1s/kKAAD//wgmGelPAwAA +`, + }, + + "/songs/Good Good Father.md": { + local: "songs/Good Good Father.md", + size: 1544, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8xUPW/bMBDd71fc5sVF/0BQoCmQQlO7dryI54g1TQokZVX/vo+nFFbjLAkCJB4I8T7f +Pd7z95Qc23EnddBMn/CjmzHrF/ox7LnbnZUHlexYuA5pKhIdl5qy10LpwPMgFQ5dcPh45CVNu6wc/FGJ +bqe6rYAwrhqdZqT5MqIdKoSEAB/N61Qcwxb9w1CJvqIXCiIpBD4huTV77DAGlaLOYsze7U4c9YziElJE +919roNh8+/+m7OquAEOy6pJ1T/6pha9MK57WpkF2fL80z6VWx3LaFHrmSkRGR1GNfJK44EtyD+Ie6JAA +PJZZc+GDtG/Hs3f/WORjTDPPahOBjUvi3SYxxWCgeMzpbMnfZCpqJivweyp1fbNZwRb4u1V01nYtsoCs +OWX3Qbm7zCJtATQftK9tdRoh2Bp4sFmylAb/LWK4Jp4KvVW5l7Rs4rP5TR4FRugmerkPSh10yb1EHqAq +PDiUJEeinyr9Y6j+GYP4+Gy06RTvUYzJXlZpOVWggrJ9CK/2URcBvyHeb84Puk0vAXUN4RrnK0A9xfQO +e3bz2f7r/wYAAP//3v7OFwgGAAA= +`, + }, + + "/songs/Great Are You Lord.md": { + local: "songs/Great Are You Lord.md", + size: 1254, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/+xUsUrEQBDt5yumsznxBw7hChFBsPBArtzzxsxyy06Y2eTI3zu7OdAiWFhIClNl5r23 ++/Ie5FEpFNwp4UEGfBY9wa0/sO2V7qHuujgSpvhBm0YJTk0yUsOOGnPnYMcFi2BhwlPQcyazLy1Lf9Uq +WREleBhJJ2QK6jL2+6P5UXKmDDAbCrOhzewInsqN1Vmd5jBjzFinNOTO4FXwQtjXhQylAb2GaARvy+tf +n7eX9h2S0wT/4fwUzipN7VJqNdRsGS/RR2MXwOGb4sVfW/o2M951gj2TER7Fu7vKvNrlNv7ijlWGu0pT +27v2H/sMAAD//+FpE1fmBAAA +`, + }, + + "/songs/How Can I Keep From Singing.md": { + local: "songs/How Can I Keep From Singing.md", + size: 1064, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/9RUS67bMAzc6xTcZdOiF3goUBR9aJDu3gOKLhmbsYXoY0hyDPf0HdJGmi5ygAZZBNIM +Zzik8j0v9JUTHekkMtFryZHefBrwdR/xcS9Tkc/ufZQi5CsBKqkPUivVDMy3bsxSySeKK07m4I40Chdq +o1Ccq++oaC33JfU4y/Mw2lVtucRKkVfqchSwONKYQw8w5eTes8FK7q7w1gWroWY7M3tVsxc1Wzez9CvP +habCvsoDTm5SqEJEkkrbDUf+rQx0Y6SQb/KkNvy2e/HE5vOagDS7SuzpvJrTkzrUJn1DV1dkgkA0iUYL +p0Ytm1WHCosPgYK/NIXIKtUdk9XouYDYKPlhbO41F9rlgHvjm8dB8DfgTWgvtHC44lcb1aU7Ab47PuCy +CqYgKF6sfaWpi20EmJ9FQIN/msD/l67KWI9+C7Wh9XNAqeYjotPlpmWUZPmlR8J+GnIV2+Ymk2leGEn2 +eUnEA4PyyDl0PAOuKU4eu4qw52kT+Xt1KDoCvKAnTHswUT7Qj1x693Oz0akq+lIAWkH4q5R/tG3oMBoY +O3Muwm3clC/3zcHD5UZHW4U7RVPhNEio+6vELqCvhteNrPYTXZmEyb18sj+APwEAAP//eX3LPygEAAA= +`, + }, + + "/songs/How Deep the Fathers Love.md": { + local: "songs/How Deep the Fathers Love.md", + size: 780, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/zxSwa7TMBC8+yv2xgnxA09IvIdQi3hwAXHeJpvYauyNvE6j/D2zbksPbZOdnRmP56Q7 +fRVZqUWhb4zv+sHoh94kfMQnvKxVPgdHjU/U1FFGC0A0aaXNOuDG1ugih5aReFkoC9tWJfyO3OgkZFG3 +ZaQ5YS0mIy3LQaYlNKXMVyGmvUobIp0wbfWx3rlnPLWuvnIqpBOZcE1lhgszSDzNU9tqsc4w8QDOnY/w +xWjXrYz4iQn8mWvneotqUuhXkfDayTKXbgnySvOi9QjhVaLCtuPfudC2aukPQ3Xld+DT462L3g8pFZqR +s4x0pginlA/KOlxd5KZpkPDmEenWiLPipTPaoNOEZEM4N9rZfMnJmwcYBSZOKTsSqfwpLS2U7jgeBs3r +kizKGNzFeLjQxUOLFIG4VN3m2HAntKRJwpmuBbF2ZpB4Wqnc9zHbE7wVxW2q3yksIJcWwRl+Ipc0NcOY +Vt0ROP7syUbN4RWneSz/X/wuthmCrsna3Vr3xOhIxahWGVpCB8LfeDwbcqbZL3mqmnumVXauI3wNXNxV +bxC7KYOBLtu8UI9D7ckFvIBHz/6u+yhA5Fvv0OjTCgb4Di+fesv/BQAA//9JA7hKDAMAAA== +`, + }, + + "/songs/How He Loves.md": { + local: "songs/How He Loves.md", + size: 799, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/6yTMY/UMBCF+/kV011zwA/ghASi2JWQKCgQpTeZJL51xtF4vFH49Tx7OQmhKyhYKVuM +n9/MvC855Z1Pwl/yTQq9wY+eNpMPhFos/Cwh5Vp4ysarUFdxilfhwEs1i0NQeeQzhxUVNxGiT6Jj1Jkv +ohJ8YfJFeJc4L8554hNs96gjBzyr2HAQfV9EOaTUzgOXOo6i1E2rhj2YtAPYFPSdphQHj1kLyZDiVmTk +y8FzyganjzA9s2Hs+FP4uRbnBRteJFSPU038I1eGIbXu7WSG1vnI1Zq13J2b4mVn+ro8diUSSX1/5FHy +a+X3dPpLh52I/ii8duufam+JvmWk2CdrEW7Z2qg9xTurtsJmWPuRPlvYlT0jiFHWrQuRUQMxWxgg124i +B6Cfp5ci5lXOg+B/lwc0akhK1Ctw9v6LhBtIrSKOy8F8ofvLoACFvAAIx9dYSgexHu2GOXs1hHqLOYl6 +OihqiWOHCskArk7APWZ9AC60YI+rtPnXENXx/IZvAlxovbf35YwiZuNwydX7bns4/lvaT+/6Z/ArAAD/ +/5Z8qVIfAwAA +`, + }, + + "/songs/I am.md": { + local: "songs/I am.md", + size: 1042, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/7xUwUrEMBC95yvebU/iB+wieNIF8bQXj6GZbaJJpkzSLevXO6mrFEXwYC2FJjNv3pt5 +bbrHbTJXepndIHRjDp6ENgWZUQbbEaq3FfehIPKJ0Nm8qRCynd8usUNs2KkFMH3AjiE7DIqlJZQ0WBk2 +2deQe/TS8uZgXwiJEDKmUD2eeBRYSUXbUDmnUUfbJSwGXdoMlsHro/MhOvNIJxJEqugZ+bKx2ng6oyiD +MXtVhufomjjn1opqbX+IK16XXuuDc5HAx3lXKkv6XtP2xjw0o+buqlff2DfxO56nbpZc6hQlalhMpMM1 +ky2e+QwXTiHTV5JCVZnUEk9W2jIrlfzLOOsrHNqEeqtNQmUUoa4GzRbO/TLpbYwUx2A9Ok70mZr8GaHq +1/XegrLKmFek/e0J+dMDsv5r2F3Pf4C3AAAA//8GaI0yEgQAAA== +`, + }, + + "/songs/If You Never.md": { + local: "songs/If You Never.md", + size: 1691, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/+xVPY/UMBDt/Stet81y/IETiAYpV1AhIUpnPUnMJp7V2N5o+fXMOAF0gpOWhuq2WFme +Nx9v5nnSDfjKFZ/oSuLe6M89XoTeuaeaC9aJEpYbVpY54OSvFFAYicsU0+jM8eQXAieUiTCxxO+cXFar +2rHGMll0wcxXQmb0EsepuN+eMcHPM3jAzXDjzHIz60EIQqvEYoEseC5q0tSr67D6jEA+oK/FrtAdFo0T +NYlzXYuFZIwQYoC3evXcisbAgoWOrlN6UVP7efW3jJ5Aies4KcyX1pNMRZEYhMh9eBE1ald2knEg90S5 +5mbwSmGJie6uKP5TRS+j7qioweJP2IX8iRR8JnhINCV8sclbV3uuKRybeyDrsNXqPgovu69QpqTuqhUN +f+KqSukw8vsty0Y6z0SXX+e69Jpin7KqYvAqlKHOpq0T7ylstFvpHb41Mfq08VPU2XTwOul7Kmq9enZ5 +VI4zgr89u334K7ZBu4P+NUqJSMXg/7gzZ33J+6LQkdaUi+9naho42/CVUXvLHs0Ak4s6XbcXrlx1rKql +YiuhURpFVfngPjOCxHS2HbGvis3MHBLl7Eps5SxYWHYVW9LWjCYyNW8DmchL2yWUgsXRzXYRH/P9g3uV +0v+Q0uPb9gn6EQAA//9fHCXFmwYAAA== +`, + }, + + "/songs/In Christ Alone.md": { + local: "songs/In Christ Alone.md", + size: 1184, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/1xUzW7bPBC88yk2p1ycfPc4+IA0RRIXbS9J0TMtrkQiFFcgKQt6+85Szg9iGJC5Imdn +Zoc+JLr3OZRKd1ESmyt8zO2U+X/z8crqKxpX8jIxhUK9zMntzFNboB7D4OtOf5WaOQ3VbwtJw95Uj033 +khPnUgG0o1YpEoOjx7xB9SGPqGM1eDyZ+sC5YzR3rQYSyQFd8nhtzF9vK3nWroWkpygnwC5adTxV34oT +2453ZvGcqGebC9nMgAgxstPdqINuOIU0FOrYFr4wv1ZQHXvJlXPTcBcjhaSPnfEMACyUn7bULmeLDoAC +Q3D7YtsFGglVkVcS8IhcvHmYY0xcGstHcQrpOU5RS0d7BI0XdWgIfX1T1+RnFcwyFz1snjv11NFxbYTQ +qwCGOjsy+lGxJ74x5gVytXNVc7osaGEL/eAyF3IBRqAX05Jt9W90FmwotoaCGTi6Mg+SiU+cMVAwBdZT +GNumaIPbIwUfrjg+47zbEsOJ4crLZ++GNnTAQK44xMeu5qdq05O6YZEcmzBn82tzqqBXulGYRMcZQcLQ +SMfkFXSIkgN8oe9A+jNRn2U8d4IL6gqEw8MBIBfG3KE56D/xNrSiEKfQIVyreQ7pEmlAC5xTjQIZATEb +cphU/IhMqSMHsmOToJM534SAa3Jlvm2BXULdoozb1DV2xyiw990d2PJbaJhDrMoghh4hTtLCqoVm5m7L +Ar4NShbOn/wNymdvHlSvngd13KSik141BH1INtIxK9K12abeyTg21Ui3Y3Vy3Zi8gyOMsTEpneexxRwn +dubephYEmuLcvaLzZrSa4IG438IGLzLXOSfkOyOOMRbd6kWd+xyWr2IOlzj9do1u/2t/Qv8CAAD//9WM +vo+gBAAA +`, + }, + + "/songs/Indescribable.md": { + local: "songs/Indescribable.md", + size: 981, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/9xTwY4UOwy85yt8e5cH/MAKaYUA7QWOaI/ubk8nTGI3jjNN8/U4aQ0IpP0B5jSJ7apU +VfuJF6qzpgmnTOGV/8LDpvQ2fFApYJEgpjVSNZALRPL/VoPJqCy0Way90E+VMLxTQkvC/1VQuhHmxCs8 +S1Mo+NVBjvAbd5YsOqYvmPMd86K4KvJMvVA3dYDw/kZ6wNyxmxI0Tt8ahcQnrTiFRTRIBtXbawiPOQN9 +nzOm0ufDHyL/d4BZ2DDxOAZ/H2wZZ1pOQEN/1h39egTkpWuAK8veLwtMBzAWeh3GLPqbsOCPrvWjLCf9 +JjvppeXOZl4dTI+7e6BtvsJOQzW46u7OlYlqwNrvYytTPmBTGQJe4PgSBaIPmOQFaBiUezjcOybJFvZI +PtRNidK8aZXwWT0lYs8Rb8ROUk2UvFydPePipT1ZhOpKT4pUcE18d6bxMGNNN6pufFOPyRUkqyd5eCbz +XD09zLVTe3HqEULzj2ZkLpmpjtR5TIRPwn6P7H5YlPJPhvXkGsqG+ktRRF5pbFzv90z+2qdy9IzU4C4n +y42gnG3V1bxA9PBm7O7PAAAA//8vGZhT1QMAAA== +`, + }, + + "/songs/Jesus Loves Me - Tomlin.md": { + local: "songs/Jesus Loves Me - Tomlin.md", + size: 898, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/9RTsW7rMAzc9RXcsiR4PxC8rknRbAEyqxZtCZVFQ5Rr5O97UpwiXYouHZqJksg73uX8 +zDorvcg7K52YdnSWMYZkdviZ/ZT5vznSYpWiaNnSrQ6JOm9DUnP2TIvk6MhbR5a8oJSeRjanK3m2ubQJ +S1ok8R2gA19mV4HUWzRfPCc6MHU4UC+5AoC4kzm6tCmU57T9cqI+y0iHoIQdlVPHP2y3eVRjmuxtZYxN +Ouge6vaA3nWRtdnLgv0ShUKv/PRNvzneRfchMznmqSodr6RYCa+bGCkxLAAQFVio1YMjPOJpgi0yl2pi +fXE2v5FN1aoi7SaGwZcHw2LEBLCT/dOe4VTDozc/is2Yrro/78c1T+YSiq8lYjogdqnN2Epg8226w3SL +Zp6HAe50WVRp8chcxXMBdysvUiopAlomrASO+rdciwf2byve/2uf10cAAAD//2zd+pCCAwAA +`, + }, + + "/songs/Jesus Son of God.md": { + local: "songs/Jesus Son of God.md", + size: 869, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8RTTYsVMRC851f0bS+KP2AXQcEPRPCgF4+9SWcSXqZ76GTe4L+3O7Osigviad/tpSvV +laqaT9T3Dl+FQTJ8kBRe2i/cbUqvw3fZIeJKkORgyCorfCS8Et90GEWFKXwrtcM71FHA0Vl0pQQHdmAZ +fqRQZKXwBppcCVq9kF2tfp/gEG0JCiZgupLChW1PMGxUX2iCRhFlAwusEi8nH5ui8F50qaaEeodMrcG+ +2RPmPGMk+K+FX3hOsQ1U3+osm2LtdBs+0/ChEtyTvQlKXezfKWJ69+I38yBMzxrWdHo2BW2kmeIwLdkI +HYBKc2PHqDXX+ATVL+Bfo3PJELlMpb3y7TT/Xgw9T4qHNlEqndy+uXuiEmXCYSG5gEUtzn+Y1f806zl3 +v3VcdoKHGEZBttyas98YizFp9L49NsVja7KnRzD/APFAoQsv1l+PtnpdYZPjRA1rPcPkwQUr94cmu9Dg +V7ygVjyvObHsS4EnT0O4ezU/pJ8BAAD//3RkyGtlAwAA +`, + }, + + "/songs/Joy to the World - Unspeakable Joy.md": { + local: "songs/Joy to the World - Unspeakable Joy.md", + size: 885, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8STz47UMAzG73kKzw2kAA+wK6S9LbDiwB/tObSeNkwaV3baqm/Pl041msOMBCd6aKN8 +P8f25/SzrFSESs/0KppaevMz28jhFH4lJqhv3Ts87nFU/uiu6KXSB/qB5YtoS9GokYEP7oULcdDSk3LD +cWbqWelLzN2uzawr9oAQDh2DMj3HgVRk8M495baKM2cKWOZQJgCGcP8v2m3s4O608D3MURQVxy7bw1bn +gHBQUckkd0Y8jEnWB/faRzhzjJxa284/JpHWvFNpTuYJcsKnKmMKMZtz3xiOli2nyZRbVEK/ZfV0V9kF +j4puAu/PjUxXszof+JRJYDBqWiq6cEqevqJf9DAxNQFNYe9e+KdCGo2NYqZhrSkRnuvIKHExmEKdOPfM +pFMCdrGRloiJF53wrq13GhrehjKE0w5iEFGyYeoo0VXbuyQaocoRV8CQuusLy2SZzfa7sEhuWS9IQqj/ +K8HfIv6zb48ftt/oTwAAAP//oaIt0XUDAAA= +`, + }, + + "/songs/Let Me Be.md": { + local: "songs/Let Me Be.md", + size: 1147, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8yUwY7UPgzG73kK3/6X/sULrJAWBGik3QustOLoad1J2CSuknRGfXs+pzMLSJyQkNjL +to7t7/Mvnj5Io0ehd+L+x5+7W4q8dQ9apoG+6kpchJoXSvwihXSmtJEXLs09IToXTghznqhI9by85lRd +o3vk2q7HYxFuWgYrjtdYXWvjkKW4A11CjLSszWpbwQGFvBuImsU59yQ8ekpwo3SEMofm5zXa66h5llrd +IcNqqHThrVtYQglt74yKY0SOTPCt68n3hJBrH3DiELfBmZzns1DUs0ymdTLXcXOfJek55JOhSMQV8sX+ +fcCAgKCJnqU25wwmyqCmi+SB4uu7XxMM3BLmgPEN6zfdbsA4nrkFzW4fvACZYqgfLY9FXyTTxUuWMxAe +qLZfuhZJko44sc7dOqJlvCl80sm5ewifAmZM+70CYcQz1xUckNeVT4VHcfeVgA88i8xRxgYkIfeiZ6yH ++2g3cL16rqjnPMpwVbSw5GkPuvdcymaVtV9f84qHi9dOO//X+kbB3Bf9idifE6S/jBDEDvuiZJHJsFSK +HCZCdpdtbC0tDzVY2wCxJLnVAYUR23lLnEUa8uw+YHmz0L61SEx9c23pDGbvaAtqP0Rra3OPmhYAkn91 +8Ry+AL9ze/emf2W+BwAA//8gleV8ewQAAA== +`, + }, + + "/songs/Lord I Need You.md": { + local: "songs/Lord I Need You.md", + size: 537, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/1RRwU7DMAw946/wbZciPqATEiAEQ8AuSBPHaHWbSGtcJQ5V/x47bFPZJeuz/fye3zun +Dnf4SdThNxe41R9sp0T3YKVGa0ce6e+NPeXcwiPPIQ7oKZHCfYgdjgsmygKHIJ6LGJWV3OmEbnJJWlBk +o/3iCffRXic4lNBRtmFP2gTXlfEsp8G9X3+38PxDSdu5pBUMHwuyknbUU8wq1uSEwQtxybFq3nt8YeX2 +PK8H4VBd5BAxlZiVgSYrJBySOxIGVceJ2nPfFey5qGv9M1fc7LpE8KDgP6TBiyU3Yp9ImV75FEyTTT/5 +FLKgbh8J4Ivc0Zv2zHpeYfWQyd7qXBVEFBoncRI41ljq7Wa3XBZHi8nFyIJZnGK7jSZQY9CJSnPzRrnk +Bs952O15IrRmHVkAtnc1/d8AAAD//2T9/XEZAgAA +`, + }, + + "/songs/Made to Worship.md": { + local: "songs/Made to Worship.md", + size: 1055, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/+xUQY7UMBC89yv6AQE+sEJiJcQixAmkFUdP0onNOu6o7STKjW/wPV5C2ZllFvEF5jTu +cldXV43nsxuEi/KjWvZhoVf40N1i8pbuZVQD6IUHd3R8uZ1jmHzp+GVpV4sDm2waNxnYma5paEheE9EH +HVgTezRyLrIsuDPonjgkTC9hFtA5dOym5WTMRe1gHfkhZI66CWMYyyZ2aBKiB2HvMo8hRpDpauzFWcm8 +h+KhJw1iHX0Bu3eFd2EXd3dkaJxlvogRfdO1zfwIFGvMVy/204uOjj+4A9y7NggXqpgXzRWEtClsklpp +NJHXTPToUbiRYKq5vhpiJqe6G9h71dzGXyQGbElf/+7esSdnEdqv65yaxaVydhG9w426J+q1x51H7zbp +CB7Ws+MpjAUKdeaaybM3Jr1AP9E9gkO4bc0w1imsC4SsS7NYDskdAYSSltLsvksuRxs4xWtiFfgU0vQ/ +pH9Del8FVINM+6fMfXVsLR3Jcx0G4Wvm7FsdPO01tPd0fQ0PGg9ObgYdrItSzmfBm4YqHc6fnDfkKSGv +i+7t0XWI5dePn7maWHxLrP42ajqLuZBBe/em/Qf8DgAA//9JGpFHHwQAAA== +`, + }, + + "/songs/Majesty of Heaven.md": { + local: "songs/Majesty of Heaven.md", + size: 695, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/9RSO27DMAzddQoeIE0PkKBAtgxJpy4dZYu21NBiQMlx3dOXkvMZgh6gnmzyfQkf7Rem +PAN3sEd7wWhe9DHbs+CbeV5+8ijQE8sMXSBKkD1COgVM5hB6nwu0jCYWcitQOFhBOLC4srJExuzHoSF0 +0MwwFzm1ShhbNLvB/izzyfONa945+xB7aHk463f6Q/WjMlbVPdocOCZoeALHU9zct61g3emLZgYeM6zX +a7gWNTsiqG6pmngmB5l7VFHZLOWjHbSedoeUbXTQseAFZXXXuKZ7DMwRpQ3dSFDwQznTbI4zeLSSIWgK +5U8eaUBX2YuwJY74/8o+eLbRYiUvcJFMZq/V6w3w21JeygqcNIHjAZIvUMHQx5vPM8NsX+uf+RsAAP// +CyUKBrcCAAA= +`, + }, + + "/songs/Mighty to Save.md": { + local: "songs/Mighty to Save.md", + size: 865, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/9RTS87TQAze+xTedYW4QIXEgkeBsqEXGBonGXUyLvYkUW7P5wSxANZIfxdVbI+/VybX +PIxt45vyt7QIvcKPzk+TN/RuEdu0CleRzvmu0zO5Z61UdBFuY2onxxDHuE+55DoQfZHGk9h9Q6sU1oqK +6U+sXm3Ii1RxpzYKP3LtomDtOYWQrEZ0w2TUp0S3pgZmB9Sv6UfhewL6IUXwMNeWcnW6bvxBO87O0+Gt +KXt4w8pfTQC+VwsP9HZuo1qQeSrLzhcrpi6caocA6o9ZTLqdb7CA/CQ++78mIVS5pYdEAMl505l72ERJ +kcyEhCSZ79AR32ziEJOPWck91gYYAtKFI63fbUjvtRRdKXRvbUTyfOHvUjIanCvRV13R8dlMaof385Ji +gx2JuAxuwRkgVHCt4tA6asG/WunYRWiVkwk7AthvHzQdWEVtI0iKwrJL5c9x4OD9HxwgOb/eP6OfAQAA +//+6J4HkYQMAAA== +`, + }, + + "/songs/Missions Flame.md": { + local: "songs/Missions Flame.md", + size: 837, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/5STsW7jMAyGdz0Ftyw53AsENxxwN91NTVF0ZGzaUiuLhijZSJ++tGwnMWAUaLaIv6jv +/0n/dyKOg8Bfjx2ZH/ozpz7SL/OPEowcxboeLgTJEjSZPDQcoZtvHQSacu2FDpGgZRdaGF2ygNBjkRT5 +K+cIQYWwUU6lkaBCPcEL5zQL+4hOVPpEoYYsoAWzR2MJYwJuHmjQdWDODEKzJGAq5iJV3Ab3QfMLTUE5 +nJ0HGiheIUWnTVHfSxzaTDCwq0i+4NEKiOXs6xVnkSnP0rN0OsKO9I2vd91sw/xW+zkkRZqT9j6QyCQr +EO8aWM0dVNyRmOe70AX06m8gX7xCjaMa3sL+uZs8buhgKVWRMGUdgwtrtANpm5KI/p8Q7SouwGsfUV86 +Vec9yDTTh8SOugo7x7DyBE43HElaC0uhI8/1db6tiS0bBOg53Igtxo6D+rCYdAl51FWMms/WnW7bPtju ++Xf1xpx+lk/lMwAA//+o7/7GRQMAAA== +`, + }, + + "/songs/Never Once.md": { + local: "songs/Never Once.md", + size: 1625, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/+xVvY7UMBDu/RTTXRPEC5woQAgkEBRboCtn7UniO8cT2eON8vaMYy3KRYD2RIME00Ra +f873t5p8oQsl+BotmVc65n5O9MacBKPzcQCOIKPPMHGJgj4Kz+Yz81M9eyxZYOQFekyw0N2FwPJEcB3z +KfJSgTKiQM8JKtcKWWg2D1z0TiJYvIxQslE0UdhznlEkEAxJuR38fsyJ6JmmqdgRlKSqchzpF9euEpuy +i7fC+nzJmG+YK1GCmdUQ+Li5OVlMGTRFtZvKMATKzZg6xtW8LdKcP/IK9fJImCSDxQgZX6bgmZoHyt1P +XmhMK5q1aHDeafabZxUTngDDPqEjtFYVCDXIsnmob+clHokVhdpnj2qrL6GDD+w6OP78v+d/pec/S+YG +I+YdpuTJwXltxViOWReX6F8JdZ99pOA2Cq2qFUepJyv6rMc7gg4id5UhHin+njjf/9idVUQ9OyfCam6A +q8HmuyInrquV7kKA8x7JmnrLIqHP6u9m/puB96+3T8j3AAAA//8Np3UUWQYAAA== +`, + }, + + "/songs/O Come All Ye Faithful.md": { + local: "songs/O Come All Ye Faithful.md", + size: 705, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/7SSzW7qMBBG936K7wF8ufuCKrVIUNFKLFqpYmmSSWzJ8US2A02fvuMQyroLskic5MzP +GXuPNXeEJ+9xIGyMy7YZvPonl1r1kR7VHpUQGkaQkdDMyELteJQnTKiRoxu63pqQ9cwLqvG7RGY8U7ae +LHULNZUscUey7Gu8uE6rI8eAbAmvLrTgRoCWfHpQ14yeMoYEU3OkS8jff6xtdClPZd441gul3qWaRmXZ +xXSrqpFKFy6AvgafTXYc9MzOg6hcdt8UpiBL5kQB5sgnWqqt5zgW5S3XGqrw7fTJXQStay2lfG+zAxk9 +rTXOhDaSxHxYkn25ztolyPxHdPJa1NSO0iDu0noBZXtwa751orhUn5KwKJdCGyP3qAKfi1rjKVmYvicT +Jdu99Vb/p+P5EwAA//9qVm+PwQIAAA== +`, + }, + + "/songs/O Come O Come Emanuelle.md": { + local: "songs/O Come O Come Emanuelle.md", + size: 629, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/6RSvZLTMBDu9yk+KpocPMDdMAPcAVdlBsIDbKxNvCBLZiUn+O1ZyaSjYS6NMvb3L+/x +MU+yw3biaeK0SIxCd/6jh9nkHe0x/MVs59O0oXb0PgUYp5InDDxXvQiei3F7dRi5YsqLpQJNiDlJXCG/ +NQpGMaHvqWpEHQXfckI+4XMO4HkWtjdEX+VH1kFe4faHbq4oI8fYo6DmJtCjbb7OvKU8jHnBI693ZTZN +5x11BnviwSlG+8VQZjWtBcfV4ZoExOEiqfaE971esNaKr7yCWlh3D1Ja3qTnsW4bzCo2SC8zxLyE4kL+ ++NiMsRTEBv3vVvSPVo9S1KTbc1Uf7qgp0LMPmDb/0ferPV/Tc/GfDrinDxog6bKiVNOT9Hi/FjaTWDAI +F7f7pM5orKZzzRYDXbWO+CLso7wu8LsZ5CV38/C2f1B/AgAA//9beqMxdQIAAA== +`, + }, + + "/songs/Oceans.md": { + local: "songs/Oceans.md", + size: 814, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/4RTO47cMAzteQp2aRLkAosAaQIM8it2gSClZvRsC2NLA0oaY7pcI9fLSULSzgLZYtaV +JZPvw0d/PyHkSu/0oYeL4AP9LJ1PYZ55AZfeuF9K5jaB19AglZ70dRQE/ZLPuayZ1wkCHoDGS7jxENJM +H3O0Jr0/8JD0YLBpA1puVZFudMhcnJ4jcNFra20Tr0nZaws5Eh22kwtyJYoj/C0scIrz3ogbKodjuWKX +ekWlHxOeGSRVvCWtrKXPG6agNpPkiFiOEk6gT0VUcVj8ViF35UGNLCmDyKtHqzW+nmM1DDNgcPuMvKiq +GkEaM08G45xHc89jTxEm7+XYnG9A0OYusqGrU4V7o84yFNDrEJ+VrSX/+fW72bykseZB9HhJkhrPCNFC +pC0f5W3SzXJVLW2ybI9Foun9YhpsbPP5Zd57uzFvdH2O//aD6CmcYZ3uX5iaWvUgzdXJa711VbkQj+z/ +mG0gIULlS8mjQexLortYkXXKZbCWx3BNRe7uw+d7u/D11eTvpv7w3v+NvwEAAP//fiWPvy4DAAA= +`, + }, + + "/songs/Shepherd.md": { + local: "songs/Shepherd.md", + size: 1005, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8xTQWrkMBC86xW199ndDwwLe9jDLIEcJhDmqFhly4wsGak9xr9Py4aASQg5JbFPcldX +V5XaZ8/RMzvzUx9zHDP/mAdP3KXsMCwYU5Y+RZxQvA0BMQlmG2UHatLQKm4HammzudAeID5NndfibMMV +Rnxez6IEN0VzQUhzhfoXbK2NVjw6SkERcjTmPGWGBV1KLrIUzL2OalPQbgw0+HdjVsE5DX3hVn0iQt95 +gaSqsyXF4NEz1pNXhYK+1JbIClFjjrmPnfnPMhVc0qSOtoDqiJ3pq4pi/lVNi/ahsFGBO4hOCBWiPFlN +3ghGp6DyVjDv5PLdY/mr9k8btZu5js+oi6B0zi7F4BRX8boeTmWldotEhTNKqKq7bBsV+yGmtVc3tTA2 +hNF39+WH+dxQDL7+CnDva+NaPLy+oOPv9cd+DgAA//++wEQC7QMAAA== +`, + }, + + "/songs/Strong God.md": { + local: "songs/Strong God.md", + size: 763, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/+SS0UrFMAyG7/MUeYCJL3AQBJ3enwPnem7pWuyakXQ77O1NO1SUgQ/gGGzt//Ml+ck5 +C6cRX3iAO3vgNAs9QNtlT4KZ0b7o6imSKjyRozSYxK5KN+reoRWigSd0LPVylqCcSOBKqCGNABcfFO21 +MhgSvtqv57jhHLuefqh9ZENUV+SVsEsDahZKY/YAZ6MhL7nBGFzGjRfBlUO/+3rZigiPN1KeqCCLQb9G +bGAKo8/bp1KmPkJ6o+le2pv0BxQPqHAN2eOiZY6aU4iWWioRtp1Jbokl3Vl4DQPB80rW+5uQJV3rUr3Q +TPM/CfEow4ttXfUm2yb0ZiBp7PBLGEtsh8rOL4tszXxzT/d1yT8CAAD//5zM9NT7AgAA +`, + }, + + "/songs/Stronger.md": { + local: "songs/Stronger.md", + size: 714, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8RSQc/TMAy951f4thPiD0xIgIQATbuMC8d0cZtorV3ZTqf9e5y0CCQOHL8d1sZ+ee/5 +uTcTpgklvPNfOK+CH8KPjIJQFC68oZ+iwT0uCCMLVA1f6zLMmMAYImghQjkp3IVVw0+uMAg/EJYXaG63 +IqWGGutMeCAc6vUpFoKt3I2lsPOGL7FYPnBATOiyBAnp5SaE65TBMoL6hSV8dFr7qzoWwT/OTaq1ultX +NIXmXhDDd9Sq8DlLUYNnZpjLhgpuZMHQvUVpCkco/xRujnT6PiL1do6b9/0vdYpv1vpPKWYOOIS84k8/ +7/K/WS8sCXiEOM8hXBkGnDzNQlPPjBiQUtM4SY8z87qn6e8JRyTF7qDvxpehiI897WapZTKzWoessSQo +1pSgrky9u2/sTYe++QLQWk/g2sYY3HQZzXlzmXyZ4dN/C+H8vn+1vwIAAP//wMQNX8oCAAA= +`, + }, + + "/songs/Take the World but Give Me Jesus.md": { + local: "songs/Take the World but Give Me Jesus.md", + size: 1134, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8xUzY7TMBC+z1PMnrgEeIBdIQESbNEikFppz048ib04nmrGaZS3Z+wiuNEcONBL6+Sb +72+sntwPwlMgfGZJHj8sBT/HC+FXwi+ki8Jr+8DDWegdNGwx7FqxHfYGnip4/gXu4H1KGIviC2+KTqhh +HGY30z1U8seomNhmXB89lYB0IengFISXyU6FJLuEGznRpqU2CnukjyvZtBYceB5ZCvKI84bKS7qH52hS +djq6S2TB1ZUhxDyhORHj6OCAg8uo9VkJzUofU+JVUTilXQaeqNTTJdLaYg6ctbhcUOeYLL61nI2iBWUb +L6F2EUd6VSsx4RdeJNMGj6Zi4pjI+cro7HeTDsYDO7y8gUO+WhBWrbmLLNaMhkrVW9yT8XemYq0MJiO2 +A+wlTsH6twQaOXfwyQ2mwzjWbyN5YvF4QCW6Azgylls+/ur0Y5Co5XaYPSQA30LXMIFqCHTZo6ezxau3 +gGTY7n5DEuXJXlRIL1bxFVQv5R/MuKSUybqzN0Ke5nNplXxP5CeqTyn7VAF1gXaZ2/R/4mLfbm6A/uF6 +EODhbfsH+RkAAP//zb8GkW4EAAA= +`, + }, + + "/songs/Thank You God for Saving Me.md": { + local: "songs/Thank You God for Saving Me.md", + size: 756, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8xSvW7jMAze9RTcbjrcCwQ3tk2LtEBToOjI2LQtRBYDSrKhty8pA0G6ZG6WyOT3R4kf +E8YzfHGBR+7hgQWOuPg4woHcX/253UXov/ucMEOHEfYw+oUgs3FuyzwMJFZHeFG+MykMAfJEEFgpiv+j +f2niNV67WhSYSboKirGjc3tVDIH6rRlxblyYCKWHuUIn1b2VrI5NfBRUWYw9+Kj2wQ/kDrXBM/jUVJLx +EpdghUFIXX4OPmietA2uEe71tEnwzt3Z/I8YFsyeY3PkC5n+qfig6SJEzpOxAqXkDizRPk4V5u3onnjV +9ITXmDCgz9NQQjTGb78IK4+4vaw0OygXHduydMIpQYOkYpuhU3DsqGnYw7fWjL0GhhWrc8+UStLksPgu +s9Tmqip0A1XAdWl0i8C96g2uKiFkwai/P43b/WvL/B0AAP//DIwVAPQCAAA= +`, + }, + + "/songs/That Where I Am.md": { + local: "songs/That Where I Am.md", + size: 1271, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8RUTYvbMBC9z6+Y21689F6Wwl4Khi0L2y17lu2JLSJphCTX+N93NEpILwU3PTSQxPZ8 +vTfvWe+LKfixUCLs8dnjI77ZccFvq3M2ZHiUDzzFRF8A+4B+x6+mSPZDxoXXTFC01MjXm7B3+ouJ2Wf4 +23x4DhP2Dx5ntmHGNWJLDrxBYRQQsdYZjM6MhCdOuPMKymC7MDC+u1RJSJrvaFxmHAigP0l8/mOfDnrc +rHM4sicczHhGMxsb7q5TOhXFWQgotIoMP8yuEPE9rWXp6kLwxZ6owzNRrBuTRrKVCQ4zO5j3I16S6sii +02+XjUOmomWnRFT1q+GNk2tENGUxP2sJr4MTzDCsRYY6qk914I6RZD3H0b+RJz+QLhMnO4neBceFOYtH +qIPAUq9T5WGmoKLfVSSQrnQa20WEqQ0EaaKpafE92mTLLabbOc6mebjOrXaYeAuyTG7St1ehA1vkdSjW +Nw/Jn7hbDKbeWSO8ii7/2AJeA1199Ls8n+GF5crk63ac3P5/px2xWnOanA6VTD0f7nPb0yc9zH4FAAD/ +//gh+3v3BAAA +`, + }, + + "/songs/The Glory of Your Name.md": { + local: "songs/The Glory of Your Name.md", + size: 1338, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/9xUsY7bMAzd9RXcurjoDwQFurRoUeSWLBlpm46FyKIhyTH890fScXA5HC43J5NEPz7y +vSfk0BP8CZwW4A6OPCXY40Duu/zcbkz00/0tMGMGH6EIdsZFYdAIqgKpIwSewwI11uQOPZaV5WSc2tj6 +PAZcqHXuV2zB39FlbJLvfCNcMl8r45QoFwi+ozejjfM3CiBlmH0IwDUZpwoYKXXUFPiPQy0kuLblgD7a +TG2jb9n4T3dio4p1ewZWDHCUReJ2U60dJxgICkMmQar0wnyGYQFRpXtrCRNt7nxp4JFy9RD0Tv3FN0VA +lUs+U7TFbCSn0G77mf8o7sw9y5dJvtQUPF0IGrtRLCJMbNmy8LcoRszZc8QixySJiCsztDRgbH08GauI +tly0tyYsWr92N714r+GIBoH1hKk8czg3InUwyko3L+RumaxhrLYXPK872FpXqoeASoX8ozzlB/MslE/Z +xDtDVeuJL+Re5DDyLFaqfyhPZMqacuUU0vNIINEbvqSp9LaC3lY7ZLa3t1Z9VHzm6Hc/7H/xNQAA///m +oagKOgUAAA== +`, + }, + + "/songs/The Stand.md": { + local: "songs/The Stand.md", + size: 750, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/7ySwYrcMBBE7/qKuuWyIT+wBDYhBEPCHjYQcuyx2iMxstq05DH++7RkHwZCjolPRlTX +K1XrR2C8VcrevbfPPS/KH90vWVGqiMeFJ1HGqEw1SnZfKmuOdUfMMJUitNGuX+TGqGbHpDWYoApm6VPf +dxRZE7JssNPSeX9S5h0TxbQqu5fsMZJqZN89R5VSYKomKoFm7qaWYuN4DaZaFzkjlWAsz1r+wn0TbIGq ++WcMKLR32sORF/dprZBpYjV6LAjtTnjFV/Hus8xL4sppb55G7I7Du5SwUbodQQql+9HYEWmJGisoxTu3 +6o74KU7cPDyPiez+XbqozLHw/8z+j9o4Iv+M9hhIZxuzRcGOznm62L9k9m7IoI2N0Ff9mtnwgiu1rlpp +ybkHw7OYJ3wT9U8nFWVV5WxbN78X0w6gGZa1dVqce/7QH/bvAAAA//+MfCCw7gIAAA== +`, + }, + + "/songs/The Wonderful Cross - Redman.md": { + local: "songs/The Wonderful Cross - Redman.md", + size: 668, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/5SS0arbMAyG7/0UeoCWvcBhcLYDY7DRsVMou3RrpTHYUpCdhOzp9yuBXe1mvWgUS/8v +61OuI9NNJbENc6HPpq3RmX5yqlHOV60lSzjjF14m44/hNrLQV2qzLbxRh3iF2HRu9HBtuAitY36Me+6H +ZXkw6UBfitpGKXMK3zcyFHDr9IzZ3R46S6f73Km4xaskmnQ2nEvnOnVSoVgK1Y0my4lDeGemwbTSmBuN +HNPpiKKkdoQDcw/vaqYr4RTOCyQFbzXLs3CipKuEt5yIFzZMhDvvRV7dDmF1k4thFjXBhFonbYzsPgFF +nxkm4fKXxIFxR3Gifx6HTzk1OLvb0QxU9ueQ8dfH2IGkRtC1uWxU8sL/2eEVrNZRgRdZAx/jcN/oaRHL +SBZXEo6297wXhuCX05ZY0eiG4sN01MJkHEv1BUrsMzKAx+Hqd1y9MApyA2PNTxpg2VWpVewqfHOUABVr +/I3syeOUF5e/cfU9+TqbzuXkQckD74Frw8uH/WP7EwAA//91skl4nAIAAA== +`, + }, + + "/songs/Thy Mercy.md": { + local: "songs/Thy Mercy.md", + size: 775, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/0ySQW4bMQxF9zwFd9m46AWCAikKJF501QJZyyPKYqoRB5Rkw7cvKU/gGLDh4XzyP33q +b77hb9LlBt/sA8+b0g/w4upFXG/4KhG5Yc/k35VQkpeb1LMJCT/ktpcyBe0Qapzik4TW9zfdxINgDk5K +hGcNC2EoUskKss6OxGodXeZDsW54Cz3jVarPCCnR0lnqdDjJsN/JMQomF8M79yyjo7u0K1G/H+IAR1xM +FbFKx8IXMlIl+MPVZntdKQ7DsbOZ+eidFCO1LbAC/LSBPauMc8YHvkis1NoBnGBj5f7UbMzFhkd4MbI3 +Tyv0/UxriD4eWudS8B/R1twtOAx8idtyXkVna8VgbX3JmEQf6b5nXmYkkbQ5biIqMO3lWjEHnWDGv7kc +fnFrUowKT7fJ/0A/WmxGs+d9Vk90slt023T1+qaBG4Ht0Z/umMcnyzBNva2oFCrjI2SAVyU/si3NEvTN +m5rJrL4a49FJ4VjnwEUuVEO1vdifu3DRsXBiQ7Y7BvBijHeIT9R74Ae4ZrHiNXPbfGN84WpbpVDazukX +xWKI+51RPudOMtrEWF0Nz9/njf8fAAD//6Pt+TwHAwAA +`, + }, + + "/songs/Thy Word - Amy Grant.md": { + local: "songs/Thy Word - Amy Grant.md", + size: 712, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8RSwWrrMBC871fsLZfkvR8IhZxKCi2FFkKOW7yxRBXJSHKM/r6zIgQK7aUU6oONNbOz +M2O/usaHlAfe8O7c+D5LrLTBRdsp6x0ZvhjuCwsHOU88x5oY3JNqpV0c7NyPrt6ASar7+SAdnEbeGyuw +nLL4Yc3V+fjO+9VFOaRSjbxIo5fqQ+CW5lVWcBT33BXftPhB+ax9T0w2P/JibFOWvCYpkMIhnsc0s2A2 +AqDnoFIUCv0VEgxz0GaNwz/6i0Ke0gLX3TyS8CnlEXyYzkiARnBgNgUCDcBjYwfnnagXzbZwAagZHdCD +lrlYOsiPM0pCExh0KQzXrF3Y6qPr0r7EOvpUxK8WS9/HP96+7pflbP/3//QjAAD//38En+vIAgAA +`, + }, + + "/songs/Unchanging.md": { + local: "songs/Unchanging.md", + size: 503, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/6yRMWoDMRBFe53iH8AhFzBpnc5FEkzKye73SiBrltGuF98+o3UIaWJcWI3gzfyHPvoo +XZQypDKEJz9hOxpfws4oE1LFp86Go6QpHudcWOutkRMUnmlYnfwDfC9vsMdO+xDebSbEeFWMpqdUWf/D +91rfFAth4iHMI6LmCzzQu1jdtvIpEq9tsC8Mh+gJqfCd1ufnmhSdnhjCIfX87Zn1zHVjMOl4c3bvexte +aNw0S+t9JSlnSF7kUvHFx7faPq8f/B0AAP//rq/XnfcBAAA= +`, + }, + + "/songs/We Delight.md": { + local: "songs/We Delight.md", + size: 890, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8xTvW7cMAze+RTcslzbFwgKtAjaDB0LFDfSFm0z0IkHSrbhty9pp5uvczxJFMnvD/7D ++MJZxqnBJ//g+W78FbyajipKwTYxZlpRB9x0NlzV0ueTnqoFYZ0UV6p4Zxu4bziY3rATa9PZSKIN4ZWf +Khq32YqUEZsik/df4JVy5jy/0QQxu0rO2KkTcRJT9FTsuKe5+hsjGTsaM3yrcTUSr++tVFKNtaMsjFed +ccxqG/wgp2AhK8vg8yVh1uU4SBmkSOMQ23b4JzvYL2ycsNuwy6oJ2kQuMutaD6mhqgWLFyOvFacZ0I4K +C9fKuQbgNXjd2PoNvvOgvjrmpCxcmriN3nKjcoGoBlnR2RVYUNrgcTzXf/Gcp/OfcM6zeRzNaTZuY9sd +5413w2NNn3VOu6dxGzLdGH45xcuRxCzpSKk2vleIPuPawhKXTCNJgd8+WCiMqe/OHHjGbyo9wzvhn5ri +OY7+nNiKG/7x3Hr+sv9jfwMAAP//X/f5/3oDAAA= +`, + }, + + "/songs/What Child is This.md": { + local: "songs/What Child is This.md", + size: 820, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8RTy27cMAy86yt468VNfyBo0O5l0TeaAjnTa8ZiK0sGKe/Cf9+RtkHbS67Zi9bkaGY4 +tB8iVzpETROp04+ofhde4xduV5O34f92RRulQol1olrIxGv4mukz2/7KUV4bzJPIqnm+a9iF3uVZktNs +IpUuWiNxrlEWAC8oDUBpEvIoaxSbnC5cTwCZ0K8notCcDd1AUzhEU694FPqI/nAV+sswb2wTZKYncQcq +HNmrDBSvB+yPhjIddYHzbRogIvSex9bEv/uSqTz22W5C+MKa4MBXYYMSp0Srip2EIu7XaGWb45XiZMWd +RqGxWBZ6LEYLONu5l+0GPjQ1G5q6zkOB14UnIJN4fMZGCPf/mtZ8kuyAzSVdp112MxAcyiL0TdgR9NAT +atOWS27XOn2vgbWdSIfTmatCqJP7ED5hVamcGypi4Ookuc2IcUCBOL6zNmVrBzF5aXwZWbQQjljRWW3W +3IN3cBilLSUeEeWHsg/0s+w9kD+bxIUW1vMrePF34PZN/yh+BwAA//8HAfsuNAMAAA== +`, + }, + + "/songs/Where the Love Lasts Forever.md": { + local: "songs/Where the Love Lasts Forever.md", + size: 965, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/+yTwUqDMRCE7/sUe+tF8QWKIIJS8KYgHtNm//6habZskpb/7Z1sCz6CHuyhhO43szMJ +/ZzFhNss/KZnfIXaKr+oyVmM7vGh9cnkkb60Gx/FdgtP2kvEmftJi0u3pgcpbBoiPWGW09TEka0sOmCo +Qsqp7GlTmrK77bPaMkY1FQ6g6hwgialWzWe5WhW9YKHHcVXlzSpnrm0ICG6cR+7iAJylRPpQ3gVA4Pmo +Xi8U9LNIr9iZtFeeLA2U3pU3mBvWIAmC32oNPWTNTYIJrZ5DrwL4MCKNX/cBi1NzFBFR1xNfZrnKJYOf +QpR6R6Ol9syXhEEMZSc4tnn4EP28gXfJ/ga30vR/8792838/4frB/5zfAQAA//8qJIU7xQMAAA== +`, + }, + + "/songs/Whom Shall I Fear - God of Angel Armies.md": { + local: "songs/Whom Shall I Fear - God of Angel Armies.md", + size: 1550, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/+RUTY4TPRDd+xS1+z6kMBxgRkjZAFkgFiAhlk66um2Nu2pku9PKbXwWn4wqO4EJGjEj +Vkj0xm3Xz3v96rm/Op7hs7MhwA7eoY3w/3segEfY0oQBtnH2mF6Z1/KYu4eIb803XsBp5oywOiQpPEj9 +pgVsRJhPMHMkTxMkpsl8cbxMrpbBxnvClGoZfQiyZIe1kJ9c3tRifK7lYIlYVucHPMeDxk0tyrSWpFRr +2cEoDIxCSlFckjtnI+F8qmWhASOhzXKu+xEx92Qh2I/SynGQPQ3a1WOQ1eQz1Rx52QdMCi86REnJwtlc +k9C+ykJe7onXWlbHMLGW7XHkhoRXUe0jiC3BeRpEG0kSxWsRyZWNiK4kVXXjJc+G1Z6ShPanM2+RxvS6 +T4QdM6KfKIFCHjHemg8IPoGFMXqkNs3ZE95co70Y66O+5Yg0qZya6KkWUVNkIStfKLhtrx1YOckYpcQe +sWu+epVrwOCPKuWMm16eerc2uKM/ZI4n89SY/0nVt2pMuQxO75FgzDiAnaynlPXmNTWgfVcX2bE6uGkp +5IIuHPXoMixwqoHZ/Tf3ZO3LEst8GeZD5NknFfLRXRmtz25cwuYy4seHfwtNeIbltRt+Ncvtn7ulO/gl +dqml+0Vo/TTMuVzOmmcUQRqIa8xvXKP/yh+gT2I+Z7brohtj7t60X/v3AAAA//+/cbqZDgYAAA== +`, + }, + + "/songs/Worthy You Are Worthy.md": { + local: "songs/Worthy You Are Worthy.md", + size: 745, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8xSu27jMBDs9yumc+PDfcAZB/gKXxwkcBPASElZa5EIxTX4sKC/z5J2nDRBUkZQIXJn +hjMj7iVmOy/xLAXryLis6Zc+tDpF/ksfEUYR03VNj+VgMcptC9magC1egkw63uJgQpAMN5rBBf4Dui8p +w8qEwUt0UtKbKNE69LgxOlYCsiCz93SnhJ75BAMvZ26cLrow0A4PEnuMM9jEBGt0avWzhxwrjP6VDHXT +EDNfEYk5EOl4cbP+/VV11TFO0bjEPW00/pkjjNo36M1M9F+zaT1bDE4Pq0lnetIolrELKmMFSW0020mK +r/o4SlGFkZtQ24hcIUybKGMjJ2t0rh1nTCZVtkzhy+JGjgd3LL6KLtRPV8Nfelv+sOL2vPAeSX+s7uqr +ocfqp4a3brCsl+dC/xSqJ8b3yxW0MKLV73aNXwMAAP//iFzd0ukCAAA= +`, + }, + + "/songs/You Alone Can Rescue.md": { + local: "songs/You Alone Can Rescue.md", + size: 792, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/9RSXWrcMBB+1ym+A7j0AktLKbQvC4WysORRsceWQPaYGdlm33KNXC8nyUhZspsNhLzG +Lzbjb74/6Y4X/Eo8EX77Cf9J24XcN3vcbhb64Y6BG3DAnqVr0PKSOqhfCTnQqJRW0gbuECgKeJughjjD +Avn007l/i0CDHwmbV3REM4ltm5pRQMk78yAYxLeE+IrQHFNy5R989dfahlR/Dd5Oi58bYIp9xqLohceq +Y/QGqqi2eOmK2czo49QZ0DIkKh/gJYN7c+FzcO7AV1r3ZK9BK1+IQyDNmMVHfSG+6imUhkbfEbylPpV+ +zIFRootrtHEhLf0494cFW6AJpQQbSVZsJITeC3xZrvUkNsaNpox+ETNwKagcwAUyMOk7yBfp8EhnzbmW +QacS7XaCov/08Cj1CuJvXC2oie1j/1mKDxl23+u9fw4AAP//KsXbmBgDAAA= +`, + }, + + "/songs/You Are So Good To Me - Third Day.md": { + local: "songs/You Are So Good To Me - Third Day.md", + size: 1089, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8xUy2rDMBC8+yvmAxr6A6EQKH1BT8mlRyVaW6KK1qykBP99VwpNTUvpJYH6YrwzmpnV +Ln7jgpUQ1oxHZosN45WwwMZ5sbg3U7fQp1uOQnddJRslb8mU7PsSsJ+QjkT55vRC4jhcmLaKFs84+hCQ +fBxgBuNj1+HzeGIMNXlm7KmJOjJNayv8TrF+Sj67af3BZEcCH/FE5kAqdg2ty3TfeOItoYwcoWbYBS42 +NSCQsZq05q1IlpLdWblW1qMXnzVeqhLa01X0/stOzOaSsihREwa20xywJu7qEXFTdvs5MpL0tMsV0ca+ +W3DfNq5noQPJyWvkImTBJcMoT0uCbdAFaqj1in3dsnBKc7sXSiXh6BiBD5TOl3kV0d+2dYb9GO0fssvb +9k/4CAAA///X6O2mQQQAAA== +`, + }, + + "/songs/You Hold Me Now.md": { + local: "songs/You Hold Me Now.md", + size: 1183, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8yUT4/TMBDF7/4Uc9tLEV9ghbQXRAWUCxLi6DYvsVnHjmwnVr49b9xuEX+OSNBLG3vm ++c3vOf2aVnmXwiAfIafUzCt+zOOS8cZ8ilKdrTLYXZpDlKMUwDyFcF3XVmc3yJiyzDBf7jV9a7QXSE39 +25jPDhlS1pzTGgcMct61KsuUdV9F511G2FykNCxVbLO7OaoHSPCTq5JG2bUF87k39QO7SEi04YtYyhwl +AoN5ioMaw4bMJTvLmGlee+hDNUvlQmUPn2c7QOUnktAzuyghFEQO4WADHVsqNpcCzAfUq0SKU9E+Vmz0 +kn3pI9MlraTI805JGrD4OB0kJnFr5hzUtj7qXlnHEZm7V5oaxAwWNvPrs1YPNj9HlKJKxV+eEdmpG84P +f9A4/C7SeRJU8COIpaWVm6VyNCbEaCanMXxLe5+WP7vR9+xV/arwHoiMqcFWkuXduGXbl11acL0csYMf +ybXcmHem0c49KJ5fidQx15+SWrIlw9JJmrcEpZinkPKumLvEiRLm+DDLGcFjU1/jrbC7+ZFw08ukc2ye +qWmSF9iCQ79tF53Ap0grGw/0URbopfoX2f6VaJUWmEn0dX95n+idnprn08Qxb+/uC1FOcw/lf5vm8XX/ +D/oeAAD//4MBK8+fBAAA +`, + }, + + "/songs/You Never Let Go.md": { + local: "songs/You Never Let Go.md", + size: 1097, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/9RUzYrbMBC+z1PMLZeWvsBS2EJbAkt7aGHZo2KNIxFZE+Sxjd++n+TQLqQ+FHrZHAIz +0nx/I/yiE3+TWQo/ifFXpff40cO1yEf6PEtmCzqdAx95celCFkorLQjPLiVZSftWjcF5XRiVF2eBAFz4 +KqWXzjjpLBRH7txoMZ9ZJ+NeXGGix+xZKtES8Hc8DLgEBqOYG+4QvU/ym8W0DCO3Cngp9kKQpvlgbFPJ +fHLdBZ1LhpbqzRXhDKaNCFdjSht1VvDGRF+08LDCumcgLtECD9Jux/4vB89BhyolV8fAOja0vTZ9DyB6 +16TkFnNCzGeln6+C7FwayIHwdbrN6f78MUP9oawcIgZcC7GWSZf9oSct/r5d04SxW0CdgwURdggXa4AW +Z9V/pwM2Rz3SqvIC3N0OgyaPlWR65HPSEnUab7MnWRWgNQ+MX7GLjQUAWEtbxQlMsJI9mdb+KGwI4ZRk +pE94JVO2mDYe79YKg4NnOWA0xRmX9c+uG6puz6bKC28q/hcZ7+Onf4j/v0RLPyy259sgrsVFjEHybp8e +PrSPxa8AAAD//4hCFYpJBAAA +`, + }, + + "/songs/Your Grace is Enough.md": { + local: "songs/Your Grace is Enough.md", + size: 804, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/8yTwU77MAzG73kK33b5/8ULTEgc0IAjnDh6qduEpXFlJ6v29ripmNiEhOBEb/2+5LP9 +s/LKVWAn6Amiwn3mOgT33z63nYRu3U4Iy2K1gz3GEvqaMqn+Aw6w486ZA7OQlkQwmw8lEGjMmWSjsBqq +EAiluHY6EXZQFfYn0BJTghkLiQLmDgrDSOJP7s5+MpcQ8wAeMxyIpuUSTi3nhS16pHFPsvY2EU+J3POF +6ENMnVC+kifhMSqdR3BNHT4w0IrhByr0LNa3u+KV+Ehtqrdqg3oraNWAe3hCz/vGoio1YDPhYRm+sWkE +i3AeLoHFvFpmLCmthmI6YomcGzE0mp9wLHsYTGxJfxTZ11ceCI+UrWH0gRS4loVO1V+FPW5G8LYLoW5h +eN7NN2Hbm/YG3gMAAP//Y0TuPSQDAAA= +`, + }, + + "/songs/Your Love Never Fails.md": { + local: "songs/Your Love Never Fails.md", + size: 1003, + modtime: 1516147813, + compressed: ` +H4sIAAAJbogA/+xTQW7cOgzd6xTczerPP8AEBdoCBQwUWWXTJWPTljq2aEhyDO96je58Fh+lJ+mjJkkL +FM0JOsDAgkg+vvcoftEl0Wd9ErqXJ0n0icOY3X/4ubs5yTt3r8WHOFDLkbLMnLiIQ2qk0FNDCde88uYM +6NhHIB17rFB9hXLH3hz7NepaD7mEcaSJr0JTyAXfTI9LIZQ7z6ARZaVJUhsQ6DXhTIa2dW/1QMCgeTv2 +4hHMPIkdky6Df77jQfKF/oA49tZzRMw9eEm4nQzlUWjmEI/d/rU8hsEXo3rsXxUZrU6SX+M0aYqwybn3 +saPVy0uZtsIReQntL66hTuOPb98LVa1FCY24Txy6M7kP0vKSBa6aXVQ8F9p0IWMLH85/1/9grdYQOxDK +5kTSOECyXVQaK6aWTgh1IvMFrWB5c5oAoxDEo0Yk3fQ/KwIPnU1GFs7uYyX2xowrAziZpxuFnpFZVI1W +JxdqXu0u3oaCrs0J7JJw+zIhvDRLyCioBH+9zX/D/k0/VQNshRxjl+p6Zlo1XdFjEDPxtjkbDard2d39 +Xzf5ZwAAAP//8Jz63usDAAA= +`, + }, + + "/templates/admin-login.html": { + local: "templates/admin-login.html", + size: 790, + modtime: 1516195176, + compressed: ` +H4sIAAAJbogA/6SSTW7DIBCF9zkFYm+h7m1L3bdq1LQHwDCJUYFB/DTJ7YsNie1KrVR1NzO89/iwpx0f ++kdplCVPeFK2ZbnftVJ9EqF5CB0VYCN42u8IaY/ozW3ukodmHtyrhmt1siAp4SIqtB1lfIpmEvUUTomB +OKLs6P7l8DZHTqEKtAwQS5sHq8vnaIE2etTNyWNy9CbLQs0H0CTf3NFkaf8ewFtuoGXzwUqorEuRKDnr +yKQpVby6XEW4REqc5gJG1BKmuBqVX5IiHlGkcMdjma/f/QfWnWm/z5YzevkbbNZV2KkqsK76vgHfx3/D +DD8QejBghvzbt6YRxMeAl5Vpw7u4CvXSF/bFT17rEXmGBWD7KeoLajOkGNHWoJAGo+IWrgpWdeO8Mtxf +aX+Y9S0r87p3bL14ucsLnDe/XPoVAAD//50cA/gWAwAA +`, + }, + + "/templates/footer.html": { + local: "templates/footer.html", + size: 228, + modtime: 1516195311, + compressed: ` +H4sIAAAJbogA/1yPwQqDMAyG7z5FyV1Ez7HvUteAhWwZJhV8+7lNsTaH5PB95OfHLqbVN7hvl+IIT4mB +W1lp4bCBb5zDn+D2wbkvHEvGBB67uT/xUGDN02UMh3FPmSRuX3wFVDybyUvhgJX34KA6wkJK1r4zc/Hq +bPU/nwAAAP///4iBjuQAAAA= +`, + }, + + "/templates/header.html": { + local: "templates/header.html", + size: 189, + modtime: 1516195277, + compressed: ` +H4sIAAAJbogA/7JJySxTSM5JLC62VUoDUhkKyal5JalFCtXVem4gvjNIrrZWyY5LAS7mm1pcnJieWlvL +ZaMP1G/HhWxKcj5Qf14JVINCZpqCXnBpUkhmSU6qAlCHggKy4ozUxJTUIt3c1LxSsAagbIaRHdAemJba +Wht9oAhIG8QqsKGpeSkgswABAAD//92HwGe9AAAA +`, + }, + + "/templates/htmlfooter.html": { + local: "templates/htmlfooter.html", + size: 115, + modtime: 1516195193, + compressed: ` +H4sIAAAJbogA/1IAAhv9lMwyOy4Qs7paoSgxLz1VQSVTR0GlTMHKVkEvOLkos6CkWKG2FqzEphjMVygu +SrZVAqoHqqqtVbKz0YeIw81JzUuBaLHRT8pPqbTjstHPKMnNseMCBAAA//8zytRAcwAAAA== +`, + }, + + "/templates/htmlheader.html": { + local: "templates/htmlheader.html", + size: 801, + modtime: 1516195211, + compressed: ` +H4sIAAAJbogA/5xSTY/TMBC991dMrT2uYxBCwCrpZVkJLoDUvaDVHlxnUk9x7GBPslRV/jtOP2hh98Qp +fvPx5s3LlPOPX2/vv3+7A8utW8zKwwegtKjr6ZGfLbIGY3VMyJXouZHvxWXK6xYrMRA+dSGyABM8o8+l +T1SzrWocyKDcg2sgT0zayWS0w+p18eoFqhqTidQxBX/B9lehZe4k/uxpqMStNhblVBeDu2j4EuQ+dWp0 +5H9ARFcJ3XUOJYfeWElmmmIjNpVQOuUdk6J2rRo9TKmi82sBvO2yLmr1GtUUeMaYbF7d9Az/SXfgY2KH +i92uWBJjcT+hcQQJU6RfHXGpDmWzWTmX8oEacAyf7+DD41HVwTxI0VRi8ulGKVP7TSqMC33dOB2xMKFV +eqN/KUerpKa//jZZGtSb4t0ZFZskFqU68OXjmD+gr6l5lPIoeLeDqP0a4Yqu4WqAmwqKJW8dJot5cRjH +Zz79yZ5Myhy5cxyPnmaYh5w6XxrwKV8mxuVe1HnE5dJnyrP4f7lLdbrwchXq7dG6mgaguhJOb0PPWdLv +AAAA//9ablv2IQMAAA== +`, + }, + + "/": { + isDir: true, + local: "/", + }, + + "/songs": { + isDir: true, + local: "/songs", + }, + + "/templates": { + isDir: true, + local: "/templates", + }, +} diff --git a/helpers.go b/helpers.go new file mode 100644 index 0000000..66d52ff --- /dev/null +++ b/helpers.go @@ -0,0 +1,52 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" +) + +type pageData struct { + Title string + SubTitle string + Stylesheets []string + HeaderScripts []string + Scripts []string + FlashMessage string + FlashClass string + LoggedIn bool + session *pageSession + Site *siteData + + TemplateData interface{} +} + +func (p *pageData) show(tmplName string, w http.ResponseWriter) error { + for _, tmpl := range []string{ + "htmlheader.html", + "header.html", + tmplName, + "footer.html", + "htmlfooter.html", + } { + if err := outputTemplate(tmpl, p, w); err != nil { + fmt.Printf("%s\n", err) + return err + } + } + return nil +} + +// outputTemplate +// Spit out a template +func outputTemplate(tmplName string, tmplData interface{}, w http.ResponseWriter) error { + n := "/templates/" + tmplName + l := template.Must(template.New("layout").Parse(FSMustString(site.DevMode, n))) + t := template.Must(l.Parse(FSMustString(site.DevMode, n))) + return t.Execute(w, tmplData) +} + +// redirect can be used only for GET redirects +func redirect(url string, w http.ResponseWriter, req *http.Request) { + http.Redirect(w, req, url, 303) +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..5bc2f98 --- /dev/null +++ b/main.go @@ -0,0 +1,159 @@ +package main + +//go:generate esc -o assets.go assets templates songs + +import ( + "bufio" + "flag" + "fmt" + "io/ioutil" + "log" + "net/http" + "os" + "strings" + + "golang.org/x/crypto/ssh/terminal" + + "github.com/gorilla/handlers" + "github.com/gorilla/mux" + "github.com/gorilla/sessions" + "github.com/justinas/alice" +) + +var port int +var ip string +var dir string + +var sessionSecret = "AChKj7na128CrKPPG0Rc" +var sessionStore = sessions.NewCookieStore([]byte(sessionSecret)) +var r *mux.Router +var site *siteData +var model *model + +type siteData struct { + Title string + DevMode bool +} + +func init() { + const ( + portDefault = 8080 + portUsage = "the port to listen on" + ipDefault = "127.0.0.1" + ipUsage = "the ip mask to listen for connections from" + dirDefault = "./" + dirUsage = "the directory to serve the app out of\nThere should be a 'songs' directory here." + ) + flag.StringVar(&ip, "ip", ipDefault, ipUsage) + flag.IntVar(&port, "port", portDefault, portUsage) + flag.StringVar(&dir, "dir", dirDefault, dirUsage) + if !strings.HasSuffix(dir, "/") { + dir = dir + "/" + } +} + +func main() { + flag.Parse() + loadModel() + + r := mux.NewRouter() + r.StrictSlash(true) + + //r.PathPrefix("/assets/").Handler(http.FileServer(FS(site.DevMode))) + // Public Subrouter + pub := r.PathPrefix("/").Subrouter() + pub.HandleFunc("/", handleMain) + + admin := r.PathPrefix("/admin").Subrouter() + admin.HandleFunc("/", handleAdmin) + admin.HandleFunc("/dologin", handleAdminDoLogin) + admin.HandleFunc("/dologout", handleAdminDoLogout) + admin.HandleFunc("/{action}", handleAdmin) + + http.Handle("/", r) + + chain := alice.New(loggingHandler).Then(r) + + listenAt := fmt.Sprintf("%s:%d", ip, port) + fmt.Println("Songbook Server listening at", listenAt) + log.Fatal(http.ListenAndServe(listenAt, chain)) +} + +func loadModel() { + model := NewModel(dir) + site = new(siteData) + if !model.hasUser() { + reader := bufio.NewReader(os.Stdin) + fmt.Println("Create new Admin user") + fmt.Print("Username: ") + un, _ := reader.ReadString('\n') + un = strings.TrimSpace(un) + var pw1, pw2 []byte + for string(pw1) != string(pw2) || string(pw1) == "" { + fmt.Print("Password: ") + pw1, _ = terminal.ReadPassword(0) + fmt.Println("") + fmt.Print("Repeat Password: ") + pw2, _ = terminal.ReadPassword(0) + fmt.Println("") + if string(pw1) != string(pw2) { + fmt.Println("Entered Passwords don't match!") + } + } + } + +} + +func handleMain(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + output, err := ioutil.ReadFile(dir + "currentsongs.html") + if err != nil { + output = []byte("Error reading current songs") + } + fmt.Fprint(w, string(output)) +} + +func initPageData(w http.ResponseWriter, req *http.Request) *pageData { + if site.DevMode { + w.Header().Set("Cache-Control", "no-cache") + } + p := new(pageData) + // Get the session + var err error + var s *sessions.Session + if s, err = sessionStore.Get(req, "songbook"); err != nil { + http.Error(w, err.Error(), 500) + return p + } + p.session = new(pageSession) + p.session.session = s + p.session.req = req + p.session.w = w + + // First check if we're logged in + userName, _ := p.session.getStringValue("name") + _ = userName + + p.Site = site + p.SubTitle = "Songbook" + p.Stylesheets = make([]string, 0, 0) + p.Stylesheets = append(p.Stylesheets, "/assets/vendor/css/pure-min.css") + p.Stylesheets = append(p.Stylesheets, "/assets/vendor/css/grids-responsive-min.css") + p.Stylesheets = append(p.Stylesheets, "/assets/vendor/font-awesome/css/font-awesome.min.css") + p.Stylesheets = append(p.Stylesheets, "/assets/css/gjvote.css") + + p.HeaderScripts = make([]string, 0, 0) + + p.Scripts = make([]string, 0, 0) + + p.FlashMessage, p.FlashClass = p.session.getFlashMessage() + if p.FlashClass == "" { + p.FlashClass = "hidden" + } + + return p +} + +func loggingHandler(h http.Handler) http.Handler { + return handlers.LoggingHandler(os.Stdout, h) +} diff --git a/model.go b/model.go new file mode 100644 index 0000000..4fdf7b8 --- /dev/null +++ b/model.go @@ -0,0 +1,61 @@ +package main + +import ( + "bytes" + "io/ioutil" + "strings" + + "github.com/BurntSushi/toml" +) + +func NewSongbookConfig(dir string) { + sc := &SongbookConfig{ConfigPath: dir + "songbook.toml"} + err := sc.Load() + return sc, err +} + +type SongbookConfig struct { + Username string `toml:"username"` + Password string `toml:"enc_pw"` + ConfigPath string `toml:"-"` +} + +func (sc *SongbookConfig) Load() error { + tomlData, err := ioutil.ReadFile(sc.ConfigPath) + if err != nil { + // Couldn't find the file, save a new one + if err = sc.Save(); err != nil { + return err + } + } + if _, err := toml.Decode(string(tomlData), &sc); err != nil { + return err + } + return nil +} + +func (sc *SongbookConfig) Save() error { + buf := new(bytes.Buffer) + if err := toml.NewEncoder(buf).Encode(sc); err != nil { + return err + } + return ioutil.WriteFile(sc.ConfigPath, buf.Bytes(), 0644) +} + +func NewModel(dir string) *model { + m := new(model) + m.config = NewSongbookConfig(dir) + return m +} + +type model struct { + config *SongbookConfig +} + +func (m *model) hasUser() bool { + // is there a user in the config? + if strings.TrimSpace(m.config.Username) == "" || strings.TrimSpace(m.Config.Password) == "" { + return false + } + return true +} diff --git a/page_session.go b/page_session.go new file mode 100644 index 0000000..a5fb7cd --- /dev/null +++ b/page_session.go @@ -0,0 +1,54 @@ +package main + +import ( + "fmt" + "net/http" + + "github.com/gorilla/sessions" +) + +// This is basically a convenience struct for +// easier session management (hopefully ;) +type pageSession struct { + session *sessions.Session + req *http.Request + w http.ResponseWriter +} + +func (p *pageSession) getStringValue(key string) (string, error) { + val := p.session.Values[key] + var retVal string + var ok bool + if retVal, ok = val.(string); !ok { + return "", fmt.Errorf("Unable to create string from %s", key) + } + return retVal, nil +} + +func (p *pageSession) setStringValue(key, val string) { + p.session.Values[key] = val + p.session.Save(p.req, p.w) +} + +func (p *pageSession) setFlashMessage(msg, status string) { + p.setStringValue("flash_message", msg) + p.setStringValue("flash_status", status) +} + +func (p *pageSession) getFlashMessage() (string, string) { + var err error + var msg, status string + if msg, err = p.getStringValue("flash_message"); err != nil { + return "", "hidden" + } + if status, err = p.getStringValue("flash_status"); err != nil { + return "", "hidden" + } + p.setFlashMessage("", "hidden") + return msg, status +} + +func (p *pageSession) expireSession() { + p.session.Options.MaxAge = -1 + p.session.Save(p.req, p.w) +} diff --git a/songbook b/songbook new file mode 100755 index 0000000..78c9d9e Binary files /dev/null and b/songbook differ diff --git a/templates/admin-login.html b/templates/admin-login.html new file mode 100644 index 0000000..8ae9711 --- /dev/null +++ b/templates/admin-login.html @@ -0,0 +1,23 @@ +

Admin Login

+
+
+
+
+ + +
+ +
+ + +
+ +
+ +
+ +
+
+
diff --git a/templates/footer.html b/templates/footer.html new file mode 100644 index 0000000..3076371 --- /dev/null +++ b/templates/footer.html @@ -0,0 +1,11 @@ + + diff --git a/templates/header.html b/templates/header.html new file mode 100644 index 0000000..689aeb9 --- /dev/null +++ b/templates/header.html @@ -0,0 +1,9 @@ +
+ {{.FlashMessage}} +
+
+ {{ if .SubTitle }} +
+

{{.SubTitle}}

+
+ {{ end }} diff --git a/templates/htmlfooter.html b/templates/htmlfooter.html new file mode 100644 index 0000000..10480dd --- /dev/null +++ b/templates/htmlfooter.html @@ -0,0 +1,6 @@ +
+ {{ range $i, $v := .Scripts }} + + {{ end }} + + diff --git a/templates/htmlheader.html b/templates/htmlheader.html new file mode 100644 index 0000000..6fb41eb --- /dev/null +++ b/templates/htmlheader.html @@ -0,0 +1,25 @@ + + + + + + + + + + + {{.Site.Title}} - {{.SubTitle}} + + + + {{ range $i, $v := .Stylesheets }} + + {{ end }} + {{ range $i, $v := .HeaderScripts }} + + {{ end }} + + +
diff --git a/templates/song-picker.html b/templates/song-picker.html new file mode 100644 index 0000000..730dfe5 --- /dev/null +++ b/templates/song-picker.html @@ -0,0 +1,74 @@ +{{ if not .TemplateData.Songs }} +
No songs are available
+{{ else }} +
+
+ + +
+
+
+ + + + + + + + + + + {{ range $i, $v := .TemplateData.Songs }} + Add + + + {{ end }} + +
Name
+
+ +{{ end }}