Repository: mattermost/mattermost-plugin-github
Pull request #626 (2022-12-30 10:40:07)

[GH-613]:Fixed issue "API rate limit exceeded for user ID".
**Summary** 

- User's mattermost logs were full of API rate limit exceeded warn message due to many API calls simultaneously. Mainly due to the notifications count on the mattermost sidebar.
- Please refer to this comment for further information:- https://github.com/mattermost/mattermost-plugin-github/issues/613#issuecomment-1357487107

- [Issue #613](https://github.com/mattermost/mattermost-plugin-github/issues/613) 



mattermod: Hello @Kshitij-Katiyar,

Thanks for your pull request! A Core Committer will review your pull request soon. For code contributions, you can learn more about the review process [here](https://developers.mattermost.com/contribute/getting-started/code-review/).
codecov-commenter: # [Codecov](https://codecov.io/gh/mattermost/mattermost-plugin-github/pull/626?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost) Report
Base: **15.79**% // Head: **15.59**% // Decreases project coverage by **`-0.20%`** :warning:
> Coverage data is based on head [(`1abdab2`)](https://codecov.io/gh/mattermost/mattermost-plugin-github/pull/626?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost) compared to base [(`d4cc847`)](https://codecov.io/gh/mattermost/mattermost-plugin-github/commit/d4cc84762a1e6e70beece866f0c44af1e1c6fffb?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost).
> Patch coverage: 1.72% of modified lines in pull request are covered.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master     #626      +/-   ##
==========================================
- Coverage   15.79%   15.59%   -0.21%     
==========================================
  Files          15       15              
  Lines        4203     4238      +35     
==========================================
- Hits          664      661       -3     
- Misses       3496     3534      +38     
  Partials       43       43              
```


| [Impacted Files](https://codecov.io/gh/mattermost/mattermost-plugin-github/pull/626?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost) | Coverage Δ | |
|---|---|---|
| [server/plugin/plugin.go](https://codecov.io/gh/mattermost/mattermost-plugin-github/pull/626/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost#diff-c2VydmVyL3BsdWdpbi9wbHVnaW4uZ28=) | `3.46% <0.00%> (-0.26%)` | :arrow_down: |
| [server/plugin/api.go](https://codecov.io/gh/mattermost/mattermost-plugin-github/pull/626/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost#diff-c2VydmVyL3BsdWdpbi9hcGkuZ28=) | `7.88% <4.00%> (-0.36%)` | :arrow_down: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/mattermost/mattermost-plugin-github/pull/626?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=mattermost).

spirosoik: /update-branch
mattermost-build: We don't have permissions to update this PR, please contact the submitter to apply the update.
mattermost-build: This PR has been automatically labelled "stale" because it hasn't had recent activity.
A core team member will check in on the status of the PR to help with questions.
Thank you for your contribution!


hanzei: @DHaussermann Gentle reminder to review the PR
hanzei: /update-branch
mattermost-build: We don't have permissions to update this PR, please contact the submitter to apply the update.
hanzei: @Kshitij-Katiyar Would you please merge `master` into your branch?
Kshitij-Katiyar: @hanzei Synced with master
DHaussermann: Thanks for bringing this current @Kshitij-Katiyar 

Do you see any way of validating this change with functional testing? It seems very intermittent even before the fixes. I'm just wondering if there is test guidance or a scope for regression testing based on the changes you've made. 

cc @hanzei and @mickmister 
mickmister: @DHaussermann I think general regression/smoke testing is what's needed here. I'm confident the issue we're trying to solve is solved, just want to make sure nothing is broken
mickmister: > scope for regression testing based on the changes you've made.

Everything is scoped to the sidebar counts. So making sure they are updated when you press refresh, and when your browser reconnects to the MM server (restarting server or turning on/off wifi for remote server should work)
mickmister: @DHaussermann I meant to mention you above. I've added some details to what should be regression tested
DHaussermann: Testing found no functional issues but the warning seem to still be occurring.
Current time on the sever is approx `2023/02/23 19:53:46`  and the plugin build has been deployed over 2 hours.
{
  "caller": "app/plugin_api.go:979",
  "error": "GET https://api.github.com/search/issues?q=is%3Apr+is%3Aopen+review-requested%3ADHaussermann+archived%3Afalse+: 403 API rate limit exceeded for user ID 35588783. [rate reset in 8s]",
  "github username": "DHaussermann",
  "level": "warn",
  "msg": "Failed to search for review",
  "plugin_id": "github",
  "query": "is:pr is:open review-requested:DHaussermann archived:false ",
  "timestamp": "2023-02-23 19:23:30.933 Z",
  "userid": "ft99oz9zxjrixeets3xi1zxrpw"
}

I'll setup a cleaner test on a server that only ever had this build deployed and has more readable logs.

@Kshitij-Katiyar or @mickmister any thoughts on other next steps here?  
hanzei: @DHaussermann How did you run into the rate limit issue? Did you just let the plugin sit there or did you interact with it? If so, what actions did you do?
DHaussermann: @hanzei I'm now certain the issue is still occurring. I see it on a server where no other GitHub build was ever running. 
Steps:
- Uploaded the plugin and enable it with personal oAuth app configured
- Connected test user
- Noted unread message count 
- Marked a few messages as Read on GitHub side 
- Hit refresh to ensure calls were working and user saw the count decrease
- Marked a few more messages as Read on GitHub side 
- Waited about 20 minutes
**Observed**: 
- The count increased (it's a live account and there was genuinely an increase in unread)
- Seems like it works but seems to take longer than 5 min for the data to change
- Checked the logs and saw:
```
{"timestamp":"2023-02-23 21:26:16.961 Z","level":"warn","msg":"Failed to search for assignments","caller":"app/plugin_api.go:979","plugin_id":"github","userid":"zgihwyriybbs7erwu97bfef5rw","github username":"DHaussermann","error":"GET https://api.github.com/search/issues?q=is%3Aopen+assignee%3ADHaussermann+archived%3Afalse+: 403 API rate limit exceeded for user ID 35588783. [rate reset in 15s]","query":"is:open assignee:DHaussermann archived:false "}
{"timestamp":"2023-02-23 21:26:17.002 Z","level":"warn","msg":"Failed to search for PRs","caller":"app/plugin_api.go:979","plugin_id":"github","userid":"zgihwyriybbs7erwu97bfef5rw","github username":"DHaussermann","error":"GET https://api.github.com/search/issues?q=is%3Apr+is%3Aopen+author%3ADHaussermann+archived%3Afalse+: 403 API rate limit exceeded for user ID 35588783. [rate reset in 15s]","query":"is:pr is:open author:DHaussermann archived:false "}
{"timestamp":"2023-02-23 21:26:17.043 Z","level":"warn","msg":"Failed to search for review","caller":"app/plugin_api.go:979","plugin_id":"github","error":"GET https://api.github.com/search/issues?q=is%3Apr+is%3Aopen+review-requested%3ADHaussermann+archived%3Afalse+: 403 API rate limit exceeded for user ID 35588783. [rate reset in 15s]","query":"is:pr is:open review-requested:DHaussermann archived:false ","userid":"zgihwyriybbs7erwu97bfef5rw","github username":"DHaussermann"}
```
The time stamps on this example do **not** seem to line up with when I was using this server. I believe the webapp was idle at that time. 

cc @mickmister - just FYI  
mickmister: > Seems like it works but seems to take longer than 5 min for the data to change

@DHaussermann I don't think there's a timer for this anymore. The plugin itself has a timer to refresh once an hour. The webapp used to call the plugin's websocket reconnect handler to refresh every 15 minutes, but that timer was somewhat recently removed from the webapp https://community.mattermost.com/core/pl/959tpyqp9jnpuni1qnd8i87qsc
hanzei: @DHaussermann Two questions:
- Against which server version are you testing? 
- Can you post the full (20 minute) server logs?
hanzei: @mickmister I'm not quite sure how to proceed here. I would like to find out if the plugin _really_ sends to many requests. My design, it should only do that on a websocket refresh of the LHS and on a manual refresh, right?
Kshitij-Katiyar: @hanzei @mickmister I explored a lot on this issue. From my understanding, there are different types of GitHub APIs and each has its own rate limit. Here in our case we only need to understand 2 types of APIs,
For Normal API calls the rate limit is 5000 requests per hour 
For Search API calls (where we send queries to GitHub) the rate limit is 30 requests per minute.
In our case whenever we click on refresh or get a websocket event from GitHub 4 APIs gets called and out of these 3 search API calls which are assignments, PRs, and review. I think this is what bottlenecking and causing this rate limit issue and in the above server logs provided by @DHaussermann We can see that only these 3 are giving rate limit errors and not the fourth one which was unread.

I explored whether we can convert these search APIs into normal ones. But GitHub hasn't provided any API to get these results direct. As for my open PRs data first, we need to get the organization user is a  part of then the repos, and then open PRs which is not an efficient route.

The only solution for this according to my understanding is using GraphQL as the limit for this is 5000 requests and we can get the data efficiently as well. This PR definitely lowers the number of API calls but it does not help in reducing the actual reason for bottlenecking.  

https://docs.github.com/en/rest/rate-limit
Kshitij-Katiyar: > @Kshitij-Katiyar This makes sense, thanks for the great summary +1
> 
> > We can see that only these 3 are giving rate limit errors and not the fourth one which was unread.
> 
> Great piece of investigation. So since the GitHub API endpoint for `/notifications` is a "normal" API endpoint, it's not subject to the same rate limiting of the other 3 requests we do. And that's why there's no error showing up for that endpoint.
> 
> My question is, why are we sending more than 30 search requests per minute? @DHaussermann Do you think you had refreshed the LHS counts 10 times in one minute? (30 / 3 = 10)
> 
> > The only solution for this according to my understanding is using GraphQL as the limit for this is 5000 requests and we can get the data efficiently as well
> 
> That's interesting how it's much more permissive than the search API. The GraphQL queries themselves support the same "searches" IIRC. FYI there's a WIP effort for introducing GraphQL here #404.
> 
> So maybe this PR doesn't really solve this issue then. It's still a good improvement to performance and client-server communication, so I think we should merge this regardless.
> 
> Only a couple of options come to mind to solve this issue:
>

@mickmister Thanks, Actually there is a websocket event that is sent to the client if we get webhook events from GitHub like 
1) handlePRDescriptionMentionNotification
2) handleCommentMentionNotification
3) handleCommentAuthorNotification
4) handleCommentAssigneeNotification and many more. 
and the client catches that event and calls these 3 APIs which eventually trigger the rate limit. 

> * Do some sort of caching so we don't ping GitHub 10 times a minute

Regarding the solutions, I am not able to figure out what could cache to fix this error. 

> * Implement GraphQL

Should I start implementing GraphQL?

mickmister: @hanzei Do you have any thoughts on this? Implementing GraphQL is a welcomed improvement in general, though I'm wondering if there's a solution to this with a smaller scope.

Based on discussions above, it seems that it's GitHub's "search API" that's causing these rate limit issues, so GraphQL (which has less strict API restrictions) allows us to make more requests in a given time interval.
mickmister: @trilopin Do you have any thoughts on this?
mattermost-build: This PR has been automatically labelled "stale" because it hasn't had recent activity.
A core team member will check in on the status of the PR to help with questions.
Thank you for your contribution!


Kshitij-Katiyar: @trilopin @mickmister any update on this? 
mickmister: > any update on this?

@Kshitij-Katiyar I'm fine with going the route of implementing GraphQL. @m1lt0n What are your thoughts on this?
Kshitij-Katiyar: @mickmister @hanzei I have implemented GraphQL mainly by converting the search GitHub APIs which were mainly causing the API rate limit error into graphQL implementation.
DHaussermann: @mickmister us it expected the Playwright tests would fail here?
mickmister: @DHaussermann Yeah Playwright tests currently don't work on fork PRs
hanzei: @mgdelacroix Can you help with a review here while @mickmister is out?
mattermost-build: This PR has been automatically labelled "stale" because it hasn't had recent activity.
A core team member will check in on the status of the PR to help with questions.
Thank you for your contribution!


DHaussermann: /update-branch
mattermost-build: We don't have permissions to update this PR, please contact the submitter to apply the update.
DHaussermann: @Kshitij-Katiyar I have this deployed to take another look... 
I can keep watching for the API error.  But something odd is happening. The counts are incorrectly coming back as 0 for all 4 values.
![image](https://github.com/mattermost/mattermost-plugin-github/assets/35588783/050c8099-43e9-487f-9a91-049f5f67e0c3)

I have the last commit deployed. 
![image](https://github.com/mattermost/mattermost-plugin-github/assets/35588783/d8f79cd4-494b-44da-aac2-62008431d810)

I followed my steps from earlier this year. https://github.com/mattermost/mattermost-plugin-github/pull/626#issuecomment-1442467249

Can you pleaae see if you can reproduce this?
DHaussermann: @Kshitij-Katiyar 0/5 This might only repo with account data I have. 
```
{"timestamp":"2023-06-29 19:29:30.509 Z","level":"debug","msg":"Received HTTP request","caller":"web/handlers.go:156","method":"GET","url":"/api/v4/teams/k8wxoi184bb6bd4jq9f44f688h/commands/autocomplete_suggestions","request_id":"6344za5ok3bcijkd9yrn77oi4r","status_code":"200"}
{"timestamp":"2023-06-29 19:29:34.954 Z","level":"debug","msg":"Received HTTP request","caller":"web/handlers.go:156","method":"GET","url":"/api/v4/system/ping","request_id":"oiefr9ar4f8mzrsjxn6is9j4dh","status_code":"200"}
{"timestamp":"2023-06-29 19:29:35.281 Z","level":"warn","msg":"Recovered from a panic","caller":"app/plugin_api.go:943","plugin_id":"github","url":"/api/v1/lhs-content","error":"runtime error: invalid memory address or nil pointer dereference","stack":"goroutine 157 [running]:\nruntime/debug.Stack()\n\truntime/debug/stack.go:24 +0x65\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).withRecovery.func1.1()\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:174 +0x75\npanic({0xf1a7c0, 0x1946710})\n\truntime/panic.go:884 +0x212\ngithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql.getPROrIssue(0x0, 0xc0008e2e90)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql/lhs_request.go:97 +0x38\ngithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql.(*Client).GetLHSData(0xc0004caf80, {0x126cc08, 0xc0008a8a80})\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql/lhs_request.go:67 +0xee5\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).getLHSData(0x18?, 0xc0004caf40)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:944 +0x3a\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).getSidebarData(0xc000946180?, 0x7ad2a70680f8?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:953 +0x3b\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).getSidebarContent(0xc0001272c8?, 0xc0004caf40, {0x126bcc8, 0xc0008c52e0}, 0xffffffffffffff01?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:967 +0x31\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).attachUserContext.func1({0x126bcc8, 0xc0008c52e0}, 0xc000127380?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:261 +0x1d3\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).checkAuth.func1({0x126bcc8, 0xc0008c52e0}, 0xc0007aa000)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:210 +0x19e\nnet/http.HandlerFunc.ServeHTTP(0x7ad2ce52f5b8?, {0x126bcc8?, 0xc0008c52e0?}, 0x0?)\n\tnet/http/server.go:2109 +0x2f\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).checkConfigured.func1({0x126bcc8, 0xc0008c52e0}, 0xc00063b520?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:191 +0x98\nnet/http.HandlerFunc.ServeHTTP(0xf8?, {0x126bcc8?, 0xc0008c52e0?}, 0xc0001274c8?)\n\tnet/http/server.go:2109 +0x2f\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).withRecovery.func1({0x126bcc8?, 0xc0008c52e0?}, 0xc0008bdb90?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:178 +0x85\nnet/http.HandlerFunc.ServeHTTP(0xc00064bf00?, {0x126bcc8?, 0xc0008c52e0?}, 0xc000247000?)\n\tnet/http/server.go:2109 +0x2f\ngithub.com/gorilla/mux.(*Router).ServeHTTP(0xc0000d6240, {0x126bcc8, 0xc0008c52e0}, 0xc00064b800)\n\tgithub.com/gorilla/mux@v1.8.0/mux.go:210 +0x1cf\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).ServeHTTP(0xc00063b520, 0x1070920?, {0x126bcc8, 0xc0008c52e0}, 0x3?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:281 +0xe5\ngithub.com/mattermost/mattermost-server/v6/plugin.(*hooksRPCServer).ServeHTTP(0xc000083c20, 0xc000083100, 0x1?)\n\tgithub.com/mattermost/mattermost-server/v6@v6.0.0-20221109191448-21aec2741bfe/plugin/client_rpc.go:453 +0x417\nreflect.Value.call({0xc000653c20?, 0xc000012d98?, 0x50002?}, {0x107aaa9, 0x4}, {0xc0002f0ef8, 0x3, 0xc0002f0e58?})\n\treflect/value.go:584 +0x8c5\nreflect.Value.Call({0xc000653c20?, 0xc000012d98?, 0x46e757?}, {0xc0002f0ef8?, 0x487817?, 0xc0002f0f10?})\n\treflect/value.go:368 +0xbc\nnet/rpc.(*service).call(0xc00067a500, 0x6a700e?, 0xc0008cd800?, 0xc00030aec0, 0xc0003f5a00, 0xc0008cd800?, {0xe7df20?, 0xc000083100?, 0x8de226?}, {0xe8b1e0, ...}, ...)\n\tnet/rpc/server.go:382 +0x226\ncreated by net/rpc.(*Server).ServeCodec\n\tnet/rpc/server.go:479 +0x3fe\n"}
{"timestamp":"2023-06-29 19:29:38.627 Z","level":"warn","msg":"Recovered from a panic","caller":"app/plugin_api.go:943","plugin_id":"github","url":"/api/v1/lhs-content","error":"runtime error: invalid memory address or nil pointer dereference","stack":"goroutine 161 [running]:\nruntime/debug.Stack()\n\truntime/debug/stack.go:24 +0x65\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).withRecovery.func1.1()\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:174 +0x75\npanic({0xf1a7c0, 0x1946710})\n\truntime/panic.go:884 +0x212\ngithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql.getPROrIssue(0x0, 0xc000a82e90)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql/lhs_request.go:97 +0x38\ngithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql.(*Client).GetLHSData(0xc0004cb640, {0x126cc08, 0xc000afbe60})\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql/lhs_request.go:67 +0xee5\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).getLHSData(0x18?, 0xc0004cb580)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:944 +0x3a\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).getSidebarData(0xc000689950?, 0x7ad2a70680f8?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:953 +0x3b\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).getSidebarContent(0xc0007352c8?, 0xc0004cb580, {0x126bcc8, 0xc000a16050}, 0xffffffffffffff01?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:967 +0x31\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).attachUserContext.func1({0x126bcc8, 0xc000a16050}, 0xc000735380?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:261 +0x1d3\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).checkAuth.func1({0x126bcc8, 0xc000a16050}, 0xc000183500)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:210 +0x19e\nnet/http.HandlerFunc.ServeHTTP(0x30?, {0x126bcc8?, 0xc000a16050?}, 0x0?)\n\tnet/http/server.go:2109 +0x2f\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).checkConfigured.func1({0x126bcc8, 0xc000a16050}, 0xc00063b520?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:191 +0x98\nnet/http.HandlerFunc.ServeHTTP(0xf8?, {0x126bcc8?, 0xc000a16050?}, 0xc0007354c8?)\n\tnet/http/server.go:2109 +0x2f\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).withRecovery.func1({0x126bcc8?, 0xc000a16050?}, 0xc000689830?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:178 +0x85\nnet/http.HandlerFunc.ServeHTTP(0xc000183400?, {0x126bcc8?, 0xc000a16050?}, 0xc000066400?)\n\tnet/http/server.go:2109 +0x2f\ngithub.com/gorilla/mux.(*Router).ServeHTTP(0xc0000d6240, {0x126bcc8, 0xc000a16050}, 0xc000182d00)\n\tgithub.com/gorilla/mux@v1.8.0/mux.go:210 +0x1cf\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).ServeHTTP(0xc00063b520, 0x1070920?, {0x126bcc8, 0xc000a16050}, 0x3?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:281 +0xe5\ngithub.com/mattermost/mattermost-server/v6/plugin.(*hooksRPCServer).ServeHTTP(0xc000083c20, 0xc0004a4b60, 0x1?)\n\tgithub.com/mattermost/mattermost-server/v6@v6.0.0-20221109191448-21aec2741bfe/plugin/client_rpc.go:453 +0x417\nreflect.Value.call({0xc000653c20?, 0xc000012d98?, 0x200010005?}, {0x107aaa9, 0x4}, {0xc000805ef8, 0x3, 0xc000805e58?})\n\treflect/value.go:584 +0x8c5\nreflect.Value.Call({0xc000653c20?, 0xc000012d98?, 0x46e757?}, {0xc000805ef8?, 0x487817?, 0xc000805f10?})\n\treflect/value.go:368 +0xbc\nnet/rpc.(*service).call(0xc00067a500, 0x6a700e?, 0xc000952180?, 0xc00030aec0, 0xc0003f5a00, 0xc000952180?, {0xe7df20?, 0xc0004a4b60?, 0xc000184240?}, {0xe8b1e0, ...}, ...)\n\tnet/rpc/server.go:382 +0x226\ncreated by net/rpc.(*Server).ServeCodec\n\tnet/rpc/server.go:479 +0x3fe\n"}
{"timestamp":"2023-06-29 19:29:38.714 Z","level":"debug","msg":"Checking feature flags from management service","caller":"app/feature_flags.go:45","old_flags":"{\"TestFeature\":\"on\",\"TestBoolFeature\":true,\"CollapsedThreads\":true,\"EnableRemoteClusterService\":false,\"AppsEnabled\":true,\"PluginPlaybooks\":\"\",\"PluginApps\":\"off\",\"PluginFocalboard\":\"off\",\"PluginCalls\":\"off\",\"PermalinkPreviews\":true,\"CallsMobile\":false,\"CallsEnabled\":true,\"BoardsFeatureFlags\":\"on\",\"GuidedChannelCreation\":false,\"InviteToTeam\":\"none\",\"CustomGroups\":true,\"BoardsDataRetention\":false,\"NormalizeLdapDNs\":false,\"EnableInactivityCheckJob\":false,\"UseCaseOnboarding\":true,\"GraphQL\":false,\"InsightsEnabled\":true,\"CommandPalette\":false,\"AdvancedTextEditor\":true}","new_flags":"{\"TestFeature\":\"on\",\"TestBoolFeature\":true,\"CollapsedThreads\":true,\"EnableRemoteClusterService\":false,\"AppsEnabled\":true,\"PluginPlaybooks\":\"\",\"PluginApps\":\"off\",\"PluginFocalboard\":\"off\",\"PluginCalls\":\"off\",\"PermalinkPreviews\":true,\"CallsMobile\":false,\"CallsEnabled\":true,\"BoardsFeatureFlags\":\"on\",\"GuidedChannelCreation\":false,\"InviteToTeam\":\"none\",\"CustomGroups\":true,\"BoardsDataRetention\":false,\"NormalizeLdapDNs\":false,\"EnableInactivityCheckJob\":false,\"UseCaseOnboarding\":true,\"GraphQL\":false,\"InsightsEnabled\":true,\"CommandPalette\":false,\"AdvancedTextEditor\":true}"}
{"timestamp":"2023-06-29 19:29:38.725 Z","level":"info","msg":"This node attempted to join the cluster, but could not find any nodes.","caller":"cluster/cluster.go:391"}
{"timestamp":"2023-06-29 19:29:39.954 Z","level":"debug","msg":"Received HTTP request","caller":"web/handlers.go:156","method":"GET","url":"/api/v4/system/ping","request_id":"4uqwkauqwbnpmgmc3tqmsqxbcc","status_code":"200"}
{"timestamp":"2023-06-29 19:29:39.954 Z","level":"debug","msg":"Received HTTP request","caller":"web/handlers.go:156","method":"GET","url":"/api/v4/system/ping","request_id":"o61p1ono7jgf5x47xtczckmxyr","status_code":"200"}
```

Please advise.

Kshitij-Katiyar: > @Kshitij-Katiyar 0/5 This might only repo with account data I have.
> 
> ```
> {"timestamp":"2023-06-29 19:29:30.509 Z","level":"debug","msg":"Received HTTP request","caller":"web/handlers.go:156","method":"GET","url":"/api/v4/teams/k8wxoi184bb6bd4jq9f44f688h/commands/autocomplete_suggestions","request_id":"6344za5ok3bcijkd9yrn77oi4r","status_code":"200"}
> {"timestamp":"2023-06-29 19:29:34.954 Z","level":"debug","msg":"Received HTTP request","caller":"web/handlers.go:156","method":"GET","url":"/api/v4/system/ping","request_id":"oiefr9ar4f8mzrsjxn6is9j4dh","status_code":"200"}
> {"timestamp":"2023-06-29 19:29:35.281 Z","level":"warn","msg":"Recovered from a panic","caller":"app/plugin_api.go:943","plugin_id":"github","url":"/api/v1/lhs-content","error":"runtime error: invalid memory address or nil pointer dereference","stack":"goroutine 157 [running]:\nruntime/debug.Stack()\n\truntime/debug/stack.go:24 +0x65\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).withRecovery.func1.1()\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:174 +0x75\npanic({0xf1a7c0, 0x1946710})\n\truntime/panic.go:884 +0x212\ngithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql.getPROrIssue(0x0, 0xc0008e2e90)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql/lhs_request.go:97 +0x38\ngithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql.(*Client).GetLHSData(0xc0004caf80, {0x126cc08, 0xc0008a8a80})\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql/lhs_request.go:67 +0xee5\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).getLHSData(0x18?, 0xc0004caf40)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:944 +0x3a\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).getSidebarData(0xc000946180?, 0x7ad2a70680f8?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:953 +0x3b\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).getSidebarContent(0xc0001272c8?, 0xc0004caf40, {0x126bcc8, 0xc0008c52e0}, 0xffffffffffffff01?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:967 +0x31\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).attachUserContext.func1({0x126bcc8, 0xc0008c52e0}, 0xc000127380?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:261 +0x1d3\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).checkAuth.func1({0x126bcc8, 0xc0008c52e0}, 0xc0007aa000)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:210 +0x19e\nnet/http.HandlerFunc.ServeHTTP(0x7ad2ce52f5b8?, {0x126bcc8?, 0xc0008c52e0?}, 0x0?)\n\tnet/http/server.go:2109 +0x2f\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).checkConfigured.func1({0x126bcc8, 0xc0008c52e0}, 0xc00063b520?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:191 +0x98\nnet/http.HandlerFunc.ServeHTTP(0xf8?, {0x126bcc8?, 0xc0008c52e0?}, 0xc0001274c8?)\n\tnet/http/server.go:2109 +0x2f\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).withRecovery.func1({0x126bcc8?, 0xc0008c52e0?}, 0xc0008bdb90?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:178 +0x85\nnet/http.HandlerFunc.ServeHTTP(0xc00064bf00?, {0x126bcc8?, 0xc0008c52e0?}, 0xc000247000?)\n\tnet/http/server.go:2109 +0x2f\ngithub.com/gorilla/mux.(*Router).ServeHTTP(0xc0000d6240, {0x126bcc8, 0xc0008c52e0}, 0xc00064b800)\n\tgithub.com/gorilla/mux@v1.8.0/mux.go:210 +0x1cf\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).ServeHTTP(0xc00063b520, 0x1070920?, {0x126bcc8, 0xc0008c52e0}, 0x3?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:281 +0xe5\ngithub.com/mattermost/mattermost-server/v6/plugin.(*hooksRPCServer).ServeHTTP(0xc000083c20, 0xc000083100, 0x1?)\n\tgithub.com/mattermost/mattermost-server/v6@v6.0.0-20221109191448-21aec2741bfe/plugin/client_rpc.go:453 +0x417\nreflect.Value.call({0xc000653c20?, 0xc000012d98?, 0x50002?}, {0x107aaa9, 0x4}, {0xc0002f0ef8, 0x3, 0xc0002f0e58?})\n\treflect/value.go:584 +0x8c5\nreflect.Value.Call({0xc000653c20?, 0xc000012d98?, 0x46e757?}, {0xc0002f0ef8?, 0x487817?, 0xc0002f0f10?})\n\treflect/value.go:368 +0xbc\nnet/rpc.(*service).call(0xc00067a500, 0x6a700e?, 0xc0008cd800?, 0xc00030aec0, 0xc0003f5a00, 0xc0008cd800?, {0xe7df20?, 0xc000083100?, 0x8de226?}, {0xe8b1e0, ...}, ...)\n\tnet/rpc/server.go:382 +0x226\ncreated by net/rpc.(*Server).ServeCodec\n\tnet/rpc/server.go:479 +0x3fe\n"}
> {"timestamp":"2023-06-29 19:29:38.627 Z","level":"warn","msg":"Recovered from a panic","caller":"app/plugin_api.go:943","plugin_id":"github","url":"/api/v1/lhs-content","error":"runtime error: invalid memory address or nil pointer dereference","stack":"goroutine 161 [running]:\nruntime/debug.Stack()\n\truntime/debug/stack.go:24 +0x65\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).withRecovery.func1.1()\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:174 +0x75\npanic({0xf1a7c0, 0x1946710})\n\truntime/panic.go:884 +0x212\ngithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql.getPROrIssue(0x0, 0xc000a82e90)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql/lhs_request.go:97 +0x38\ngithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql.(*Client).GetLHSData(0xc0004cb640, {0x126cc08, 0xc000afbe60})\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/graphql/lhs_request.go:67 +0xee5\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).getLHSData(0x18?, 0xc0004cb580)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:944 +0x3a\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).getSidebarData(0xc000689950?, 0x7ad2a70680f8?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:953 +0x3b\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).getSidebarContent(0xc0007352c8?, 0xc0004cb580, {0x126bcc8, 0xc000a16050}, 0xffffffffffffff01?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:967 +0x31\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).attachUserContext.func1({0x126bcc8, 0xc000a16050}, 0xc000735380?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:261 +0x1d3\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).checkAuth.func1({0x126bcc8, 0xc000a16050}, 0xc000183500)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:210 +0x19e\nnet/http.HandlerFunc.ServeHTTP(0x30?, {0x126bcc8?, 0xc000a16050?}, 0x0?)\n\tnet/http/server.go:2109 +0x2f\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).checkConfigured.func1({0x126bcc8, 0xc000a16050}, 0xc00063b520?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:191 +0x98\nnet/http.HandlerFunc.ServeHTTP(0xf8?, {0x126bcc8?, 0xc000a16050?}, 0xc0007354c8?)\n\tnet/http/server.go:2109 +0x2f\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).withRecovery.func1({0x126bcc8?, 0xc000a16050?}, 0xc000689830?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:178 +0x85\nnet/http.HandlerFunc.ServeHTTP(0xc000183400?, {0x126bcc8?, 0xc000a16050?}, 0xc000066400?)\n\tnet/http/server.go:2109 +0x2f\ngithub.com/gorilla/mux.(*Router).ServeHTTP(0xc0000d6240, {0x126bcc8, 0xc000a16050}, 0xc000182d00)\n\tgithub.com/gorilla/mux@v1.8.0/mux.go:210 +0x1cf\ngithub.com/mattermost/mattermost-plugin-github/server/plugin.(*Plugin).ServeHTTP(0xc00063b520, 0x1070920?, {0x126bcc8, 0xc000a16050}, 0x3?)\n\tgithub.com/mattermost/mattermost-plugin-github/server/plugin/api.go:281 +0xe5\ngithub.com/mattermost/mattermost-server/v6/plugin.(*hooksRPCServer).ServeHTTP(0xc000083c20, 0xc0004a4b60, 0x1?)\n\tgithub.com/mattermost/mattermost-server/v6@v6.0.0-20221109191448-21aec2741bfe/plugin/client_rpc.go:453 +0x417\nreflect.Value.call({0xc000653c20?, 0xc000012d98?, 0x200010005?}, {0x107aaa9, 0x4}, {0xc000805ef8, 0x3, 0xc000805e58?})\n\treflect/value.go:584 +0x8c5\nreflect.Value.Call({0xc000653c20?, 0xc000012d98?, 0x46e757?}, {0xc000805ef8?, 0x487817?, 0xc000805f10?})\n\treflect/value.go:368 +0xbc\nnet/rpc.(*service).call(0xc00067a500, 0x6a700e?, 0xc000952180?, 0xc00030aec0, 0xc0003f5a00, 0xc000952180?, {0xe7df20?, 0xc0004a4b60?, 0xc000184240?}, {0xe8b1e0, ...}, ...)\n\tnet/rpc/server.go:382 +0x226\ncreated by net/rpc.(*Server).ServeCodec\n\tnet/rpc/server.go:479 +0x3fe\n"}
> {"timestamp":"2023-06-29 19:29:38.714 Z","level":"debug","msg":"Checking feature flags from management service","caller":"app/feature_flags.go:45","old_flags":"{\"TestFeature\":\"on\",\"TestBoolFeature\":true,\"CollapsedThreads\":true,\"EnableRemoteClusterService\":false,\"AppsEnabled\":true,\"PluginPlaybooks\":\"\",\"PluginApps\":\"off\",\"PluginFocalboard\":\"off\",\"PluginCalls\":\"off\",\"PermalinkPreviews\":true,\"CallsMobile\":false,\"CallsEnabled\":true,\"BoardsFeatureFlags\":\"on\",\"GuidedChannelCreation\":false,\"InviteToTeam\":\"none\",\"CustomGroups\":true,\"BoardsDataRetention\":false,\"NormalizeLdapDNs\":false,\"EnableInactivityCheckJob\":false,\"UseCaseOnboarding\":true,\"GraphQL\":false,\"InsightsEnabled\":true,\"CommandPalette\":false,\"AdvancedTextEditor\":true}","new_flags":"{\"TestFeature\":\"on\",\"TestBoolFeature\":true,\"CollapsedThreads\":true,\"EnableRemoteClusterService\":false,\"AppsEnabled\":true,\"PluginPlaybooks\":\"\",\"PluginApps\":\"off\",\"PluginFocalboard\":\"off\",\"PluginCalls\":\"off\",\"PermalinkPreviews\":true,\"CallsMobile\":false,\"CallsEnabled\":true,\"BoardsFeatureFlags\":\"on\",\"GuidedChannelCreation\":false,\"InviteToTeam\":\"none\",\"CustomGroups\":true,\"BoardsDataRetention\":false,\"NormalizeLdapDNs\":false,\"EnableInactivityCheckJob\":false,\"UseCaseOnboarding\":true,\"GraphQL\":false,\"InsightsEnabled\":true,\"CommandPalette\":false,\"AdvancedTextEditor\":true}"}
> {"timestamp":"2023-06-29 19:29:38.725 Z","level":"info","msg":"This node attempted to join the cluster, but could not find any nodes.","caller":"cluster/cluster.go:391"}
> {"timestamp":"2023-06-29 19:29:39.954 Z","level":"debug","msg":"Received HTTP request","caller":"web/handlers.go:156","method":"GET","url":"/api/v4/system/ping","request_id":"4uqwkauqwbnpmgmc3tqmsqxbcc","status_code":"200"}
> {"timestamp":"2023-06-29 19:29:39.954 Z","level":"debug","msg":"Received HTTP request","caller":"web/handlers.go:156","method":"GET","url":"/api/v4/system/ping","request_id":"o61p1ono7jgf5x47xtczckmxyr","status_code":"200"}
> ```
> 
> Please advise.

@DHaussermann I have fixed the above issue. Just needed a minor change. Please test this again 
DHaussermann: @hanzei and @mickmister, I re-requested dev review but I'm now seeing there were not too many commits since last round.  re-review would probably have been plenty. Sorry I though Dev review approvals were much older as this task has been going for some time now.   

Patch:
diff --git a/go.mod b/go.mod
index 20823a1..eb6cd5b 100644
--- a/go.mod
+++ b/go.mod
@@ -12,7 +12,7 @@ require (
 	github.com/microcosm-cc/bluemonday v1.0.19
 	github.com/pkg/errors v0.9.1
 	github.com/stretchr/testify v1.8.0
-	golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
+	golang.org/x/oauth2 v0.4.0
 )
 
 require (
@@ -65,6 +65,8 @@ require (
 	github.com/rudderlabs/analytics-go v3.3.2+incompatible // indirect
 	github.com/segmentio/backo-go v1.0.1 // indirect
 	github.com/shopspring/decimal v1.2.0 // indirect
+	github.com/shurcooL/githubv4 v0.0.0-20230424031643-6cea62ecd5a9
+	github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29 // indirect
 	github.com/sirupsen/logrus v1.9.0 // indirect
 	github.com/spf13/cast v1.3.1 // indirect
 	github.com/stretchr/objx v0.4.0 // indirect
@@ -83,8 +85,8 @@ require (
 	golang.org/x/sys v0.5.0 // indirect
 	golang.org/x/text v0.7.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
-	google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1 // indirect
-	google.golang.org/grpc v1.48.0 // indirect
+	google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
+	google.golang.org/grpc v1.53.0 // indirect
 	google.golang.org/protobuf v1.28.1 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
diff --git a/go.sum b/go.sum
index 7b2fea0..ae29971 100644
--- a/go.sum
+++ b/go.sum
@@ -2,45 +2,13 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
 cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
-cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
-cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
-cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
-cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
-cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
-cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
-cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
-cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
-cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
-cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
-cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
-cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
-cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
-cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
-cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
-cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
-cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
-cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
-cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
-cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
-cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
-cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
-cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
-cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
-cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
-cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
-cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
-cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
-cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
 dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
-dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
 dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
 dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
 git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
 github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
 github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
@@ -48,7 +16,6 @@ github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0
 github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
 github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
 github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
-github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
 github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
 github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -59,18 +26,7 @@ github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2y
 github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
 github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
 github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
-github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
-github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
-github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
-github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -79,12 +35,6 @@ github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4
 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
 github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a h1:etIrTD8BQqzColk9nKRusM9um5+1q0iOEJLqfBMIK64=
 github.com/dyatlov/go-opengraph/opengraph v0.0.0-20220524092352-606d7b1e5f8a/go.mod h1:emQhSYTXqB0xxjLITTw4EaWZ+8IIQYw+kx9GqNUKdLg=
-github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
-github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
 github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
@@ -97,9 +47,6 @@ github.com/go-asn1-ber/asn1-ber v1.3.2-0.20191121212151-29be175fc3a3/go.mod h1:h
 github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
 github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
 github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
-github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
@@ -107,49 +54,23 @@ github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfC
 github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
-github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
 github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
-github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
-github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
-github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
-github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
-github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
-github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
-github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
 github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
 github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
 github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg=
 github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg=
@@ -158,24 +79,13 @@ github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD
 github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
-github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
 github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
 github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
 github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
-github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
-github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
 github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
@@ -187,18 +97,14 @@ github.com/graph-gophers/graphql-go v1.4.0 h1:JE9wveRTSXwJyjdRd6bOQ7Ob5bewTUQ58J
 github.com/graph-gophers/graphql-go v1.4.0/go.mod h1:YtmJZDLbF1YYNrlNAuiO5zAStUWc3XZT07iGsVqe1Os=
 github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
 github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
-github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
 github.com/hashicorp/go-hclog v1.2.2 h1:ihRI7YFwcZdiSD7SIenIhHfQH3OuDvWerAUBZbeQS3M=
 github.com/hashicorp/go-hclog v1.2.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
 github.com/hashicorp/go-plugin v1.4.4 h1:NVdrSdFRt3SkZtNckJ6tog7gbpRrcbOjQi/rgF7JYWQ=
 github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s=
-github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
 github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
 github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs=
 github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
-github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
 github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
 github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
@@ -207,7 +113,6 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
-github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
 github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
@@ -285,11 +190,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
 github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
-github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
 github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
 github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
@@ -304,10 +206,14 @@ github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFR
 github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
 github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
 github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
+github.com/shurcooL/githubv4 v0.0.0-20230424031643-6cea62ecd5a9 h1:nCBaIs5/R0HFP5+aPW/SzFUF8z0oKuCXmuDmHWaxzjY=
+github.com/shurcooL/githubv4 v0.0.0-20230424031643-6cea62ecd5a9/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo=
 github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
 github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
 github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
 github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=
+github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29 h1:B1PEwpArrNp4dkQrfxh/abbBAOZBVp0ds+fBEOUOqOc=
+github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg=
 github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
 github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
 github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=
@@ -364,28 +270,17 @@ github.com/wiggin77/srslog v1.0.1 h1:gA2XjSMy3DrRdX9UqLuDtuVAAshb8bE1NhX1YK0Qe+8
 github.com/wiggin77/srslog v1.0.1/go.mod h1:fehkyYDq1QfuYn60TDPu9YdY2bB85VUW2mvN1WynEls=
 github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c h1:3lbZUMbMiGUW/LMkfsEABsc5zNT9+b1CvsJx47JzJ8g=
 github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM=
-github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
-go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
-go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
-go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI=
 go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs=
-go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
 go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
 golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
 golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -393,35 +288,9 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y
 golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 h1:GIAS/yBem/gq2MUqgNIzUHW7cJMmx3TGZOrnyYaNQ6c=
 golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
-golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
-golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
-golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
-golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
-golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
-golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
-golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
-golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
-golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
-golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
-golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -430,29 +299,10 @@ golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73r
 golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
@@ -462,53 +312,25 @@ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAG
 golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
-golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M=
+golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec=
 golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -521,7 +343,6 @@ golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -531,83 +352,24 @@ golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
-golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
-golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
-golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
 golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0=
 google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
 google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
 google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
-google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
-google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
-google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
-google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
-google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
-google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
-google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
-google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
-google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
 google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
 google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
@@ -615,75 +377,20 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA
 google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
 google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
-google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
-google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
-google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
-google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1 h1:C2UVWqrgLYKrT5nh5oU6hLRm1AeEklCK5eloQA1NtFY=
-google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
+google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w=
+google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
 google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
-google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
-google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
-google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
-google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
-google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
-google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=
-google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
-google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
-google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
-google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
-google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
-google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
-google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
+google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
 google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
 gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
@@ -691,7 +398,6 @@ gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXL
 gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
@@ -702,13 +408,5 @@ grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJd
 honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
-honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
-rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
-rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
 sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
 sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
diff --git a/server/plugin/api.go b/server/plugin/api.go
index 97103c1..8dd636d 100644
--- a/server/plugin/api.go
+++ b/server/plugin/api.go
@@ -57,6 +57,18 @@ type PRDetails struct {
 	Reviews            []*github.PullRequestReview `json:"reviews"`
 }
 
+type FilteredNotification struct {
+	github.Notification
+	HTMLURL string `json:"html_url"`
+}
+
+type SidebarContent struct {
+	PRs         []*github.Issue         `json:"prs"`
+	Reviews     []*github.Issue         `json:"reviews"`
+	Assignments []*github.Issue         `json:"assignments"`
+	Unreads     []*FilteredNotification `json:"unreads"`
+}
+
 type Context struct {
 	Ctx    context.Context
 	UserID string
@@ -134,15 +146,11 @@ func (p *Plugin) initializeAPI() {
 
 	apiRouter.HandleFunc("/user", p.checkAuth(p.attachContext(p.getGitHubUser), ResponseTypeJSON)).Methods(http.MethodPost)
 	apiRouter.HandleFunc("/todo", p.checkAuth(p.attachUserContext(p.postToDo), ResponseTypeJSON)).Methods(http.MethodPost)
-	apiRouter.HandleFunc("/reviews", p.checkAuth(p.attachUserContext(p.getReviews), ResponseTypePlain)).Methods(http.MethodGet)
-	apiRouter.HandleFunc("/yourprs", p.checkAuth(p.attachUserContext(p.getYourPrs), ResponseTypePlain)).Methods(http.MethodGet)
 	apiRouter.HandleFunc("/prsdetails", p.checkAuth(p.attachUserContext(p.getPrsDetails), ResponseTypePlain)).Methods(http.MethodPost)
 	apiRouter.HandleFunc("/searchissues", p.checkAuth(p.attachUserContext(p.searchIssues), ResponseTypePlain)).Methods(http.MethodGet)
-	apiRouter.HandleFunc("/yourassignments", p.checkAuth(p.attachUserContext(p.getYourAssignments), ResponseTypePlain)).Methods(http.MethodGet)
 	apiRouter.HandleFunc("/createissue", p.checkAuth(p.attachUserContext(p.createIssue), ResponseTypePlain)).Methods(http.MethodPost)
 	apiRouter.HandleFunc("/createissuecomment", p.checkAuth(p.attachUserContext(p.createIssueComment), ResponseTypePlain)).Methods(http.MethodPost)
 	apiRouter.HandleFunc("/mentions", p.checkAuth(p.attachUserContext(p.getMentions), ResponseTypePlain)).Methods(http.MethodGet)
-	apiRouter.HandleFunc("/unreads", p.checkAuth(p.attachUserContext(p.getUnreads), ResponseTypePlain)).Methods(http.MethodGet)
 	apiRouter.HandleFunc("/labels", p.checkAuth(p.attachUserContext(p.getLabels), ResponseTypePlain)).Methods(http.MethodGet)
 	apiRouter.HandleFunc("/milestones", p.checkAuth(p.attachUserContext(p.getMilestones), ResponseTypePlain)).Methods(http.MethodGet)
 	apiRouter.HandleFunc("/assignees", p.checkAuth(p.attachUserContext(p.getAssignees), ResponseTypePlain)).Methods(http.MethodGet)
@@ -150,6 +158,7 @@ func (p *Plugin) initializeAPI() {
 	apiRouter.HandleFunc("/settings", p.checkAuth(p.attachUserContext(p.updateSettings), ResponseTypePlain)).Methods(http.MethodPost)
 	apiRouter.HandleFunc("/issue", p.checkAuth(p.attachUserContext(p.getIssueByNumber), ResponseTypePlain)).Methods(http.MethodGet)
 	apiRouter.HandleFunc("/pr", p.checkAuth(p.attachUserContext(p.getPrByNumber), ResponseTypePlain)).Methods(http.MethodGet)
+	apiRouter.HandleFunc("/lhs-content", p.checkAuth(p.attachUserContext(p.getSidebarContent), ResponseTypePlain)).Methods(http.MethodGet)
 
 	apiRouter.HandleFunc("/config", checkPluginRequest(p.getConfig)).Methods(http.MethodGet)
 	apiRouter.HandleFunc("/token", checkPluginRequest(p.getToken)).Methods(http.MethodGet)
@@ -651,22 +660,16 @@ func (p *Plugin) getMentions(c *UserContext, w http.ResponseWriter, r *http.Requ
 	p.writeJSON(w, result.Issues)
 }
 
-func (p *Plugin) getUnreads(c *UserContext, w http.ResponseWriter, r *http.Request) {
+func (p *Plugin) getUnreadsData(c *UserContext) []*FilteredNotification {
 	githubClient := p.githubConnectUser(c.Context.Ctx, c.GHInfo)
 
 	notifications, _, err := githubClient.Activity.ListNotifications(c.Ctx, &github.NotificationListOptions{})
 	if err != nil {
 		c.Log.WithError(err).Warnf("Failed to list notifications")
-		return
-	}
-
-	type filteredNotification struct {
-		github.Notification
-
-		HTMLUrl string `json:"html_url"`
+		return nil
 	}
 
-	filteredNotifications := []*filteredNotification{}
+	filteredNotifications := []*FilteredNotification{}
 	for _, n := range notifications {
 		if n.GetReason() == notificationReasonSubscribed {
 			continue
@@ -684,45 +687,13 @@ func (p *Plugin) getUnreads(c *UserContext, w http.ResponseWriter, r *http.Reque
 			subjectURL = n.GetSubject().GetLatestCommentURL()
 		}
 
-		filteredNotifications = append(filteredNotifications, &filteredNotification{
+		filteredNotifications = append(filteredNotifications, &FilteredNotification{
 			Notification: *n,
-			HTMLUrl:      fixGithubNotificationSubjectURL(subjectURL, issueNum),
+			HTMLURL:      fixGithubNotificationSubjectURL(subjectURL, issueNum),
 		})
 	}
 
-	p.writeJSON(w, filteredNotifications)
-}
-
-func (p *Plugin) getReviews(c *UserContext, w http.ResponseWriter, r *http.Request) {
-	config := p.getConfiguration()
-
-	githubClient := p.githubConnectUser(c.Context.Ctx, c.GHInfo)
-	username := c.GHInfo.GitHubUsername
-
-	query := getReviewSearchQuery(username, config.GitHubOrg)
-	result, _, err := githubClient.Search.Issues(c.Ctx, query, &github.SearchOptions{})
-	if err != nil {
-		c.Log.WithError(err).With(logger.LogContext{"query": query}).Warnf("Failed to search for review")
-		return
-	}
-
-	p.writeJSON(w, result.Issues)
-}
-
-func (p *Plugin) getYourPrs(c *UserContext, w http.ResponseWriter, r *http.Request) {
-	config := p.getConfiguration()
-
-	githubClient := p.githubConnectUser(c.Context.Ctx, c.GHInfo)
-	username := c.GHInfo.GitHubUsername
-
-	query := getYourPrsSearchQuery(username, config.GitHubOrg)
-	result, _, err := githubClient.Search.Issues(c.Ctx, query, &github.SearchOptions{})
-	if err != nil {
-		c.Log.WithError(err).With(logger.LogContext{"query": query}).Warnf("Failed to search for PRs")
-		return
-	}
-
-	p.writeJSON(w, result.Issues)
+	return filteredNotifications
 }
 
 func (p *Plugin) getPrsDetails(c *UserContext, w http.ResponseWriter, r *http.Request) {
@@ -967,20 +938,39 @@ func (p *Plugin) createIssueComment(c *UserContext, w http.ResponseWriter, r *ht
 	p.writeJSON(w, result)
 }
 
-func (p *Plugin) getYourAssignments(c *UserContext, w http.ResponseWriter, r *http.Request) {
-	config := p.getConfiguration()
+func (p *Plugin) getLHSData(c *UserContext) (reviewResp []*github.Issue, assignmentResp []*github.Issue, openPRResp []*github.Issue, err error) {
+	graphQLClient := p.graphQLConnect(c.GHInfo)
 
-	githubClient := p.githubConnectUser(c.Context.Ctx, c.GHInfo)
+	reviewResp, assignmentResp, openPRResp, err = graphQLClient.GetLHSData(c.Context.Ctx)
+	if err != nil {
+		return []*github.Issue{}, []*github.Issue{}, []*github.Issue{}, err
+	}
 
-	username := c.GHInfo.GitHubUsername
-	query := getYourAssigneeSearchQuery(username, config.GitHubOrg)
-	result, _, err := githubClient.Search.Issues(c.Ctx, query, &github.SearchOptions{})
+	return reviewResp, assignmentResp, openPRResp, nil
+}
+
+func (p *Plugin) getSidebarData(c *UserContext) (*SidebarContent, error) {
+	reviewResp, assignmentResp, openPRResp, err := p.getLHSData(c)
 	if err != nil {
-		c.Log.WithError(err).With(logger.LogContext{"query": query}).Warnf("Failed to search for assignments")
+		return nil, err
+	}
+
+	return &SidebarContent{
+		PRs:         openPRResp,
+		Assignments: assignmentResp,
+		Reviews:     reviewResp,
+		Unreads:     p.getUnreadsData(c),
+	}, nil
+}
+
+func (p *Plugin) getSidebarContent(c *UserContext, w http.ResponseWriter, r *http.Request) {
+	sidebarContent, err := p.getSidebarData(c)
+	if err != nil {
+		c.Log.WithError(err).Warnf("Failed to search for the sidebar data")
 		return
 	}
 
-	p.writeJSON(w, result.Issues)
+	p.writeJSON(w, sidebarContent)
 }
 
 func (p *Plugin) postToDo(c *UserContext, w http.ResponseWriter, r *http.Request) {
diff --git a/server/plugin/graphql/client.go b/server/plugin/graphql/client.go
new file mode 100644
index 0000000..6563cd7
--- /dev/null
+++ b/server/plugin/graphql/client.go
@@ -0,0 +1,62 @@
+package graphql
+
+import (
+	"context"
+	"net/url"
+	"path"
+
+	pluginapi "github.com/mattermost/mattermost-plugin-api"
+	"github.com/pkg/errors"
+	"github.com/shurcooL/githubv4"
+	"golang.org/x/oauth2"
+)
+
+// Client encapsulates the third party package that communicates with Github GraphQL API
+type Client struct {
+	client   *githubv4.Client
+	org      string
+	username string
+	logger   pluginapi.LogService
+}
+
+// NewClient creates and returns Client. The third party package that queries GraphQL is initialized here.
+func NewClient(logger pluginapi.LogService, token oauth2.Token, username, orgName, enterpriseBaseURL string) *Client {
+	ts := oauth2.StaticTokenSource(&token)
+	httpClient := oauth2.NewClient(context.Background(), ts)
+	var client Client
+
+	if enterpriseBaseURL == "" {
+		client = Client{
+			username: username,
+			client:   githubv4.NewClient(httpClient),
+			logger:   logger,
+			org:      orgName,
+		}
+	} else {
+		baseURL, err := url.Parse(enterpriseBaseURL)
+		if err != nil {
+			logger.Debug("Not able to parse the URL", "Error", err.Error())
+			return nil
+		}
+
+		baseURL.Path = path.Join(baseURL.Path, "api", "graphql")
+
+		client = Client{
+			client:   githubv4.NewEnterpriseClient(baseURL.String(), httpClient),
+			username: username,
+			org:      orgName,
+			logger:   logger,
+		}
+	}
+
+	return &client
+}
+
+// executeQuery takes a query struct and sends it to Github GraphQL API via helper package.
+func (c *Client) executeQuery(ctx context.Context, qry interface{}, params map[string]interface{}) error {
+	if err := c.client.Query(ctx, qry, params); err != nil {
+		return errors.Wrap(err, "error in executing query")
+	}
+
+	return nil
+}
diff --git a/server/plugin/graphql/lhs_query.go b/server/plugin/graphql/lhs_query.go
new file mode 100644
index 0000000..29c17a7
--- /dev/null
+++ b/server/plugin/graphql/lhs_query.go
@@ -0,0 +1,91 @@
+package graphql
+
+import (
+	"github.com/shurcooL/githubv4"
+)
+
+type (
+	repositoryQuery struct {
+		Name          githubv4.String
+		NameWithOwner githubv4.String
+		URL           githubv4.URI
+	}
+
+	authorQuery struct {
+		Login githubv4.String
+	}
+
+	prSearchNodes struct {
+		PullRequest struct {
+			Body              githubv4.String
+			Number            githubv4.Int
+			AuthorAssociation githubv4.String
+			CreatedAt         githubv4.DateTime
+			UpdatedAt         githubv4.DateTime
+			Repository        repositoryQuery
+			State             githubv4.String
+			Title             githubv4.String
+			Author            authorQuery
+			URL               githubv4.URI
+		} `graphql:"... on PullRequest"`
+	}
+)
+
+type (
+	assignmentSearchNodes struct {
+		Issue struct {
+			Body              githubv4.String
+			Number            githubv4.Int
+			AuthorAssociation githubv4.String
+			CreatedAt         githubv4.DateTime
+			UpdatedAt         githubv4.DateTime
+			Repository        repositoryQuery
+			State             githubv4.String
+			Title             githubv4.String
+			Author            authorQuery
+			URL               githubv4.URI
+		} `graphql:"... on Issue"`
+
+		PullRequest struct {
+			Body              githubv4.String
+			Number            githubv4.Int
+			AuthorAssociation githubv4.String
+			CreatedAt         githubv4.DateTime
+			UpdatedAt         githubv4.DateTime
+			Repository        repositoryQuery
+			State             githubv4.String
+			Title             githubv4.String
+			Author            authorQuery
+			URL               githubv4.URI
+		} `graphql:"... on PullRequest"`
+	}
+)
+
+var mainQuery struct {
+	ReviewRequests struct {
+		IssueCount int
+		Nodes      []prSearchNodes
+		PageInfo   struct {
+			EndCursor   githubv4.String
+			HasNextPage bool
+		}
+	} `graphql:"pullRequest: search(first:100, after:$reviewsCursor, query: $prReviewQueryArg, type: ISSUE)"`
+
+	Assignments struct {
+		IssueCount int
+		Nodes      []assignmentSearchNodes
+		PageInfo   struct {
+			EndCursor   githubv4.String
+			HasNextPage bool
+		}
+	} `graphql:"assignee: search(first:100, after:$assignmentsCursor, query: $assigneeQueryArg, type: ISSUE)"`
+
+	OpenPullRequests struct {
+		IssueCount int
+		Nodes      []prSearchNodes
+		PageInfo   struct {
+			EndCursor   githubv4.String
+			HasNextPage bool
+		}
+	} `graphql:"graphql: search(first:100, after:$openPrsCursor, query: $prOpenQueryArg, type: ISSUE)"`
+}
diff --git a/server/plugin/graphql/lhs_request.go b/server/plugin/graphql/lhs_request.go
new file mode 100644
index 0000000..8c7d2db
--- /dev/null
+++ b/server/plugin/graphql/lhs_request.go
@@ -0,0 +1,128 @@
+package graphql
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/google/go-github/v41/github"
+	"github.com/pkg/errors"
+	"github.com/shurcooL/githubv4"
+)
+
+const (
+	queryParamReviewsCursor     = "reviewsCursor"
+	queryParamAssignmentsCursor = "assignmentsCursor"
+	queryParamOpenPRsCursor     = "openPrsCursor"
+
+	queryParamOpenPRQueryArg   = "prOpenQueryArg"
+	queryParamReviewPRQueryArg = "prReviewQueryArg"
+	queryParamAssigneeQueryArg = "assigneeQueryArg"
+)
+
+func (c *Client) GetLHSData(ctx context.Context) ([]*github.Issue, []*github.Issue, []*github.Issue, error) {
+	params := map[string]interface{}{
+		queryParamOpenPRQueryArg:    githubv4.String(fmt.Sprintf("author:%s is:pr is:%s archived:false", c.username, githubv4.PullRequestStateOpen)),
+		queryParamReviewPRQueryArg:  githubv4.String(fmt.Sprintf("review-requested:%s is:pr is:%s archived:false", c.username, githubv4.PullRequestStateOpen)),
+		queryParamAssigneeQueryArg:  githubv4.String(fmt.Sprintf("assignee:%s is:%s archived:false", c.username, githubv4.PullRequestStateOpen)),
+		queryParamReviewsCursor:     (*githubv4.String)(nil),
+		queryParamAssignmentsCursor: (*githubv4.String)(nil),
+		queryParamOpenPRsCursor:     (*githubv4.String)(nil),
+	}
+
+	if c.org != "" {
+		params[queryParamOpenPRQueryArg] = githubv4.String(fmt.Sprintf("org:%s %s", c.org, params[queryParamOpenPRQueryArg]))
+		params[queryParamReviewPRQueryArg] = githubv4.String(fmt.Sprintf("org:%s %s", c.org, params[queryParamReviewPRQueryArg]))
+		params[queryParamAssigneeQueryArg] = githubv4.String(fmt.Sprintf("org:%s %s", c.org, params[queryParamAssigneeQueryArg]))
+	}
+
+	var resultReview, resultAssignee, resultOpenPR []*github.Issue
+	allReviewRequestsFetched, allAssignmentsFetched, allOpenPRsFetched := false, false, false
+
+	for {
+		if allReviewRequestsFetched && allAssignmentsFetched && allOpenPRsFetched {
+			break
+		}
+
+		if err := c.executeQuery(ctx, &mainQuery, params); err != nil {
+			return nil, nil, nil, errors.Wrap(err, "Not able to excute the query")
+		}
+
+		if !allReviewRequestsFetched {
+			for i := range mainQuery.ReviewRequests.Nodes {
+				resp := mainQuery.ReviewRequests.Nodes[i]
+				pr := getPR(&resp)
+				resultReview = append(resultReview, pr)
+			}
+
+			if !mainQuery.ReviewRequests.PageInfo.HasNextPage {
+				allReviewRequestsFetched = true
+			}
+
+			params[queryParamReviewsCursor] = githubv4.NewString(mainQuery.ReviewRequests.PageInfo.EndCursor)
+		}
+
+		if !allAssignmentsFetched {
+			for i := range mainQuery.Assignments.Nodes {
+				resp := mainQuery.Assignments.Nodes[i]
+				issue := getIssue(&resp)
+				resultAssignee = append(resultAssignee, issue)
+			}
+
+			if !mainQuery.Assignments.PageInfo.HasNextPage {
+				allAssignmentsFetched = true
+			}
+
+			params[queryParamAssignmentsCursor] = githubv4.NewString(mainQuery.Assignments.PageInfo.EndCursor)
+		}
+
+		if !allOpenPRsFetched {
+			for i := range mainQuery.OpenPullRequests.Nodes {
+				resp := mainQuery.OpenPullRequests.Nodes[i]
+				pr := getPR(&resp)
+				resultOpenPR = append(resultOpenPR, pr)
+			}
+
+			if !mainQuery.OpenPullRequests.PageInfo.HasNextPage {
+				allOpenPRsFetched = true
+			}
+
+			params[queryParamOpenPRsCursor] = githubv4.NewString(mainQuery.OpenPullRequests.PageInfo.EndCursor)
+		}
+	}
+
+	return resultReview, resultAssignee, resultOpenPR, nil
+}
+
+func getPR(prResp *prSearchNodes) *github.Issue {
+	resp := prResp.PullRequest
+
+	return getGithubIssue(resp.Number, resp.Title, resp.Author.Login, resp.Repository.URL, resp.URL, resp.CreatedAt, resp.UpdatedAt)
+}
+
+func getIssue(assignmentResp *assignmentSearchNodes) *github.Issue {
+	resp := assignmentResp.PullRequest
+
+	return getGithubIssue(resp.Number, resp.Title, resp.Author.Login, resp.Repository.URL, resp.URL, resp.CreatedAt, resp.UpdatedAt)
+}
+
+func getGithubIssue(prNumber githubv4.Int, title, login githubv4.String, repositoryURL, htmlURL githubv4.URI, createdAt, updatedAt githubv4.DateTime) *github.Issue {
+	number := int(prNumber)
+	repoURL := repositoryURL.String()
+	issuetitle := string(title)
+	userLogin := (string)(login)
+	url := htmlURL.String()
+	createdAtTime := createdAt.Time
+	updatedAtTime := updatedAt.Time
+
+	return &github.Issue{
+		Number:        &number,
+		RepositoryURL: &repoURL,
+		Title:         &issuetitle,
+		CreatedAt:     &createdAtTime,
+		UpdatedAt:     &updatedAtTime,
+		User: &github.User{
+			Login: &userLogin,
+		},
+		HTMLURL: &url,
+	}
+}
diff --git a/server/plugin/plugin.go b/server/plugin/plugin.go
index 74748ff..8918806 100644
--- a/server/plugin/plugin.go
+++ b/server/plugin/plugin.go
@@ -2,6 +2,7 @@ package plugin
 
 import (
 	"context"
+	"encoding/json"
 	"fmt"
 	"net/http"
 	"net/url"
@@ -14,6 +15,7 @@ import (
 	"github.com/google/go-github/v41/github"
 	"github.com/gorilla/mux"
 	pluginapi "github.com/mattermost/mattermost-plugin-api"
+	"github.com/mattermost/mattermost-plugin-api/experimental/bot/logger"
 	"github.com/mattermost/mattermost-plugin-api/experimental/bot/poster"
 	"github.com/mattermost/mattermost-plugin-api/experimental/telemetry"
 	"github.com/mattermost/mattermost-server/v6/model"
@@ -22,6 +24,7 @@ import (
 	"golang.org/x/oauth2"
 
 	root "github.com/mattermost/mattermost-plugin-github"
+	"github.com/mattermost/mattermost-plugin-github/server/plugin/graphql"
 )
 
 const (
@@ -158,6 +161,11 @@ func (p *Plugin) githubConnectUser(ctx context.Context, info *GitHubUserInfo) *g
 	return p.githubConnectToken(tok)
 }
 
+func (p *Plugin) graphQLConnect(info *GitHubUserInfo) *graphql.Client {
+	conf := p.getConfiguration()
+	return graphql.NewClient(p.client.Log, *info.Token, info.GitHubUsername, conf.GitHubOrg, conf.EnterpriseBaseURL)
+}
+
 func (p *Plugin) githubConnectToken(token oauth2.Token) *github.Client {
 	config := p.getConfiguration()
 
@@ -975,13 +983,64 @@ func (p *Plugin) isOrganizationLocked() bool {
 }
 
 func (p *Plugin) sendRefreshEvent(userID string) {
+	eventLogger := logger.New(p.API).With(logger.LogContext{
+		"userid": userID,
+	})
+
+	ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
+
+	context := &Context{
+		Ctx:    ctx,
+		UserID: userID,
+		Log:    eventLogger,
+	}
+
+	defer cancel()
+
+	info, apiErr := p.getGitHubUserInfo(context.UserID)
+	if apiErr != nil {
+		p.API.LogWarn("Failed to get github user info", "error", apiErr.Error())
+		return
+	}
+
+	userContext := &UserContext{
+		Context: *context,
+		GHInfo:  info,
+	}
+
+	sidebarContent, err := p.getSidebarData(userContext)
+	if err != nil {
+		p.API.LogWarn("Failed to get the sidebar data", "error", err.Error())
+		return
+	}
+
+	contentMap, err := sidebarContent.toMap()
+	if err != nil {
+		p.API.LogWarn("Failed to convert sidebar content to map", "error", err.Error())
+		return
+	}
+
 	p.client.Frontend.PublishWebSocketEvent(
 		wsEventRefresh,
-		nil,
+		contentMap,
 		&model.WebsocketBroadcast{UserId: userID},
 	)
 }
 
+func (s *SidebarContent) toMap() (map[string]interface{}, error) {
+	var m map[string]interface{}
+	bytes, err := json.Marshal(&s)
+	if err != nil {
+		return nil, err
+	}
+
+	if err = json.Unmarshal(bytes, &m); err != nil {
+		return nil, err
+	}
+
+	return m, nil
+}
+
 // getUsername returns the GitHub username for a given Mattermost user,
 // if the user is connected to GitHub via this plugin.
 // Otherwise it return the Mattermost username. It will be escaped via backticks.
diff --git a/webapp/package-lock.json b/webapp/package-lock.json
index 129ae34..f745039 100644
--- a/webapp/package-lock.json
+++ b/webapp/package-lock.json
@@ -10557,18 +10557,6 @@
           "dev": true,
           "optional": true
         },
-        "tough-cookie": {
-          "version": "4.1.2",
-          "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz",
-          "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==",
-          "dev": true,
-          "requires": {
-            "psl": "^1.1.33",
-            "punycode": "^2.1.1",
-            "universalify": "^0.2.0",
-            "url-parse": "^1.5.3"
-          }
-        },
         "tr46": {
           "version": "2.1.0",
           "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
@@ -15322,6 +15310,18 @@
         "to-no-case": "^1.0.0"
       }
     },
+    "tough-cookie": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
+      "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
+      "dev": true,
+      "requires": {
+        "psl": "^1.1.33",
+        "punycode": "^2.1.1",
+        "universalify": "^0.2.0",
+        "url-parse": "^1.5.3"
+      }
+    },
     "tr46": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz",
diff --git a/webapp/src/action_types/index.js b/webapp/src/action_types/index.js
index 88da099..24480e9 100644
--- a/webapp/src/action_types/index.js
+++ b/webapp/src/action_types/index.js
@@ -5,13 +5,10 @@ import {id as pluginId} from '../manifest';
 
 export default {
     RECEIVED_REPOSITORIES: pluginId + '_received_repositories',
-    RECEIVED_REVIEWS: pluginId + '_received_reviews',
     RECEIVED_REVIEWS_DETAILS: pluginId + '_received_reviews_details',
-    RECEIVED_YOUR_PRS: pluginId + '_received_your_prs',
     RECEIVED_YOUR_PRS_DETAILS: pluginId + '_received_your_prs_details',
-    RECEIVED_YOUR_ASSIGNMENTS: pluginId + '_received_your_assignments',
+    RECEIVED_SIDEBAR_CONTENT: pluginId + '_received_sidebar_content',
     RECEIVED_MENTIONS: pluginId + '_received_mentions',
-    RECEIVED_UNREADS: pluginId + '_received_unreads',
     RECEIVED_CONNECTED: pluginId + '_received_connected',
     RECEIVED_CONFIGURATION: pluginId + '_received_configuration',
     RECEIVED_GITHUB_USER: pluginId + '_received_github_user',
diff --git a/webapp/src/actions/index.js b/webapp/src/actions/index.js
index 1788ae9..16998ec 100644
--- a/webapp/src/actions/index.js
+++ b/webapp/src/actions/index.js
@@ -42,29 +42,6 @@ function checkAndHandleNotConnected(data) {
     };
 }
 
-export function getReviews() {
-    return async (dispatch, getState) => {
-        let data;
-        try {
-            data = await Client.getReviews();
-        } catch (error) {
-            return {error};
-        }
-
-        const connected = await checkAndHandleNotConnected(data)(dispatch, getState);
-        if (!connected) {
-            return {error: data};
-        }
-
-        dispatch({
-            type: ActionTypes.RECEIVED_REVIEWS,
-            data,
-        });
-
-        return {data};
-    };
-}
-
 export function getReviewsDetails(prList) {
     return async (dispatch, getState) => {
         let data;
@@ -111,11 +88,11 @@ export function getRepos() {
     };
 }
 
-export function getYourPrs() {
+export function getSidebarContent() {
     return async (dispatch, getState) => {
         let data;
         try {
-            data = await Client.getYourPrs();
+            data = await Client.getSidebarContent();
         } catch (error) {
             return {error};
         }
@@ -126,7 +103,7 @@ export function getYourPrs() {
         }
 
         dispatch({
-            type: ActionTypes.RECEIVED_YOUR_PRS,
+            type: ActionTypes.RECEIVED_SIDEBAR_CONTENT,
             data,
         });
 
@@ -211,29 +188,6 @@ export function getMilestoneOptions(repo) {
     };
 }
 
-export function getYourAssignments() {
-    return async (dispatch, getState) => {
-        let data;
-        try {
-            data = await Client.getYourAssignments();
-        } catch (error) {
-            return {error};
-        }
-
-        const connected = await checkAndHandleNotConnected(data)(dispatch, getState);
-        if (!connected) {
-            return {error: data};
-        }
-
-        dispatch({
-            type: ActionTypes.RECEIVED_YOUR_ASSIGNMENTS,
-            data,
-        });
-
-        return {data};
-    };
-}
-
 export function getMentions() {
     return async (dispatch, getState) => {
         let data;
@@ -257,29 +211,6 @@ export function getMentions() {
     };
 }
 
-export function getUnreads() {
-    return async (dispatch, getState) => {
-        let data;
-        try {
-            data = await Client.getUnreads();
-        } catch (error) {
-            return {error};
-        }
-
-        const connected = await checkAndHandleNotConnected(data)(dispatch, getState);
-        if (!connected) {
-            return {error: data};
-        }
-
-        dispatch({
-            type: ActionTypes.RECEIVED_UNREADS,
-            data,
-        });
-
-        return {data};
-    };
-}
-
 const GITHUB_USER_GET_TIMEOUT_MILLISECONDS = 1000 * 60 * 60; // 1 hour
 
 export function getGitHubUser(userID) {
diff --git a/webapp/src/client/client.js b/webapp/src/client/client.js
index 25d6f3f..7358dbf 100644
--- a/webapp/src/client/client.js
+++ b/webapp/src/client/client.js
@@ -15,30 +15,18 @@ export default class Client {
         return this.doGet(`${this.url}/connected?reminder=${reminder}`);
     }
 
-    getReviews = async () => {
-        return this.doGet(`${this.url}/reviews`);
-    }
-
-    getYourPrs = async () => {
-        return this.doGet(`${this.url}/yourprs`);
+    getSidebarContent = async () => {
+        return this.doGet(`${this.url}/lhs-content`);
     }
 
     getPrsDetails = async (prList) => {
         return this.doPost(`${this.url}/prsdetails`, prList);
     }
 
-    getYourAssignments = async () => {
-        return this.doGet(`${this.url}/yourassignments`);
-    }
-
     getMentions = async () => {
         return this.doGet(`${this.url}/mentions`);
     }
 
-    getUnreads = async () => {
-        return this.doGet(`${this.url}/unreads`);
-    }
-
     getGitHubUser = async (userID) => {
         return this.doPost(`${this.url}/user`, {user_id: userID});
     }
diff --git a/webapp/src/components/sidebar_buttons/index.js b/webapp/src/components/sidebar_buttons/index.js
index 0ebdff1..862a1d0 100644
--- a/webapp/src/components/sidebar_buttons/index.js
+++ b/webapp/src/components/sidebar_buttons/index.js
@@ -4,7 +4,7 @@
 import {connect} from 'react-redux';
 import {bindActionCreators} from 'redux';
 
-import {getConnected, getReviews, getUnreads, getYourAssignments, getYourPrs, updateRhsState} from '../../actions';
+import {getConnected, updateRhsState, getSidebarContent} from '../../actions';
 
 import {id as pluginId} from '../../manifest';
 
@@ -14,10 +14,10 @@ function mapStateToProps(state) {
     return {
         connected: state[`plugins-${pluginId}`].connected,
         clientId: state[`plugins-${pluginId}`].clientId,
-        reviews: state[`plugins-${pluginId}`].reviews,
-        yourPrs: state[`plugins-${pluginId}`].yourPrs,
-        yourAssignments: state[`plugins-${pluginId}`].yourAssignments,
-        unreads: state[`plugins-${pluginId}`].unreads,
+        reviews: state[`plugins-${pluginId}`].sidebarContent.reviews,
+        yourPrs: state[`plugins-${pluginId}`].sidebarContent.prs,
+        yourAssignments: state[`plugins-${pluginId}`].sidebarContent.assignments,
+        unreads: state[`plugins-${pluginId}`].sidebarContent.unreads,
         enterpriseURL: state[`plugins-${pluginId}`].enterpriseURL,
         showRHSPlugin: state[`plugins-${pluginId}`].rhsPluginAction,
     };
@@ -27,11 +27,8 @@ function mapDispatchToProps(dispatch) {
     return {
         actions: bindActionCreators({
             getConnected,
-            getReviews,
-            getUnreads,
-            getYourPrs,
-            getYourAssignments,
             updateRhsState,
+            getSidebarContent,
         }, dispatch),
     };
 }
diff --git a/webapp/src/components/sidebar_buttons/sidebar_buttons.jsx b/webapp/src/components/sidebar_buttons/sidebar_buttons.jsx
index 079f9cd..63d1d5c 100644
--- a/webapp/src/components/sidebar_buttons/sidebar_buttons.jsx
+++ b/webapp/src/components/sidebar_buttons/sidebar_buttons.jsx
@@ -22,10 +22,7 @@ export default class SidebarButtons extends React.PureComponent {
         showRHSPlugin: PropTypes.func.isRequired,
         actions: PropTypes.shape({
             getConnected: PropTypes.func.isRequired,
-            getReviews: PropTypes.func.isRequired,
-            getUnreads: PropTypes.func.isRequired,
-            getYourPrs: PropTypes.func.isRequired,
-            getYourAssignments: PropTypes.func.isRequired,
+            getSidebarContent: PropTypes.func.isRequired,
             updateRhsState: PropTypes.func.isRequired,
         }).isRequired,
     };
@@ -72,12 +69,7 @@ export default class SidebarButtons extends React.PureComponent {
         }
 
         this.setState({refreshing: true});
-        await Promise.all([
-            this.props.actions.getReviews(),
-            this.props.actions.getUnreads(),
-            this.props.actions.getYourPrs(),
-            this.props.actions.getYourAssignments(),
-        ]);
+        await this.props.actions.getSidebarContent();
         this.setState({refreshing: false});
     }
 
diff --git a/webapp/src/components/sidebar_right/index.jsx b/webapp/src/components/sidebar_right/index.jsx
index 746b27b..f96a08a 100644
--- a/webapp/src/components/sidebar_right/index.jsx
+++ b/webapp/src/components/sidebar_right/index.jsx
@@ -5,46 +5,22 @@ import {connect} from 'react-redux';
 import {bindActionCreators} from 'redux';
 
 import {getReviewsDetails, getYourPrsDetails} from '../../actions';
-import {id as pluginId} from '../../manifest';
 
-import SidebarRight from './sidebar_right.jsx';
-
-function mapPrsToDetails(prs, details) {
-    if (!prs) {
-        return [];
-    }
-
-    return prs.map((pr) => {
-        let foundDetails;
-        if (details) {
-            foundDetails = details.find((prDetails) => {
-                return (pr.repository_url === prDetails.url) && (pr.number === prDetails.number);
-            });
-        }
-        if (!foundDetails) {
-            return pr;
-        }
+import {getSidebarData} from 'src/selectors';
 
-        return {
-            ...pr,
-            status: foundDetails.status,
-            mergeable: foundDetails.mergeable,
-            requestedReviewers: foundDetails.requestedReviewers,
-            reviews: foundDetails.reviews,
-        };
-    });
-}
+import SidebarRight from './sidebar_right.jsx';
 
 function mapStateToProps(state) {
+    const {username, reviews, yourPrs, yourAssignments, unreads, enterpriseURL, org, rhsState} = getSidebarData(state);
     return {
-        username: state[`plugins-${pluginId}`].username,
-        reviews: mapPrsToDetails(state[`plugins-${pluginId}`].reviews, state[`plugins-${pluginId}`].reviewsDetails),
-        yourPrs: mapPrsToDetails(state[`plugins-${pluginId}`].yourPrs, state[`plugins-${pluginId}`].yourPrsDetails),
-        yourAssignments: state[`plugins-${pluginId}`].yourAssignments,
-        unreads: state[`plugins-${pluginId}`].unreads,
-        enterpriseURL: state[`plugins-${pluginId}`].enterpriseURL,
-        org: state[`plugins-${pluginId}`].organization,
-        rhsState: state[`plugins-${pluginId}`].rhsState,
+        username,
+        reviews,
+        yourPrs,
+        yourAssignments,
+        unreads,
+        enterpriseURL,
+        org,
+        rhsState,
     };
 }
 
diff --git a/webapp/src/components/sidebar_right/sidebar_right.jsx b/webapp/src/components/sidebar_right/sidebar_right.jsx
index 162efdf..71bb121 100644
--- a/webapp/src/components/sidebar_right/sidebar_right.jsx
+++ b/webapp/src/components/sidebar_right/sidebar_right.jsx
@@ -103,37 +103,38 @@ export default class SidebarRight extends React.PureComponent {
     render() {
         const baseURL = this.props.enterpriseURL ? this.props.enterpriseURL : 'https://github.com';
         const orgQuery = this.props.org ? '+org%3A' + this.props.org : '';
+        const {yourPrs, reviews, unreads, yourAssignments, username, rhsState} = this.props;
 
         let title = '';
         let githubItems = [];
         let listUrl = '';
 
-        switch (this.props.rhsState) {
+        switch (rhsState) {
         case RHSStates.PRS:
 
-            githubItems = this.props.yourPrs;
+            githubItems = yourPrs;
             title = 'Your Open Pull Requests';
-            listUrl = baseURL + '/pulls?q=is%3Aopen+is%3Apr+author%3A' + this.props.username + '+archived%3Afalse' + orgQuery;
+            listUrl = baseURL + '/pulls?q=is%3Aopen+is%3Apr+author%3A' + username + '+archived%3Afalse' + orgQuery;
 
             break;
         case RHSStates.REVIEWS:
 
-            githubItems = this.props.reviews;
-            listUrl = baseURL + '/pulls?q=is%3Aopen+is%3Apr+review-requested%3A' + this.props.username + '+archived%3Afalse' + orgQuery;
+            githubItems = reviews;
+            listUrl = baseURL + '/pulls?q=is%3Aopen+is%3Apr+review-requested%3A' + username + '+archived%3Afalse' + orgQuery;
             title = 'Pull Requests Needing Review';
 
             break;
         case RHSStates.UNREADS:
 
-            githubItems = this.props.unreads;
+            githubItems = unreads;
             title = 'Unread Messages';
             listUrl = baseURL + '/notifications';
             break;
         case RHSStates.ASSIGNMENTS:
 
-            githubItems = this.props.yourAssignments;
+            githubItems = yourAssignments;
             title = 'Your Assignments';
-            listUrl = baseURL + '/pulls?q=is%3Aopen+archived%3Afalse+assignee%3A' + this.props.username + orgQuery;
+            listUrl = baseURL + '/pulls?q=is%3Aopen+archived%3Afalse+assignee%3A' + username + orgQuery;
             break;
         default:
             break;
diff --git a/webapp/src/reducers/index.js b/webapp/src/reducers/index.js
index 0ebcf51..39f8f29 100644
--- a/webapp/src/reducers/index.js
+++ b/webapp/src/reducers/index.js
@@ -77,16 +77,7 @@ function clientId(state = '', action) {
     }
 }
 
-function reviews(state = [], action) {
-    switch (action.type) {
-    case ActionTypes.RECEIVED_REVIEWS:
-        return action.data;
-    default:
-        return state;
-    }
-}
-
-function reviewsDetails(state = [], action) {
+function reviewDetails(state = [], action) {
     switch (action.type) {
     case ActionTypes.RECEIVED_REVIEWS_DETAILS:
         return action.data;
@@ -95,9 +86,16 @@ function reviewsDetails(state = [], action) {
     }
 }
 
-function yourPrs(state = [], action) {
+const defaultSidebarContent = {
+    reviews: [],
+    prs: [],
+    assignments: [],
+    unreads: [],
+};
+
+function sidebarContent(state = defaultSidebarContent, action) {
     switch (action.type) {
-    case ActionTypes.RECEIVED_YOUR_PRS:
+    case ActionTypes.RECEIVED_SIDEBAR_CONTENT:
         return action.data;
     default:
         return state;
@@ -113,7 +111,7 @@ function yourRepos(state = [], action) {
     }
 }
 
-function yourPrsDetails(state = [], action) {
+function yourPrDetails(state = [], action) {
     switch (action.type) {
     case ActionTypes.RECEIVED_YOUR_PRS_DETAILS:
         return action.data;
@@ -122,15 +120,6 @@ function yourPrsDetails(state = [], action) {
     }
 }
 
-function yourAssignments(state = [], action) {
-    switch (action.type) {
-    case ActionTypes.RECEIVED_YOUR_ASSIGNMENTS:
-        return action.data;
-    default:
-        return state;
-    }
-}
-
 function mentions(state = [], action) {
     switch (action.type) {
     case ActionTypes.RECEIVED_MENTIONS:
@@ -140,15 +129,6 @@ function mentions(state = [], action) {
     }
 }
 
-function unreads(state = [], action) {
-    switch (action.type) {
-    case ActionTypes.RECEIVED_UNREADS:
-        return action.data;
-    default:
-        return state;
-    }
-}
-
 function githubUsers(state = {}, action) {
     switch (action.type) {
     case ActionTypes.RECEIVED_GITHUB_USER: {
@@ -238,14 +218,10 @@ export default combineReducers({
     userSettings,
     configuration,
     clientId,
-    reviews,
-    reviewsDetails,
-    yourPrs,
+    reviewDetails,
     yourRepos,
-    yourPrsDetails,
-    yourAssignments,
+    yourPrDetails,
     mentions,
-    unreads,
     githubUsers,
     rhsPluginAction,
     rhsState,
@@ -253,4 +229,5 @@ export default combineReducers({
     createIssueModal,
     attachCommentToIssueModalVisible,
     attachCommentToIssueModalForPostId,
+    sidebarContent,
 });
diff --git a/webapp/src/selectors.js b/webapp/src/selectors.js
index a8d3f26..d6de652 100644
--- a/webapp/src/selectors.js
+++ b/webapp/src/selectors.js
@@ -1,7 +1,11 @@
 import {getConfig} from 'mattermost-redux/selectors/entities/general';
 
+import {createSelector} from 'reselect';
+
 import {id as pluginId} from './manifest';
 
+const emptyArray = [];
+
 const getPluginState = (state) => state['plugins-' + pluginId] || {};
 
 export const isEnabled = (state) => getPluginState(state).enabled;
@@ -19,4 +23,46 @@ export const getServerRoute = (state) => {
     return basePath;
 };
 
+function mapPrsToDetails(prs, details) {
+    if (!prs) {
+        return [];
+    }
+
+    return prs.map((pr) => {
+        let foundDetails;
+        if (details) {
+            foundDetails = details.find((prDetails) => {
+                return (pr.repository_url === prDetails.url) && (pr.number === prDetails.number);
+            });
+        }
+        if (!foundDetails) {
+            return pr;
+        }
+
+        return {
+            ...pr,
+            status: foundDetails.status,
+            mergeable: foundDetails.mergeable,
+            requestedReviewers: foundDetails.requestedReviewers,
+            reviews: foundDetails.reviews,
+        };
+    });
+}
+
+export const getSidebarData = createSelector(
+    getPluginState,
+    (pluginState) => {
+        const {username, sidebarContent, reviewDetails, yourPrDetails, organization, rhsState} = pluginState;
+        return {
+            username,
+            reviews: mapPrsToDetails(sidebarContent.reviews || emptyArray, reviewDetails),
+            yourPrs: mapPrsToDetails(sidebarContent.prs || emptyArray, yourPrDetails),
+            yourAssignments: sidebarContent.assignments || emptyArray,
+            unreads: sidebarContent.unreads || emptyArray,
+            org: organization,
+            rhsState,
+        };
+    },
+);
+
 export const configuration = (state) => getPluginState(state).configuration;
diff --git a/webapp/src/websocket/index.js b/webapp/src/websocket/index.js
index 15021af..7e871b6 100644
--- a/webapp/src/websocket/index.js
+++ b/webapp/src/websocket/index.js
@@ -5,15 +5,14 @@ import ActionTypes from '../action_types';
 import Constants from '../constants';
 import {
     getConnected,
-    getReviews,
-    getUnreads,
-    getYourAssignments,
-    getYourPrs,
+    getSidebarContent,
     openCreateIssueModalWithoutPost,
 } from '../actions';
 
 import {id as pluginId} from '../manifest';
 
+let timeoutId;
+const RECONNECT_JITTER_MAX_TIME_IN_SEC = 10;
 export function handleConnect(store) {
     return (msg) => {
         if (!msg.data) {
@@ -66,21 +65,28 @@ export function handleReconnect(store, reminder = false) {
     return async () => {
         const {data} = await getConnected(reminder)(store.dispatch, store.getState);
         if (data && data.connected) {
-            getReviews()(store.dispatch, store.getState);
-            getUnreads()(store.dispatch, store.getState);
-            getYourPrs()(store.dispatch, store.getState);
-            getYourAssignments()(store.dispatch, store.getState);
+            if (typeof timeoutId === 'number') {
+                clearTimeout(timeoutId);
+            }
+
+            const rand = Math.floor(Math.random() * RECONNECT_JITTER_MAX_TIME_IN_SEC) + 1;
+            timeoutId = setTimeout(() => {
+                getSidebarContent()(store.dispatch, store.getState);
+                timeoutId = undefined; //eslint-disable-line no-undefined
+            }, rand * 1000);
         }
     };
 }
 
 export function handleRefresh(store) {
-    return () => {
+    return (msg) => {
         if (store.getState()[`plugins-${pluginId}`].connected) {
-            getReviews()(store.dispatch, store.getState);
-            getUnreads()(store.dispatch, store.getState);
-            getYourPrs()(store.dispatch, store.getState);
-            getYourAssignments()(store.dispatch, store.getState);
+            const {data} = msg;
+
+            store.dispatch({
+                type: ActionTypes.RECEIVED_SIDEBAR_CONTENT,
+                data,
+            });
         }
     };
 }


Test patch:
diff --git a/server/plugin/api_test.go b/server/plugin/api_test.go
index c1e9ad8..e2f7d7f 100644
--- a/server/plugin/api_test.go
+++ b/server/plugin/api_test.go
@@ -88,7 +88,7 @@ func TestPlugin_ServeHTTP(t *testing.T) {
 			httpTest: httpTestString,
 			request: testutils.Request{
 				Method: http.MethodGet,
-				URL:    "/api/v1/reviews",
+				URL:    "/api/v1/lhs-content",
 				Body:   nil,
 			},
 			expectedResponse: testutils.ExpectedResponse{