28 |
29 |
30 |
31 |
32 |
33 | {{.Body}}
34 |
35 |
36 |
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 | [](https://github.com/avelino/awesome-go)
41 | [](https://github.com/avelino/awesome-go)
42 |
43 | ```md
44 | [](https://github.com/avelino/awesome-go)
45 | [](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 |
28 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
🗺️ back to content menu
66 |
67 |
72 |
73 |
74 |
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 |
--------------------------------------------------------------------------------