--------------------------------------------------------------------------------
{-# LANGUAGE OverloadedStrings #-}
import           Control.Monad (filterM)
import           Data.Maybe (fromMaybe)
import           Data.Monoid (mappend)
import           Data.Time
import           Data.Time.Format (parseTimeM, defaultTimeLocale, formatTime)
import           Hakyll


--------------------------------------------------------------------------------
main :: IO ()
main = hakyll $ do
    match "images/**" $ do
        route   idRoute
        compile copyFileCompiler

    match "lib/**" $ do
        route   idRoute
        compile copyFileCompiler

    match "css/*" $ do
        route   idRoute
        compile compressCssCompiler

    match (fromList ["about.rst", "contact.markdown"]) $ do
        route   $ setExtension "html"
        compile $ pandocCompiler
            >>= loadAndApplyTemplate "templates/default.html" staticPageContext
            >>= relativizeUrls

    match "posts/**/*" $ do
        route $ setExtension "html"
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            pandocCompiler
                >>= loadAndApplyTemplate "templates/post.html"    (postCtx lang)
                >>= loadAndApplyTemplate "templates/default.html" (postCtx lang)
                >>= relativizeUrls

    match "events/**/*" $ do
        route $ setExtension "html"
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            pandocCompiler
                >>= loadAndApplyTemplate "templates/event.html"   (postCtx lang)
                >>= loadAndApplyTemplate "templates/default.html" (postCtx lang)
                >>= relativizeUrls

    match "pages/en/japan/language/**" $ do
        route $ setExtension "html"
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            pandocCompiler
                >>= loadAndApplyTemplate "templates/japan/language-note.html"   (postCtx lang)
                >>= loadAndApplyTemplate "templates/default.html" (postCtx lang)
                >>= relativizeUrls

    match "pages/*/plamo/equipment/**" $ do
        route $ setExtension "html"
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            pandocCompiler
                >>= loadAndApplyTemplate "templates/equipment.html" (postCtx lang)
                >>= loadAndApplyTemplate "templates/default.html" (postCtx lang)
                >>= relativizeUrls

    match "pages/*/plamo/model-kits/**" $ do
        route $ setExtension "html"
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            let dateValue = lookupString "date" metadata
                purchaseDateValue = lookupString "purchase_date" metadata
                formattedPurchaseDate = maybe "" (formatDate lang) purchaseDateValue
                modelKitTemplate = 
                    if dateValue == Just "1990-01-01"
                        then "templates/model-kit-not-ready.html"
                        else "templates/model-kit.html"

                extendedCtx = constField "formatted_purchase_date" formattedPurchaseDate <> (postCtx lang)

            pandocCompiler
                >>= loadAndApplyTemplate modelKitTemplate extendedCtx
                >>= loadAndApplyTemplate "templates/default.html" extendedCtx
                >>= relativizeUrls

    match "pages/*/radio/**/*" $ do
        route $ setExtension "html"
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            pandocCompiler
                >>= loadAndApplyTemplate "templates/radio.html" (postCtx lang)
                >>= loadAndApplyTemplate "templates/default.html" (postCtx lang)
                >>= relativizeUrls

    match "pages/*/software/**" $ do
        route $ setExtension "html"
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            pandocCompiler
                -- >>= loadAndApplyTemplate "templates/software-post.html"   (postCtx lang)
                >>= loadAndApplyTemplate "templates/default.html" (postCtx lang)
                >>= relativizeUrls

    match (fromList
        [ "nl/plamo.html"
        , "jp/plamo.html"
        , "en/plamo.html"
        ]) $ do
        route idRoute
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            let url = "pages/" ++ lang ++ "/plamo/model-kits/**"
            kits <- recentFirst =<< loadAll (fromGlob (url))

            let plamoCtx =
                    listField  "kits" (kitCtx lang) (return kits) <>
                    lastUpdateField lang <>
                    langDict lang <>
                    defaultContext

            getResourceBody
                >>= applyAsTemplate plamoCtx
                >>= loadAndApplyTemplate "templates/default.html" plamoCtx
                >>= relativizeUrls

    match (fromList
        [ "nl/japan.html"
        , "jp/japan.html"
        , "en/japan.html"
        ]) $ do
        route idRoute
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            notes <- loadAll "pages/en/japan/language/notes/*"
            teforms <- loadAll "pages/en/japan/language/te-form/*"
            particles <- loadAll "pages/en/japan/language/particles/*"
            adverbial_particles <- loadAll "pages/en/japan/language/particles/adverbial-particles/*"
            binding_particles <- loadAll "pages/en/japan/language/particles/binding-particles/*"
            verbs <- loadAll "pages/en/japan/language/verbs/*"
            other <- loadAll "pages/en/japan/language/other/*"

            let japanCtx =
                    listField "notes" (postCtx lang) (return notes) <>
                    listField "teforms" (postCtx lang) (return teforms) <>
                    listField "particles" (postCtx lang) (return particles) <>
                    listField "adverbial_particles" (postCtx lang) (return adverbial_particles) <>
                    listField "binding_particles" (postCtx lang) (return binding_particles) <>
                    listField "verbs" (postCtx lang) (return verbs) <>
                    listField "other" (postCtx lang) (return other) <>
                    lastUpdateField lang <>
                    langDict lang <>
                    defaultContext

            getResourceBody
                >>= applyAsTemplate japanCtx
                >>= loadAndApplyTemplate "templates/default.html" japanCtx
                >>= relativizeUrls

    match (fromList
        [ "nl/radio.html"
        , "jp/radio.html"
        , "en/radio.html"
        ]) $ do
        route idRoute
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            antenna   <- loadAll $ (fromGlob ("pages/" ++ lang ++ "/radio/antenna/*"))
            fielddays <- loadAll $ (fromGlob ("pages/" ++ lang ++ "/radio/fielddays/*"))
            fielddays <- recentFirst fielddays

            let radioCtx =
                    listField "antenna"   (postCtx lang) (return antenna) <>
                    listField "fielddays" (postCtx lang) (return fielddays) <>
                    lastUpdateField lang <>
                    langDict lang <>
                    defaultContext

            getResourceBody
                >>= applyAsTemplate radioCtx
                >>= loadAndApplyTemplate "templates/default.html" radioCtx
                >>= relativizeUrls

    match (fromList
        [ "nl/software.html"
        , "jp/software.html"
        , "en/software.html"
        ]) $ do
        route idRoute
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            projects <- loadAll $ (fromGlob ("pages/" ++ lang ++ "/software/projects/*"))
            projects <- recentFirst projects

            let softwareCtx =
                    listField "projects" (postCtx lang) (return projects) <>
                    lastUpdateField lang <>
                    langDict lang <>
                    defaultContext

            getResourceBody
                >>= applyAsTemplate softwareCtx
                >>= loadAndApplyTemplate "templates/default.html" softwareCtx
                >>= relativizeUrls

    match (fromList
        [ "nl/code/blazor.html"
        , "jp/code/blazor.html"
        , "en/code/blazor.html"
        ]) $ do
        route idRoute
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            blazorPages  <- loadAll "pages/en/software/code/blazor/*"

            let softwareCtx =
                    listField "blazorPages"  (postCtx lang) (return blazorPages) <>
                    lastUpdateField lang <>
                    langDict lang <>
                    defaultContext

            pandocCompiler
                >>= loadAndApplyTemplate "templates/code.html"    softwareCtx
                >>= loadAndApplyTemplate "templates/default.html" softwareCtx
                >>= relativizeUrls

    match (fromList
        [ "nl/code/elm.html"
        , "jp/code/elm.html"
        , "en/code/elm.html"
        ]) $ do
        route idRoute
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            elmPages     <- loadAll "pages/en/software/code/elm/*"

            let softwareCtx =
                    listField "elmPages"     (postCtx lang) (return elmPages) <>
                    lastUpdateField lang <>
                    langDict lang <>
                    defaultContext

            pandocCompiler
                >>= loadAndApplyTemplate "templates/code.html"    softwareCtx
                >>= loadAndApplyTemplate "templates/default.html" softwareCtx
                >>= relativizeUrls

    match (fromList
        [ "nl/code/haskell.html"
        , "jp/code/haskell.html"
        , "en/code/haskell.html"
        ]) $ do
        route idRoute
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            haskellPages <- loadAll "pages/en/software/code/haskell/*"

            let softwareCtx =
                    listField "haskellPages" (postCtx lang) (return haskellPages) <>
                    lastUpdateField lang <>
                    langDict lang <>
                    defaultContext

            pandocCompiler
                >>= loadAndApplyTemplate "templates/code.html"    softwareCtx
                >>= loadAndApplyTemplate "templates/default.html" softwareCtx
                >>= relativizeUrls

    match (fromList
        [ "nl/equipment.html"
        , "jp/equipment.html"
        , "en/equipment.html"
        ]) $ do
        route idRoute
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            equipment <- loadAll $ (fromGlob ("pages/" ++ lang ++ "/plamo/equipment/*"))

            let equipmentCtx =
                    listField "equipment" (postCtx lang) (return equipment) <>
                    lastUpdateField lang <>
                    langDict lang <>
                    defaultContext

            getResourceBody
                >>= applyAsTemplate equipmentCtx
                >>= loadAndApplyTemplate "templates/default.html" equipmentCtx
                >>= relativizeUrls

    match (fromList
        [ "nl/paints.html"
        , "jp/paints.html"
        , "en/paints.html"
        ]) $ do
        route idRoute
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            let paintsCtx =
                    lastUpdateField lang <>
                    langDict lang <>
                    defaultContext

            getResourceBody
                >>= applyAsTemplate paintsCtx
                >>= loadAndApplyTemplate "templates/default.html" paintsCtx
                >>= relativizeUrls

    match (fromList
        [ "nl/archive-events.html"
        , "jp/archive-events.html"
        , "en/archive-events.html"
        ]) $ do
        route idRoute
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            events  <- recentFirst =<< loadAll (fromGlob ("events/" ++ lang ++ "/*"))

            let eventsCtx =
                    listField "events"  (postCtx lang) (return events)  <>
                    lastUpdateField lang <>
                    langDict lang <>
                    defaultContext

            getResourceBody
                >>= applyAsTemplate eventsCtx
                >>= loadAndApplyTemplate "templates/default.html" eventsCtx
                >>= relativizeUrls

    match (fromList
        [ "nl/archive-posts.html"
        , "jp/archive-posts.html"
        , "en/archive-posts.html"
        ]) $ do
        route idRoute
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            posts  <- recentFirst =<< loadAll (fromGlob ("posts/" ++ lang ++ "/*"))

            let postsCtx =
                    listField "posts"  (postCtx lang) (return posts)  <>
                    lastUpdateField lang <>
                    langDict lang <>
                    defaultContext

            getResourceBody
                >>= applyAsTemplate postsCtx
                >>= loadAndApplyTemplate "templates/default.html" postsCtx
                >>= relativizeUrls

    match (fromList
        [ "index.html"
        , "nl/index.html"
        , "jp/index.html"
        , "en/index.html"
        ]) $ do
        route idRoute
        compile $ do
            identifier <- getUnderlying
            metadata   <- getMetadata identifier
            let language = lookupString "language" metadata
            let lang = fromMaybe "en" language

            posts  <- recentFirst =<< loadAll (fromGlob ("posts/" ++ lang ++ "/*"))
            now    <- unsafeCompiler getCurrentTime
            ident  <- getUnderlying
            --language <- getMetadataField' ident "language"

            -- Seven days from today.
            let cutoff = addUTCTime (negate 7 * 24 * 60 * 60) now

            events <-
                loadAll (fromGlob ("events/" ++ lang ++ "/*"))
                    >>= filterM (isUpcoming cutoff)
                    >>= chronological

            let indexCtx =
                    -- (<> is the modern version of `mappend`.)
                    listField "posts"  (postCtx lang) (return posts)  <>
                    listField "events" (postCtx lang) (return events) <>
                    lastUpdateField lang <>
                    langDict lang <>
                    defaultContext

            getResourceBody
                >>= applyAsTemplate indexCtx
                >>= loadAndApplyTemplate "templates/default.html" indexCtx
                >>= relativizeUrls

    match "templates/*" $ compile templateBodyCompiler
    match "templates/**/*" $ compile templateBodyCompiler


--------------------------------------------------------------------------------
staticPageContext :: Context String
staticPageContext =
        lastUpdateField "en" <>
        langDict "en" <>
        defaultContext

localeFor :: String -> TimeLocale
localeFor "nl" = dutchLocale
localeFor "jp" = japaneseLocale
localeFor _    = defaultTimeLocale

dutchLocale :: TimeLocale
dutchLocale = defaultTimeLocale
  { months =
      [ ("januari", "jan"), ("februari", "feb"), ("maart", "mrt")
      , ("april", "apr"), ("mei", "mei"), ("juni", "jun")
      , ("juli", "jul"), ("augustus", "aug"), ("september", "sep")
      , ("oktober", "okt"), ("november", "nov"), ("december", "dec")
      ]
  }

japaneseLocale :: TimeLocale
japaneseLocale = defaultTimeLocale
  { months =
      [ ("1月","1月"), ("2月","2月"), ("3月","3月")
      , ("4月","4月"), ("5月","5月"), ("6月","6月")
      , ("7月","7月"), ("8月","8月"), ("9月","9月")
      , ("10月","10月"), ("11月","11月"), ("12月","12月")
      ]
  }

formatStringFor :: String -> String
formatStringFor "en" = "%e %B %Y"
formatStringFor "nl" = "%e %B %Y"
formatStringFor "jp" = "%Y年 %m月 %e日"
formatStringFor _    = "%e %B %Y"

formatDate :: String -> String -> String
formatDate lang s =
    case parseTimeM True defaultTimeLocale "%Y-%m-%d" s :: Maybe Day of
        Just day -> formatTime (localeFor lang) (formatStringFor lang) day
        Nothing  -> s

lastUpdateField :: String -> Context a
lastUpdateField lang =
    field "last-update" $ \_ -> do
        now <- unsafeCompiler getCurrentTime
        let dayString = formatTime defaultTimeLocale "%Y-%m-%d" now
        pure $ formatDate lang dayString

postCtx :: String -> Context String
postCtx language =
    let
        -- Custom field for formatted date
        formattedDateField :: Context String
        formattedDateField = field "formatted_date" $ \item -> do
            -- Get the metadata for this item
            meta <- getMetadata (itemIdentifier item)
            let mDate = lookupString "date" meta
            return $ maybe "" (formatDate language) mDate

    in  -- Keep the original "date" field.
        dateField "date" "%e %B %Y" <>
        constField "language" language <>
        formattedDateField <>
        lastUpdateField language <>
        langDict language <>
        defaultContext

kitCtx :: String -> Context String
kitCtx language =
    (field "formatted_purchase_date" $ \item -> do
        metadata <- getMetadata (itemIdentifier item)
        let purchaseDateValue = lookupString "purchase_date" metadata
        return $ maybe "" (formatDate language) purchaseDateValue
    )
    <> (postCtx language)

isUpcoming :: UTCTime -> Item a -> Compiler Bool
isUpcoming cutoff item = do
    metadata <- getMetadata (itemIdentifier item)
    case lookupString "date" metadata of
        Nothing -> return False
        Just ds ->
            case parseTimeM True defaultTimeLocale "%Y-%m-%d" ds of
                Nothing   -> return False
                Just date -> return (date >= cutoff)

langDict :: String -> Context a
langDict "nl" =
    constField "filter" "Filter" <>
    constField "filter-plamo-in-box" "Nog in het doosje" <>
    constField "filter-plamo-building" "Aan het bouwen" <>
    constField "filter-plamo-built" "Gebouwd" <>
    constField "filter-plamo-complete" "Compleet" <>
    constField "filter-plamo-category-aircraft" "Luchtvaartuig" <>
    constField "filter-plamo-category-armoured-car" "Pantserwagen" <>
    constField "filter-plamo-category-automobile" "Automobiel" <>
    constField "filter-plamo-category-fantasy-vehicle" "Fantasie-voertuig" <>
    constField "filter-plamo-category-figure" "Figuur" <>
    constField "filter-plamo-category-gundam" "Gundam" <>
    constField "filter-plamo-category-mecha" "Mecha" <>
    constField "filter-plamo-category-motorcycle" "Motorfiets" <>
    constField "filter-plamo-category-spacecraft" "Ruimtevaartuig" <>
    constField "filter-plamo-category-tractor" "Trekker" <>
    constField "filter-plamo-series-msg" "Mobile Suit Gundam" <>
    constField "filter-plamo-series-msg-pocket" "Mobile Suit Gundam 0080: War in the Pocket" <>
    constField "filter-plamo-series-msg-stardust" "Mobile Suit Gundam 0083: Stardust Memory" <>
    constField "filter-plamo-series-msg-char" "Mobile Suit Gundam: Char's Counterattack" <>
    constField "filter-plamo-series-msg-gqx" "Mobile Suit Gundam GQuuuuuuX" <>
    constField "filter-plamo-series-msg-ironblood" "Mobile Suit Gundam Iron Blooded Orphans" <>
    constField "filter-plamo-series-msg-seed" "Mobile Suit Gundam SEED" <>
    constField "filter-plamo-series-msg-seed-destiny" "Mobile Suit Gundam SEED Destiny" <>
    constField "filter-plamo-series-msg-seed-freedom" "Mobile Suit Gundam SEED Freedom" <>
    constField "filter-plamo-series-msg-witch" "Mobile Suit Gundam the Witch from Mercury" <>
    constField "filter-plamo-series-msg-unicorn" "Mobile Suit Gundam Unicorn" <>
    constField "filter-plamo-series-msg-zz" "Mobile Suit Gundam ZZ" <>
    constField "filter-plamo-series-msg-zeta" "Mobile Suit Zeta Gundam" <>
    constField "filter-plamo-series-gundam-wing-endless-waltz" "Gundam Wing: Endless Waltz" <>
    constField "filter-plamo-series-mfg-gundam" "Mobile Fighter G Gundam" <>
    constField "filter-plamo-series-gundam-bf-try" "Gundam Build Fighters Try" <>
    constField "filter-plamo-series-dragonball" "Dragonball" <>
    constField "filter-plamo-series-dragonball-z" "Dragonball Z" <>
    constField "filter-plamo-series-halo" "Halo" <>
    constField "filter-plamo-series-ikaruga" "Ikaruga" <>
    constField "filter-plamo-series-kampf-riesen-mars" "Kampf Riesen Mars 1941/1945" <>
    constField "filter-plamo-series-kyoukai-senki" "Kyōkai Senki, Amaim Warrior at the Borderline" <>
    constField "filter-plamo-series-maschinen-krieger" "Maschinen Krieger" <>
    constField "filter-plamo-series-nausicaa" "Nausicaä of the Valley of the Wind" <>
    constField "filter-plamo-series-patlabor" "Mobile Police Patlabor" <>
    constField "filter-plamo-series-pokemon" "Pokémon" <>
    constField "filter-plamo-series-space-battleship-yamato" "Space Battleship Yamato" <>
    constField "filter-plamo-series-star-wars" "Star Wars" <>
    constField "filter-plamo-series-transformers" "Transformers" <>
    constField "filter-plamo-series-xenoblade-x" "Xenoblade Chronicles X" <>
    constField "switcher" "Taal" <>
    constField "title-japan" "Japan" <>
    constField "title-plamo" "Plamo" <>
    constField "title-radio" "Radio" <>
    constField "title-software" "Software" <>
    constField "posted-on" "Geplaatst op:" <>
    constField "text-plamo-not-ready" "Deze model-kit heeft nog geen gepubliceerd werk." <>
    constField "text-plamo-back" "Terug naar plamo kits" <>
    constField "text-radio-back" "Terug naar radio overzicht" <>
    constField "table-plamo-model-info" "Model-informatie" <>
    constField "table-plamo-status" "Status" <>
    constField "table-plamo-model" "Model" <>
    constField "table-plamo-category" "Categorie" <>
    constField "table-plamo-scale" "Schaal" <>
    constField "table-plamo-series" "Serie" <>
    constField "table-plamo-manufacturer" "Fabrikant" <>
    constField "table-plamo-release-year" "Release jaar" <>
    constField "table-plamo-kit-number" "Kit nummer" <>
    constField "table-plamo-purchase-information" "Aankoop-informatie" <>
    constField "table-plamo-date" "Datum" <>
    constField "table-plamo-price" "Prijs" <>
    constField "table-plamo-store" "Winkel" <>
    constField "table-plamo-venue" "Venue" <>
    constField "table-plamo-location" "Locatie" <>
    constField "footer" "Deze website is gebouwd met <a href=\"http://jaspervdj.be/hakyll\" target=\"_blank\" rel=\"noopener noreferrer\">Hakyll</a>, <a href=\"https://flagicons.lipis.dev/\" target=\"_blank\" rel=\"noopener noreferrer\">Flag icons</a> en <a href=\"https://getbootstrap.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Bootstrap</a>, met <a href=\"https://www.docker.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Docker</a> containers en <a href=\"https://www.nginx.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Nginx</a> op een <a href=\"https://www.strato.nl/server/vps-linux/\" target=\"_blank\" rel=\"noopener noreferrer\">Strato VPS</a>." <>
    constField "last-update-text" "Website geüpdate" <>
    mempty

langDict "jp" =
    constField "filter" "フィルター" <>
    constField "filter-plamo-in-box" "未開封" <>
    constField "filter-plamo-building" "製作中" <>
    constField "filter-plamo-built" "組立完了" <>
    constField "filter-plamo-complete" "完成" <>
    constField "filter-plamo-category-aircraft" "航空機" <>
    constField "filter-plamo-category-armoured-car" "装甲車" <>
    constField "filter-plamo-category-automobile" "自動車" <>
    constField "filter-plamo-category-fantasy-vehicle" "ファンタジーの乗り物" <>
    constField "filter-plamo-category-figure" "フィギュア" <>
    constField "filter-plamo-category-gundam" "ガンダム" <>
    constField "filter-plamo-category-mecha" "メカ" <>
    constField "filter-plamo-category-motorcycle" "オートバイ" <>
    constField "filter-plamo-category-spacecraft" "宇宙機" <>
    constField "filter-plamo-category-tractor" "トラクター" <>
    constField "filter-plamo-series-msg" "機動戦士ガンダム" <>
    constField "filter-plamo-series-msg-pocket" "機動戦士ガンダム0080 ポケットの中の戦争" <>
    constField "filter-plamo-series-msg-stardust" "機動戦士ガンダム0083スターダストメモリー" <>
    constField "filter-plamo-series-msg-char" "機動戦士ガンダム 逆襲のシャア" <>
    constField "filter-plamo-series-msg-gqx" "機動戦士ガンダム ジークアクス" <>
    constField "filter-plamo-series-msg-ironblood" "機動戦士ガンダム 鉄血のオルフェンズ" <>
    constField "filter-plamo-series-msg-seed" "機動戦士ガンダム SEED" <>
    constField "filter-plamo-series-msg-seed-destiny" "機動戦士ガンダム SEED Destiny" <>
    constField "filter-plamo-series-msg-seed-freedom" "機動戦士ガンダム SEED Freedom" <>
    constField "filter-plamo-series-msg-witch" "機動戦士ガンダム 水星の魔女" <>
    constField "filter-plamo-series-msg-unicorn" "機動戦士ガンダムユニコーン" <>
    constField "filter-plamo-series-gundam-wing-endless-waltz" "新機動戦記ガンダムウイング・エンドレス ワルツ" <>
    constField "filter-plamo-series-msg-zz" "機動戦士ガンダムΖΖ" <>
    constField "filter-plamo-series-msg-zeta" "機動戦士Ζガンダム" <>
    constField "filter-plamo-series-mfg-gundam" "機動武闘伝Gガンダム" <>
    constField "filter-plamo-series-gundam-bf-try" "ガンダムビルドファイターズトライ" <>
    constField "filter-plamo-series-dragonball" "ドラゴンボール" <>
    constField "filter-plamo-series-dragonball-z" "ドラゴンボールZ" <>
    constField "filter-plamo-series-halo" "ヘイロー" <>
    constField "filter-plamo-series-ikaruga" "斑鳩" <>
    constField "filter-plamo-series-kampf-riesen-mars" "Kampf Riesen Mars 1941/1945" <>
    constField "filter-plamo-series-kyoukai-senki" "境界戦機" <>
    constField "filter-plamo-series-maschinen-krieger" "マシーネンクリーガー" <>
    constField "filter-plamo-series-nausicaa" "風の谷のナウシカ" <>
    constField "filter-plamo-series-patlabor" "機動警察パトレイバー" <>
    constField "filter-plamo-series-pokemon" "ポケットモンスター" <>
    constField "filter-plamo-series-space-battleship-yamato" "宇宙戦艦ヤマト" <>
    constField "filter-plamo-series-star-wars" "スター・ウォーズ" <>
    constField "filter-plamo-series-transformers" "トランスフォーマー" <>
    constField "filter-plamo-series-xenoblade-x" "ゼノブレイドクロス" <>
    constField "switcher" "言語" <>
    constField "title-japan" "日本" <>
    constField "title-plamo" "プラモ" <>
    constField "title-radio" "ラジオ" <>
    constField "title-software" "ソフトウェア" <>
    constField "posted-on" "投稿日：" <>
    constField "text-plamo-not-ready" "この模型キットには、まだ制作例が公開されていません。" <>
    constField "text-plamo-back" "プラモデルキットに戻る" <>
    constField "text-radio-back" "ラジオに戻る" <>
    constField "table-plamo-model-info" "モデル情報" <>
    constField "table-plamo-status" "現在の状態" <>
    constField "table-plamo-model" "モデル" <>
    constField "table-plamo-category" "カテゴリ" <>
    constField "table-plamo-scale" "スケール" <>
    constField "table-plamo-series" "シリーズ" <>
    constField "table-plamo-manufacturer" "メーカー" <>
    constField "table-plamo-release-year" "発売年" <>
    constField "table-plamo-kit-number" "キット番号" <>
    constField "table-plamo-purchase-information" "購入情報" <>
    constField "table-plamo-date" "日" <>
    constField "table-plamo-price" "値段" <>
    constField "table-plamo-store" "店" <>
    constField "table-plamo-venue" "購入場所" <>
    constField "table-plamo-location" "場所" <>
    constField "footer" "<a href=\"http://jaspervdj.be/hakyll\" target=\"_blank\" rel=\"noopener noreferrer\">Hakyll</a> と <a href=\"https://flagicons.lipis.dev/\" target=\"_blank\" rel=\"noopener noreferrer\">Flag icons</a> と <a href=\"https://getbootstrap.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Bootstrap</a> を使用し、<a href=\"https://www.docker.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Docker</a> コンテナと <a href=\"https://www.nginx.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Nginx</a> を用いた <a href=\"https://www.strato.nl/server/vps-linux/\" target=\"_blank\" rel=\"noopener noreferrer\">Strato VPS</a> 上で誇りをもって生成されています。" <>
    constField "last-update-text" "最終更新" <>
    mempty

langDict "en" =
    constField "filter" "Filter" <>
    constField "filter-plamo-in-box" "Still in box" <>
    constField "filter-plamo-building" "Building" <>
    constField "filter-plamo-built" "Built" <>
    constField "filter-plamo-complete" "Complete" <>
    constField "filter-plamo-category-aircraft" "Aircraft" <>
    constField "filter-plamo-category-armoured-car" "Armoured car" <>
    constField "filter-plamo-category-automobile" "Automobile" <>
    constField "filter-plamo-category-fantasy-vehicle" "Fantasy vehicle" <>
    constField "filter-plamo-category-figure" "Figure" <>
    constField "filter-plamo-category-gundam" "Gundam" <>
    constField "filter-plamo-category-mecha" "Mecha" <>
    constField "filter-plamo-category-motorcycle" "Motorcycle" <>
    constField "filter-plamo-category-spacecraft" "Spacecraft" <>
    constField "filter-plamo-category-tractor" "Tractor" <>
    constField "filter-plamo-series-msg" "Mobile Suit Gundam" <>
    constField "filter-plamo-series-msg-pocket" "Mobile Suit Gundam 0080: War in the Pocket" <>
    constField "filter-plamo-series-msg-stardust" "Mobile Suit Gundam 0083: Stardust Memory" <>
    constField "filter-plamo-series-msg-char" "Mobile Suit Gundam: Char's Counterattack" <>
    constField "filter-plamo-series-msg-gqx" "Mobile Suit Gundam GQuuuuuuX" <>
    constField "filter-plamo-series-msg-ironblood" "Mobile Suit Gundam Iron Blooded Orphans" <>
    constField "filter-plamo-series-msg-seed" "Mobile Suit Gundam SEED" <>
    constField "filter-plamo-series-msg-seed-destiny" "Mobile Suit Gundam SEED Destiny" <>
    constField "filter-plamo-series-msg-seed-freedom" "Mobile Suit Gundam SEED Freedom" <>
    constField "filter-plamo-series-msg-witch" "Mobile Suit Gundam the Witch from Mercury" <>
    constField "filter-plamo-series-msg-unicorn" "Mobile Suit Gundam Unicorn" <>
    constField "filter-plamo-series-msg-zz" "Mobile Suit Gundam ZZ" <>
    constField "filter-plamo-series-msg-zeta" "Mobile Suit Zeta Gundam" <>
    constField "filter-plamo-series-gundam-wing-endless-waltz" "Gundam Wing: Endless Waltz" <>
    constField "filter-plamo-series-mfg-gundam" "Mobile Fighter G Gundam" <>
    constField "filter-plamo-series-gundam-bf-try" "Gundam Build Fighters Try" <>
    constField "filter-plamo-series-dragonball" "Dragonball" <>
    constField "filter-plamo-series-dragonball-z" "Dragonball Z" <>
    constField "filter-plamo-series-halo" "Halo" <>
    constField "filter-plamo-series-ikaruga" "Ikaruga" <>
    constField "filter-plamo-series-kampf-riesen-mars" "Kampf Riesen Mars 1941/1945" <>
    constField "filter-plamo-series-kyoukai-senki" "Kyōkai Senki, Amaim Warrior at the Borderline" <>
    constField "filter-plamo-series-maschinen-krieger" "Maschinen Krieger" <>
    constField "filter-plamo-series-nausicaa" "Nausicaä of the Valley of the Wind" <>
    constField "filter-plamo-series-patlabor" "Mobile Police Patlabor" <>
    constField "filter-plamo-series-pokemon" "Pokémon" <>
    constField "filter-plamo-series-space-battleship-yamato" "Space Battleship Yamato" <>
    constField "filter-plamo-series-star-wars" "Star Wars" <>
    constField "filter-plamo-series-transformers" "Transformers" <>
    constField "filter-plamo-series-xenoblade-x" "Xenoblade Chronicles X" <>
    constField "switcher" "Language" <>
    constField "title-japan" "Japan" <>
    constField "title-plamo" "Plamo" <>
    constField "title-radio" "Radio" <>
    constField "title-software" "Software" <>
    constField "posted-on" "Posted on:" <>
    constField "text-plamo-not-ready" "This model kit has no work published for it yet." <>
    constField "text-plamo-back" "Back to plamo kits" <>
    constField "text-radio-back" "Back to radio overview" <>
    constField "table-plamo-model-info" "Model information" <>
    constField "table-plamo-status" "Status" <>
    constField "table-plamo-model" "Model" <>
    constField "table-plamo-category" "Category" <>
    constField "table-plamo-scale" "Scale" <>
    constField "table-plamo-series" "Series" <>
    constField "table-plamo-manufacturer" "Manufacturer" <>
    constField "table-plamo-release-year" "Release year" <>
    constField "table-plamo-kit-number" "Kit number" <>
    constField "table-plamo-purchase-information" "Purchase information" <>
    constField "table-plamo-date" "Date" <>
    constField "table-plamo-price" "Price" <>
    constField "table-plamo-store" "Store" <>
    constField "table-plamo-venue" "Venue" <>
    constField "table-plamo-location" "Location" <>
    constField "footer" "Site proudly generated by <a href=\"http://jaspervdj.be/hakyll\" target=\"_blank\" rel=\"noopener noreferrer\">Hakyll</a>, <a href=\"https://getbootstrap.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Bootstrap</a> and <a href=\"https://flagicons.lipis.dev/\" target=\"_blank\" rel=\"noopener noreferrer\">Flag icons</a> using <a href=\"https://www.docker.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Docker</a> containers with <a href=\"https://www.nginx.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Nginx</a> on a <a href=\"https://www.strato.nl/server/vps-linux/\" target=\"_blank\" rel=\"noopener noreferrer\">Strato VPS</a>." <>
    constField "last-update-text" "Last update" <>
    mempty

langDict _ = mempty
