úÎo‘iw`      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_Dennis Gosnell 2017BSD3(Dennis Gosnell (cdep.illabout@gmail.com) experimentalunknownSafe¥This is a simple version of !, just used for tagging a given ` as a directory or a file.?This tree structure represents the directory structure on disk.A file with it's ` and contents as a a.A directory with it's ` and the files under it.Get the  for a given ` . Calls b% if it is not a file or a directory.  Convert a  to a  . Return c if the input  is , and that directory is empty. Convert an input directory ` to a !. Fails if the input directory ` is not a directory.  Just like  , but returns an error with b" if the input directory is empty.   Dennis Gosnell 2017BSD3(Dennis Gosnell (cdep.illabout@gmail.com) experimentalunknownSafe°Remove a leading period from a d.removeLeadingPeriod ".jpg""jpg"Just return the d# if it doesn't start with a period:removeLeadingPeriod "hello""hello"GReturn an empty string if the only character in the string is a period:removeLeadingPeriod "."""Remove at most one period:removeLeadingPeriod "..bye"".bye"Return an extension for a ` . Just like e), but doesn't return the leading period.getExtension "/some/file.html""html"5Empty string is returned for files with no extension:getExtension "file"""Dennis Gosnell 2017BSD3(Dennis Gosnell (cdep.illabout@gmail.com) experimentalunknownNone  .>?.í%GEXF file (xml for graph application)XML file JSON file#Hold f;s and functions work working with a given file type, like html or js.You can find examples of # in the function ,.%A g fw representing a type to use for the content type of a Servant API. For instance, HTML files will use something like [t||]2, while Javascript files will use something like [t||].&A g fx representing the type to use for the return vale of a Servant API. For instance, HTML files will use something like [t||]1, while JavascriptFiles will use something like [t|a|].'A function that turns a a into an h. For an example, look at + and byteStringtoExp.,!A mapping from an extension like html or js to a # for that extension.- Just like ., but throw an error using b! if the extension for the given ` is not found.. Lookup the # for a given ` (that has an extension like .html or .js ). Returns c if the #' for the given extension is not found.0 text/css2  image/gif4  image/jpeg6 icon/ico8 application/javascript:  image/png<  image/svg>  text/plain@  fonts/eotB  fonts/ttfD  fonts/woffF  fonts/woff2H application/jsonJ application/xmlL application/gexf !"#$'&%()*+,-.9#$%&'()*+,-."0/!21 436587:9<;>=@?BADCFEHGJILK#$%&'NoneQVJP(Take a template directory argument as a ` and create a iZ function that serves the files under the directory. Empty directories will be ignored.ØNote that the file contents will be embedded in the function. They will not be served dynamically at runtime. This makes it easy to create a Haskell binary for a website with all static files completely baked-in.HFor example, assume the following directory structure and file contents: A $ tree dir/ dir/ %%% js %   %%% test.js %%% index.html  a $ cat dir/index.html <p>Hello World</p> $ cat dir/js/test.js console.log("hello world"); P is used like the following: X {-# LANGUAGE DataKinds #-} {-# LANGUAGE TemplateHaskell #-} type FrontEndAPI = $( "dir") frontEndServer :: j m => i$ FrontEndAPI m frontEndServer = $(P "dir") ƒAt compile time, this expands to something like the following. This has been slightly simplified to make it easier to understand: # type FrontEndAPI = "js"    "test.js"       '[]    k "index.html"       '[]  frontEndServer :: j m => i+ FrontEndAPI m frontEndServer = l% "console.log(\"hello world\");" k l "<p>Hello World</p>" QThis is similar to P1, but it creates the whole function declaration.Given the following code: E {-# LANGUAGE DataKinds #-} {-# LANGUAGE TemplateHaskell #-} $(Q! "FrontAPI" "frontServer" "dir") 2You can think of it as expanding to the following:  frontServer :: j m => i FrontAPI m frontServer = $(P "dir") Qname of the api type synonymname of the server function!directory name to read files fromMNOPQMNOPQNone-STZÓSGiven a list of g f!, combine them with Servant's '(: |&)' function and return the resulting g f.U(Take a template directory argument as a `i and create a Servant type representing the files in the directory. Empty directories will be ignored.6For example, assume the following directory structure: A $ tree dir/ dir/ %%% js %   %%% test.js %%% index.html U is used like the following: X {-# LANGUAGE DataKinds #-} {-# LANGUAGE TemplateHaskell #-} type FrontEndAPI = $(U "dir") 1At compile time, it will expand to the following: # type FrontEndAPI = "js" m "test.js" m n '[]    k "index.html" m n '[]  VThis is similar to U5, but it creates the whole type synonym declaration.Given the following code: E {-# LANGUAGE DataKinds #-} {-# LANGUAGE TemplateHaskell #-} $(V "FrontAPI" "dir") 2You can think of it as expanding to the following:  type FrontAPI = $(U "dir") U!directory name to read files fromVname of the api type synonym!directory name to read files fromRSTUVRSTUVNone[31  !"#$%&'()*+,-.MNOPQRSTUVDennis Gosnell 2017BSD3(Dennis Gosnell (cdep.illabout@gmail.com) experimentalunknownNoneh WThis is the directory "frontend/dist".X This is the d  "FrontEnd".Y This is the d "frontEndServer".ZThis is the same as U W.[This is the same as V X W.\This is the same as P W.]This is the same as Q X Y W.^This is a combination of V and Q3. This function is the one most users should use.Given the following code: E {-# LANGUAGE DataKinds #-} {-# LANGUAGE TemplateHaskell #-} $(^! "FrontAPI" "frontServer" "dir") 2You can think of it as expanding to the following:  $(V "FrontAPI" "dir") $(Q! "FrontAPI" "frontServer" "dir") _This is the same as ^ X Y W.^name of the api type synonymname of the server function!directory name to read files from !"PQUVWXYZ[\]^_UVPQ^"! WXYZ[\]_o !"#$%&'()*+,-./01234566789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstu qvwqvxqvyz{|}~}~€}~‚ƒ„qv…†‡ˆqv‰†Š †‹ Œ0servant-static-th-0.2.2.0-1WfHkUOW1nE4dpTfxl52UiServant.Static.TH#Servant.Static.TH.Internal.FileTreeServant.Static.TH.Internal.UtilServant.Static.TH.Internal.Mime!Servant.Static.TH.Internal.ServerServant.Static.TH.Internal.ApiServant.Static.TH.Internal.API createApiType Servant.API:>GetData.ByteString ByteStringServant.HTML.BlazeHTMLText.Blaze.HtmlHtmlServant.Static.TH.Internal(blaze-html-0.9.1.1-DoAL600Quo3KrEJqTmOx3(servant-blaze-0.8-9NyLv9EcpuZI0HgEoZML8bFileType FileTypeFile FileTypeDirFileTree FileTreeFile FileTreeDir getFileTypefileTypeToFileTree getFileTreegetFileTreeIgnoreEmpty $fEqFileTree$fReadFileTree$fShowFileTree $fEqFileType$fReadFileType$fShowFileTyperemoveLeadingPeriod getExtensionGEXFXMLJSONWOFF2WOFFTTFEOTTXTSVGPNGJSICOJPEGGIFCSS MimeTypeInfomimeTypeInfoContentTypemimeTypeInfoRespTypemimeTypeInfoToExpression stringToBsbyteStringToExputf8ByteStringToExp htmlToExpextensionMimeTypeMapextensionToMimeTypeInfoExextensionToMimeTypeInfo$fMimeRenderTYPECSSByteString$fAcceptTYPECSS$fMimeRenderTYPEGIFByteString$fAcceptTYPEGIF$fMimeRenderTYPEJPEGByteString$fAcceptTYPEJPEG$fMimeRenderTYPEICOByteString$fAcceptTYPEICO$fMimeRenderTYPEJSByteString$fAcceptTYPEJS$fMimeRenderTYPEPNGByteString$fAcceptTYPEPNG$fMimeRenderTYPESVGByteString$fAcceptTYPESVG$fMimeRenderTYPETXTByteString$fAcceptTYPETXT$fMimeRenderTYPEEOTByteString$fAcceptTYPEEOT$fMimeRenderTYPETTFByteString$fAcceptTYPETTF$fMimeRenderTYPEWOFFByteString$fAcceptTYPEWOFF$fMimeRenderTYPEWOFF2ByteString$fAcceptTYPEWOFF2$fMimeRenderTYPEJSONByteString$fAcceptTYPEJSON$fMimeRenderTYPEXMLByteString$fAcceptTYPEXML$fMimeRenderTYPEGEXFByteString$fAcceptTYPEGEXFcombineWithExpcombineWithServantOrfileTreeToServercreateServerExpcreateServerDecfileTreeToApiTypecombineWithServantOrTcombineWithType createApiDecfrontEndTemplateDirfrontEndApiNamefrontEndServerNamecreateApiFrontEndTypecreateApiFrontEndDeccreateServerFrontEndExpcreateServerFrontEndDeccreateApiAndServerDecscreateApiAndServerFrontEndDecsbaseGHC.IOFilePathbytestring-0.10.8.2Data.ByteString.InternalGHC.BasefailNothingStringfilepath-1.4.1.2System.FilePath.Posix takeExtensiontemplate-haskellLanguage.Haskell.TH.SyntaxTypeQExp*servant-server-0.12-7ItyRphZVdc8qWtEkdCdrbServant.Server.InternalServerT Applicative%servant-0.12.1-IQpBeDNqCOaI4mofnuNxjcServant.API.Alternative:<|>pureServant.API.SubServant.API.Verbs