Add palette

This commit is contained in:
Trevor Slocum 2021-11-02 17:35:20 -07:00
parent ee5ab2ed49
commit b6d4e6da17
5 changed files with 229 additions and 60 deletions

View File

@ -21,27 +21,55 @@ import (
var spinner = []byte(`-\|/`)
var cursorX, cursorY int
var hoverImg *ebiten.Image
var uiWidth int
type Application struct {
screenW, screenH int
cursorX, cursorY int
palette *colorPalette
canvases []*canvas
colorA color.RGBA
colorB color.RGBA
active int
spinnerIndex int
hoverImg *ebiten.Image
uiImg *ebiten.Image
op *ebiten.DrawImageOptions
}
func rgba(c color.Color) color.RGBA {
r, g, b, a := c.RGBA()
return color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)}
}
func NewApplication() *Application {
app := &Application{
op: &ebiten.DrawImageOptions{},
palette: NewPalette(),
colorA: color.RGBA{255, 255, 255, 255},
colorB: color.RGBA{0, 0, 0, 255},
op: &ebiten.DrawImageOptions{},
}
app.palette.columns = 2
app.palette.colors = append(app.palette.colors, color.RGBA{255, 255, 255, 255})
app.palette.colors = append(app.palette.colors, color.RGBA{0, 0, 0, 255})
app.palette.colors = append(app.palette.colors, rgba(colornames.Red))
app.palette.colors = append(app.palette.colors, rgba(colornames.Orange))
app.palette.colors = append(app.palette.colors, rgba(colornames.Yellow))
app.palette.colors = append(app.palette.colors, rgba(colornames.Green))
app.palette.colors = append(app.palette.colors, rgba(colornames.Blue))
app.palette.colors = append(app.palette.colors, rgba(colornames.Indigo))
app.palette.colors = append(app.palette.colors, rgba(colornames.Violet))
app.addNewCanvas(8, 8)
c := app.activeCanvas()
@ -122,13 +150,6 @@ func (app *Application) activeCanvas() *canvas {
return app.canvases[app.active]
}
func (app *Application) screenToCanvas(x, y int) (int, int) {
c := app.activeCanvas()
cx, cy := float64(x)/c.scale, float64(y)/c.scale
cx, cy = cx+c.x, cy+c.y
return int(cx), int(cy)
}
func (app *Application) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
s := ebiten.DeviceScaleFactor()
outsideWidth, outsideHeight = int(float64(outsideWidth)*s), int(float64(outsideHeight)*s)
@ -137,6 +158,21 @@ func (app *Application) Layout(outsideWidth, outsideHeight int) (screenWidth, sc
}
app.screenW, app.screenH = outsideWidth, outsideHeight
// TODO
uiWidth = 200
app.uiImg = ebiten.NewImage(uiWidth, app.screenH)
app.drawUIBuffer()
app.palette.setRect(0, 0, uiWidth, app.screenH)
for _, c := range app.canvases {
c.x = uiWidth
c.y = 0
c.w = app.screenW - uiWidth
c.h = app.screenH
}
return app.screenW, app.screenH
}
@ -146,6 +182,8 @@ func (app *Application) Update() error {
return nil
}
// TODO move canvas related code into Canvas, treat as widget
if _, y := ebiten.Wheel(); y != 0 {
scroll := math.Ceil(y)
if scroll < -1 {
@ -173,54 +211,58 @@ func (app *Application) Update() error {
app.drawHoverImage()
}
app.cursorX, app.cursorY = ebiten.CursorPosition()
cursorX, cursorY = ebiten.CursorPosition()
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
cx, cy := app.screenToCanvas(app.cursorX, app.cursorY)
c := app.activeCanvas()
c.img.Set(cx, cy, colornames.White)
if cursorX < uiWidth {
colorSwatch, ok := app.palette.colorSwatchAt(cursorX, cursorY)
if ok {
app.colorA = colorSwatch
}
} else {
c := app.activeCanvas()
cx, cy := c.screenToCanvas(cursorX, cursorY)
c.img.Set(cx, cy, app.colorA)
}
}
c := app.activeCanvas()
panSize := 2 / c.scale
if ebiten.IsKeyPressed(ebiten.KeyRight) {
c.x += panSize
if ebiten.IsKeyPressed(ebiten.KeyRight) || ebiten.IsKeyPressed(ebiten.KeyD) {
c.vx += panSize
}
if ebiten.IsKeyPressed(ebiten.KeyLeft) {
c.x -= panSize
if ebiten.IsKeyPressed(ebiten.KeyLeft) || ebiten.IsKeyPressed(ebiten.KeyA) {
c.vx -= panSize
}
if ebiten.IsKeyPressed(ebiten.KeyUp) {
c.y -= panSize
if ebiten.IsKeyPressed(ebiten.KeyUp) || ebiten.IsKeyPressed(ebiten.KeyW) {
c.vy -= panSize
}
if ebiten.IsKeyPressed(ebiten.KeyDown) {
c.y += panSize
if ebiten.IsKeyPressed(ebiten.KeyDown) || ebiten.IsKeyPressed(ebiten.KeyS) {
c.vy += panSize
}
return nil
}
func (app *Application) Draw(screen *ebiten.Image) {
// Draw canvas.
c := app.activeCanvas()
app.op.GeoM.Reset()
app.op.GeoM.Translate(-c.x, -c.y)
app.op.GeoM.Scale(c.scale, c.scale)
screen.DrawImage(c.img, app.op)
func (app *Application) drawUI(screen *ebiten.Image) {
app.palette.Draw(screen)
}
// Draw hover outline.
cx, cy := app.screenToCanvas(app.cursorX, app.cursorY)
p := c.pixelScreenRect(cx, cy)
app.op.GeoM.Reset()
app.op.GeoM.Translate(float64(p.Min.X), float64(p.Min.Y))
screen.DrawImage(app.hoverImg, app.op)
func (app *Application) Draw(screen *ebiten.Image) {
c := app.activeCanvas()
c.Draw(screen)
app.drawUI(screen)
hoverX, hoverY := c.screenToCanvas(cursorX, cursorY)
// Print debug information.
debugInfo := fmt.Sprintf("SCA %0.2f\nFPS %c %0.0f", app.activeCanvas().scale, spinner[app.spinnerIndex], ebiten.CurrentFPS())
debugInfo := fmt.Sprintf("FPS %c %0.0f\nSCA %0.2f\nVPT %.1f,%.1f\nPOS %d,%d", spinner[app.spinnerIndex], ebiten.CurrentFPS(), app.activeCanvas().scale, c.vx, c.vy, hoverX, hoverY)
debugBox := image.NewRGBA(image.Rect(10, 20, 200, 200))
debugImg := ebiten.NewImageFromImage(debugBox)
ebitenutil.DebugPrint(debugImg, debugInfo)
app.op.GeoM.Reset()
app.op.GeoM.Translate(3, 0)
app.op.GeoM.Scale(2, 2)
app.op.GeoM.Translate(float64(uiWidth)+4, 0)
screen.DrawImage(debugImg, app.op)
app.spinnerIndex++
@ -235,8 +277,8 @@ func (app *Application) drawHoverImage() {
if hoverImgSize < 1 {
hoverImgSize = 1
}
if app.hoverImg == nil || app.hoverImg.Bounds().Dx() != hoverImgSize || app.hoverImg.Bounds().Dy() != hoverImgSize {
app.hoverImg = ebiten.NewImage(hoverImgSize, hoverImgSize)
if hoverImg == nil || hoverImg.Bounds().Dx() != hoverImgSize || hoverImg.Bounds().Dy() != hoverImgSize {
hoverImg = ebiten.NewImage(hoverImgSize, hoverImgSize)
}
var colorWhite bool
@ -249,7 +291,7 @@ func (app *Application) drawHoverImage() {
}
}
img := app.hoverImg
img := hoverImg
img.Clear()
bounds := img.Bounds()
@ -279,6 +321,10 @@ func (app *Application) drawHoverImage() {
}
}
func (app *Application) drawUIBuffer() {
app.uiImg.Fill(colornames.Purple)
}
func (app *Application) Exit() {
os.Exit(0)
}

View File

@ -8,26 +8,58 @@ import (
)
type canvas struct {
x, y int
w, h int
x, y float64 // View position
vx, vy float64 // Viewport position
img *ebiten.Image
scale float64
op *ebiten.DrawImageOptions
}
func NewCanvas(w, h int) *canvas {
return &canvas{
x: uiWidth,
y: 0,
w: w,
h: h,
img: ebiten.NewImage(w, h),
scale: 1,
op: &ebiten.DrawImageOptions{},
}
}
func (c *canvas) pixelScreenRect(x, y int) image.Rectangle {
rx, ry := (float64(x)-c.x)*c.scale, (float64(y)-c.y)*c.scale
rxCorner, ryCorner := (float64(x+1)-c.x)*c.scale, (float64(y+1)-c.y)*c.scale
rx, ry := (float64(x)-c.vx)*c.scale, (float64(y)-c.vy)*c.scale
rx += float64(c.x)
ry += float64(c.y)
rxCorner, ryCorner := (float64(x+1)-c.vx)*c.scale, (float64(y+1)-c.vy)*c.scale
rxCorner += float64(c.x)
ryCorner += float64(c.y)
return image.Rect(int(math.Floor(rx)), int(math.Floor(ry)), int(math.Ceil(rxCorner)), int(math.Ceil(ryCorner)))
}
func (c *canvas) screenToCanvas(x, y int) (int, int) {
cx, cy := float64(x-c.x)/c.scale, float64(y-c.y)/c.scale
cx, cy = cx+c.vx, cy+c.vy
return int(cx), int(cy)
}
func (c *canvas) Draw(screen *ebiten.Image) {
// Draw canvas.
c.op.GeoM.Reset()
c.op.GeoM.Scale(c.scale, c.scale)
c.op.GeoM.Translate(float64(c.x), float64(c.y))
c.op.GeoM.Translate(-c.vx*c.scale, -c.vy*c.scale)
screen.DrawImage(c.img, c.op)
// Draw hover outline.
cx, cy := c.screenToCanvas(cursorX, cursorY)
p := c.pixelScreenRect(cx, cy)
c.op.GeoM.Reset()
c.op.GeoM.Translate(float64(p.Min.X), float64(p.Min.Y))
screen.DrawImage(hoverImg, c.op)
}

79
application/pallette.go Normal file
View File

@ -0,0 +1,79 @@
package application
import (
"image"
"image/color"
"math"
"github.com/hajimehoshi/ebiten/v2"
)
type colorPalette struct {
x, y int
w, h int
columns int
img *ebiten.Image
colors []color.RGBA
colorRects []image.Rectangle
op *ebiten.DrawImageOptions
}
func NewPalette() *colorPalette {
return &colorPalette{
op: &ebiten.DrawImageOptions{},
}
}
func (p *colorPalette) setRect(x, y, w, h int) {
if p.x == x && p.y == y && p.w == w && p.h == h {
return
}
redraw := p.w != w || p.h != h
p.x, p.y, p.w, p.h = x, y, w, h
if redraw {
p.drawBuffer()
}
}
func (p *colorPalette) drawBuffer() {
p.img = ebiten.NewImage(p.w, p.h)
p.img.Fill(color.Black)
p.colorRects = make([]image.Rectangle, len(p.colors))
rows := int(math.Ceil(float64(len(p.colors)) / float64(p.columns)))
swatchWidth := p.w / p.columns
swatchHeight := p.h / rows
for i, colorSwatch := range p.colors {
row := i / p.columns
x, y := (i%p.columns)*swatchWidth, row*swatchHeight
p.colorRects[i] = image.Rect(x, y, x+swatchWidth, y+swatchHeight)
p.img.SubImage(p.colorRects[i]).(*ebiten.Image).Fill(colorSwatch)
}
}
func (p *colorPalette) colorSwatchAt(x, y int) (color.RGBA, bool) {
for i, colorRect := range p.colorRects {
point := image.Point{x, y}
if point.In(colorRect) {
return p.colors[i], true
}
}
return color.RGBA{}, false
}
func (p *colorPalette) Draw(screen *ebiten.Image) {
p.op.GeoM.Reset()
p.op.GeoM.Translate(float64(p.x), float64(p.y))
screen.DrawImage(p.img, p.op)
}

12
go.mod
View File

@ -3,15 +3,15 @@ module code.rocketnine.space/tslocum/edbit
go 1.17
require (
github.com/hajimehoshi/ebiten/v2 v2.2.0
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d
github.com/hajimehoshi/ebiten/v2 v2.2.1
golang.org/x/image v0.0.0-20211028202545-6944b10bf410
)
require (
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be // indirect
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be // indirect
github.com/jezek/xgb v0.0.0-20210312150743-0e0f116e1240 // indirect
golang.org/x/exp v0.0.0-20211012155715-ffe10e552389 // indirect
golang.org/x/mobile v0.0.0-20210924032853-1c027f395ef7 // indirect
golang.org/x/exp v0.0.0-20211102154824-3b956f2825b8 // indirect
golang.org/x/mobile v0.0.0-20211102000317-2ab7fee9df46 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20211015200801-69063c4bb744 // indirect
golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 // indirect
)

34
go.sum
View File

@ -56,8 +56,9 @@ github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be h1:vEIVIuBApEBQTEJt19GfhoU+zFSV+sNTa9E9FdnRYfk=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be h1:Z28GdQBfKOL8tNHjvaDn3wHDO7AzTRkmAXvHvnopp98=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
@ -97,8 +98,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hajimehoshi/bitmapfont/v2 v2.1.3/go.mod h1:2BnYrkTQGThpr/CY6LorYtt/zEPNzvE/ND69CRTaHMs=
github.com/hajimehoshi/ebiten/v2 v2.2.0 h1:2mP9HrLLqiH9X3MajElYZEjVZU/CGh22iFkjatxhT4w=
github.com/hajimehoshi/ebiten/v2 v2.2.0/go.mod h1:olKl/qqhMBBAm2oI7Zy292nCtE+nitlmYKNF3UpbFn0=
github.com/hajimehoshi/ebiten/v2 v2.2.1 h1:YhITMaBQmnwb4kzAXCCfSkSZmeQX7pfQ7BnC32cnPjc=
github.com/hajimehoshi/ebiten/v2 v2.2.1/go.mod h1:olKl/qqhMBBAm2oI7Zy292nCtE+nitlmYKNF3UpbFn0=
github.com/hajimehoshi/file2byteslice v0.0.0-20210813153925-5340248a8f41/go.mod h1:CqqAHp7Dk/AqQiwuhV1yT2334qbA/tFWQW0MD2dGqUE=
github.com/hajimehoshi/go-mp3 v0.3.2/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=
github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
@ -253,6 +254,7 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
@ -282,16 +284,18 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
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-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
golang.org/x/exp v0.0.0-20211012155715-ffe10e552389 h1:qFfBYVpJAdBCk6Nmd7ZbcyhGmKmv8fps+OyoOfpjvu8=
golang.org/x/exp v0.0.0-20211012155715-ffe10e552389/go.mod h1:a3o/VtDNHN+dCVLEpzjjUHOzR+Ln3DHX056ZPzoZGGA=
golang.org/x/exp v0.0.0-20211102154824-3b956f2825b8 h1:xzBAK+9A1hFQDCBJuvec/IFvr5cDiJ1UwZMALklzilw=
golang.org/x/exp v0.0.0-20211102154824-3b956f2825b8/go.mod h1:OyI624f2tQ/aU3IMa7GB16Hk54CHURAfHfj6tMqtyhA=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs=
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
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=
@ -301,15 +305,16 @@ golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
golang.org/x/mobile v0.0.0-20210902104108-5d9a33257ab5/go.mod h1:c4YKU3ZylDmvbw+H/PSvm42vhdWbuxCzbonauEAP9B8=
golang.org/x/mobile v0.0.0-20210924032853-1c027f395ef7 h1:CyFUjc175y/mbMjxe+WdqI72jguLyjQChKCDe9mfTvg=
golang.org/x/mobile v0.0.0-20210924032853-1c027f395ef7/go.mod h1:c4YKU3ZylDmvbw+H/PSvm42vhdWbuxCzbonauEAP9B8=
golang.org/x/mobile v0.0.0-20211102000317-2ab7fee9df46 h1:yT9tfMKqMvPaN5Bqa3eWyjS4/rJY9mAvvaHGY7hM99I=
golang.org/x/mobile v0.0.0-20211102000317-2ab7fee9df46/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ=
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.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.1-0.20210830214625-1b1db11ec8f4/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
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=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -327,8 +332,10 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -364,15 +371,18 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211015200801-69063c4bb744 h1:KzbpndAYEM+4oHRp9JmB2ewj0NHHxO3Z0g7Gus2O1kk=
golang.org/x/sys v0.0.0-20211015200801-69063c4bb744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc=
golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/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-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -394,6 +404,8 @@ golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.6/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
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=