From f06f021f402270951f849dde7bee3f3340b8a1d5 Mon Sep 17 00:00:00 2001 From: Christine Dodrill Date: Mon, 1 Apr 2019 10:05:03 -0700 Subject: reorg --- cmd/appsluggr/main.go | 153 ++++++ cmd/dnsd/dnsd.conf | 7 + cmd/dnsd/main.go | 128 +++++ cmd/ff-primitive/main.go | 55 +++ cmd/johaus/build.go | 39 ++ cmd/johaus/main.go | 72 +++ cmd/la-baujmi/.gitignore | 2 + cmd/la-baujmi/README.md | 66 +++ cmd/la-baujmi/const.go | 5 + cmd/la-baujmi/corpus.txt | 23 + cmd/la-baujmi/fact.go | 210 +++++++++ cmd/la-baujmi/fact_test.go | 278 +++++++++++ cmd/la-baujmi/main.go | 70 +++ cmd/license/.gitignore | 3 + cmd/license/licenses/licenses.go | 978 +++++++++++++++++++++++++++++++++++++++ cmd/license/main.go | 125 +++++ cmd/mainsanow/main.go | 21 + cmd/minipaas/main.go | 20 + cmd/mkapp/main.go | 37 ++ cmd/priorworkgen/.gitignore | 1 + cmd/priorworkgen/main.go | 105 +++++ cmd/quickserv/.gitignore | 1 + cmd/quickserv/main.go | 21 + cmd/relayd/main.go | 68 +++ cmd/thumber/in/XjScp8a.png | Bin 0 -> 292689 bytes cmd/thumber/in/lB4ICS3.png | Bin 0 -> 369886 bytes cmd/thumber/in/oaw79y9.jpg | Bin 0 -> 67119 bytes cmd/thumber/main.go | 57 +++ cmd/within.website/.gitignore | 2 + cmd/within.website/build.go | 39 ++ cmd/within.website/main.go | 70 +++ 31 files changed, 2656 insertions(+) create mode 100644 cmd/appsluggr/main.go create mode 100644 cmd/dnsd/dnsd.conf create mode 100644 cmd/dnsd/main.go create mode 100644 cmd/ff-primitive/main.go create mode 100644 cmd/johaus/build.go create mode 100644 cmd/johaus/main.go create mode 100644 cmd/la-baujmi/.gitignore create mode 100644 cmd/la-baujmi/README.md create mode 100644 cmd/la-baujmi/const.go create mode 100644 cmd/la-baujmi/corpus.txt create mode 100644 cmd/la-baujmi/fact.go create mode 100644 cmd/la-baujmi/fact_test.go create mode 100644 cmd/la-baujmi/main.go create mode 100644 cmd/license/.gitignore create mode 100644 cmd/license/licenses/licenses.go create mode 100644 cmd/license/main.go create mode 100644 cmd/mainsanow/main.go create mode 100644 cmd/minipaas/main.go create mode 100644 cmd/mkapp/main.go create mode 100644 cmd/priorworkgen/.gitignore create mode 100644 cmd/priorworkgen/main.go create mode 100644 cmd/quickserv/.gitignore create mode 100644 cmd/quickserv/main.go create mode 100644 cmd/relayd/main.go create mode 100644 cmd/thumber/in/XjScp8a.png create mode 100644 cmd/thumber/in/lB4ICS3.png create mode 100644 cmd/thumber/in/oaw79y9.jpg create mode 100644 cmd/thumber/main.go create mode 100644 cmd/within.website/.gitignore create mode 100644 cmd/within.website/build.go create mode 100644 cmd/within.website/main.go (limited to 'cmd') diff --git a/cmd/appsluggr/main.go b/cmd/appsluggr/main.go new file mode 100644 index 0000000..b4701a1 --- /dev/null +++ b/cmd/appsluggr/main.go @@ -0,0 +1,153 @@ +package main + +import ( + "archive/tar" + "compress/gzip" + "flag" + "fmt" + "io" + "io/ioutil" + "log" + "os" + "path/filepath" + "strings" + + "github.com/otiai10/copy" + "github.com/Xe/x/internal" +) + +var ( + web = flag.String("web", "", "path to binary for web process") + webScale = flag.Int("web-scale", 1, "default scale for web process if defined") + worker = flag.String("worker", "", "path to binary for worker process") + workerScale = flag.Int("worker-scale", 1, "default scale for worker process if defined") + fname = flag.String("fname", "slug.tar.gz", "slug name") +) + +func main() { + internal.HandleStartup() + + fout, err := os.Create(*fname) + if err != nil { + log.Fatal(err) + } + defer fout.Close() + + gzw := gzip.NewWriter(fout) + defer gzw.Close() + + tw := tar.NewWriter(gzw) + defer tw.Close() + + dir, err := ioutil.TempDir("", "appsluggr") + if err != nil { + log.Fatal(err) + } + + defer os.RemoveAll(dir) // clean up + + os.MkdirAll(filepath.Join(dir, "bin"), 0777) + var procfile, scalefile string + + copy.Copy("translations", filepath.Join(dir, "translations")) + if *web != "" { + procfile += "web: /app/bin/web\n" + scalefile += fmt.Sprintf("web=%d", *webScale) + Copy(*web, filepath.Join(dir, "bin", "web")) + + } + if *worker != "" { + procfile += "worker: /app/bin/worker\n" + scalefile += fmt.Sprintf("worker=%d", *workerScale) + Copy(*worker, filepath.Join(dir, "bin", "worker")) + } + + os.MkdirAll(filepath.Join(dir, ".config"), 0777) + + err = ioutil.WriteFile(filepath.Join(dir, ".buildpacks"), []byte("https://github.com/ryandotsmith/null-buildpack"), 0666) + if err != nil { + log.Fatal(err) + } + err = ioutil.WriteFile(filepath.Join(dir, "DOKKU_SCALE"), []byte(scalefile), 0666) + if err != nil { + log.Fatal(err) + } + err = ioutil.WriteFile(filepath.Join(dir, "Procfile"), []byte(procfile), 0666) + if err != nil { + log.Fatal(err) + } + + filepath.Walk(dir, func(file string, fi os.FileInfo, err error) error { + // return on any error + if err != nil { + log.Printf("got error on %s: %v", file, err) + return err + } + + if fi.IsDir() { + return nil // not a file. ignore. + } + + // create a new dir/file header + header, err := tar.FileInfoHeader(fi, fi.Name()) + if err != nil { + return err + } + + // update the name to correctly reflect the desired destination when untaring + header.Name = strings.TrimPrefix(strings.Replace(file, dir, "", -1), string(filepath.Separator)) + + // write the header + if err := tw.WriteHeader(header); err != nil { + return err + } + + // return on non-regular files (thanks to [kumo](https://medium.com/@komuw/just-like-you-did-fbdd7df829d3) for this suggested update) + if !fi.Mode().IsRegular() { + return nil + } + + // open files for taring + f, err := os.Open(file) + if err != nil { + return err + } + + // copy file data into tar writer + if _, err := io.Copy(tw, f); err != nil { + return err + } + + // manually close here after each file operation; defering would cause each file close + // to wait until all operations have completed. + f.Close() + + return nil + }) +} + +// Copy the src file to dst. Any existing file will be overwritten and will not +// copy file attributes. +func Copy(src, dst string) error { + in, err := os.Open(src) + if err != nil { + return err + } + defer in.Close() + st, err := in.Stat() + if err != nil { + return err + } + + out, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY, st.Mode()) + if err != nil { + return err + } + defer out.Close() + + _, err = io.Copy(out, in) + if err != nil { + return err + } + return out.Close() +} diff --git a/cmd/dnsd/dnsd.conf b/cmd/dnsd/dnsd.conf new file mode 100644 index 0000000..e490d13 --- /dev/null +++ b/cmd/dnsd/dnsd.conf @@ -0,0 +1,7 @@ +port 5900 +forward-server 1.1.1.1:53 + +zone-url ( + https://xena.greedo.xeserv.us/files/akua.zone + https://xena.greedo.xeserv.us/files/adblock.zone +) \ No newline at end of file diff --git a/cmd/dnsd/main.go b/cmd/dnsd/main.go new file mode 100644 index 0000000..314c86d --- /dev/null +++ b/cmd/dnsd/main.go @@ -0,0 +1,128 @@ +package main + +import ( + "bufio" + "flag" + "log" + "net/http" + + "os" + "os/signal" + "syscall" + + "github.com/Xe/x/internal" + "github.com/miekg/dns" + "github.com/mmikulicic/stringlist" +) + +var ( + port = flag.String("port", "53", "UDP port to listen on for DNS") + server = flag.String("forward-server", "1.1.1.1:53", "forward DNS server") + + zoneURLs = stringlist.Flag("zone-url", "DNS zonefiles to load") +) + +var ( + defaultZoneURLS = []string{ + "https://xena.greedo.xeserv.us/files/akua.zone", + "https://xena.greedo.xeserv.us/files/adblock.zone", + } +) + +func main() { + internal.HandleStartup() + + if len(*zoneURLs) == 0 { + *zoneURLs = defaultZoneURLS + } + + for _, zurl := range *zoneURLs { + log.Printf("conf: -zone-url=%s", zurl) + } + log.Printf("conf: -port=%s", *port) + log.Printf("conf: -forward-server=%s", *server) + + rrs := []dns.RR{} + + for _, zurl := range *zoneURLs { + resp, err := http.Get(zurl) + if err != nil { + panic(err) + } + + reader := bufio.NewReaderSize(resp.Body, 2048) + + var i int + zp := dns.NewZoneParser(reader, "", zurl) + for rr, ok := zp.Next(); ok; rr, ok = zp.Next() { + rrs = append(rrs, rr) + i++ + } + + if zp.Err() != nil { + panic(zp.Err()) + } + + resp.Body.Close() + + log.Printf("%s: %d records", zurl, i) + } + + dns.HandleFunc(".", func(w dns.ResponseWriter, r *dns.Msg) { + m := new(dns.Msg) + m.SetReply(r) + m.Authoritative = true + + for _, q := range r.Question { + answers := []dns.RR{} + for _, rr := range rrs { + rh := rr.Header() + + if rh.Rrtype == dns.TypeCNAME && q.Name == rh.Name { + answers = append(answers, rr) + + for _, a := range resolver("127.0.0.1:"+*port, rr.(*dns.CNAME).Target, q.Qtype) { + answers = append(answers, a) + } + } + + if q.Name == rh.Name && q.Qtype == rh.Rrtype && q.Qclass == rh.Class { + answers = append(answers, rr) + } + } + if len(answers) == 0 && *server != "" { + for _, a := range resolver(*server, q.Name, q.Qtype) { + answers = append(answers, a) + } + } + for _, a := range answers { + m.Answer = append(m.Answer, a) + } + } + w.WriteMsg(m) + }) + + go func() { + srv := &dns.Server{Addr: ":" + *port, Net: "udp"} + if err := srv.ListenAndServe(); err != nil { + log.Fatalf("Failed to set udp listener %s\n", err.Error()) + } + }() + + sig := make(chan os.Signal) + signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM) + s := <-sig + log.Fatalf("Signal (%v) received, stopping\n", s) +} + +func resolver(server, fqdn string, r_type uint16) []dns.RR { + m1 := new(dns.Msg) + m1.Id = dns.Id() + m1.SetQuestion(fqdn, r_type) + + in, err := dns.Exchange(m1, server) + if err == nil { + return in.Answer + } + return []dns.RR{} +} diff --git a/cmd/ff-primitive/main.go b/cmd/ff-primitive/main.go new file mode 100644 index 0000000..3ee0882 --- /dev/null +++ b/cmd/ff-primitive/main.go @@ -0,0 +1,55 @@ +package main + +import ( + "flag" + "image" + "log" + "os" + "runtime" + "runtime/pprof" + + "github.com/Xe/x/internal" + "github.com/fogleman/primitive/primitive" + farbfeld "github.com/hullerob/go.farbfeld" +) + +var ( + shapeCount = flag.Int("count", 150, "number of shapes used") + repeatShapeCount = flag.Int("repeat-count", 0, "number of extra shapes drawn in each step") + alpha = flag.Int("alpha", 128, "alpha of all shapes") + cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file") +) + +func stepImg(img image.Image, count int) image.Image { + bg := primitive.MakeColor(primitive.AverageImageColor(img)) + model := primitive.NewModel(img, bg, 512, runtime.NumCPU()) + + for range make([]struct{}, count) { + model.Step(primitive.ShapeTypeTriangle, *alpha, *repeatShapeCount) + } + + return model.Context.Image() +} + +func main() { + internal.HandleStartup() + + if *cpuprofile != "" { + f, err := os.Create(*cpuprofile) + if err != nil { + log.Fatal(err) + } + pprof.StartCPUProfile(f) + defer pprof.StopCPUProfile() + } + + img, err := farbfeld.Decode(os.Stdin) + if err != nil { + log.Fatal(err) + } + + err = farbfeld.Encode(os.Stdout, stepImg(img, *shapeCount)) + if err != nil { + log.Fatal(err) + } +} diff --git a/cmd/johaus/build.go b/cmd/johaus/build.go new file mode 100644 index 0000000..07e8489 --- /dev/null +++ b/cmd/johaus/build.go @@ -0,0 +1,39 @@ +//+build ignore + +// Builds and deploys the application to minipaas. +package main + +import ( + "context" + "log" + "os" + + "github.com/Xe/x/internal/greedo" + "github.com/Xe/x/internal/minipaas" + "github.com/Xe/x/internal/yeet" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + env := append(os.Environ(), []string{"CGO_ENABLED=0", "GOOS=linux"}...) + yeet.ShouldWork(ctx, env, yeet.WD, "vgo", "build", "-o=web") + yeet.ShouldWork(ctx, env, yeet.WD, "appsluggr", "-web=web") + fin, err := os.Open("slug.tar.gz") + if err != nil { + log.Fatal(err) + } + defer fin.Close() + + fname := "johaus-" + yeet.DateTag + ".tar.gz" + pubURL, err := greedo.CopyFile(fname, fin) + if err != nil { + log.Fatal(err) + } + + err = minipaas.Exec("tar:from johaus " + pubURL) + if err != nil { + log.Fatal(err) + } +} diff --git a/cmd/johaus/main.go b/cmd/johaus/main.go new file mode 100644 index 0000000..5c9c59e --- /dev/null +++ b/cmd/johaus/main.go @@ -0,0 +1,72 @@ +package main + +import ( + "encoding/json" + "flag" + "io/ioutil" + "log" + "net/http" + + "github.com/Xe/x/internal" + "within.website/johaus/parser" + _ "within.website/johaus/parser/camxes" + "within.website/johaus/pretty" +) + +const dialect = "camxes" + +var ( + port = flag.String("port", "9001", "TCP port to bind on for HTTP") +) + +func main() { + internal.HandleStartup() + + log.Printf("Listening on http://0.0.0.0:%s", *port) + + http.DefaultServeMux.HandleFunc("/tree", tree) + http.DefaultServeMux.HandleFunc("/braces", braces) + + http.ListenAndServe(":"+*port, nil) +} + +func braces(w http.ResponseWriter, r *http.Request) { + data, err := ioutil.ReadAll(r.Body) + if err != nil { + http.Error(w, "can't parse: "+err.Error(), http.StatusBadRequest) + return + } + + tree, err := parser.Parse(dialect, string(data)) + if err != nil { + http.Error(w, "can't parse: "+err.Error(), http.StatusBadRequest) + return + } + + parser.RemoveMorphology(tree) + parser.AddElidedTerminators(tree) + parser.RemoveSpace(tree) + parser.CollapseLists(tree) + + pretty.Braces(w, tree) +} +func tree(w http.ResponseWriter, r *http.Request) { + data, err := ioutil.ReadAll(r.Body) + if err != nil { + http.Error(w, "can't parse: "+err.Error(), http.StatusBadRequest) + return + } + + tree, err := parser.Parse(dialect, string(data)) + if err != nil { + http.Error(w, "can't parse: "+err.Error(), http.StatusBadRequest) + return + } + + parser.RemoveMorphology(tree) + parser.AddElidedTerminators(tree) + parser.RemoveSpace(tree) + parser.CollapseLists(tree) + + json.NewEncoder(w).Encode(tree) +} diff --git a/cmd/la-baujmi/.gitignore b/cmd/la-baujmi/.gitignore new file mode 100644 index 0000000..07b6fbf --- /dev/null +++ b/cmd/la-baujmi/.gitignore @@ -0,0 +1,2 @@ +.env +la-baujmi \ No newline at end of file diff --git a/cmd/la-baujmi/README.md b/cmd/la-baujmi/README.md new file mode 100644 index 0000000..10aa48d --- /dev/null +++ b/cmd/la-baujmi/README.md @@ -0,0 +1,66 @@ +# la baujmi + +Combination of: + +> bangu +> +> x1 is a/the language/dialect used by x2 to express/communicate x3 (si'o/du'u, not quote). + +> jimpe +> +> x1 understands/comprehends fact/truth x2 (du'u) about subject x3; x1 understands (fi) x3. + +This is an attempt to create a tool that can understand language. + +At first, [Toki Pona](http://tokipona.net) will be used. At a high level a toki pona sentence consists of four main parts: + +- context phrase +- subject + descriptors +- verb + descriptors +- object + descriptors + +You can describe a sentence as a form of predicate relation between those four parts. If you are told "Stacy purchased a tool for strange-plant", you can later then ask the program who purchased a tool for strange-plant. + +Because a Toki Pona sentence always matches the following form: + +``` +[ o,] [context la] [li [e ]] +``` + +And the particle `seme` fills in the part of a question that you don't know. So from this we can fill in the blanks with prolog. + +Consider the following: + +``` +jan Kesi li toki. +Cadey is speaking +toki(jan_Kesi). + +jan Kesi en jan Pola li toki. +Cadey and Pola are speaking. +toki(jan_Kesi). +toki(jan_Pola). + +jan Kesi li toki e jan Pola. +Cadey is talking about Pola +toki(jan_Kesi, jan_Pola). + +jan Kesi li toki e toki pona. +Cadey is talking about toki pona. +toki(jan_Kesi, toki_pona). + +ilo Kesi o, toki e jan Kesi. +Robo-Cadey: talk about Cadey. +command(ilo_Kesi, toki(ziho, jan_Kesi)). % ziho -> nothing in lojban (zi'o) +``` + +And then we can ask prolog questions about this sentence: + +``` +seme li toki? +> toki(X). +toki(jan_Kesi). +jan Kesi li toki. +toki(jan_Pola). +jan Pola li toki. +``` diff --git a/cmd/la-baujmi/const.go b/cmd/la-baujmi/const.go new file mode 100644 index 0000000..2b70d19 --- /dev/null +++ b/cmd/la-baujmi/const.go @@ -0,0 +1,5 @@ +package main + +const ( + tokiPonaAPIURL = "https://us-central1-golden-cove-408.cloudfunctions.net/toki-pona-verb-marker" +) diff --git a/cmd/la-baujmi/corpus.txt b/cmd/la-baujmi/corpus.txt new file mode 100644 index 0000000..5313317 --- /dev/null +++ b/cmd/la-baujmi/corpus.txt @@ -0,0 +1,23 @@ +sina li lukin e ni la sina pilin pona. sina li lukin e ni la pilin pona ni li suli suwi. sina li lukin e ni la sina li pona ale. sina li lukin e ni la sina li pali e ijo mute mute. + +sina li pona ale la sina pali ijo mute mute. + +sina li jan pi pali ijo mute mute. sina ken pali ijo mute mute. + +sina li wile pali e ilo suli la sina wile jo lukin wawa e tawa ala pi tenpo ni. lukin wawa e tawa ala pi tenpo ni li ilo sina kama e pali ijo pi tenpo pini. nasin ni li pilin sina ala. sina li kama pi toki lawa insa ala e pali ijo pi tenpo pini. + +tenpo ni li ni tenpo. + +tenpo pini li tenpo ni ala. tenpo ni la tenpo pini li suli ala. + +tenpo kama li tenpo ni ala. tenpo ni la tenpo kama li suli ala. + +tenpo ni li tawa ale. sina ken tawa ale e tawa ala pi tenpo ni. + +sina wile jo tawa ala pi tenpo ni la sina wile tawa ni: + +tenpo mute anu sina pilin ni la sijelo sina suli. +tenpo mute anu sina pilin ni la sijelo sina lili. +sina lukin e ijo mute la sina lukin wawa e nena insa. + +sina ken tawa ijo mute la sina kepeken tawa ala pi tenpo ni e sina. sina jo e ni la sina jo lukin wawa pona. sina jo lukin wawa mute en tawa ala pi tenpo ni ale li pali pona e ilo suli. diff --git a/cmd/la-baujmi/fact.go b/cmd/la-baujmi/fact.go new file mode 100644 index 0000000..a421d1e --- /dev/null +++ b/cmd/la-baujmi/fact.go @@ -0,0 +1,210 @@ +package main + +import ( + "errors" + "strings" + + "github.com/Xe/x/web/tokiponatokens" +) + +// Selbri is a predicate relationship between its arguments. The name comes from +// the lojban term selbri: http://jbovlaste.lojban.org/dict/selbri. +type Selbri struct { + Predicate string + Arguments []string +} + +// Fact converts a selbri into a prolog fact. +func (s Selbri) Fact() string { + var sb strings.Builder + + var varCount byte + + sb.WriteString("selbri(verb(") + + if s.Predicate == "seme" { + sb.WriteByte(byte('A') + varCount) + varCount++ + } else { + sb.WriteString(s.Predicate) + } + sb.WriteString("), ") + + for i, arg := range s.Arguments { + if i != 0 { + sb.WriteString(", ") + } + + switch arg { + case "subject(seme)", "object(seme)": + if strings.HasPrefix(arg, "subject") { + sb.WriteString("subject(") + } else { + sb.WriteString("object(") + } + sb.WriteByte(byte('A') + varCount) + varCount++ + sb.WriteByte(')') + continue + } + sb.WriteString(arg) + } + + sb.WriteString(").") + return sb.String() +} + +var ( + // ErrNoPredicate is raised when the given sentence does not have a verb. + // This is a side effect of the way we are potentially misusing prolog + // here. + ErrNoPredicate = errors.New("la-baujmi: sentence must have a verb to function as the logical predicate") +) + +// SentenceToSelbris creates logical facts derived from toki pona sentences. +// This is intended to be the first step in loading them into prolog. +func SentenceToSelbris(s tokiponatokens.Sentence) ([]Selbri, error) { + var ( + subjects []string + verbs []string + objects []string + context string + ) + + for _, pt := range s { + switch pt.Type { + case tokiponatokens.PartSubject: + if strings.Contains(pt.Braces(), " en ") { + temp := strings.Split(strings.Join(pt.Tokens, " "), " en ") + + for _, t := range temp { + subjects = append(subjects, "subject("+t+")") + } + + continue + } + + if len(pt.Parts) != 0 { + var sb strings.Builder + sb.WriteString("subject(") + + for i, sp := range pt.Parts { + if i != 0 { + sb.WriteString(", ") + } + if sp.Sep != nil && *sp.Sep == "pi" { + sb.WriteString("pi(") + for j, tk := range sp.Tokens { + if j != 0 { + sb.WriteString(", ") + } + + sb.WriteString(tk) + } + sb.WriteString(")") + } else { + sb.WriteString(strings.Join(sp.Tokens, "_")) + } + } + + sb.WriteString(")") + + subjects = append(objects, sb.String()) + continue + } + + subjects = append(subjects, "subject("+strings.Join(pt.Tokens, "_")+")") + + case tokiponatokens.PartVerbMarker: + verbs = append(verbs, strings.Join(pt.Tokens, "_")) + + case tokiponatokens.PartObjectMarker: + if len(pt.Parts) != 0 { + var sb strings.Builder + sb.WriteString("object(") + + for i, sp := range pt.Parts { + if i != 0 { + sb.WriteString(", ") + } + if sp.Sep != nil && *sp.Sep == "pi" { + sb.WriteString("pi(") + for j, tk := range sp.Tokens { + if j != 0 { + sb.WriteString(", ") + } + + sb.WriteString(tk) + } + sb.WriteString(")") + } else { + sb.WriteString(strings.Join(sp.Tokens, "_")) + } + } + + sb.WriteString(")") + + objects = append(objects, sb.String()) + continue + } + objects = append(objects, "object("+strings.Join(pt.Tokens, "_")+")") + + case tokiponatokens.PartPunctuation: + if len(pt.Tokens) == 1 { + switch pt.Tokens[0] { + case "la": + context = "context(" + subjects[len(subjects)-1] + ")" + subjects = subjects[:len(subjects)-1] + + case tokiponatokens.PunctComma: + return nil, errors.New("please avoid commas in this function") + } + } + } + } + + if len(verbs) == 0 { + return nil, ErrNoPredicate + } + + var result []Selbri + + for _, v := range verbs { + for _, s := range subjects { + if len(objects) == 0 { + // sumti: x1 is a/the argument of predicate function x2 filling place x3 (kind/number) + var sumti []string + if context != "" { + sumti = append([]string{}, context) + } + sumti = append(sumti, s) + + r := Selbri{ + Predicate: v, + Arguments: sumti, + } + + result = append(result, r) + } + + for _, o := range objects { + // sumti: x1 is a/the argument of predicate function x2 filling place x3 (kind/number) + var sumti []string + if context != "" { + sumti = append([]string{}, context) + } + sumti = append(sumti, s) + sumti = append(sumti, o) + + r := Selbri{ + Predicate: v, + Arguments: sumti, + } + + result = append(result, r) + } + } + } + + return result, nil +} diff --git a/cmd/la-baujmi/fact_test.go b/cmd/la-baujmi/fact_test.go new file mode 100644 index 0000000..43f7a4b --- /dev/null +++ b/cmd/la-baujmi/fact_test.go @@ -0,0 +1,278 @@ +package main + +import ( + "encoding/json" + "log" + "testing" + + "github.com/Xe/x/web/tokiponatokens" + "github.com/kr/pretty" +) + +// equal tells whether a and b contain the same elements. +// A nil argument is equivalent to an empty slice. +func equal(a, b []string) bool { + if len(a) != len(b) { + return false + } + for _, v := range a { + var has bool + for _, vv := range b { + if v == vv { + has = true + } + } + if !has { + return false + } + } + return true +} + +func selbrisEqual(a, b []Selbri) bool { + if len(a) != len(b) { + return false + } + for _, v := range a { + var has bool + for _, vv := range b { + if v.Eq(vv) { + has = true + } + } + + if !has { + return false + } + } + return true +} + +// Eq checks two Selbri instances for equality. +func (lhs Selbri) Eq(rhs Selbri) bool { + switch { + case lhs.Predicate != rhs.Predicate: + return false + case len(lhs.Arguments) != len(rhs.Arguments): + return false + case len(lhs.Arguments) == len(rhs.Arguments): + return equal(lhs.Arguments, rhs.Arguments) + } + + return true +} + +func TestSentenceToSelbris(t *testing.T) { + cases := []struct { + name string + json []byte + want []Selbri + wantFacts []string + }{ + { + name: "basic", + json: []byte(`[{"part":"subject","tokens":["ona"]},{"part":"verbMarker","sep":"li","tokens":["sona"]},{"part":"objectMarker","sep":"e","tokens":["mute"]},{"part":"punctuation","tokens":["period"]}]`), + want: []Selbri{ + { + Predicate: "sona", + Arguments: []string{"subject(ona)", "object(mute)"}, + }, + }, + wantFacts: []string{"selbri(verb(sona), subject(ona), object(mute))."}, + }, + { + name: "zen", + json: []byte(`[{"part":"subject","tokens":["tenpo","ni"]},{"part":"punctuation","tokens":["la"]},{"part":"subject","tokens":["seme"]},{"part":"verbMarker","sep":"li","tokens":["ala"]}]`), + want: []Selbri{ + { + Predicate: "ala", + Arguments: []string{"context(subject(tenpo_ni))", "subject(seme)"}, + }, + }, + wantFacts: []string{"selbri(verb(ala), context(subject(tenpo_ni)), subject(A))."}, + }, + { + name: "pi_subject", + json: []byte(`[{"part":"subject","parts":[{"part":"subject","tokens":["ilo","mi"]},{"part":"subject","sep":"pi","tokens":["kasi","nasa"]}]},{"part":"verbMarker","sep":"li","tokens":["pona","ale"]}]`), + want: []Selbri{ + { + Predicate: "pona_ale", + Arguments: []string{"subject(ilo_mi, pi(kasi, nasa))"}, + }, + }, + wantFacts: []string{"selbri(verb(pona_ale), subject(ilo_mi, pi(kasi, nasa)))."}, + }, + { + name: "pi_object", + json: []byte(`[{"part":"subject","tokens":["mi"]},{"part":"verbMarker","sep":"li","tokens":["esun"]},{"part":"objectMarker","sep":"e","parts":[{"part":"objectMarker","tokens":["ilo"]},{"part":"objectMarker","sep":"pi","tokens":["kalama","musi"]}]},{"part":"punctuation","tokens":["period"]}]`), + want: []Selbri{ + { + Predicate: "esun", + Arguments: []string{"subject(mi)", "object(ilo, pi(kalama, musi))"}, + }, + }, + wantFacts: []string{"selbri(verb(esun), subject(mi), object(ilo, pi(kalama, musi)))."}, + }, + { + name: "multiple verbs", + json: []byte(`[{"part":"subject","tokens":["ona"]},{"part":"verbMarker","sep":"li","tokens":["sona"]},{"part":"verbMarker","sep":"li","tokens":["pona"]},{"part":"objectMarker","sep":"e","tokens":["mute"]},{"part":"punctuation","tokens":["period"]}]`), + want: []Selbri{ + { + Predicate: "sona", + Arguments: []string{"subject(ona)", "object(mute)"}, + }, + { + Predicate: "pona", + Arguments: []string{"subject(ona)", "object(mute)"}, + }, + }, + wantFacts: []string{ + "selbri(verb(sona), subject(ona), object(mute)).", + "selbri(verb(pona), subject(ona), object(mute)).", + }, + }, + { + name: "multiple subjects and verbs", + json: []byte(`[{"part":"subject","tokens":["ona","en","sina","en","mi"]},{"part":"verbMarker","sep":"li","tokens":["sona"]},{"part":"verbMarker","sep":"li","tokens":["pona"]},{"part":"objectMarker","sep":"e","tokens":["mute"]},{"part":"punctuation","tokens":["period"]}]`), + want: []Selbri{ + { + Predicate: "sona", + Arguments: []string{"subject(ona)", "object(mute)"}, + }, + { + Predicate: "pona", + Arguments: []string{"subject(ona)", "object(mute)"}, + }, + { + Predicate: "sona", + Arguments: []string{"subject(sina)", "object(mute)"}, + }, + { + Predicate: "pona", + Arguments: []string{"subject(sina)", "object(mute)"}, + }, + { + Predicate: "sona", + Arguments: []string{"subject(mi)", "object(mute)"}, + }, + { + Predicate: "pona", + Arguments: []string{"subject(mi)", "object(mute)"}, + }, + }, + wantFacts: []string{ + "selbri(verb(sona), subject(ona), object(mute)).", + "selbri(verb(sona), subject(sina), object(mute)).", + "selbri(verb(sona), subject(mi), object(mute)).", + "selbri(verb(pona), subject(ona), object(mute)).", + "selbri(verb(pona), subject(sina), object(mute)).", + "selbri(verb(pona), subject(mi), object(mute)).", + }, + }, + { + name: "multiple subjects and verbs and objects", + json: []byte(`[{"part":"subject","tokens":["ona","en","sina","en","mi"]},{"part":"verbMarker","sep":"li","tokens":["sona"]},{"part":"verbMarker","sep":"li","tokens":["pona"]},{"part":"objectMarker","sep":"e","tokens":["ijo","mute"]},{"part":"objectMarker","sep":"e","tokens":["ilo","mute"]},{"part":"punctuation","tokens":["period"]}]`), + want: []Selbri{ + { + Predicate: "sona", + Arguments: []string{"subject(ona)", "object(ijo_mute)"}, + }, + { + Predicate: "sona", + Arguments: []string{"subject(ona)", "object(ilo_mute)"}, + }, + { + Predicate: "pona", + Arguments: []string{"subject(ona)", "object(ijo_mute)"}, + }, + { + Predicate: "pona", + Arguments: []string{"subject(ona)", "object(ilo_mute)"}, + }, + { + Predicate: "sona", + Arguments: []string{"subject(sina)", "object(ijo_mute)"}, + }, + { + Predicate: "sona", + Arguments: []string{"subject(sina)", "object(ilo_mute)"}, + }, + { + Predicate: "pona", + Arguments: []string{"subject(sina)", "object(ijo_mute)"}, + }, + { + Predicate: "pona", + Arguments: []string{"subject(sina)", "object(ilo_mute)"}, + }, + { + Predicate: "sona", + Arguments: []string{"subject(mi)", "object(ijo_mute)"}, + }, + { + Predicate: "sona", + Arguments: []string{"subject(mi)", "object(ilo_mute)"}, + }, + { + Predicate: "pona", + Arguments: []string{"subject(mi)", "object(ijo_mute)"}, + }, + { + Predicate: "pona", + Arguments: []string{"subject(mi)", "object(ilo_mute)"}, + }, + }, + wantFacts: []string{ + "selbri(verb(sona), subject(ona), object(ijo_mute)).", + "selbri(verb(sona), subject(ona), object(ilo_mute)).", + "selbri(verb(sona), subject(sina), object(ijo_mute)).", + "selbri(verb(sona), subject(sina), object(ilo_mute)).", + "selbri(verb(sona), subject(mi), object(ijo_mute)).", + "selbri(verb(sona), subject(mi), object(ilo_mute)).", + "selbri(verb(pona), subject(ona), object(ijo_mute)).", + "selbri(verb(pona), subject(ona), object(ilo_mute)).", + "selbri(verb(pona), subject(sina), object(ijo_mute)).", + "selbri(verb(pona), subject(sina), object(ilo_mute)).", + "selbri(verb(pona), subject(mi), object(ijo_mute)).", + "selbri(verb(pona), subject(mi), object(ilo_mute)).", + }, + }, + } + + for _, cs := range cases { + t.Run(cs.name, func(t *testing.T) { + var s tokiponatokens.Sentence + err := json.Unmarshal(cs.json, &s) + if err != nil { + t.Fatal(err) + } + + sb, err := SentenceToSelbris(s) + if err != nil { + t.Fatal(err) + } + + if !selbrisEqual(cs.want, sb) { + log.Println("want:") + pretty.Println(cs.want) + log.Println("got:") + pretty.Println(sb) + + t.Error("see logs") + } + + var facts []string + for _, s := range sb { + facts = append(facts, s.Fact()) + } + + t.Run("facts", func(t *testing.T) { + if !equal(cs.wantFacts, facts) { + t.Logf("wanted: %v", cs.wantFacts) + t.Logf("got: %v", facts) + t.Error("see -v") + } + }) + }) + } +} diff --git a/cmd/la-baujmi/main.go b/cmd/la-baujmi/main.go new file mode 100644 index 0000000..5183909 --- /dev/null +++ b/cmd/la-baujmi/main.go @@ -0,0 +1,70 @@ +package main + +import ( + "log" + "os" + "strings" + + "github.com/Xe/x/internal" + _ "github.com/Xe/x/internal/tokipona" + "github.com/Xe/x/web/tokiponatokens" + "github.com/mndrix/golog" + line "github.com/peterh/liner" +) + +func main() { + internal.HandleStartup() + var m golog.Machine + m = golog.NewMachine() + + for { + l := line.NewLiner() + if inp, err := l.Prompt("|toki: "); err == nil { + if inp == "" { + return + } + + l.AppendHistory(inp) + + parts, err := tokiponatokens.Tokenize(tokiPonaAPIURL, inp) + if err != nil { + log.Printf("error: %v", err) + continue + } + + for _, sentence := range parts { + sbs, err := SentenceToSelbris(sentence) + if err != nil { + log.Printf("can't derive facts: %v", err) + continue + } + + for _, sb := range sbs { + f := sb.Fact() + + if strings.Contains(inp, "?") { + log.Printf("Query: %s", f) + + solutions := m.ProveAll(f) + for _, solution := range solutions { + log.Println("found", strings.Replace(f, "A", solution.ByName_("A").String(), -1)) + } + + continue + } + + log.Printf("registering fact: %s", f) + m = m.Consult(f) + } + } + } else if err == line.ErrPromptAborted { + log.Print("Aborted") + break + } else { + log.Print("Error reading line: ", err) + break + } + } + + os.Exit(0) +} diff --git a/cmd/license/.gitignore b/cmd/license/.gitignore new file mode 100644 index 0000000..03a3b4e --- /dev/null +++ b/cmd/license/.gitignore @@ -0,0 +1,3 @@ +LICENSE +UNLICENSE +license diff --git a/cmd/license/licenses/licenses.go b/cmd/license/licenses/licenses.go new file mode 100644 index 0000000..297a8d6 --- /dev/null +++ b/cmd/license/licenses/licenses.go @@ -0,0 +1,978 @@ +package licenses + +var List map[string]string + +func init() { + List = map[string]string{ + "zlib": ZlibLicense, + "unlicense": Unlicense, + "mit": MitLicense, + "apache": ApacheLicense, + "bsd-2": Bsd2Clause, + "bsd-3": Bsd3Clause, + "bzip2": BzipLicense, + "isc": ISCLicense, + "gpl-2": Gpl2License, + "gpl-3": Gpl3License, + "lgpl-2": LGPL2License, + "wtfpl": WTFPlLicense, + "afreeo": AfreeoLicense, + "hackmii": HackMiiLicense, + "artistic": ArtisticLicense, + "cc0": CC0License, + "allpermissive": AllPermissiveLicense, + "json": JsonLicense, + "lha": LhaLicense, + "allrightsreserved": AllRightsReserved, + "mmpl": MinecraftMod, + "nwhml": TumblrLicense, + "pftus": PftusLicense, + "bola": BOLALicense, + "downloadmii": DownloadMiiLicense, + "sqlite": SQLiteBlessing, + "fair": FairLicense, + "yolo": YoloLicense, + "icu996": ICU996License, + } +} + +var ICU996License = ` The 996ICU License (996ICU) + Version 0.1, March 2019 + +PACKAGE is distributed under LICENSE with the following restriction: + +The above license is only granted to entities that act in concordance +with local labor laws. In addition, the following requirements must be +observed: + +* The licensee must not, explicitly or implicitly, request or schedule + their employees to work more than 45 hours in any single week. +* The licensee must not, explicitly or implicitly, request or schedule + their employees to be at work consecutively for 10 hours.` + +var YoloLicense = ` YOLO LICENSE + Version 1, July 10 2015 + +THIS SOFTWARE LICENSE IS PROVIDED "ALL CAPS" SO THAT YOU KNOW IT IS SUPER +SERIOUS AND YOU DON'T MESS AROUND WITH COPYRIGHT LAW BECAUSE YOU WILL GET IN +TROUBLE HERE ARE SOME OTHER BUZZWORDS COMMONLY IN THESE THINGS WARRANTIES +LIABILITY CONTRACT TORT LIABLE CLAIMS RESTRICTION MERCHANTABILITY SUBJECT TO +THE FOLLOWING CONDITIONS: + +1. #yolo +2. #swag +3. #blazeit +` + +var FairLicense = `Copyright {{.Year}} {{.Name}} <{{.Email}}> + +Usage of the works is permitted provided that this instrument is retained +with the works, so that any entity that uses the works is notified of +this instrument. + +DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.` + +var SQLiteBlessing = `The author disclaims copyright to this source code. In place of +a legal notice, here is a blessing: + + May you do good and not evil. + May you find forgiveness for yourself and forgive others. + May you share freely, never taking more than you give.` + +var PftusLicense = `The P.F.T.U.S(Protected Free To Use Software) License +Copyright {{.Year}} {{.Name}} <{{.Email}}>, see the bottom of the document. +Version 1.1x + +Unless required by applicable law or agreed to in writing, software +distributed under this License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +You are not allowed to re-license this Software, Product, Binary, Source +Code at all; unless you are the copyright holder. + +Your use of this software indicates your acceptance of this license agreement +and warranty. We reserve rights to change this license or completely remove it +at ANY TIME without ANY notice. + + +Please notice that you are refereed to as "You", "Your" and "Mirrorer" and +"Re-distributor" + +# SOURCE CODE + 1. You do not have permissions to use this code to make a profit in ANY + POSSIBLE WAY, NOR are you allowed to use it for competing purposes[1]; + contributing to the source code is allowed provided you do it either + via forking or similar way AND you don't make any kind of profit from it + unless you were specifically hired to contribute. + 2. Mirroring is allowed as long as the mirrorer don't make any profit from + mirroring of the code. + +# BINARIES + 1. Binaries may not be re-distributed at all[2] + 2. Mirroring is allowed as long as the mirrorer don't make any profit + from mirroring the produced binaries. + +# DOCUMENTATION + 1. Redistribution of the included documentation is allowed as long as the + re-distributor comply the the following term(s): + a. You shall not make any more profit from it than what the upkeep of + the documentation costs. + b. You shall link back to the original documentation in the header of + the redistribution web-page. + 2. Re-writing new documentation is allowed as long as it comply to the + following term(s): + a. It's clearly stated in the documentation that it isn't official. + b. You are allowed to make a profit from it; as long as it is under + 10 000 USD annually. + +Please notice that you can request written permission from the owner of this +Source Code/Binary or Project for Redistribution, using this software +for competing purposes or/and bypass the whole license. + +[1] "competing purposes" means ANY software on ANY platform that is designed to +be used in similar fashion(eg serves the same or similar purposes as the +original software). + +[2] This doesn't apply to the following domains: + * github.com + * AND any domain with written permissions + +Copyright {{.Year}} {{.Name}} <{{.Email}}>, changing is not permitted, +redistribution is allowed. Some rights reserved.` + +var BOLALicense = `I don't like licenses, because I don't like having to worry about all this +legal stuff just for a simple piece of software I don't really mind anyone +using. But I also believe that it's important that people share and give back; +so I'm placing this work under the following license. + + +BOLA - Buena Onda License Agreement (v1.1) +------------------------------------------ + +This work is provided 'as-is', without any express or implied warranty. In no +event will the authors be held liable for any damages arising from the use of +this work. + +To all effects and purposes, this work is to be considered Public Domain. + + +However, if you want to be "buena onda", you should: + +1. Not take credit for it, and give proper recognition to the authors. +2. Share your modifications, so everybody benefits from them. +3. Do something nice for the authors. +4. Help someone who needs it: sign up for some volunteer work or help your + neighbour paint the house. +5. Don't waste. Anything, but specially energy that comes from natural + non-renewable resources. Extra points if you discover or invent something + to replace them. +6. Be tolerant. Everything that's good in nature comes from cooperation.` + +var DownloadMiiLicense = `DownloadMii License + Version 1.0x + +Copyright (c) {{.Year}} {{.Name}} <{{.Email}}> +All rights reserved. + +You do not have permissions to use this code to make a profit[1] in anyway, +nor to use it for competing purposes; contributing via forking and such is +allowed. + +Mirroring is allowed as long as the mirrorer don't make any profit from +mirroring of code and produced binaries. + +[1] If you however are developing software that is not competing with this +software you're allowed to make profit from it.` + +var TumblrLicense = `Copyright (c) {{.Year}} {{.Name}} <{{.Email}}> + +Non-White-Heterosexual-Male License + +If you are not a white heterosexual male you are permitted to copy, +sell and use this work in any manner you choose without need to +include any attribution you do not see fit. You are asked as a +courtesy to retain this license in any derivatives but you are not +required. If you are a white heterosexual male you are provided the +same permissions (reuse, modification, resale) but are required to +include this license in any documentation and any public facing +derivative. You are also required to include attribution to the +original author or to an author responsible for redistribution +of a derivative. + +For additional details see http://nonwhiteheterosexualmalelicense.org` + +var AllRightsReserved = `Copyright (c) {{.Year}} {{.Name}} <{{.Email}}> + +All rights reserved.` + +var LhaLicense = `Copyright (c) {{.Year}} {{.Name}} <{{.Email}}> + +Original Authors License Statement (from man/lha.man, translated by +Osamu Aoki ): + + Permission is given for redistribution, copy, and modification provided + following conditions are met. + + 1. Do not remove copyright clause. + 2. Distribution shall conform: + a. The content of redistribution (i.e., source code, documentation, + and reference guide for programmers) shall include original contents. + If contents are modified, the document clearly indicating + the fact of modification must be included. + b. If LHa is redistributed with added values, you must put your best + effort to include them (Translator comment: If read literally, + original Japanese was unclear what "them" means here. But + undoubtedly this "them" means source code for the added value + portion and this is a typical Japanese sloppy writing style to + abbreviate as such) Also the document clearly indicating that + added value was added must be included. + c. Binary only distribution is not allowed (including added value + ones.) + 3. You need to put effort to distribute the latest version (This is not + your duty). + + NB: Distribution on Internet is free. Please notify me by e-mail or + other means prior to the distribution if distribution is done through + non-Internet media (Magazine, CDROM etc.) If not, make sure to Email + me later. + + 4. Any damage caused by the existence and use of this program will not + be compensated. + + 5. Author will not be responsible to correct errors even if program is + defective. + + 6. This program, either as a part of this or as a whole of this, may be + included into other programs. In this case, that program is not LHa + and can not call itself LHa. + + 7. For commercial use, in addition to above conditions, following + condition needs to be met. + + a. The program whose content is mainly this program can not be used + commercially. + b. If the recipient of commercial use deems inappropriate as a + program user, you must not distribute. + c. If used as a method for the installation, you must not force + others to use this program. In this case, commercial user will + perform its work while taking full responsibility of its outcome. + d. If added value is done under the commercial use by using this + program, commercial user shall provide its support. + + +(Osamu Aoki also comments: + Here "commercial" may be interpreted as "for-fee". "Added value" seems + to mean "feature enhancement". ) + +Translated License Statement by Tsugio Okamoto (translated by +GOTO Masanori ): + + It's free to distribute on the network, but if you distribute for + the people who cannot access the network (by magazine or CD-ROM), + please send E-Mail (Inter-Net address) to the author before the + distribution. That's well where this software is appeard. + If you cannot do, you must send me the E-Mail later.` + +var JsonLicense = `Copyright (c) {{.Year}} {{.Name}} <{{.Email}}> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.` + +var AllPermissiveLicense = `Copyright (c) {{.Year}} {{.Name}} <{{.Email}}> + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without any warranty.` + +var ZlibLicense = `Copyright (c) {{.Year}} {{.Name}} <{{.Email}}> + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgement in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution.` + +var Unlicense = `This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to ` + +var MitLicense = `Copyright (c) {{.Year}} {{.Name}} <{{.Email}}> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE.` + +var ApacheLicense = `Copyright {{.Year}} {{.Name}} <{{.Email}}> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License.` + +var Bsd2Clause = `Copyright (c) {{.Year}} {{.Name}} <{{.Email}}> +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.` + +var Gpl2License = `Copyright (C) {{.Year}} {{.Name}} <{{.Email}}> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.` + +var Gpl3License = `Copyright (C) {{.Year}} {{.Name}} <{{.Email}}> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see .` + +var WTFPlLicense = `DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + +Copyright (C) {{.Year}} {{.Name}} <{{.Email}}> + +Everyone is permitted to copy and distribute verbatim or modified +copies of this license document, and changing it is allowed as long +as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO.` + +var AfreeoLicense = `Copyright (C) {{.Year}} {{.Name}} <{{.Email}}> + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see .` + +var HackMiiLicense = `Copyright (C) {{.Year}} {{.Name}} <{{.Email}}> + +you are not allowed to in anyway use this material (including but is not +limited to: source code, images, binaries, documents) for use in +competeting purpuse in ANY WAY. You are also not allowed to redistribute +NOR mirror the code & binarys in any way, link to us instead!` + +var ArtisticLicense = ` The Artistic License 2.0 + + Copyright (c) {{.Year}} {{.Name}} <{{.Email}}> + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +Preamble + +This license establishes the terms under which a given free software +Package may be copied, modified, distributed, and/or redistributed. +The intent is that the Copyright Holder maintains some artistic +control over the development of that Package while still keeping the +Package available as open source and free software. + +You are always permitted to make arrangements wholly outside of this +license directly with the Copyright Holder of a given Package. If the +terms of this license do not permit the full use that you propose to +make of the Package, you should contact the Copyright Holder and seek +a different licensing arrangement. + +Definitions + + "Copyright Holder" means the individual(s) or organization(s) + named in the copyright notice for the entire Package. + + "Contributor" means any party that has contributed code or other + material to the Package, in accordance with the Copyright Holder's + procedures. + + "You" and "your" means any person who would like to copy, + distribute, or modify the Package. + + "Package" means the collection of files distributed by the + Copyright Holder, and derivatives of that collection and/or of + those files. A given Package may consist of either the Standard + Version, or a Modified Version. + + "Distribute" means providing a copy of the Package or making it + accessible to anyone else, or in the case of a company or + organization, to others outside of your company or organization. + + "Distributor Fee" means any fee that you charge for Distributing + this Package or providing support for this Package to another + party. It does not mean licensing fees. + + "Standard Version" refers to the Package if it has not been + modified, or has been modified only in ways explicitly requested + by the Copyright Holder. + + "Modified Version" means the Package, if it has been changed, and + such changes were not explicitly requested by the Copyright + Holder. + + "Original License" means this Artistic License as Distributed with + the Standard Version of the Package, in its current version or as + it may be modified by The Perl Foundation in the future. + + "Source" form means the source code, documentation source, and + configuration files for the Package. + + "Compiled" form means the compiled bytecode, object code, binary, + or any other form resulting from mechanical transformation or + translation of the Source form. + + +Permission for Use and Modification Without Distribution + +(1) You are permitted to use the Standard Version and create and use +Modified Versions for any purpose without restriction, provided that +you do not Distribute the Modified Version. + + +Permissions for Redistribution of the Standard Version + +(2) You may Distribute verbatim copies of the Source form of the +Standard Version of this Package in any medium without restriction, +either gratis or for a Distributor Fee, provided that you duplicate +all of the original copyright notices and associated disclaimers. At +your discretion, such verbatim copies may or may not include a +Compiled form of the Package. + +(3) You may apply any bug fixes, portability changes, and other +modifications made available from the Copyright Holder. The resulting +Package will still be considered the Standard Version, and as such +will be subject to the Original License. + + +Distribution of Modified Versions of the Package as Source + +(4) You may Distribute your Modified Version as Source (either gratis +or for a Distributor Fee, and with or without a Compiled form of the +Modified Version) provided that you clearly document how it differs +from the Standard Version, including, but not limited to, documenting +any non-standard features, executables, or modules, and provided that +you do at least ONE of the following: + + (a) make the Modified Version available to the Copyright Holder + of the Standard Version, under the Original License, so that the + Copyright Holder may include your modifications in the Standard + Version. + + (b) ensure that installation of your Modified Version does not + prevent the user installing or running the Standard Version. In + addition, the Modified Version must bear a name that is different + from the name of the Standard Version. + + (c) allow anyone who receives a copy of the Modified Version to + make the Source form of the Modified Version available to others + under + + (i) the Original License or + + (ii) a license that permits the licensee to freely copy, + modify and redistribute the Modified Version using the same + licensing terms that apply to the copy that the licensee + received, and requires that the Source form of the Modified + Version, and of any works derived from it, be made freely + available in that license fees are prohibited but Distributor + Fees are allowed. + + +Distribution of Compiled Forms of the Standard Version +or Modified Versions without the Source + +(5) You may Distribute Compiled forms of the Standard Version without +the Source, provided that you include complete instructions on how to +get the Source of the Standard Version. Such instructions must be +valid at the time of your distribution. If these instructions, at any +time while you are carrying out such distribution, become invalid, you +must provide new instructions on demand or cease further distribution. +If you provide valid instructions or cease distribution within thirty +days after you become aware that the instructions are invalid, then +you do not forfeit any of your rights under this license. + +(6) You may Distribute a Modified Version in Compiled form without +the Source, provided that you comply with Section 4 with respect to +the Source of the Modified Version. + + +Aggregating or Linking the Package + +(7) You may aggregate the Package (either the Standard Version or +Modified Version) with other packages and Distribute the resulting +aggregation provided that you do not charge a licensing fee for the +Package. Distributor Fees are permitted, and licensing fees for other +components in the aggregation are permitted. The terms of this license +apply to the use and Distribution of the Standard or Modified Versions +as included in the aggregation. + +(8) You are permitted to link Modified and Standard Versions with +other works, to embed the Package in a larger work of your own, or to +build stand-alone binary or bytecode versions of applications that +include the Package, and Distribute the result without restriction, +provided the result does not expose a direct interface to the Package. + + +Items That are Not Considered Part of a Modified Version + +(9) Works (including, but not limited to, modules and scripts) that +merely extend or make use of the Package, do not, by themselves, cause +the Package to be a Modified Version. In addition, such works are not +considered parts of the Package itself, and are not subject to the +terms of this license. + + +General Provisions + +(10) Any use, modification, and distribution of the Standard or +Modified Versions is governed by this Artistic License. By using, +modifying or distributing the Package, you accept this license. Do not +use, modify, or distribute the Package, if you do not accept this +license. + +(11) If your Modified Version has been derived from a Modified +Version made by someone other than you, you are nevertheless required +to ensure that your Modified Version complies with the requirements of +this license. + +(12) This license does not grant you the right to use any trademark, +service mark, tradename, or logo of the Copyright Holder. + +(13) This license includes the non-exclusive, worldwide, +free-of-charge patent license to make, have made, use, offer to sell, +sell, import and otherwise transfer the Package with respect to any +patent claims licensable by the Copyright Holder that are necessarily +infringed by the Package. If you institute patent litigation +(including a cross-claim or counterclaim) against any party alleging +that the Package constitutes direct or contributory patent +infringement, then this Artistic License to you shall terminate on the +date that such litigation is filed. + +(14) Disclaimer of Warranty: +THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS +IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR +NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL +LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.` + +var ISCLicense = `Copyright (C) {{.Year}} {{.Name}} <{{.Email}}> + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.` + +var Bsd3Clause = `Copyright (C) {{.Year}} {{.Name}} <{{.Email}}> + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of [project] nor the names of its + contributors may b