aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristine Dodrill <me@christine.website>2018-07-25 14:50:13 -0700
committerChristine Dodrill <me@christine.website>2018-07-25 14:50:13 -0700
commit73344db07bd55329f87a4176802443edb7c464ae (patch)
tree05032079968010b4d9168752a097607160c3de02
parentf52b09be25fb0ec0d654fbf027120e1702ac404f (diff)
parent9243dc2b7583119d8306cef006aaaae299547209 (diff)
downloadx-73344db07bd55329f87a4176802443edb7c464ae.tar.xz
x-73344db07bd55329f87a4176802443edb7c464ae.zip
Merge branch 'master' of github.com:Xe/tools
-rw-r--r--cmd/ghettoscale/main.go42
-rw-r--r--cmd/ghettoscale/redis.go27
-rw-r--r--cmd/ghettoscale/scale.go75
-rw-r--r--discord/cadeybot/.gitignore3
-rwxr-xr-xdiscord/cadeybot/corpusmake.sh9
-rw-r--r--discord/cadeybot/importer/main.go42
-rw-r--r--discord/cadeybot/main.go102
-rw-r--r--discord/cadeybot/markov.go137
-rw-r--r--discord/pdevbitcoinbot/.gitignore1
-rw-r--r--discord/pdevbitcoinbot/Gopkg.lock30
-rw-r--r--discord/pdevbitcoinbot/Gopkg.toml33
-rw-r--r--discord/pdevbitcoinbot/data.json1
-rw-r--r--discord/pdevbitcoinbot/main.go181
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/caarlos0/env/.gitignore1
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/caarlos0/env/.hound.yml2
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/caarlos0/env/.travis.yml16
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/caarlos0/env/LICENSE.md21
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/caarlos0/env/README.md114
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/caarlos0/env/env.go336
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/caarlos0/env/env_test.go372
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/caarlos0/env/examples/first.go48
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/caarlos0/env/parsers/README.md35
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/caarlos0/env/parsers/parsers.go23
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/codahale/hdrhistogram/.travis.yml5
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/codahale/hdrhistogram/LICENSE21
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/codahale/hdrhistogram/README.md15
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/codahale/hdrhistogram/hdr.go564
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/codahale/hdrhistogram/hdr_test.go388
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/codahale/hdrhistogram/window.go45
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/codahale/hdrhistogram/window_test.go64
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/joho/godotenv/.gitignore1
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/joho/godotenv/.travis.yml8
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/joho/godotenv/LICENCE23
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/joho/godotenv/README.md163
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/joho/godotenv/autoload/autoload.go15
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/joho/godotenv/cmd/godotenv/cmd.go54
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/joho/godotenv/fixtures/equals.env2
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/joho/godotenv/fixtures/exported.env2
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/joho/godotenv/fixtures/invalid1.env2
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/joho/godotenv/fixtures/plain.env7
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/joho/godotenv/fixtures/quoted.env8
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/joho/godotenv/godotenv.go314
-rw-r--r--discord/pdevbitcoinbot/vendor/github.com/joho/godotenv/godotenv_test.go377
-rw-r--r--sdl/zerohackr/main.go12
-rw-r--r--tools/graphirot/README.md3
-rw-r--r--tools/graphirot/main.go100
-rw-r--r--tools/graphirot/tree.svg198
-rw-r--r--version/go1.10/main.go24
-rw-r--r--version/go1.9.3/main.go24
-rw-r--r--version/go1.9.4/main.go24
50 files changed, 4113 insertions, 1 deletions
diff --git a/cmd/ghettoscale/main.go b/cmd/ghettoscale/main.go
new file mode 100644
index 0000000..8ad78c6
--- /dev/null
+++ b/cmd/ghettoscale/main.go
@@ -0,0 +1,42 @@
+package main
+
+import (
+ "context"
+ "flag"
+ "net/url"
+ "os"
+ "time"
+
+ "github.com/Xe/ln"
+ _ "github.com/joho/godotenv/autoload"
+)
+
+var (
+ every = flag.Duration("every", 10*time.Minute, "how often this binary is being run")
+ do = flag.Int("do", 1, "do this number of scale checks, staggered by -every")
+)
+
+func main() {
+ flag.Parse()
+ ctx := context.Background()
+ ctx = ln.WithF(ctx, ln.F{"at": "main"})
+
+ pool, err := NewRedisPoolFromURL(os.Getenv("REDIS_URL"))
+ if err != nil {
+ ln.FatalErr(ctx, err)
+ }
+ _ = pool
+
+ for _, a := range flag.Args() {
+ ln.Log(ctx, ln.F{"url": a})
+ u, err := url.Parse(a)
+ if err != nil {
+ ln.FatalErr(ctx, err)
+ }
+
+ err = Check(ctx, u)
+ if err != nil {
+ ln.FatalErr(ctx, err)
+ }
+ }
+}
diff --git a/cmd/ghettoscale/redis.go b/cmd/ghettoscale/redis.go
new file mode 100644
index 0000000..94375c0
--- /dev/null
+++ b/cmd/ghettoscale/redis.go
@@ -0,0 +1,27 @@
+package main
+
+import (
+ "time"
+
+ "github.com/garyburd/redigo/redis"
+)
+
+// NewRedisPoolFromURL returns a new *redigo/redis.Pool configured for th1e supplied url
+// The url can include a password in the standard form and if so is used to AUTH against
+// the redis server.
+func NewRedisPoolFromURL(url string) (*redis.Pool, error) {
+ return &redis.Pool{
+ MaxIdle: 3,
+ IdleTimeout: 240 * time.Second,
+ Dial: func() (redis.Conn, error) {
+ return redis.DialURL(url)
+ },
+ TestOnBorrow: func(c redis.Conn, t time.Time) error {
+ if time.Since(t) < time.Minute {
+ return nil
+ }
+ _, err := c.Do("PING")
+ return err
+ },
+ }, nil
+}
diff --git a/cmd/ghettoscale/scale.go b/cmd/ghettoscale/scale.go
new file mode 100644
index 0000000..fa503f8
--- /dev/null
+++ b/cmd/ghettoscale/scale.go
@@ -0,0 +1,75 @@
+package main
+
+import (
+ "context"
+ "fmt"
+ "net/url"
+)
+
+// State is the state of the ghetto autoscaler.
+type State int
+
+/*
+States that this can be in
+
+ digraph G {
+ ok [label="OK"]
+ scaling_up [label="Scaling Up"]
+ scaling_down [label="Scaling Down"]
+ max_scale [label="Max Scale"]
+
+ init -> ok [label="test passes"]
+ init -> scaling_up [label="test fails"]
+ ok -> scaling_up [label="test fails"]
+ scaling_up -> scaling_up [label="test fails"]
+ scaling_up -> max_scale [label="test fails"]
+ scaling_up -> ok [label="test passes"]
+ scaling_down -> ok [label="minimum\nscale"]
+ ok -> scaling_down [label="test has\npassed\nn times"]
+ scaling_down -> scaling_down [label="test passes"]
+ max_scale -> scaling_down [label="test passes"]
+ max_scale -> ok [label="test passes"]
+ }
+
+This is the overall state machine for the autoscaler.
+*/
+const (
+ Init State = iota
+ OK
+ ScalingUp
+ MaxScale
+ ScalingDown
+)
+
+func Check(ctx context.Context, u *url.URL) error {
+ switch u.Scheme {
+ case "heroku":
+ return CheckHeroku(ctx, u)
+ }
+
+ return fmt.Errorf("no such scheme for %s", u.Scheme)
+}
+
+func CheckHeroku(ctx context.Context, u *url.URL) error {
+ // q := u.Query()
+ var err error
+
+ // heroku://printerfacts/web?kind=lang&metric=g:go.routines_max&min=1&max=3&stagger=1&mode=threshold&threshold=500
+ // appID := u.Host
+ // processType := u.Path[1:]
+ // kind := q.Get("kind")
+ // metric := q.Get("metric")
+ // min := q.Get("min")
+ // max := q.Get("max")
+ // stagger := q.Get("stagger")
+ // mode := q.Get("mode")
+
+ // get redis connection
+ // check if app:process type is currently staggered in redis
+ // if so decrement stagger counter in redis and exit
+ // fetch metrics data from metrics-api
+ // fetch current number of dynos for this app id and process type
+ // fetch state of the
+
+ return err
+}
diff --git a/discord/cadeybot/.gitignore b/discord/cadeybot/.gitignore
new file mode 100644
index 0000000..a029fb7
--- /dev/null
+++ b/discord/cadeybot/.gitignore
@@ -0,0 +1,3 @@
+.env
+cadeybot
+*.gob
diff --git a/discord/cadeybot/corpusmake.sh b/discord/cadeybot/corpusmake.sh
new file mode 100755
index 0000000..884f3d0
--- /dev/null
+++ b/discord/cadeybot/corpusmake.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+set -e
+set -x
+
+for dir in $(find -type d)
+do
+ [ "$dir" != . ] && ./importer ./"$dir"/messages.csv >> brain.txt
+done
diff --git a/discord/cadeybot/importer/main.go b/discord/cadeybot/importer/main.go
new file mode 100644
index 0000000..bb38417
--- /dev/null
+++ b/discord/cadeybot/importer/main.go
@@ -0,0 +1,42 @@
+package main
+
+import (
+ "encoding/csv"
+ "flag"
+ "fmt"
+ "log"
+ "os"
+)
+
+func main() {
+ flag.Parse()
+
+ if flag.NArg() != 1 {
+ log.Fatal("usage: importer <messages.csv>")
+ }
+
+ fname := flag.Arg(0)
+ if fname == "" {
+ log.Fatal("usage: importer <messages.csv>")
+ }
+
+ fin, err := os.Open(fname)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ csvReader := csv.NewReader(fin)
+ _, err = csvReader.Read() // ignore the first row, it's the index
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ all, err := csvReader.ReadAll()
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ for _, row := range all {
+ fmt.Println(row[2])
+ }
+}
diff --git a/discord/cadeybot/main.go b/discord/cadeybot/main.go
new file mode 100644
index 0000000..6b18fd8
--- /dev/null
+++ b/discord/cadeybot/main.go
@@ -0,0 +1,102 @@
+package main
+
+import (
+ "bufio"
+ "flag"
+ "log"
+ "math/rand"
+ "os"
+ "os/signal"
+ "syscall"
+ "time"
+
+ "github.com/bwmarrin/discordgo"
+ "github.com/facebookgo/flagenv"
+ _ "github.com/joho/godotenv"
+)
+
+var (
+ token = flag.String("token", "", "discord token")
+ brainInput = flag.String("brain", "", "brain file")
+)
+
+func main() {
+ flagenv.Parse()
+ flag.Parse()
+
+ chain := NewChain(3)
+
+ if *brainInput != "" {
+ log.Printf("Opening %s...", *brainInput)
+
+ fin, err := os.Open(*brainInput)
+ if err != nil {
+ panic(err)
+ }
+
+ s := bufio.NewScanner(fin)
+ for s.Scan() {
+ t := s.Text()
+
+ _, err := chain.Write(t)
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ err = chain.Save("cadey.gob")
+ if err != nil {
+ panic(err)
+ }
+ } else {
+ err := chain.Load("cadey.gob")
+ if err != nil {
+ panic(err)
+ }
+ }
+
+ rand.Seed(time.Now().Unix())
+
+ mc := func(s *discordgo.Session, m *discordgo.MessageCreate) {
+ // Ignore all messages created by the bot itself
+ // This isn't required in this specific example but it's a good practice.
+ if m.Author.ID == s.State.User.ID {
+ return
+ }
+
+ mentionsMe := false
+ for _, us := range m.Mentions {
+ if us.ID == s.State.User.ID {
+ mentionsMe = true
+ break
+ }
+ }
+
+ if !mentionsMe {
+ return
+ }
+
+ s.ChannelMessageSend(m.ChannelID, chain.Generate(15))
+ }
+
+ if *token == "" {
+ log.Fatal("set -token or TOKEN")
+ }
+
+ dg, err := discordgo.New("Bot " + *token)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ dg.AddHandler(mc)
+
+ err = dg.Open()
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer dg.Close()
+
+ sc := make(chan os.Signal, 1)
+ signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
+ <-sc
+}
diff --git a/discord/cadeybot/markov.go b/discord/cadeybot/markov.go
new file mode 100644
index 0000000..f31c133
--- /dev/null
+++ b/discord/cadeybot/markov.go
@@ -0,0 +1,137 @@
+package main
+
+// This Markov chain code is taken from the "Generating arbitrary text"
+// codewalk: http://golang.org/doc/codewalk/markov/
+//
+// Minor modifications have been made to make it easier to integrate
+// with a webserver and to save/load state
+
+import (
+ "encoding/gob"
+ "fmt"
+ "math/rand"
+ "os"
+ "strings"
+ "sync"
+)
+
+// Prefix is a Markov chain prefix of one or more words.
+type Prefix []string
+
+// String returns the Prefix as a string (for use as a map key).
+func (p Prefix) String() string {
+ return strings.Join(p, " ")
+}
+
+// Shift removes the first word from the Prefix and appends the given word.
+func (p Prefix) Shift(word string) {
+ copy(p, p[1:])
+ p[len(p)-1] = word
+}
+
+// Chain contains a map ("chain") of prefixes to a list of suffixes.
+// A prefix is a string of prefixLen words joined with spaces.
+// A suffix is a single word. A prefix can have multiple suffixes.
+type Chain struct {
+ Chain map[string][]string
+ prefixLen int
+ mu sync.Mutex
+}
+
+// NewChain returns a new Chain with prefixes of prefixLen words.
+func NewChain(prefixLen int) *Chain {
+ return &Chain{
+ Chain: make(map[string][]string),
+ prefixLen: prefixLen,
+ }
+}
+
+// Write parses the bytes into prefixes and suffixes that are stored in Chain.
+func (c *Chain) Write(in string) (int, error) {
+ sr := strings.NewReader(in)
+ p := make(Prefix, c.prefixLen)
+ for {
+ var s string
+ if _, err := fmt.Fscan(sr, &s); err != nil {
+ break
+ }
+ key := p.String()
+ c.mu.Lock()
+ c.Chain[key] = append(c.Chain[key], s)
+ c.mu.Unlock()
+ p.Shift(s)
+ }
+ return len(in), nil
+}
+
+// Generate returns a string of at most n words generated from Chain.
+func (c *Chain) Generate(n int) string {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ p := make(Prefix, c.prefixLen)
+ var words []string
+ for i := 0; i < n; i++ {
+ choices := c.Chain[p.String()]
+ if len(choices) == 0 {
+ break
+ }
+ next := choices[rand.Intn(len(choices))]
+ words = append(words, next)
+ p.Shift(next)
+ }
+ return strings.Join(words, " ")
+}
+
+// Save the chain to a file
+func (c *Chain) Save(fileName string) error {
+ // Open the file for writing
+ fo, err := os.Create(fileName)
+ if err != nil {
+ return err
+ }
+ // close fo on exit and check for its returned error
+ defer func() {
+ if err := fo.Close(); err != nil {
+ panic(err)
+ }
+ }()
+
+ // Create an encoder and dump to it
+ c.mu.Lock()
+ defer c.mu.Unlock()
+
+ enc := gob.NewEncoder(fo)
+ err = enc.Encode(c)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// Load the chain from a file
+func (c *Chain) Load(fileName string) error {
+ // Open the file for reading
+ fi, err := os.Open(fileName)
+ if err != nil {
+ return err
+ }
+ // close fi on exit and check for its returned error
+ defer func() {
+ if err := fi.Close(); err != nil {
+ panic(err)
+ }
+ }()
+
+ // Create a decoder and read from it
+ c.mu.Lock()
+ defer c.mu.Unlock()
+
+ dec := gob.NewDecoder(fi)
+ err = dec.Decode(c)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/discord/pdevbitcoinbot/.gitignore b/discord/pdevbitcoinbot/.gitignore
new file mode 100644
index 0000000..2eea525
--- /dev/null
+++ b/discord/pdevbitcoinbot/.gitignore
@@ -0,0 +1 @@
+.env \ No newline at end of file
diff --git a/discord/pdevbitcoinbot/Gopkg.lock b/discord/pdevbitcoinbot/Gopkg.lock
new file mode 100644
index 0000000..c30a77f
--- /dev/null
+++ b/discord/pdevbitcoinbot/Gopkg.lock
@@ -0,0 +1,30 @@
+# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
+
+
+[[projects]]
+ name = "github.com/caarlos0/env"
+ packages = ["."]
+ revision = "7cd7992b3bc86f920394f8de92c13900da1a46b7"
+ version = "v3.2.0"
+
+[[projects]]
+ branch = "master"
+ name = "github.com/codahale/hdrhistogram"
+ packages = ["."]
+ revision = "3a0bb77429bd3a61596f5e8a3172445844342120"
+
+[[projects]]
+ name = "github.com/joho/godotenv"
+ packages = [
+ ".",
+ "autoload"
+ ]
+ revision = "a79fa1e548e2c689c241d10173efd51e5d689d5b"
+ version = "v1.2.0"
+
+[solve-meta]
+ analyzer-name = "dep"
+ analyzer-version = 1
+ inputs-digest = "ce13f8ee2ca2392356358cef4fbb7bf0e8361b29789607b061ba3b024d9cf493"
+ solver-name = "gps-cdcl"
+ solver-version = 1
diff --git a/discord/pdevbitcoinbot/Gopkg.toml b/discord/pdevbitcoinbot/Gopkg.toml
new file mode 100644
index 0000000..1fecccd
--- /dev/null
+++ b/discord/pdevbitcoinbot/Gopkg.toml
@@ -0,0 +1,33 @@
+# Gopkg.toml example
+#
+# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
+# for detailed Gopkg.toml documentation.
+#
+# required = ["github.com/user/thing/cmd/thing"]
+# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
+#
+# [[constraint]]
+# name = "github.com/user/project"
+# version = "1.0.0"
+#
+# [[constraint]]
+# name = "github.com/user/project2"
+# branch = "dev"
+# source = "github.com/myfork/project2"
+#
+# [[override]]
+# name = "github.com/x/y"
+# version = "2.4.0"
+
+
+[[constraint]]
+ name = "github.com/caarlos0/env"
+ version = "3.2.0"
+
+[[constraint]]
+ branch = "master"
+ name = "github.com/codahale/hdrhistogram"
+
+[[constraint]]
+ name = "github.com/joho/godotenv"
+ version = "1.2.0"
diff --git a/discord/pdevbitcoinbot/data.json b/discord/pdevbitcoinbot/data.json
new file mode 100644
index 0000000..1ea89a5
--- /dev/null
+++ b/discord/pdevbitcoinbot/data.json
@@ -0,0 +1 @@
+{"Snapshot":{"LowestTrackableValue":-400,"HighestTrackableValue":3000000000,"SignificantFigures":5,"Counts":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0