Index: trunk/cmd/mai/flag.go
===================================================================
--- trunk/cmd/mai/flag.go	(revision 56)
+++ trunk/cmd/mai/flag.go	(revision 56)
@@ -0,0 +1,12 @@
+// Set up a basic command line flags parsing
+package main
+
+import (
+	"flag"
+)
+
+func parseFlags() {
+	var configfile string
+	flag.StringVar(&configfile, "f", "", "Configuration file")
+	flag.Parse()
+}
Index: trunk/cmd/mai/main.go
===================================================================
--- trunk/cmd/mai/main.go	(revision 56)
+++ trunk/cmd/mai/main.go	(revision 56)
@@ -0,0 +1,251 @@
+package main
+
+import (
+	"bytes"
+	"net/http"
+	"net/url"
+	"time"
+	"runtime"
+
+	"marisa.chaotic.ninja/mai/engines"
+	"github.com/gofiber/fiber/v2"
+	"github.com/gofiber/template/html/v2"
+)
+
+var conf struct {
+	listen string
+	staticpath string
+	tmplpath string
+}
+func main() {
+	parseFlags()
+
+	if configfile != "" {
+		readConf(configfile)
+	}
+
+	// Default settings
+	conf.listen = "127.0.0.1:5000"
+	conf.staticpath = "./static"
+	conf.tmplpath = "./views"
+	
+	engine := html.New(conf.tmplpath, ".html")
+	engine.AddFunc("inc", func(i int) int { return i + 1 })
+
+	app := fiber.New(fiber.Config{
+		Views: engine,
+	})
+
+	api := app.Group("/api")
+
+	app.All("/", func(c *fiber.Ctx) error {
+		engine := c.Cookies("engine")
+		if c.Query("engine") != "" {
+			engine = c.Query("engine")
+		}
+		if _, ok := engines.Engines[engine]; !ok {
+			engine = "google"
+		}
+		targetLanguages, err := engines.Engines[engine].TargetLanguages()
+		if err != nil {
+			return c.SendStatus(500)
+		}
+		sourceLanguages, err := engines.Engines[engine].SourceLanguages()
+		if err != nil {
+			return c.SendStatus(500)
+		}
+		originalText := ""
+		translatedText := ""
+		from := ""
+		to := ""
+		ttsFrom := ""
+		ttsTo := ""
+		sourceLanguage := ""
+
+		var translation engines.TranslationResult
+		if c.Method() == "POST" {
+			from = c.FormValue("from")
+			to = c.FormValue("to")
+			originalText = c.FormValue("text")
+			if result, err := engines.Engines[engine].Translate(originalText, from, to); err != nil {
+				return c.SendStatus(500)
+			} else {
+				translatedText = result.TranslatedText
+				translation = result
+				sourceLanguage = result.SourceLanguage
+			}
+
+			ttsFromURL, _ := url.Parse("api/tts")
+			fromQuery := url.Values{}
+			fromQuery.Add("lang", from)
+			fromQuery.Add("text", originalText)
+			ttsFromURL.RawQuery = fromQuery.Encode()
+			ttsFrom = ttsFromURL.String()
+
+			ttsToURL, _ := url.Parse("api/tts")
+			toQuery := url.Values{}
+			toQuery.Add("lang", to)
+			toQuery.Add("text", translatedText)
+			ttsToURL.RawQuery = toQuery.Encode()
+			ttsTo = ttsToURL.String()
+
+			fromCookie := new(fiber.Cookie)
+			fromCookie.Name = "from"
+			fromCookie.Value = from
+			fromCookie.Expires = time.Now().Add(time.Hour * 24 * 365)
+			c.Cookie(fromCookie)
+
+			toCookie := new(fiber.Cookie)
+			toCookie.Name = "to"
+			toCookie.Value = to
+			toCookie.Expires = time.Now().Add(time.Hour * 24 * 365)
+			c.Cookie(toCookie)
+
+			engineCookie := new(fiber.Cookie)
+			engineCookie.Name = "engine"
+			engineCookie.Value = engine
+			engineCookie.Expires = time.Now().Add(time.Hour * 24 * 365)
+			c.Cookie(engineCookie)
+		} else if c.Method() == "GET" {
+			from = c.Cookies("from")
+			to = c.Cookies("to")
+		} else {
+			return c.SendStatus(400)
+		}
+
+		if from == "" {
+			from = "auto"
+		}
+
+		enginesNames := map[string]string{}
+		for k, v := range engines.Engines {
+			enginesNames[k] = v.DisplayName()
+		}
+
+		return c.Render("index", fiber.Map{
+			"Engine":          engine,
+			"enginesNames":    enginesNames,
+			"SourceLanguages": sourceLanguages,
+			"TargetLanguages": targetLanguages,
+			"OriginalText":    originalText,
+			"Translation":     translation,
+			"From":            from,
+			"To":              to,
+			"TtsFrom":         ttsFrom,
+			"TtsTo":           ttsTo,
+			"SourceLanguage":  sourceLanguage,
+		})
+	})
+
+	api.All("/api/translate", func(c *fiber.Ctx) error {
+		from := ""
+		to := ""
+		engine := ""
+		text := ""
+		if c.Method() == "GET" {
+			engine = c.Query("engine")
+			text = c.Query("text")
+			from = c.Query("from")
+			to = c.Query("to")
+		} else if c.Method() == "POST" {
+			engine = c.FormValue("engine")
+			text = c.FormValue("text")
+			from = c.FormValue("from")
+			to = c.FormValue("to")
+		} else {
+			return c.SendStatus(400)
+		}
+		if _, ok := engines.Engines[engine]; !ok || engine == "" {
+			engine = "google"
+		}
+		if to == "" {
+			return c.SendStatus(400)
+		}
+		if result, err := engines.Engines[engine].Translate(text, from, to); err != nil {
+			return c.SendStatus(500)
+		} else {
+			return c.JSON(result)
+		}
+	})
+
+	api.Get("/api/source_languages", func(c *fiber.Ctx) error {
+		engine := c.Query("engine")
+		if _, ok := engines.Engines[engine]; !ok || engine == "" {
+			engine = "google"
+		}
+		if result, err := engines.Engines[engine].SourceLanguages(); err != nil {
+			return c.SendStatus(500)
+		} else {
+			return c.JSON(result)
+		}
+	})
+
+	api.Get("/api/target_languages", func(c *fiber.Ctx) error {
+		engine := c.Query("engine")
+		if _, ok := engines.Engines[engine]; !ok || engine == "" {
+			engine = "google"
+		}
+		if result, err := engines.Engines[engine].TargetLanguages(); err != nil {
+			return c.SendStatus(500)
+		} else {
+			return c.JSON(result)
+		}
+	})
+
+	api.Get("/api/tts", func(c *fiber.Ctx) error {
+		engine := c.Query("engine")
+		if _, ok := engines.Engines[engine]; !ok || engine == "" {
+			engine = "google"
+		}
+
+		text := c.Query("text")
+		if text == "" {
+			return c.SendStatus(400)
+		}
+
+		lang := c.Query("lang")
+
+		if url, err := engines.Engines[engine].Tts(text, lang); err != nil {
+			return c.SendStatus(500)
+		} else {
+			if response, err := http.Get(url); err != nil {
+				return c.SendStatus(500)
+			} else {
+				defer response.Body.Close()
+				var buf bytes.Buffer
+				response.Write(&buf)
+				c.Context().SetContentType("audio/mpeg")
+				return c.Send(buf.Bytes())
+			}
+		}
+	})
+	api.Get("/version", func(c *fiber.Ctx) error {
+		return c.JSON(fiber.Map{
+			"fiberversion": fiber.Version,
+			"goversion": runtime.Version(),
+		})
+	})
+	app.Post("/switchlanguages", func(c *fiber.Ctx) error {
+		if c.Cookies("from") != "" {
+			fromCookie := new(fiber.Cookie)
+			fromCookie.Name = "from"
+			fromCookie.Value = c.Cookies("to")
+			fromCookie.Expires = time.Now().Add(24 * time.Hour * 365)
+
+			toCookie := new(fiber.Cookie)
+			toCookie.Name = "to"
+			toCookie.Value = c.Cookies("from")
+			toCookie.Expires = time.Now().Add(24 * time.Hour * 365)
+
+			c.Cookie(fromCookie)
+			c.Cookie(toCookie)
+		}
+		return c.Redirect("/")
+	})
+	app.Static("/static", conf.staticpath, fiber.Static{
+		Compress: true,
+		ByteRange: true,
+		Browse: true,
+	})
+	app.Listen(conf.listen)
+}
Index: trunk/cmd/mai/readconf.go
===================================================================
--- trunk/cmd/mai/readconf.go	(revision 56)
+++ trunk/cmd/mai/readconf.go	(revision 56)
@@ -0,0 +1,20 @@
+// Read the INI-style configuration file
+package main
+
+import (
+	"gopkg.in/ini.v1"
+)
+
+func readConf(file string) error {        
+	cfg, err := ini.Load(file)
+	if err != nil {
+		return err					        
+	}
+
+	conf.listen = cfg.Section("mai").Key("listen").String()
+	conf.staticpath = cfg.Section("mai").Key("rootdir").String()						
+	conf.tmplpath = cfg.Section("mai").Key("tmplpath").String()
+
+	return nil
+}
+
Index: trunk/cmd/simplytranslate/flag.go
===================================================================
--- trunk/cmd/simplytranslate/flag.go	(revision 55)
+++ 	(revision )
@@ -1,12 +1,0 @@
-// Set up a basic command line flags parsing
-package main
-
-import (
-	"flag"
-)
-
-func parseFlags() {
-	var configfile string
-	flag.StringVar(&configfile, "f", "", "Configuration file")
-	flag.Parse()
-}
Index: trunk/cmd/simplytranslate/main.go
===================================================================
--- trunk/cmd/simplytranslate/main.go	(revision 55)
+++ 	(revision )
@@ -1,251 +1,0 @@
-package main
-
-import (
-	"bytes"
-	"net/http"
-	"net/url"
-	"time"
-	"runtime"
-
-	"git.chaotic.ninja/yakumo.izuru/simplytranslate/engines"
-	"github.com/gofiber/fiber/v2"
-	"github.com/gofiber/template/html/v2"
-)
-
-var conf struct {
-	listen string
-	staticpath string
-	tmplpath string
-}
-func main() {
-	parseFlags()
-
-	if configfile != "" {
-		readConf(configfile)
-	}
-
-	// Default settings
-	conf.listen = "127.0.0.1:5000"
-	conf.staticpath = "./static"
-	conf.tmplpath = "./views"
-	
-	engine := html.New(conf.tmplpath, ".html")
-	engine.AddFunc("inc", func(i int) int { return i + 1 })
-
-	app := fiber.New(fiber.Config{
-		Views: engine,
-	})
-
-	api := app.Group("/api")
-
-	app.All("/", func(c *fiber.Ctx) error {
-		engine := c.Cookies("engine")
-		if c.Query("engine") != "" {
-			engine = c.Query("engine")
-		}
-		if _, ok := engines.Engines[engine]; !ok {
-			engine = "google"
-		}
-		targetLanguages, err := engines.Engines[engine].TargetLanguages()
-		if err != nil {
-			return c.SendStatus(500)
-		}
-		sourceLanguages, err := engines.Engines[engine].SourceLanguages()
-		if err != nil {
-			return c.SendStatus(500)
-		}
-		originalText := ""
-		translatedText := ""
-		from := ""
-		to := ""
-		ttsFrom := ""
-		ttsTo := ""
-		sourceLanguage := ""
-
-		var translation engines.TranslationResult
-		if c.Method() == "POST" {
-			from = c.FormValue("from")
-			to = c.FormValue("to")
-			originalText = c.FormValue("text")
-			if result, err := engines.Engines[engine].Translate(originalText, from, to); err != nil {
-				return c.SendStatus(500)
-			} else {
-				translatedText = result.TranslatedText
-				translation = result
-				sourceLanguage = result.SourceLanguage
-			}
-
-			ttsFromURL, _ := url.Parse("api/tts")
-			fromQuery := url.Values{}
-			fromQuery.Add("lang", from)
-			fromQuery.Add("text", originalText)
-			ttsFromURL.RawQuery = fromQuery.Encode()
-			ttsFrom = ttsFromURL.String()
-
-			ttsToURL, _ := url.Parse("api/tts")
-			toQuery := url.Values{}
-			toQuery.Add("lang", to)
-			toQuery.Add("text", translatedText)
-			ttsToURL.RawQuery = toQuery.Encode()
-			ttsTo = ttsToURL.String()
-
-			fromCookie := new(fiber.Cookie)
-			fromCookie.Name = "from"
-			fromCookie.Value = from
-			fromCookie.Expires = time.Now().Add(time.Hour * 24 * 365)
-			c.Cookie(fromCookie)
-
-			toCookie := new(fiber.Cookie)
-			toCookie.Name = "to"
-			toCookie.Value = to
-			toCookie.Expires = time.Now().Add(time.Hour * 24 * 365)
-			c.Cookie(toCookie)
-
-			engineCookie := new(fiber.Cookie)
-			engineCookie.Name = "engine"
-			engineCookie.Value = engine
-			engineCookie.Expires = time.Now().Add(time.Hour * 24 * 365)
-			c.Cookie(engineCookie)
-		} else if c.Method() == "GET" {
-			from = c.Cookies("from")
-			to = c.Cookies("to")
-		} else {
-			return c.SendStatus(400)
-		}
-
-		if from == "" {
-			from = "auto"
-		}
-
-		enginesNames := map[string]string{}
-		for k, v := range engines.Engines {
-			enginesNames[k] = v.DisplayName()
-		}
-
-		return c.Render("index", fiber.Map{
-			"Engine":          engine,
-			"enginesNames":    enginesNames,
-			"SourceLanguages": sourceLanguages,
-			"TargetLanguages": targetLanguages,
-			"OriginalText":    originalText,
-			"Translation":     translation,
-			"From":            from,
-			"To":              to,
-			"TtsFrom":         ttsFrom,
-			"TtsTo":           ttsTo,
-			"SourceLanguage":  sourceLanguage,
-		})
-	})
-
-	api.All("/api/translate", func(c *fiber.Ctx) error {
-		from := ""
-		to := ""
-		engine := ""
-		text := ""
-		if c.Method() == "GET" {
-			engine = c.Query("engine")
-			text = c.Query("text")
-			from = c.Query("from")
-			to = c.Query("to")
-		} else if c.Method() == "POST" {
-			engine = c.FormValue("engine")
-			text = c.FormValue("text")
-			from = c.FormValue("from")
-			to = c.FormValue("to")
-		} else {
-			return c.SendStatus(400)
-		}
-		if _, ok := engines.Engines[engine]; !ok || engine == "" {
-			engine = "google"
-		}
-		if to == "" {
-			return c.SendStatus(400)
-		}
-		if result, err := engines.Engines[engine].Translate(text, from, to); err != nil {
-			return c.SendStatus(500)
-		} else {
-			return c.JSON(result)
-		}
-	})
-
-	api.Get("/api/source_languages", func(c *fiber.Ctx) error {
-		engine := c.Query("engine")
-		if _, ok := engines.Engines[engine]; !ok || engine == "" {
-			engine = "google"
-		}
-		if result, err := engines.Engines[engine].SourceLanguages(); err != nil {
-			return c.SendStatus(500)
-		} else {
-			return c.JSON(result)
-		}
-	})
-
-	api.Get("/api/target_languages", func(c *fiber.Ctx) error {
-		engine := c.Query("engine")
-		if _, ok := engines.Engines[engine]; !ok || engine == "" {
-			engine = "google"
-		}
-		if result, err := engines.Engines[engine].TargetLanguages(); err != nil {
-			return c.SendStatus(500)
-		} else {
-			return c.JSON(result)
-		}
-	})
-
-	api.Get("/api/tts", func(c *fiber.Ctx) error {
-		engine := c.Query("engine")
-		if _, ok := engines.Engines[engine]; !ok || engine == "" {
-			engine = "google"
-		}
-
-		text := c.Query("text")
-		if text == "" {
-			return c.SendStatus(400)
-		}
-
-		lang := c.Query("lang")
-
-		if url, err := engines.Engines[engine].Tts(text, lang); err != nil {
-			return c.SendStatus(500)
-		} else {
-			if response, err := http.Get(url); err != nil {
-				return c.SendStatus(500)
-			} else {
-				defer response.Body.Close()
-				var buf bytes.Buffer
-				response.Write(&buf)
-				c.Context().SetContentType("audio/mpeg")
-				return c.Send(buf.Bytes())
-			}
-		}
-	})
-	api.Get("/version", func(c *fiber.Ctx) error {
-		return c.JSON(fiber.Map{
-			"fiberversion": fiber.Version,
-			"goversion": runtime.Version(),
-		})
-	})
-	app.Post("/switchlanguages", func(c *fiber.Ctx) error {
-		if c.Cookies("from") != "" {
-			fromCookie := new(fiber.Cookie)
-			fromCookie.Name = "from"
-			fromCookie.Value = c.Cookies("to")
-			fromCookie.Expires = time.Now().Add(24 * time.Hour * 365)
-
-			toCookie := new(fiber.Cookie)
-			toCookie.Name = "to"
-			toCookie.Value = c.Cookies("from")
-			toCookie.Expires = time.Now().Add(24 * time.Hour * 365)
-
-			c.Cookie(fromCookie)
-			c.Cookie(toCookie)
-		}
-		return c.Redirect("/")
-	})
-	app.Static("/static", conf.staticpath, fiber.Static{
-		Compress: true,
-		ByteRange: true,
-		Browse: true,
-	})
-	app.Listen(conf.listen)
-}
Index: trunk/cmd/simplytranslate/readconf.go
===================================================================
--- trunk/cmd/simplytranslate/readconf.go	(revision 55)
+++ 	(revision )
@@ -1,20 +1,0 @@
-// Read the INI-style configuration file
-package main
-
-import (
-	"gopkg.in/ini.v1"
-)
-
-func readConf(file string) error {        
-	cfg, err := ini.Load(file)
-	if err != nil {
-		return err					        
-	}
-
-	conf.listen = cfg.Section("simplytranslate").Key("listen").String()
-	conf.staticpath = cfg.Section("simplytranslate").Key("rootdir").String()						
-	conf.tmplpath = cfg.Section("simplytranslate").Key("tmplpath").String()
-
-	return nil
-}
-
