├── .dockerignore ├── tmpl ├── robots.txt ├── _redirects ├── assets │ ├── logo.png │ ├── fonts │ │ ├── firasans.ttf │ │ ├── firasans.woff │ │ ├── firasans.woff2 │ │ ├── firasansbold.ttf │ │ ├── firasansbook.ttf │ │ ├── firasansbold.woff │ │ ├── firasansbold.woff2 │ │ ├── firasansbook.woff │ │ ├── firasansbook.woff2 │ │ ├── firasansitalic.ttf │ │ ├── firasansitalic.woff │ │ ├── firasanslight.ttf │ │ ├── firasanslight.woff │ │ ├── firasanslight.woff2 │ │ ├── firasansmedium.ttf │ │ ├── firasansmedium.woff │ │ ├── firasansitalic.woff2 │ │ ├── firasansmedium.woff2 │ │ ├── firasanssemibold.ttf │ │ ├── firasanssemibold.woff │ │ ├── firasansbolditalic.ttf │ │ ├── firasansbolditalic.woff │ │ ├── firasansbolditalic.woff2 │ │ ├── firasansbookitalic.ttf │ │ ├── firasansbookitalic.woff │ │ ├── firasansbookitalic.woff2 │ │ ├── firasansextralight.ttf │ │ ├── firasansextralight.woff │ │ ├── firasansextralight.woff2 │ │ ├── firasanslightitalic.ttf │ │ ├── firasanslightitalic.woff │ │ ├── firasansmediumitalic.ttf │ │ ├── firasanssemibold.woff2 │ │ ├── firasanslightitalic.woff2 │ │ ├── firasansmediumitalic.woff │ │ ├── firasansmediumitalic.woff2 │ │ ├── firasanssemibolditalic.ttf │ │ ├── firasansextralightitalic.ttf │ │ ├── firasansextralightitalic.woff │ │ ├── firasanssemibolditalic.woff │ │ ├── firasanssemibolditalic.woff2 │ │ ├── firasansextralightitalic.woff2 │ │ └── firasans.css │ ├── sponsors │ │ └── doppler.png │ ├── awesome-go.css │ └── normalize.css ├── sitemap-tmpl.xml ├── tmpl.html └── cat-tmpl.html ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── awesome-go-com.md │ └── awesome-go-related-topic.md ├── workflows │ ├── tests.yaml │ ├── run-check.yaml │ ├── stale.yml │ └── site-deploy.yaml └── PULL_REQUEST_TEMPLATE.md ├── .gitattributes ├── .gitignore ├── .codeclimate.yml ├── MAINTAINERS ├── go.mod ├── LICENSE ├── scripts.go ├── make_site.go ├── repo_test.go ├── CONTRIBUTING.md ├── CODE_OF_CONDUCT.md ├── test_stale_repositories.go └── go.sum /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | -------------------------------------------------------------------------------- /tmpl/robots.txt: -------------------------------------------------------------------------------- 1 | User-Agent: * 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: avelino 2 | -------------------------------------------------------------------------------- /tmpl/_redirects: -------------------------------------------------------------------------------- 1 | /awesome-cloud-native/ / 2 | /awesome-go-fork/ / 3 | -------------------------------------------------------------------------------- /tmpl/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/logo.png -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasans.ttf -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasans.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasans.woff -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasans.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasans.woff2 -------------------------------------------------------------------------------- /tmpl/assets/sponsors/doppler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/sponsors/doppler.png -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansbold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansbold.ttf -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansbook.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansbook.ttf -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansbold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansbold.woff -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansbold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansbold.woff2 -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansbook.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansbook.woff -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansbook.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansbook.woff2 -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansitalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansitalic.ttf -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansitalic.woff -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasanslight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasanslight.ttf -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasanslight.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasanslight.woff -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasanslight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasanslight.woff2 -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansmedium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansmedium.ttf -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansmedium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansmedium.woff -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansitalic.woff2 -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansmedium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansmedium.woff2 -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasanssemibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasanssemibold.ttf -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasanssemibold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasanssemibold.woff -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | tmpl/assets/* linguist-vendored 2 | *.js linguist-vendored 3 | *.css linguist-vendored 4 | *.html linguist-vendored 5 | -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansbolditalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansbolditalic.ttf -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansbolditalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansbolditalic.woff -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansbolditalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansbolditalic.woff2 -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansbookitalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansbookitalic.ttf -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansbookitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansbookitalic.woff -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansbookitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansbookitalic.woff2 -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansextralight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansextralight.ttf -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansextralight.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansextralight.woff -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansextralight.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansextralight.woff2 -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasanslightitalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasanslightitalic.ttf -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasanslightitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasanslightitalic.woff -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansmediumitalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansmediumitalic.ttf -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasanssemibold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasanssemibold.woff2 -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasanslightitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasanslightitalic.woff2 -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansmediumitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansmediumitalic.woff -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansmediumitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansmediumitalic.woff2 -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasanssemibolditalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasanssemibolditalic.ttf -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansextralightitalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansextralightitalic.ttf -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansextralightitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansextralightitalic.woff -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasanssemibolditalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasanssemibolditalic.woff -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasanssemibolditalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasanssemibolditalic.woff2 -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasansextralightitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphael/awesome-go/main/tmpl/assets/fonts/firasansextralightitalic.woff2 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | tmpl/index.html 2 | awesome-go 3 | 4 | # Folders 5 | .idea 6 | .vscode 7 | test_stale_repositories_log 8 | *.exe 9 | # Local Netlify folder 10 | .netlify 11 | *.html 12 | sitemap.xml 13 | -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | --- 2 | engines: 3 | rubocop: 4 | enabled: true 5 | golint: 6 | enabled: true 7 | gofmt: 8 | enabled: true 9 | govet: 10 | enabled: true 11 | fixme: 12 | enabled: true 13 | duplication: 14 | enabled: true 15 | config: 16 | languages: 17 | - go 18 | ratings: 19 | paths: 20 | - "**.go" 21 | exclude_paths: 22 | - vendor/ 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/awesome-go-com.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: awesome-go.com 3 | about: website-related 4 | title: "[awesome-go.com]: issue title here" 5 | labels: awesome-go.com 6 | assignees: '' 7 | 8 | --- 9 | 10 | 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/awesome-go-related-topic.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: awesome-go related topic 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: help wanted 6 | assignees: '' 7 | 8 | --- 9 | 10 | 14 | -------------------------------------------------------------------------------- /.github/workflows/tests.yaml: -------------------------------------------------------------------------------- 1 | name: tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'main' 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | name: Running test 12 | runs-on: ubuntu-latest 13 | container: golang:latest 14 | steps: 15 | - uses: actions/checkout@1.0.0 16 | - name: Get dependencies 17 | run: go get -v -t -d ./... 18 | - name: Run tests 19 | run: go test repo_test.go scripts.go 20 | -------------------------------------------------------------------------------- /.github/workflows/run-check.yaml: -------------------------------------------------------------------------------- 1 | name: Check For Stale Repositories 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | - cron: '0 0 * * 0' 6 | jobs: 7 | build: 8 | name: Running test 9 | runs-on: ubuntu-latest 10 | container: golang:latest 11 | steps: 12 | - uses: actions/checkout@1.0.0 13 | - name: Get dependencies 14 | run: go get -v -t -d ./... 15 | - name: run script 16 | run: go run test_stale_repositories.go scripts.go 17 | env: 18 | OAUTH_TOKEN: ${{secrets.OAUTH_TOKEN}} 19 | -------------------------------------------------------------------------------- /tmpl/sitemap-tmpl.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | https://www.awesome-go.com/ 10 | 2016-10-10T07:39:03+00:00 11 | 12 | {{range .}} 13 | 14 | https://www.awesome-go.com/{{.Slug}} 15 | 2016-10-10T07:39:03+00:00 16 | 17 | {{end}} 18 | 19 | -------------------------------------------------------------------------------- /MAINTAINERS: -------------------------------------------------------------------------------- 1 | Avelino (@avelino) 2 | Duke (@dukex) 3 | Dmitri Shuralyov (@dmitshur) 4 | Dobrosław Żybort (@matrixik) 5 | Dean Karn (@joeybloggs) 6 | Kirill Danshin (@kirillDanshin) 7 | Felipe Oliveira (@felipeweb) 8 | Bo-Yi Wu (@appleboy) 9 | Cássio Botaro (@cassiobotaro) 10 | Jessica Temporal (@jtemporal) 11 | Ceriath (@ceriath) 12 | Andy Pan (@panjf2000) 13 | Phani Rithvij (@phanirithvij) 14 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/avelino/awesome-go 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/PuerkitoBio/goquery v1.8.0 7 | github.com/avelino/slugify v0.0.0-20180501145920-855f152bd774 8 | github.com/gomarkdown/markdown v0.0.0-20211212230626-5af6ad2f47df 9 | github.com/russross/blackfriday v1.6.0 10 | golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 11 | ) 12 | 13 | require ( 14 | github.com/andybalholm/cascadia v1.3.1 // indirect 15 | github.com/golang/protobuf v1.4.2 // indirect 16 | golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 // indirect 17 | golang.org/x/text v0.3.6 // indirect 18 | google.golang.org/appengine v1.6.6 // indirect 19 | google.golang.org/protobuf v1.25.0 // indirect 20 | ) 21 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: PR auto close, if you stay more than 8 days open 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: '0 0 * * *' 7 | 8 | jobs: 9 | stale: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/stale@v1 13 | with: 14 | repo-token: ${{ secrets.GITHUB_TOKEN }} 15 | stale-pr-message: > 16 | This PR has been automatically marked as closed because it has not had 17 | recent activity. They will wait 15 days for your interaction, after 18 | that the PR will be closed. 19 | Please read more in https://github.com/avelino/awesome-go/blob/master/CONTRIBUTING.md 20 | stale-pr-label: 'stale' 21 | days-before-stale: 15 22 | days-before-close: 7 23 | -------------------------------------------------------------------------------- /.github/workflows/site-deploy.yaml: -------------------------------------------------------------------------------- 1 | name: site-deploy 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'main' 7 | 8 | jobs: 9 | build: 10 | name: Make and Deploy site 11 | runs-on: ubuntu-latest 12 | environment: netlify 13 | container: golang:latest 14 | steps: 15 | - uses: actions/checkout@1.0.0 16 | - name: Get dependencies 17 | run: go get -v -t -d ./... 18 | - name: Make awesome-go.com 19 | run: go run make_site.go scripts.go 20 | - name: deploy awesome-go.com 21 | uses: jsmrcaga/action-netlify-deploy@v1.1.0 22 | with: 23 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} 24 | NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} 25 | NETLIFY_DEPLOY_TO_PROD: true 26 | build_directory: tmpl 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Thiago Avelino 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /scripts.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | "text/template" 9 | 10 | "github.com/PuerkitoBio/goquery" 11 | "github.com/gomarkdown/markdown" 12 | "github.com/gomarkdown/markdown/parser" 13 | "github.com/russross/blackfriday" 14 | ) 15 | 16 | func readme() []byte { 17 | input, err := ioutil.ReadFile("./README.md") 18 | if err != nil { 19 | panic(err) 20 | } 21 | html := fmt.Sprintf("%s", blackfriday.MarkdownCommon(input)) 22 | htmlByteArray := []byte(html) 23 | return htmlByteArray 24 | } 25 | 26 | func startQuery() *goquery.Document { 27 | buf := bytes.NewBuffer(readme()) 28 | query, err := goquery.NewDocumentFromReader(buf) 29 | if err != nil { 30 | panic(err) 31 | } 32 | return query 33 | } 34 | 35 | type content struct { 36 | Body string 37 | } 38 | 39 | // GenerateHTML generate site html (index.html) from markdown file 40 | func GenerateHTML() (err error) { 41 | // options 42 | readmePath := "./README.md" 43 | tplPath := "tmpl/tmpl.html" 44 | idxPath := "tmpl/index.html" 45 | input, _ := ioutil.ReadFile(readmePath) 46 | extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.LaxHTMLBlocks 47 | parser := parser.NewWithExtensions(extensions) 48 | 49 | body := string(markdown.ToHTML(input, parser, nil)) 50 | c := &content{Body: body} 51 | t := template.Must(template.ParseFiles(tplPath)) 52 | f, err := os.Create(idxPath) 53 | t.Execute(f, c) 54 | return 55 | } 56 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | > Please check if what you want to add to `awesome-go` list meets [quality standards](https://github.com/avelino/awesome-go/blob/main/CONTRIBUTING.md#quality-standards) before sending pull request. Thanks! 2 | 3 | **Please provide package links to:** 4 | 5 | - repo link (github.com, gitlab.com, etc): 6 | - pkg.go.dev: 7 | - goreportcard.com: 8 | - coverage service link ([codecov](https://codecov.io/), [coveralls](https://coveralls.io/), [gocover](http://gocover.io/) etc.): 9 | 10 | **Note**: _that new categories can be added only when there are 3 packages or more._ 11 | 12 | **Make sure that you've checked the boxes below before you submit PR:** 13 | _not every repository (project) will fit into every option, but most projects should_ 14 | 15 | - [ ] I have added my package in alphabetical order. 16 | - [ ] I have an appropriate description with correct grammar. 17 | - [ ] I know that this package was not listed before. 18 | - [ ] I have added pkg.go.dev link to the repo and to my pull request. 19 | - [ ] I have added coverage service link to the repo and to my pull request. 20 | - [ ] I have added goreportcard link to the repo and to my pull request. 21 | - [ ] I have read [Contribution guidelines](https://github.com/avelino/awesome-go/blob/main/CONTRIBUTING.md#contribution-guidelines), [maintainers note](https://github.com/avelino/awesome-go/blob/main/CONTRIBUTING.md#maintainers) and [Quality standard](https://github.com/avelino/awesome-go/blob/main/CONTRIBUTING.md#quality-standards). 22 | 23 | Thanks for your PR, you're awesome! :+1: 24 | -------------------------------------------------------------------------------- /tmpl/assets/awesome-go.css: -------------------------------------------------------------------------------- 1 | * { 2 | max-width: 100%; 3 | box-sizing: border-box; 4 | font-family: "Fira Sans"; 5 | text-decoration: none; 6 | font-weight: 300; 7 | } 8 | .awesome-logo { 9 | max-width: 500px; 10 | width: 100%; 11 | margin: auto; 12 | display: block; 13 | } 14 | 15 | a { 16 | color: #669; 17 | } 18 | a:visited, h1, h2, h3, h4 { 19 | color: #494368; 20 | font-weight: 400; 21 | } 22 | h1 > a:nth-child(1) { 23 | margin-left: 10px; 24 | } 25 | h1 > a img { 26 | padding-right: 5px; 27 | } 28 | 29 | #content { 30 | width: 100%; 31 | padding: 40px 80px; 32 | } 33 | 34 | @media (max-width: 720px) { 35 | #content { 36 | padding: 20px 40px; 37 | } 38 | } 39 | @media (max-width: 420px) { 40 | #content * { 41 | word-wrap: break-word; 42 | } 43 | } 44 | 45 | /** ADs 46 | * */ 47 | #ads { 48 | max-width: 330px; 49 | width: 100%; 50 | margin: auto; 51 | margin-top: auto; 52 | margin-right: auto; 53 | margin-bottom: auto; 54 | margin-left: auto; 55 | display: block; 56 | } 57 | 58 | #carbonads { 59 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, 60 | Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif; 61 | } 62 | 63 | #carbonads { 64 | display: flex; 65 | max-width: 330px; 66 | background-color: hsl(0, 0%, 98%); 67 | box-shadow: 0 1px 4px 1px hsla(0, 0%, 0%, .1); 68 | } 69 | 70 | #carbonads a { 71 | color: inherit; 72 | text-decoration: none; 73 | } 74 | 75 | #carbonads a:hover { 76 | color: inherit; 77 | } 78 | 79 | #carbonads span { 80 | position: relative; 81 | display: block; 82 | overflow: hidden; 83 | } 84 | 85 | #carbonads .carbon-wrap { 86 | display: flex; 87 | } 88 | 89 | .carbon-img { 90 | display: block; 91 | margin: 0; 92 | line-height: 1; 93 | } 94 | 95 | .carbon-img img { 96 | display: block; 97 | } 98 | 99 | .carbon-text { 100 | font-size: 13px; 101 | padding: 10px; 102 | line-height: 1.5; 103 | text-align: left; 104 | } 105 | 106 | .carbon-poweredby { 107 | display: block; 108 | padding: 8px 10px; 109 | background: repeating-linear-gradient(-45deg, transparent, transparent 5px, hsla(0, 0%, 0%, .025) 5px, hsla(0, 0%, 0%, .025) 10px) hsla(203, 11%, 95%, .4); 110 | text-align: center; 111 | text-transform: uppercase; 112 | letter-spacing: .5px; 113 | font-weight: 600; 114 | font-size: 9px; 115 | line-height: 1; 116 | } 117 | -------------------------------------------------------------------------------- /make_site.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "log" 8 | "os" 9 | "strings" 10 | "text/template" 11 | 12 | "github.com/PuerkitoBio/goquery" 13 | "github.com/avelino/slugify" 14 | ) 15 | 16 | type Link struct { 17 | Title string 18 | Url string 19 | Description string 20 | } 21 | 22 | type Object struct { 23 | Title string 24 | Slug string 25 | Description string 26 | Items []Link 27 | } 28 | 29 | func main() { 30 | GenerateHTML() 31 | input, err := ioutil.ReadFile("./tmpl/index.html") 32 | if err != nil { 33 | panic(err) 34 | } 35 | buf := bytes.NewBuffer(input) 36 | query, err := goquery.NewDocumentFromReader(buf) 37 | if err != nil { 38 | panic(err) 39 | } 40 | 41 | objs := []Object{} 42 | query.Find("body #content ul ul").First().Each(func(_ int, s *goquery.Selection) { 43 | 44 | s.Find("li a").Each(func(_ int, s *goquery.Selection) { 45 | selector, _ := s.Attr("href") 46 | obj := makeObjById(selector, query.Find("body")) 47 | objs = append(objs, obj) 48 | }) 49 | }) 50 | 51 | makeSiteStruct(objs) 52 | makeSitemap(objs) 53 | changeLinksInIndex(string(input), query) 54 | } 55 | 56 | func makeSiteStruct(objs []Object) { 57 | for _, obj := range objs { 58 | folder := fmt.Sprintf("tmpl/%s", obj.Slug) 59 | err := os.Mkdir(folder, 0755) 60 | if err != nil { 61 | log.Println(err) 62 | } 63 | 64 | t := template.Must(template.ParseFiles("tmpl/cat-tmpl.html")) 65 | f, _ := os.Create(fmt.Sprintf("%s/index.html", folder)) 66 | t.Execute(f, obj) 67 | } 68 | } 69 | 70 | func makeSitemap(objs []Object) { 71 | t := template.Must(template.ParseFiles("tmpl/sitemap-tmpl.xml")) 72 | f, _ := os.Create("tmpl/sitemap.xml") 73 | t.Execute(f, objs) 74 | } 75 | 76 | func makeObjById(selector string, s *goquery.Selection) (obj Object) { 77 | s.Find(selector).Each(func(_ int, s *goquery.Selection) { 78 | desc := s.NextFiltered("p") 79 | ul := desc.NextFiltered("ul") 80 | 81 | links := []Link{} 82 | ul.Find("li").Each(func(_ int, s *goquery.Selection) { 83 | url, _ := s.Find("a").Attr("href") 84 | link := Link{ 85 | Title: s.Find("a").Text(), 86 | Description: s.Text(), 87 | Url: url, 88 | } 89 | links = append(links, link) 90 | }) 91 | obj = Object{ 92 | Slug: slugify.Slugify(s.Text()), 93 | Title: s.Text(), 94 | Description: desc.Text(), 95 | Items: links, 96 | } 97 | }) 98 | return 99 | } 100 | 101 | func changeLinksInIndex(html string, query *goquery.Document) { 102 | query.Find("body #content ul li ul li a").Each(func(_ int, s *goquery.Selection) { 103 | 104 | href, exists := s.Attr("href") 105 | if exists { 106 | uri := strings.SplitAfter(href, "#") 107 | if len(uri) >= 2 { 108 | html = strings.ReplaceAll(html, fmt.Sprintf(`href="%s"`, href), fmt.Sprintf(`href="%s"`, uri[1])) 109 | } 110 | } 111 | }) 112 | 113 | os.WriteFile("./tmpl/index.html", []byte(html), 0644) 114 | } 115 | -------------------------------------------------------------------------------- /tmpl/tmpl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A curated list of awesome Go frameworks, libraries and software - Awesome Go / Golang 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |

29 |

30 | 31 |

32 | 33 | {{.Body}} 34 | 35 | 36 | Deploys by Netlify 37 | 38 |
39 | 40 | 41 | 42 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /repo_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io/ioutil" 5 | "regexp" 6 | "sort" 7 | "strings" 8 | "testing" 9 | 10 | "github.com/PuerkitoBio/goquery" 11 | ) 12 | 13 | var ( 14 | reContainsLink = regexp.MustCompile(`\* \[.*\]\(.*\)`) 15 | reOnlyLink = regexp.MustCompile(`\* \[.*\]\([^()]*\)$`) 16 | reLinkWithDescription = regexp.MustCompile(`\* \[.*\]\(.*\) - \S.*[\.\!]`) 17 | ) 18 | 19 | func TestAlpha(t *testing.T) { 20 | query := startQuery() 21 | query.Find("body > ul").Each(func(i int, s *goquery.Selection) { 22 | if i != 0 { 23 | // skip content menu 24 | // TODO: the sub items (with 3 hash marks `###`) are staying in 25 | // the main list, not respecting the hierarchy and making it 26 | // impossible to test the alphabetical order 27 | testList(t, s) 28 | } 29 | }) 30 | } 31 | 32 | func TestDuplicatedLinks(t *testing.T) { 33 | query := startQuery() 34 | links := make(map[string]bool, 0) 35 | query.Find("body li > a:first-child").Each(func(_ int, s *goquery.Selection) { 36 | t.Run(s.Text(), func(t *testing.T) { 37 | href, ok := s.Attr("href") 38 | if !ok { 39 | t.Error("expected to have href") 40 | } 41 | if links[href] { 42 | t.Fatalf("duplicated link '%s'", href) 43 | } 44 | links[href] = true 45 | }) 46 | }) 47 | } 48 | 49 | // Test if an entry has description, it must be separated from link with ` - ` 50 | func TestSeparator(t *testing.T) { 51 | var matched, containsLink, noDescription bool 52 | input, err := ioutil.ReadFile("./README.md") 53 | if err != nil { 54 | panic(err) 55 | } 56 | lines := strings.Split(string(input), "\n") 57 | for _, line := range lines { 58 | line = strings.Trim(line, " ") 59 | containsLink = reContainsLink.MatchString(line) 60 | if containsLink { 61 | noDescription = reOnlyLink.MatchString(line) 62 | if noDescription { 63 | continue 64 | } 65 | matched = reLinkWithDescription.MatchString(line) 66 | if !matched { 67 | t.Errorf("expected entry to be in form of `* [link] - description.`, got '%s'", line) 68 | } 69 | } 70 | } 71 | } 72 | func TestGenerateHTML(t *testing.T) { 73 | err := GenerateHTML() 74 | if err != nil { 75 | t.Errorf("html generate error '%s'", err.Error()) 76 | } 77 | } 78 | 79 | func testList(t *testing.T, list *goquery.Selection) { 80 | list.Find("ul").Each(func(_ int, items *goquery.Selection) { 81 | testList(t, items) 82 | items.RemoveFiltered("ul") 83 | }) 84 | t.Run(list.Prev().Text(), func(t *testing.T) { 85 | checkAlphabeticOrder(t, list) 86 | }) 87 | } 88 | 89 | func checkAlphabeticOrder(t *testing.T, s *goquery.Selection) { 90 | items := s.Find("li > a:first-child").Map(func(_ int, li *goquery.Selection) string { 91 | return strings.ToLower(li.Text()) 92 | }) 93 | sorted := make([]string, len(items)) 94 | copy(sorted, items) 95 | sort.Strings(sorted) 96 | for k, item := range items { 97 | if item != sorted[k] { 98 | t.Errorf("expected '%s' but actual is '%s'", sorted[k], item) 99 | } 100 | } 101 | if t.Failed() { 102 | t.Logf("expected order is:\n%s", strings.Join(sorted, "\n")) 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | This resource was made by the Go community and wouldn't be possible without you! We appreciate and recognize [all contributors](https://github.com/avelino/awesome-go/graphs/contributors). 2 | 3 | # Contribution Guidelines 4 | 5 | > Please be aware that we want to accept your contribution, but we have **some rules to keep the minimum quality** of the packages listed here. All reviews are **not personal feedback**, even if you are a _developer reviewing your contribution_. **Sorry if we can't meet your expectations, we do our best**. 6 | 7 | - **To add, remove, or change things on the list:** Submit a pull request 8 | 9 | To set this list apart from and complement the excellent [Go wiki Projects page](https://golang.org/wiki/Projects), awesome-go is a specially curated list for high-quality, actively maintained Go packages and resources. 10 | 11 | - List items should be sorted *alphabetically*; 12 | - Each item should be limited to one link; 13 | - The link should be the name of the package or project; 14 | - Descriptions should be clear, concise, and non-promotional; 15 | - Descriptions should follow the link, on the same line and end with a punctuation mark; 16 | - At least 3 items are needed to create a new category; 17 | - The package or project had to be maintained under **open source license** ( *we make a brief review of the code before the link enters the list* ), [see list of allowed licenses](https://opensource.org/licenses/alphabetical); 18 | - Remember to put a period `.` at end of the project description. 19 | 20 | Please contribute links to packages/projects you have used or are familiar with. This will help ensure high-quality entries. 21 | 22 | If you removed our PR template you can find it [here](https://github.com/avelino/awesome-go/blob/main/.github/PULL_REQUEST_TEMPLATE.md). 23 | 24 | 25 | ## Quality standards 26 | 27 | To be on the list, project repositories should adhere to these quality standards (https://goreportcard.com/report/github.com/ **github_user** / **github_repo**): 28 | 29 | - Code functions as documented and expected 30 | - Generally useful to the wider community of Go programmers 31 | - Actively maintained 32 | - Regular, recent commits 33 | - Or, for finished projects, issues and pull requests are responded to 34 | - Stable or progressing toward stable 35 | - Thoroughly documented (README, pkg.go.dev doc comments, etc.) in english language, so everyone is able to understand the project's intention and how it works 36 | - Tests, where practical. If the library/program is testable, then coverage should be >= 80% for non-data-related packages and >=90% for data related packages. **Notice**: the tests will be reviewed too. We will check your coverage manually if your package's coverage is just a benchmark results. 37 | 38 | ## Congrats, your project got accepted - what now? 39 | You are an awesome project now! Feel encouraged to tell others about it by adding one of these badges: 40 | [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go) 41 | [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go) 42 | 43 | ```md 44 | [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go) 45 | [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go) 46 | ``` 47 | 48 | 49 | ## Maintainers 50 | 51 | To make sure every PR is checked, we have [team maintainers](MAINTAINERS). Every PR MUST be reviewed by at least one maintainer before it can get merged. 52 | 53 | The maintainers will review your PR and notify you and tag it in case any 54 | information is still missing. They will wait 15 days for your interaction, after 55 | that the PR will be closed. 56 | 57 | 58 | ## Reporting issues 59 | 60 | Please open an issue if you would like to discuss anything that could be improved or have suggestions for making the list a more valuable resource. We realize sometimes packages fall into abandonment or have breaking builds for extended periods of time, so if you see that, feel free to change its listing or let us know. We also realize that sometimes projects are just going through transitions or are more experimental in nature. These can still be cool, but we can indicate them as transitory or experimental. 61 | 62 | Removal changes will not be applied until they have been pending for a minimum of 1 week (7 days). This grace window benefits projects that may be going through a temporary transition but are otherwise worthy of being on the list. 63 | 64 | Thanks everyone! 65 | -------------------------------------------------------------------------------- /tmpl/assets/fonts/firasans.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Fira Sans'; 3 | src: local('Fira Sans ExtraLight'), 4 | local('FiraSans-ExtraLight'), 5 | url('/assets/fonts/firasansextralight.woff2') format('woff2'), 6 | url('/assets/fonts/firasansextralight.woff') format('woff'), 7 | url('/assets/fonts/firasansextralight.ttf') format('truetype'); 8 | font-weight: 100; 9 | font-style: normal; 10 | } 11 | @font-face { 12 | font-family: 'Fira Sans'; 13 | src: local('Fira Sans ExtraLight Italic'), 14 | local('FiraSans-ExtraLightItalic'), 15 | url('/assets/fonts/firasansextralightitalic.woff2') format('woff2'), 16 | url('/assets/fonts/firasansextralightitalic.woff') format('woff'), 17 | url('/assets/fonts/firasansextralightitalic.ttf') format('truetype'); 18 | font-weight: 100; 19 | font-style: italic; 20 | } 21 | @font-face { 22 | font-family: 'Fira Sans'; 23 | src: local('Fira Sans Light'), 24 | local('FiraSans-Light'), 25 | url('/assets/fonts/firasanslight.woff2') format('woff2'), 26 | url('/assets/fonts/firasanslight.woff') format('woff'), 27 | url('/assets/fonts/firasanslight.ttf') format('truetype'); 28 | font-weight: 200; 29 | font-style: normal; 30 | } 31 | @font-face { 32 | font-family: 'Fira Sans'; 33 | src: local('Fira Sans Light Italic'), 34 | local('FiraSans-LightItalic'), 35 | url('/assets/fonts/firasanslightitalic.woff2') format('woff2'), 36 | url('/assets/fonts/firasanslightitalic.woff') format('woff'), 37 | url('/assets/fonts/firasanslightitalic.ttf') format('truetype'); 38 | font-weight: 200; 39 | font-style: italic; 40 | } 41 | @font-face { 42 | font-family: 'Fira Sans'; 43 | src: local('Fira Sans Book'), 44 | local('FiraSans-Book'), 45 | url('/assets/fonts/firasansbook.woff2') format('woff2'), 46 | url('/assets/fonts/firasansbook.woff') format('woff'), 47 | url('/assets/fonts/firasansbook.ttf') format('truetype'); 48 | font-weight: 300; 49 | font-style: normal; 50 | } 51 | @font-face { 52 | font-family: 'Fira Sans'; 53 | src: local('Fira Sans Book Italic'), 54 | local('FiraSans-BookItalic'), 55 | url('/assets/fonts/firasansbookitalic.woff2') format('woff2'), 56 | url('/assets/fonts/firasansbookitalic.woff') format('woff'), 57 | url('/assets/fonts/firasansbookitalic.ttf') format('truetype'); 58 | font-weight: 300; 59 | font-style: italic; 60 | } 61 | @font-face { 62 | font-family: 'Fira Sans'; 63 | src: local('Fira Sans'), 64 | local('FiraSans-Regular'), 65 | url('/assets/fonts/firasans.woff2') format('woff2'), 66 | url('/assets/fonts/firasans.woff') format('woff'), 67 | url('/assets/fonts/firasans.ttf') format('truetype'); 68 | font-weight: 400; 69 | font-style: normal; 70 | } 71 | @font-face { 72 | font-family: 'Fira Sans'; 73 | src: local('Fira Sans Italic'), 74 | local('FiraSans-Italic'), 75 | url('/assets/fonts/firasansitalic.woff2') format('woff2'), 76 | url('/assets/fonts/firasansitalic.woff') format('woff'), 77 | url('/assets/fonts/firasansitalic.ttf') format('truetype'); 78 | font-weight: 400; 79 | font-style: italic; 80 | } 81 | @font-face { 82 | font-family: 'Fira Sans'; 83 | src: local('Fira Sans Medium'), 84 | local('FiraSans-Medium'), 85 | url('/assets/fonts/firasansmedium.woff2') format('woff2'), 86 | url('/assets/fonts/firasansmedium.woff') format('woff'), 87 | url('/assets/fonts/firasansmedium.ttf') format('truetype'); 88 | font-weight: 500; 89 | font-style: normal; 90 | } 91 | @font-face { 92 | font-family: 'Fira Sans'; 93 | src: local('Fira Sans Medium Italic'), 94 | local('FiraSans-MediumItalic'), 95 | url('/assets/fonts/firasansmediumitalic.woff2') format('woff2'), 96 | url('/assets/fonts/firasansmediumitalic.woff') format('woff'), 97 | url('/assets/fonts/firasansmediumitalic.ttf') format('truetype'); 98 | font-weight: 500; 99 | font-style: italic; 100 | } 101 | @font-face { 102 | font-family: 'Fira Sans'; 103 | src: local('Fira Sans SemiBold'), 104 | local('FiraSans-SemiBold'), 105 | url('/assets/fonts/firasanssemibold.woff2') format('woff2'), 106 | url('/assets/fonts/firasanssemibold.woff') format('woff'), 107 | url('/assets/fonts/firasanssemibold.ttf') format('truetype'); 108 | font-weight: 600; 109 | font-style: normal; 110 | } 111 | @font-face { 112 | font-family: 'Fira Sans'; 113 | src: local('Fira Sans SemiBold Italic'), 114 | local('FiraSans-SemiBoldItalic'), 115 | url('/assets/fonts/firasanssemibolditalic.woff2') format('woff2'), 116 | url('/assets/fonts/firasanssemibolditalic.woff') format('woff'), 117 | url('/assets/fonts/firasanssemibolditalic.ttf') format('truetype'); 118 | font-weight: 600; 119 | font-style: italic; 120 | } 121 | @font-face { 122 | font-family: 'Fira Sans'; 123 | src: local('Fira Sans Bold'), 124 | local('FiraSans-Bold'), 125 | url('/assets/fonts/firasansbold.woff2') format('woff2'), 126 | url('/assets/fonts/firasansbold.woff') format('woff'), 127 | url('/assets/fonts/firasansbold.ttf') format('truetype'); 128 | font-weight: 700; 129 | font-style: normal; 130 | } 131 | @font-face { 132 | font-family: 'Fira Sans'; 133 | src: local('Fira Sans Bold Italic'), 134 | local('FiraSans-BoldItalic'), 135 | url('/assets/fonts/firasansbolditalic.woff2') format('woff2'), 136 | url('/assets/fonts/firasansbolditalic.woff') format('woff'), 137 | url('/assets/fonts/firasansbolditalic.ttf') format('truetype'); 138 | font-weight: 700; 139 | font-style: italic; 140 | } 141 | -------------------------------------------------------------------------------- /tmpl/cat-tmpl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{.Title}} - Awesome Go / Golang 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |

30 | 31 | awesome-go 32 | 33 | {{.Title}} - Awesome Go 34 |

35 | 36 |

{{.Description}}

37 | 38 |

39 | Build Status 40 | Awesome 41 | Slack Widget 42 | Netlify Status 43 | Track Awesome List 44 |

45 | 46 |

47 | 48 |

49 | 50 |
51 |
52 |

Sponsorships

53 |

54 |

55 | 56 |

57 |

58 | Doppler 59 |

60 |

61 | Digital Ocean 62 |

63 |
64 | 65 | 🗺️ back to content menu 66 | 67 | 72 | 73 | 74 | Deploys by Netlify 75 | 76 |
77 | 78 | 79 | 80 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | ## 1. Purpose 4 | 5 | A primary goal of Awesome Go is to be inclusive to the largest number of contributors, with the most varied and diverse backgrounds possible. As such, we are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, ability, ethnicity, socioeconomic status, and religion (or lack thereof). 6 | 7 | This code of conduct outlines our expectations for all those who participate in our community, as well as the consequences for unacceptable behavior. 8 | 9 | We invite all those who participate in Awesome Go to help us create safe and positive experiences for everyone. 10 | 11 | ## 2. Open Source Citizenship 12 | 13 | A supplemental goal of this Code of Conduct is to increase open source citizenship by encouraging participants to recognize and strengthen the relationships between our actions and their effects on our community. 14 | 15 | Communities mirror the societies in which they exist and positive action is essential to counteract the many forms of inequality and abuses of power that exist in society. 16 | 17 | If you see someone who is making an extra effort to ensure our community is welcoming, friendly, and encourages all participants to contribute to the fullest extent, we want to know. 18 | 19 | ## 3. Expected Behavior 20 | 21 | The following behaviors are expected and requested of all community members: 22 | 23 | * Participate in an authentic and active way. In doing so, you contribute to the health and longevity of this community. 24 | * Exercise consideration and respect in your speech and actions. 25 | * Attempt collaboration before conflict. 26 | * Refrain from demeaning, discriminatory, or harassing behavior and speech. 27 | * Be mindful of your surroundings and of your fellow participants. Alert community leaders if you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, even if they seem inconsequential. 28 | * Remember that community event venues may be shared with members of the public; please be respectful to all patrons of these locations. 29 | 30 | ## 4. Unacceptable Behavior 31 | 32 | The following behaviors are considered harassment and are unacceptable within our community: 33 | 34 | * Violence, threats of violence or violent language directed against another person. 35 | * Sexist, racist, homophobic, transphobic, ableist or otherwise discriminatory jokes and language. 36 | * Posting or displaying sexually explicit or violent material. 37 | * Posting or threatening to post other people’s personally identifying information ("doxing"). 38 | * Personal insults, particularly those related to gender, sexual orientation, race, religion, or disability. 39 | * Inappropriate photography or recording. 40 | * Inappropriate physical contact. You should have someone’s consent before touching them. 41 | * Unwelcome sexual attention. This includes, sexualized comments or jokes; inappropriate touching, groping, and unwelcomed sexual advances. 42 | * Deliberate intimidation, stalking or following (online or in person). 43 | * Advocating for, or encouraging, any of the above behavior. 44 | * Sustained disruption of community events, including talks and presentations. 45 | 46 | ## 5. Consequences of Unacceptable Behavior 47 | 48 | Unacceptable behavior from any community member, including sponsors and those with decision-making authority, will not be tolerated. 49 | 50 | Anyone asked to stop unacceptable behavior is expected to comply immediately. 51 | 52 | If a community member engages in unacceptable behavior, the community organizers may take any action they deem appropriate, up to and including a temporary ban or permanent expulsion from the community without warning (and without refund in the case of a paid event). 53 | 54 | ## 6. Reporting Guidelines 55 | 56 | If you are subject to or witness unacceptable behavior, or have any other concerns, please notify a community organizer as soon as possible. t@avelino.xxx. 57 | 58 | [Reporting Guidelines](https://github.com/avelino/awesome-go/blob/main/CONTRIBUTING.md#contribution-guidelines) 59 | 60 | Additionally, community organizers are available to help community members engage with local law enforcement or to otherwise help those experiencing unacceptable behavior feel safe. In the context of in-person events, organizers will also provide escorts as desired by the person experiencing distress. 61 | 62 | ## 7. Addressing Grievances 63 | 64 | If you feel you have been falsely or unfairly accused of violating this Code of Conduct, you should notify Avelino with a concise description of your grievance. Your grievance will be handled in accordance with our existing governing policies. 65 | 66 | [Policy](https://github.com/avelino/awesome-go/blob/main/CONTRIBUTING.md) 67 | 68 | ## 8. Scope 69 | 70 | We expect all community participants (contributors, paid or otherwise; sponsors; and other guests) to abide by this Code of Conduct in all community venues–online and in-person–as well as in all one-on-one communications pertaining to community business. 71 | 72 | This code of conduct and its related procedures also applies to unacceptable behavior occurring outside the scope of community activities when such behavior has the potential to adversely affect the safety and well-being of community members. 73 | 74 | ## 9. Contact info 75 | 76 | t@avelino.xxx 77 | 78 | ## 10. License and attribution 79 | 80 | This Code of Conduct is distributed under a [Creative Commons Attribution-ShareAlike license](http://creativecommons.org/licenses/by-sa/3.0/). 81 | 82 | Portions of text derived from the [Django Code of Conduct](https://www.djangoproject.com/conduct/) and the [Geek Feminism Anti-Harassment Policy](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy). 83 | 84 | Retrieved on November 22, 2016 from [http://citizencodeofconduct.org/](http://citizencodeofconduct.org/) 85 | -------------------------------------------------------------------------------- /test_stale_repositories.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | "net/http" 9 | "os" 10 | "regexp" 11 | "strings" 12 | "text/template" 13 | "time" 14 | 15 | "github.com/PuerkitoBio/goquery" 16 | "golang.org/x/oauth2" 17 | ) 18 | 19 | const issueTemplate = ` 20 | {{range .}} 21 | - [ ] {{.}} 22 | {{end}} 23 | ` 24 | 25 | var reGithubRepo = regexp.MustCompile("https://github.com/[a-zA-Z0-9-._]+/[a-zA-Z0-9-._]+$") 26 | var githubGETREPO = "https://api.github.com/repos%s" 27 | var githubGETCOMMITS = "https://api.github.com/repos%s/commits" 28 | var githubPOSTISSUES = "https://api.github.com/repos/avelino/awesome-go/issues" 29 | var awesomeGoGETISSUES = "http://api.github.com/repos/avelino/awesome-go/issues" //only returns open issues 30 | var numberOfYears time.Duration = 1 31 | var timeNow = time.Now() 32 | var issueTitle = fmt.Sprintf("Investigate repositories with more than 1 year without update - %s", timeNow.Format("2006-01-02")) 33 | 34 | const deadLinkMessage = " this repository might no longer exist! (status code >= 400 returned)" 35 | const movedPermanently = " status code 301 received" 36 | const status302 = " status code 302 received" 37 | const archived = " repository has been archived" 38 | 39 | var delay time.Duration = 1 40 | 41 | //LIMIT specifies the max number of repositories that are added in a single run of the script 42 | var LIMIT = 10 43 | var ctr = 0 44 | 45 | type tokenSource struct { 46 | AccessToken string 47 | } 48 | type issue struct { 49 | Title string `json:"title"` 50 | Body string `json:"body"` 51 | } 52 | type repo struct { 53 | Archived bool `json:"archived"` 54 | } 55 | 56 | func (t *tokenSource) Token() (*oauth2.Token, error) { 57 | token := &oauth2.Token{ 58 | AccessToken: t.AccessToken, 59 | } 60 | return token, nil 61 | } 62 | func getRepositoriesFromBody(body string) []string { 63 | links := strings.Split(body, "- ") 64 | for idx, link := range links { 65 | str := strings.ReplaceAll(link, "\r", "") 66 | str = strings.ReplaceAll(str, "[ ]", "") 67 | str = strings.ReplaceAll(str, "[x]", "") 68 | str = strings.ReplaceAll(str, " ", "") 69 | str = strings.ReplaceAll(str, "\n", "") 70 | str = strings.ReplaceAll(str, deadLinkMessage, "") 71 | str = strings.ReplaceAll(str, movedPermanently, "") 72 | str = strings.ReplaceAll(str, status302, "") 73 | str = strings.ReplaceAll(str, archived, "") 74 | links[idx] = str 75 | } 76 | return links 77 | } 78 | func generateIssueBody(repositories []string) (string, error) { 79 | var writer bytes.Buffer 80 | t := template.New("issue") 81 | temp, err := t.Parse(issueTemplate) 82 | if err != nil { 83 | log.Print("Failed to generate template") 84 | return "", err 85 | } 86 | err = temp.Execute(&writer, repositories) 87 | if err != nil { 88 | log.Print("Failed to generate template") 89 | return "", err 90 | } 91 | issueBody := writer.String() 92 | return issueBody, nil 93 | } 94 | func createIssue(staleRepos []string, client *http.Client) { 95 | if len(staleRepos) == 0 { 96 | log.Print("NO STALE REPOSITORIES") 97 | return 98 | } 99 | body, err := generateIssueBody(staleRepos) 100 | if err != nil { 101 | log.Print("Failed at CreateIssue") 102 | return 103 | } 104 | newIssue := &issue{ 105 | Title: issueTitle, 106 | Body: body, 107 | } 108 | buf := new(bytes.Buffer) 109 | json.NewEncoder(buf).Encode(newIssue) 110 | req, err := http.NewRequest("POST", githubPOSTISSUES, buf) 111 | if err != nil { 112 | log.Print("Failed at CreateIssue") 113 | return 114 | } 115 | client.Do(req) 116 | } 117 | func getAllFlaggedRepositories(client *http.Client, flaggedRepositories *map[string]bool) error { 118 | req, err := http.NewRequest("GET", awesomeGoGETISSUES, nil) 119 | if err != nil { 120 | log.Print("Failed to get all issues") 121 | return err 122 | } 123 | res, err := client.Do(req) 124 | if err != nil { 125 | log.Print("Failed to get all issues") 126 | return err 127 | } 128 | target := []issue{} 129 | defer res.Body.Close() 130 | json.NewDecoder(res.Body).Decode(&target) 131 | for _, i := range target { 132 | if i.Title == issueTitle { 133 | repos := getRepositoriesFromBody(i.Body) 134 | for _, repo := range repos { 135 | (*flaggedRepositories)[repo] = true 136 | } 137 | } 138 | } 139 | return nil 140 | } 141 | func containsOpenIssue(link string, openIssues map[string]bool) bool { 142 | _, ok := openIssues[link] 143 | if ok { 144 | return true 145 | } 146 | return false 147 | } 148 | func testRepoState(toRun bool, href string, client *http.Client, staleRepos *[]string) bool { 149 | if toRun { 150 | ownerRepo := strings.ReplaceAll(href, "https://github.com", "") 151 | apiCall := fmt.Sprintf(githubGETREPO, ownerRepo) 152 | req, err := http.NewRequest("GET", apiCall, nil) 153 | var repoResp repo 154 | isRepoAdded := false 155 | if err != nil { 156 | log.Printf("Failed at repository %s\n", href) 157 | return false 158 | } 159 | resp, err := client.Do(req) 160 | if err != nil { 161 | log.Printf("Failed at repository %s\n", href) 162 | return false 163 | } 164 | defer resp.Body.Close() 165 | json.NewDecoder(resp.Body).Decode(&repoResp) 166 | if resp.StatusCode == 301 { 167 | *staleRepos = append(*staleRepos, href+movedPermanently) 168 | log.Printf("%s returned 301", href) 169 | isRepoAdded = true 170 | } 171 | if resp.StatusCode == 302 && !isRepoAdded { 172 | *staleRepos = append(*staleRepos, href+status302) 173 | log.Printf("%s returned 302", href) 174 | isRepoAdded = true 175 | } 176 | if resp.StatusCode >= 400 && !isRepoAdded { 177 | *staleRepos = append(*staleRepos, href+deadLinkMessage) 178 | log.Printf("%s might not exist!", href) 179 | isRepoAdded = true 180 | } 181 | if repoResp.Archived && !isRepoAdded { 182 | *staleRepos = append(*staleRepos, href+archived) 183 | log.Printf("%s is archived!", href) 184 | isRepoAdded = true 185 | } 186 | return isRepoAdded 187 | } 188 | return false 189 | } 190 | func testCommitAge(toRun bool, href string, client *http.Client, staleRepos *[]string) bool { 191 | if toRun { 192 | var respObj []map[string]interface{} 193 | since := timeNow.Add(-1 * 365 * 24 * numberOfYears * time.Hour) 194 | sinceQuery := since.Format(time.RFC3339) 195 | ownerRepo := strings.ReplaceAll(href, "https://github.com", "") 196 | apiCall := fmt.Sprintf(githubGETCOMMITS, ownerRepo) 197 | req, err := http.NewRequest("GET", apiCall, nil) 198 | isRepoAdded := false 199 | if err != nil { 200 | log.Printf("Failed at repository %s\n", href) 201 | return false 202 | } 203 | q := req.URL.Query() 204 | q.Add("since", sinceQuery) 205 | req.URL.RawQuery = q.Encode() 206 | resp, err := client.Do(req) 207 | if err != nil { 208 | log.Printf("Failed at repository %s\n", href) 209 | return false 210 | } 211 | defer resp.Body.Close() 212 | json.NewDecoder(resp.Body).Decode(&respObj) 213 | isAged := len(respObj) == 0 214 | if isAged { 215 | log.Printf("%s has not had a commit in a while", href) 216 | *staleRepos = append(*staleRepos, href) 217 | isRepoAdded = true 218 | } 219 | return isRepoAdded 220 | } 221 | return false 222 | } 223 | func testStaleRepository() { 224 | query := startQuery() 225 | var staleRepos []string 226 | addressedRepositories := make(map[string]bool) 227 | oauth := os.Getenv("OAUTH_TOKEN") 228 | client := &http.Client{} 229 | if oauth == "" { 230 | log.Print("No oauth token found. Using unauthenticated client ...") 231 | } else { 232 | tokenSource := &tokenSource{ 233 | AccessToken: oauth, 234 | } 235 | client = oauth2.NewClient(oauth2.NoContext, tokenSource) 236 | } 237 | err := getAllFlaggedRepositories(client, &addressedRepositories) 238 | 239 | if err != nil { 240 | log.Println("Failed to get existing issues. Exiting...") 241 | return 242 | } 243 | query.Find("body li > a:first-child").EachWithBreak(func(_ int, s *goquery.Selection) bool { 244 | href, ok := s.Attr("href") 245 | if !ok { 246 | log.Println("expected to have href") 247 | return true 248 | } 249 | if ctr >= LIMIT && LIMIT != -1 { 250 | log.Print("Max number of issues created") 251 | return false 252 | } 253 | issueExists := containsOpenIssue(href, addressedRepositories) 254 | if issueExists { 255 | log.Printf("issue already exists for %s\n", href) 256 | } else { 257 | isGithubRepo := reGithubRepo.MatchString(href) 258 | if isGithubRepo { 259 | isRepoAdded := testRepoState(true, href, client, &staleRepos) 260 | isRepoAdded = testCommitAge(!isRepoAdded, href, client, &staleRepos) 261 | if isRepoAdded { 262 | ctr++ 263 | } 264 | } else { 265 | log.Printf("%s non-github repo not currently handled", href) 266 | } 267 | } 268 | return true 269 | }) 270 | createIssue(staleRepos, client) 271 | } 272 | 273 | func main() { 274 | testStaleRepository() 275 | } 276 | -------------------------------------------------------------------------------- /tmpl/assets/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.1 | MIT License | git.io/normalize */ 2 | 3 | /** 4 | * 1. Set default font family to sans-serif. 5 | * 2. Prevent iOS text size adjust after orientation change, without disabling 6 | * user zoom. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | -ms-text-size-adjust: 100%; /* 2 */ 12 | -webkit-text-size-adjust: 100%; /* 2 */ 13 | } 14 | 15 | /** 16 | * Remove default margin. 17 | */ 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | /* HTML5 display definitions 24 | ========================================================================== */ 25 | 26 | /** 27 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 and Firefox. 29 | * Correct `block` display not defined for `main` in IE 11. 30 | */ 31 | 32 | article, 33 | aside, 34 | details, 35 | figcaption, 36 | figure, 37 | footer, 38 | header, 39 | hgroup, 40 | main, 41 | nav, 42 | section, 43 | summary { 44 | display: block; 45 | } 46 | 47 | /** 48 | * 1. Correct `inline-block` display not defined in IE 8/9. 49 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 50 | */ 51 | 52 | audio, 53 | canvas, 54 | progress, 55 | video { 56 | display: inline-block; /* 1 */ 57 | vertical-align: baseline; /* 2 */ 58 | } 59 | 60 | /** 61 | * Prevent modern browsers from displaying `audio` without controls. 62 | * Remove excess height in iOS 5 devices. 63 | */ 64 | 65 | audio:not([controls]) { 66 | display: none; 67 | height: 0; 68 | } 69 | 70 | /** 71 | * Address `[hidden]` styling not present in IE 8/9/10. 72 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. 73 | */ 74 | 75 | [hidden], 76 | template { 77 | display: none; 78 | } 79 | 80 | /* Links 81 | ========================================================================== */ 82 | 83 | /** 84 | * Remove the gray background color from active links in IE 10. 85 | */ 86 | 87 | a { 88 | background: transparent; 89 | } 90 | 91 | /** 92 | * Improve readability when focused and also mouse hovered in all browsers. 93 | */ 94 | 95 | a:active, 96 | a:hover { 97 | outline: 0; 98 | } 99 | 100 | /* Text-level semantics 101 | ========================================================================== */ 102 | 103 | /** 104 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 105 | */ 106 | 107 | abbr[title] { 108 | border-bottom: 1px dotted; 109 | } 110 | 111 | /** 112 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 113 | */ 114 | 115 | b, 116 | strong { 117 | font-weight: bold; 118 | } 119 | 120 | /** 121 | * Address styling not present in Safari and Chrome. 122 | */ 123 | 124 | dfn { 125 | font-style: italic; 126 | } 127 | 128 | /** 129 | * Address variable `h1` font-size and margin within `section` and `article` 130 | * contexts in Firefox 4+, Safari, and Chrome. 131 | */ 132 | 133 | h1 { 134 | font-size: 2em; 135 | margin: 0.67em 0; 136 | } 137 | 138 | /** 139 | * Address styling not present in IE 8/9. 140 | */ 141 | 142 | mark { 143 | background: #ff0; 144 | color: #000; 145 | } 146 | 147 | /** 148 | * Address inconsistent and variable font size in all browsers. 149 | */ 150 | 151 | small { 152 | font-size: 80%; 153 | } 154 | 155 | /** 156 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 157 | */ 158 | 159 | sub, 160 | sup { 161 | font-size: 75%; 162 | line-height: 0; 163 | position: relative; 164 | vertical-align: baseline; 165 | } 166 | 167 | sup { 168 | top: -0.5em; 169 | } 170 | 171 | sub { 172 | bottom: -0.25em; 173 | } 174 | 175 | /* Embedded content 176 | ========================================================================== */ 177 | 178 | /** 179 | * Remove border when inside `a` element in IE 8/9/10. 180 | */ 181 | 182 | img { 183 | border: 0; 184 | } 185 | 186 | /** 187 | * Correct overflow not hidden in IE 9/10/11. 188 | */ 189 | 190 | svg:not(:root) { 191 | overflow: hidden; 192 | } 193 | 194 | /* Grouping content 195 | ========================================================================== */ 196 | 197 | /** 198 | * Address margin not present in IE 8/9 and Safari. 199 | */ 200 | 201 | figure { 202 | margin: 1em 40px; 203 | } 204 | 205 | /** 206 | * Address differences between Firefox and other browsers. 207 | */ 208 | 209 | hr { 210 | -moz-box-sizing: content-box; 211 | box-sizing: content-box; 212 | height: 0; 213 | } 214 | 215 | /** 216 | * Contain overflow in all browsers. 217 | */ 218 | 219 | pre { 220 | overflow: auto; 221 | } 222 | 223 | /** 224 | * Address odd `em`-unit font size rendering in all browsers. 225 | */ 226 | 227 | code, 228 | kbd, 229 | pre, 230 | samp { 231 | font-family: monospace, monospace; 232 | font-size: 1em; 233 | } 234 | 235 | /* Forms 236 | ========================================================================== */ 237 | 238 | /** 239 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 240 | * styling of `select`, unless a `border` property is set. 241 | */ 242 | 243 | /** 244 | * 1. Correct color not being inherited. 245 | * Known issue: affects color of disabled elements. 246 | * 2. Correct font properties not being inherited. 247 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 248 | */ 249 | 250 | button, 251 | input, 252 | optgroup, 253 | select, 254 | textarea { 255 | color: inherit; /* 1 */ 256 | font: inherit; /* 2 */ 257 | margin: 0; /* 3 */ 258 | } 259 | 260 | /** 261 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 262 | */ 263 | 264 | button { 265 | overflow: visible; 266 | } 267 | 268 | /** 269 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 270 | * All other form control elements do not inherit `text-transform` values. 271 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 272 | * Correct `select` style inheritance in Firefox. 273 | */ 274 | 275 | button, 276 | select { 277 | text-transform: none; 278 | } 279 | 280 | /** 281 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 282 | * and `video` controls. 283 | * 2. Correct inability to style clickable `input` types in iOS. 284 | * 3. Improve usability and consistency of cursor style between image-type 285 | * `input` and others. 286 | */ 287 | 288 | button, 289 | html input[type="button"], /* 1 */ 290 | input[type="reset"], 291 | input[type="submit"] { 292 | -webkit-appearance: button; /* 2 */ 293 | cursor: pointer; /* 3 */ 294 | } 295 | 296 | /** 297 | * Re-set default cursor for disabled elements. 298 | */ 299 | 300 | button[disabled], 301 | html input[disabled] { 302 | cursor: default; 303 | } 304 | 305 | /** 306 | * Remove inner padding and border in Firefox 4+. 307 | */ 308 | 309 | button::-moz-focus-inner, 310 | input::-moz-focus-inner { 311 | border: 0; 312 | padding: 0; 313 | } 314 | 315 | /** 316 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 317 | * the UA stylesheet. 318 | */ 319 | 320 | input { 321 | line-height: normal; 322 | } 323 | 324 | /** 325 | * It's recommended that you don't attempt to style these elements. 326 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 327 | * 328 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 329 | * 2. Remove excess padding in IE 8/9/10. 330 | */ 331 | 332 | input[type="checkbox"], 333 | input[type="radio"] { 334 | box-sizing: border-box; /* 1 */ 335 | padding: 0; /* 2 */ 336 | } 337 | 338 | /** 339 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 340 | * `font-size` values of the `input`, it causes the cursor style of the 341 | * decrement button to change from `default` to `text`. 342 | */ 343 | 344 | input[type="number"]::-webkit-inner-spin-button, 345 | input[type="number"]::-webkit-outer-spin-button { 346 | height: auto; 347 | } 348 | 349 | /** 350 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome. 351 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome 352 | * (include `-moz` to future-proof). 353 | */ 354 | 355 | input[type="search"] { 356 | -webkit-appearance: textfield; /* 1 */ 357 | -moz-box-sizing: content-box; 358 | -webkit-box-sizing: content-box; /* 2 */ 359 | box-sizing: content-box; 360 | } 361 | 362 | /** 363 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 364 | * Safari (but not Chrome) clips the cancel button when the search input has 365 | * padding (and `textfield` appearance). 366 | */ 367 | 368 | input[type="search"]::-webkit-search-cancel-button, 369 | input[type="search"]::-webkit-search-decoration { 370 | -webkit-appearance: none; 371 | } 372 | 373 | /** 374 | * Define consistent border, margin, and padding. 375 | */ 376 | 377 | fieldset { 378 | border: 1px solid #c0c0c0; 379 | margin: 0 2px; 380 | padding: 0.35em 0.625em 0.75em; 381 | } 382 | 383 | /** 384 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 385 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 386 | */ 387 | 388 | legend { 389 | border: 0; /* 1 */ 390 | padding: 0; /* 2 */ 391 | } 392 | 393 | /** 394 | * Remove default vertical scrollbar in IE 8/9/10/11. 395 | */ 396 | 397 | textarea { 398 | overflow: auto; 399 | } 400 | 401 | /** 402 | * Don't inherit the `font-weight` (applied by a rule above). 403 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 404 | */ 405 | 406 | optgroup { 407 | font-weight: bold; 408 | } 409 | 410 | /* Tables 411 | ========================================================================== */ 412 | 413 | /** 414 | * Remove most spacing between table cells. 415 | */ 416 | 417 | table { 418 | border-collapse: collapse; 419 | border-spacing: 0; 420 | } 421 | 422 | td, 423 | th { 424 | padding: 0; 425 | } 426 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= 4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= 5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= 6 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= 7 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= 8 | cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= 9 | cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= 10 | cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= 11 | cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= 12 | cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= 13 | cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= 14 | cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= 15 | cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= 16 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= 17 | cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= 18 | cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= 19 | cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= 20 | cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= 21 | cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 22 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= 23 | cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= 24 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= 25 | cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 26 | cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= 27 | cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= 28 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= 29 | cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= 30 | cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= 31 | cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= 32 | cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= 33 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 34 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 35 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 36 | github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U= 37 | github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI= 38 | github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= 39 | github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= 40 | github.com/avelino/slugify v0.0.0-20180501145920-855f152bd774 h1:HrMVYtly2IVqg9EBooHsakQ256ueojP7QuG32K71X/U= 41 | github.com/avelino/slugify v0.0.0-20180501145920-855f152bd774/go.mod h1:5wi5YYOpfuAKwL5XLFYopbgIl/v7NZxaJpa/4X6yFKE= 42 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 43 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 44 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 45 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 46 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 47 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 48 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 49 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 50 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 51 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 52 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 53 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 54 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 55 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 56 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 57 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 58 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 59 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 60 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 61 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 62 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= 63 | github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 64 | github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 65 | github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 66 | github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= 67 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 68 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 69 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 70 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 71 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 72 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= 73 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 74 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 75 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 76 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 77 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 78 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 79 | github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= 80 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 81 | github.com/gomarkdown/markdown v0.0.0-20211212230626-5af6ad2f47df h1:M7mdNDTRraBcrHZg2aOYiFP9yTDajb6fquRZRpXnbVA= 82 | github.com/gomarkdown/markdown v0.0.0-20211212230626-5af6ad2f47df/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= 83 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 84 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 85 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 86 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 87 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 88 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 89 | github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 90 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 91 | github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k= 92 | github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 93 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 94 | github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 95 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 96 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 97 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 98 | github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 99 | github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 100 | github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 101 | github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 102 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 103 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 104 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 105 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 106 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 107 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 108 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 109 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= 110 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 111 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 112 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 113 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 114 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 115 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 116 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 117 | github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= 118 | github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= 119 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 120 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 121 | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 122 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 123 | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 124 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 125 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 126 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 127 | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 128 | go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 129 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 130 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 131 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 132 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 133 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 134 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 135 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 136 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= 137 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= 138 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= 139 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 140 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 141 | golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 142 | golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= 143 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= 144 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 145 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 146 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 147 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 148 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 149 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 150 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 151 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 152 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 153 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 154 | golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 155 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 156 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= 157 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= 158 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 159 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 160 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 161 | golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 162 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 163 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 164 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 165 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 166 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 167 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 168 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 169 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 170 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 171 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 172 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 173 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 174 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 175 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 176 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 177 | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 178 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 179 | golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 180 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 181 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 182 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 183 | golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 184 | golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 185 | golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 186 | golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 187 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 188 | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 189 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 190 | golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 h1:/6y1LfuqNuQdHAm0jjtPtgRcxIxjVZgm5OTu8/QhZvk= 191 | golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 192 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 193 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 194 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 195 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 196 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 197 | golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg= 198 | golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 199 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 200 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 201 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 202 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 203 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 204 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 205 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 206 | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 207 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 208 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 209 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 210 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 211 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 212 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 213 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 214 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 215 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 216 | golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 217 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 218 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 219 | golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 220 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 221 | golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 222 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 223 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 224 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 225 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 226 | golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 227 | golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 228 | golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 229 | golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 230 | golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 231 | golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 232 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 233 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 234 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 235 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 236 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 237 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 238 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 239 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 240 | golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= 241 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 242 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 243 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 244 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 245 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 246 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 247 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 248 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 249 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 250 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 251 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 252 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 253 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 254 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 255 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 256 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 257 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 258 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 259 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 260 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 261 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 262 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 263 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 264 | golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 265 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 266 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 267 | golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 268 | golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 269 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 270 | golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 271 | golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 272 | golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 273 | golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 274 | golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 275 | golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 276 | golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 277 | golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= 278 | golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 279 | golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 280 | golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 281 | golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 282 | golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 283 | golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 284 | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 285 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 286 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 287 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 288 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= 289 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 290 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= 291 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= 292 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 293 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 294 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 295 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 296 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 297 | google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 298 | google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 299 | google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 300 | google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 301 | google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 302 | google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 303 | google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 304 | google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= 305 | google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= 306 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 307 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 308 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 309 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= 310 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 311 | google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= 312 | google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 313 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 314 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 315 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 316 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 317 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 318 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 319 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 320 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= 321 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 322 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 323 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 324 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 325 | google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 326 | google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 327 | google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= 328 | google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 329 | google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 330 | google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 331 | google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 332 | google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 333 | google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 334 | google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 335 | google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 336 | google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= 337 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 338 | google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= 339 | google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 340 | google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 341 | google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 342 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 343 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 344 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 345 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 346 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= 347 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 348 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 349 | google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 350 | google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= 351 | google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= 352 | google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 353 | google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 354 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 355 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 356 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 357 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 358 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 359 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 360 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 361 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 362 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 363 | google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= 364 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 365 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 366 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 367 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 368 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 369 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 370 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 371 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 372 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 373 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 374 | honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 375 | honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 376 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 377 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= 378 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 379 | --------------------------------------------------------------------------------