mirror of
https://github.com/ivanizag/izapple2.git
synced 2025-08-05 17:25:23 +00:00
Experiment with ebitengine as a new frontend
This commit is contained in:
159
frontend/a2ebiten/ebitenKeyboard.go
Normal file
159
frontend/a2ebiten/ebitenKeyboard.go
Normal file
@@ -0,0 +1,159 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ivanizag/izapple2"
|
||||
"github.com/ivanizag/izapple2/screen"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/hajimehoshi/ebiten/v2/inpututil"
|
||||
)
|
||||
|
||||
type ebitenKeyboard struct {
|
||||
a *izapple2.Apple2
|
||||
keyChannel *izapple2.KeyboardChannel
|
||||
|
||||
showHelp bool
|
||||
showPages bool
|
||||
showCharGen bool
|
||||
showAltText bool
|
||||
screenMode int
|
||||
}
|
||||
|
||||
func newEbitenKeyBoard(a *izapple2.Apple2) *ebitenKeyboard {
|
||||
var k ebitenKeyboard
|
||||
k.a = a
|
||||
k.keyChannel = izapple2.NewKeyboardChannel(a)
|
||||
|
||||
k.screenMode = screen.ScreenModeNTSC
|
||||
return &k
|
||||
}
|
||||
|
||||
func (k *ebitenKeyboard) update() {
|
||||
runes := ebiten.AppendInputChars(nil)
|
||||
if len(runes) > 0 {
|
||||
fmt.Println("Runes: ", string(runes))
|
||||
k.putText(string(runes))
|
||||
}
|
||||
|
||||
keys := inpututil.AppendJustPressedKeys(nil)
|
||||
for _, key := range keys {
|
||||
s := key.String()
|
||||
fmt.Println("Key pressed: ", s)
|
||||
k.putKey(key)
|
||||
}
|
||||
}
|
||||
|
||||
func (k *ebitenKeyboard) putText(text string) {
|
||||
k.keyChannel.PutText(text)
|
||||
}
|
||||
|
||||
func (k *ebitenKeyboard) putKey(key ebiten.Key) {
|
||||
/*
|
||||
See "Apple II reference manual", page 5
|
||||
|
||||
To get keys as understood by the Apple2 hardware run:
|
||||
10 A=PEEK(49152)
|
||||
20 PRINT A, A - 128
|
||||
30 GOTO 10
|
||||
*/
|
||||
|
||||
ctrl := ebiten.IsKeyPressed(ebiten.KeyControl)
|
||||
shift := ebiten.IsKeyPressed(ebiten.KeyShift)
|
||||
|
||||
if ctrl {
|
||||
if key >= ebiten.KeyA && key <= ebiten.KeyZ {
|
||||
fmt.Println("Control Key: ", key.String())
|
||||
k.keyChannel.PutChar(uint8(key-ebiten.KeyA) - 97 + 1)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
result := uint8(0)
|
||||
|
||||
switch key {
|
||||
case ebiten.KeyEscape:
|
||||
result = 27
|
||||
case ebiten.KeyBackspace:
|
||||
result = 8
|
||||
case ebiten.KeyEnter:
|
||||
result = 13
|
||||
case ebiten.KeyNumpadEnter:
|
||||
result = 13
|
||||
case ebiten.KeyLeft:
|
||||
if ctrl {
|
||||
result = 31 // Base64A
|
||||
} else {
|
||||
result = 8
|
||||
}
|
||||
case ebiten.KeyRight:
|
||||
result = 21
|
||||
|
||||
// Apple //e
|
||||
case ebiten.KeyUp:
|
||||
result = 11 // 31 in the Base64A
|
||||
case ebiten.KeyDown:
|
||||
result = 10
|
||||
case ebiten.KeyTab:
|
||||
result = 9
|
||||
case ebiten.KeyDelete:
|
||||
result = 127 // 24 in the Base64A
|
||||
|
||||
// Base64A clone particularities
|
||||
case ebiten.KeyF3:
|
||||
result = 127 // Base64A
|
||||
|
||||
// Control of the emulator
|
||||
case ebiten.KeyF1:
|
||||
k.showHelp = !k.showHelp
|
||||
case ebiten.KeyF2:
|
||||
if ctrl {
|
||||
k.a.SendCommand(izapple2.CommandReset)
|
||||
}
|
||||
case ebiten.KeyF4:
|
||||
k.a.SendCommand(izapple2.CommandToggleCPUTrace)
|
||||
case ebiten.KeyF5:
|
||||
if ctrl {
|
||||
k.a.SendCommand(izapple2.CommandShowSpeed)
|
||||
} else {
|
||||
k.a.SendCommand(izapple2.CommandToggleSpeed)
|
||||
}
|
||||
case ebiten.KeyF6:
|
||||
k.screenMode = screen.NextScreenMode(k.screenMode)
|
||||
case ebiten.KeyF7:
|
||||
k.showPages = !k.showPages
|
||||
case ebiten.KeyF9:
|
||||
k.a.SendCommand(izapple2.CommandDumpDebugInfo)
|
||||
case ebiten.KeyF10:
|
||||
if ctrl {
|
||||
k.showCharGen = !k.showCharGen
|
||||
} else if shift {
|
||||
k.showAltText = !k.showAltText
|
||||
} else {
|
||||
k.a.SendCommand(izapple2.CommandNextCharGenPage)
|
||||
}
|
||||
case ebiten.KeyF12:
|
||||
fallthrough
|
||||
case ebiten.KeyPrintScreen:
|
||||
if ctrl {
|
||||
screen.AddScenario(k.a.GetVideoSource(), "../../screen/test_resources/")
|
||||
} else {
|
||||
err := screen.SaveSnapshot(k.a.GetVideoSource(), screen.ScreenModeNTSC, "snapshot.png")
|
||||
if err != nil {
|
||||
fmt.Printf("Error saving snapshoot: %v.\n.", err)
|
||||
} else {
|
||||
fmt.Println("Saving snapshot 'snapshot.png'")
|
||||
}
|
||||
}
|
||||
case ebiten.KeyPause:
|
||||
k.a.SendCommand(izapple2.CommandPauseUnpause)
|
||||
}
|
||||
|
||||
// Missing values 91 to 95. Usually control for [\]^_
|
||||
// On the Base64A it's control for \]./
|
||||
|
||||
if result != 0 {
|
||||
k.keyChannel.PutChar(result)
|
||||
}
|
||||
}
|
137
frontend/a2ebiten/main.go
Normal file
137
frontend/a2ebiten/main.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
|
||||
"github.com/ivanizag/izapple2"
|
||||
a_screen "github.com/ivanizag/izapple2/screen"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/pkg/profile"
|
||||
)
|
||||
|
||||
type Game struct {
|
||||
a *izapple2.Apple2
|
||||
image *ebiten.Image
|
||||
keyboard *ebitenKeyboard
|
||||
|
||||
paused bool
|
||||
title string
|
||||
}
|
||||
|
||||
const (
|
||||
virtualWidth = 1128
|
||||
virtualHeight = 768
|
||||
)
|
||||
|
||||
func (g *Game) Update() error {
|
||||
g.keyboard.update()
|
||||
|
||||
if g.paused != g.a.IsPaused() {
|
||||
if g.a.IsPaused() {
|
||||
ebiten.SetWindowTitle(g.title + " - PAUSED")
|
||||
} else {
|
||||
ebiten.SetWindowTitle(g.title)
|
||||
}
|
||||
g.paused = g.a.IsPaused()
|
||||
}
|
||||
|
||||
if !g.a.IsPaused() {
|
||||
var img *image.RGBA
|
||||
vs := g.a.GetVideoSource()
|
||||
if g.keyboard.showHelp {
|
||||
img = a_screen.SnapshotMessageGenerator(vs, helpMessage)
|
||||
} else if g.keyboard.showCharGen {
|
||||
cgPage, cgPages := g.a.GetCgPageInfo()
|
||||
img = a_screen.SnapshotCharacterGenerator(vs, g.keyboard.showAltText)
|
||||
ebiten.SetWindowTitle(fmt.Sprintf("%v character map, page %v/%v", g.a.Name, cgPage+1, cgPages))
|
||||
} else if g.keyboard.showPages {
|
||||
img = a_screen.SnapshotParts(vs, g.keyboard.screenMode)
|
||||
ebiten.SetWindowTitle(fmt.Sprintf("%v %v %vx%v", g.a.Name, a_screen.VideoModeName(vs), img.Rect.Dx()/2, img.Rect.Dy()/2))
|
||||
} else {
|
||||
img = a_screen.Snapshot(vs, g.keyboard.screenMode)
|
||||
}
|
||||
if img != nil {
|
||||
g.image = ebiten.NewImageFromImage(img)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Game) Draw(screen *ebiten.Image) {
|
||||
if g.image != nil {
|
||||
op := &ebiten.DrawImageOptions{}
|
||||
size := g.image.Bounds().Size()
|
||||
scaleX := virtualWidth / float64(size.X)
|
||||
scaleY := virtualHeight / float64(size.Y)
|
||||
op.GeoM.Scale(scaleX, scaleY)
|
||||
|
||||
screen.DrawImage(g.image, op)
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
|
||||
return virtualWidth, virtualHeight
|
||||
}
|
||||
|
||||
func main() {
|
||||
a, err := izapple2.CreateConfiguredApple()
|
||||
if err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
}
|
||||
if a != nil {
|
||||
if a.IsProfiling() {
|
||||
// See the log with:
|
||||
// go tool pprof --pdf ~/go/bin/izapple2sdl /tmp/profile329536248/cpu.pprof > profile.pdf
|
||||
defer profile.Start().Stop()
|
||||
}
|
||||
|
||||
ebitenRun(a)
|
||||
}
|
||||
}
|
||||
|
||||
func ebitenRun(a *izapple2.Apple2) {
|
||||
ebiten.SetWindowSize(virtualWidth, virtualHeight)
|
||||
ebiten.SetWindowResizingMode(ebiten.WindowResizingModeEnabled)
|
||||
|
||||
title := "iz-" + a.Name + " (F1 for help)"
|
||||
ebiten.SetWindowTitle(title)
|
||||
|
||||
go a.Run()
|
||||
|
||||
game := &Game{
|
||||
a: a,
|
||||
keyboard: newEbitenKeyBoard(a),
|
||||
}
|
||||
|
||||
if err := ebiten.RunGame(game); err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
var helpMessage = `
|
||||
|
||||
F1: Show/Hide help
|
||||
Ctrl-F2: Reset
|
||||
F4: Show/Hide CPU trace
|
||||
F5: Fast/Normal speed
|
||||
Ctrl-F5: Show speed
|
||||
F6: Next screen mode
|
||||
F7: Show/Hide pages
|
||||
F10: Next character set
|
||||
Ctrl-F10: Show/Hide character set
|
||||
Shift-F10: Show/Hide alternate text
|
||||
F12: Save screen snapshot
|
||||
Pause: Pause the emulation
|
||||
|
||||
Left alt or option key: Open-Apple
|
||||
Right alt or option key: Closed-Apple
|
||||
|
||||
Drop a file on the left or right
|
||||
side of the window to load a disk
|
||||
|
||||
Run izapple2 -h for more options
|
||||
https://github.com/ivanizag/izapple2
|
||||
`
|
19
go.mod
19
go.mod
@@ -1,6 +1,8 @@
|
||||
module github.com/ivanizag/izapple2
|
||||
|
||||
go 1.21
|
||||
go 1.22.0
|
||||
|
||||
toolchain go1.23.2
|
||||
|
||||
require (
|
||||
fyne.io/fyne/v2 v2.1.4
|
||||
@@ -12,6 +14,14 @@ require (
|
||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325 // indirect
|
||||
github.com/ebitengine/hideconsole v1.0.0 // indirect
|
||||
github.com/ebitengine/purego v0.8.0 // indirect
|
||||
github.com/jezek/xgb v1.1.1 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/felixge/fgprof v0.9.3 // indirect
|
||||
@@ -21,15 +31,16 @@ require (
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/goki/freetype v1.0.2 // indirect
|
||||
github.com/google/pprof v0.0.0-20240117000934-35fc243c5815 // indirect
|
||||
github.com/hajimehoshi/ebiten/v2 v2.8.3
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
|
||||
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
github.com/yuin/goldmark v1.6.0 // indirect
|
||||
golang.org/x/image v0.18.0 // indirect
|
||||
golang.org/x/image v0.20.0 // indirect
|
||||
golang.org/x/net v0.23.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
golang.org/x/text v0.18.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
26
go.sum
26
go.sum
@@ -13,6 +13,12 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325 h1:Gk1XUEttOk0/hb6Tq3WkmutWa0ZLhNn/6fc6XZpM7tM=
|
||||
github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325/go.mod h1:ulhSQcbPioQrallSuIzF8l1NKQoD7xmMZc5NxzibUMY=
|
||||
github.com/ebitengine/hideconsole v1.0.0 h1:5J4U0kXF+pv/DhiXt5/lTz0eO5ogJ1iXb8Yj1yReDqE=
|
||||
github.com/ebitengine/hideconsole v1.0.0/go.mod h1:hTTBTvVYWKBuxPr7peweneWdkUwEuHuB3C1R/ielR1A=
|
||||
github.com/ebitengine/purego v0.8.0 h1:JbqvnEzRvPpxhCJzJJ2y0RbiZ8nyjccVUrSM3q+GvvE=
|
||||
github.com/ebitengine/purego v0.8.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
|
||||
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
|
||||
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3/go.mod h1:CzM2G82Q9BDUvMTGHnXf/6OExw/Dz2ivDj48nVg7Lg8=
|
||||
@@ -34,13 +40,19 @@ github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x
|
||||
github.com/goki/freetype v0.0.0-20181231101311-fa8a33aabaff/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw=
|
||||
github.com/goki/freetype v1.0.2 h1:qLd8BgI0NWlysKqN+yhsE1R9OtUMQi6Q3tNnFF2xz9g=
|
||||
github.com/goki/freetype v1.0.2/go.mod h1:ni9Dgz8vA6o+13u1Ke0q3kJcCJ9GuXb1dtlfKho98vs=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
|
||||
github.com/google/pprof v0.0.0-20240117000934-35fc243c5815 h1:WzfWbQz/Ze8v6l++GGbGNFZnUShVpP/0xffCPLL+ax8=
|
||||
github.com/google/pprof v0.0.0-20240117000934-35fc243c5815/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/hajimehoshi/ebiten/v2 v2.8.3 h1:AKHqj3QbQMzNEhK33MMJeRwXm9UzftrUUo6AWwFV258=
|
||||
github.com/hajimehoshi/ebiten/v2 v2.8.3/go.mod h1:SXx/whkvpfsavGo6lvZykprerakl+8Uo1X8d2U5aAnA=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
github.com/ivanizag/iz6502 v1.4.0 h1:7eYygUkCPwFRH0tf2JSg1k+Sy27wwPi3ActuVNVv1Uc=
|
||||
github.com/ivanizag/iz6502 v1.4.0/go.mod h1:h4gbw3IK6WCYawi00kBhQ4ACeQkGWgqbUeAgDaQpy6s=
|
||||
github.com/jackmordaunt/icns v0.0.0-20181231085925-4f16af745526/go.mod h1:UQkeMHVoNcyXYq9otUupF7/h/2tmHlhrS2zw7ZVvUqc=
|
||||
github.com/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4=
|
||||
github.com/jezek/xgb v1.1.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
|
||||
github.com/josephspurrier/goversioninfo v0.0.0-20200309025242-14b0ab84c6ca/go.mod h1:eJTEwMjXb7kZ633hO3Ln9mBUCOjX2+FlTljvpl9SYdE=
|
||||
github.com/koron-go/z80 v0.10.1 h1:Jfb0esP/QFL4cvcr+eFECVG0Y/mA9JBLC4EKbMU5zAY=
|
||||
github.com/koron-go/z80 v0.10.1/go.mod h1:ry+Zl9kRKelzaDG9UzEtUpUnXy0Yv/kk1YEaX958xdk=
|
||||
@@ -89,8 +101,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA=
|
||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
|
||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
|
||||
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
|
||||
golang.org/x/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw=
|
||||
golang.org/x/image v0.20.0/go.mod h1:0a88To4CYVBAHp5FXJm8o7QbUl37Vd85ply1vyD8auM=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@@ -99,6 +111,8 @@ golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -108,13 +122,13 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/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-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
|
Reference in New Issue
Block a user