Bläddra i källkod

d07 Массовые исправления

SVI 1 år sedan
förälder
incheckning
42703a2365
100 ändrade filer med 302 tillägg och 11030 borttagningar
  1. 58 0
      .env
  2. 0 83
      cmd/desk/main.go
  3. 1 2
      cmd/server/main.go
  4. 48 0
      desc_lorca/desc_lorca.go
  5. 36 0
      desc_lorca/lorca_gui/lorca_gui.go
  6. 16 0
      dev.cmd
  7. 21 43
      doc/index.md
  8. 40 659
      go.sum
  9. 5 0
      make.py
  10. 2 3
      pkg/alias/alias.go
  11. 1 2
      pkg/components/scene_net/scene_web_worker/scene_web_worker.go
  12. 1 2
      pkg/components/sound/sound.go
  13. 0 0
      pkg/scene/scene_mode/scene_mode.go
  14. 2 3
      pkg/types/ibase.go
  15. 1 1
      pkg/types/ibot_cookie.go
  16. 1 2
      pkg/types/ibot_net.go
  17. 2 2
      pkg/types/iconvoy.go
  18. 3 5
      pkg/types/iserver_stat.go
  19. 1 2
      server/serv_bots/warbot/angar/angarnet/angarnet.go
  20. 1 2
      server/serv_bots/warbot/angar/base/market/market.go
  21. 1 2
      server/serv_bots/warbot/angar/base/market/marketnet/marketnet.go
  22. 1 2
      server/serv_bots/warbot/angar/battle/battle_register/battle_register.go
  23. 1 2
      server/serv_bots/warbot/angar/battle/battle_worker/battleon/battlesound/battlesound.go
  24. 1 2
      server/serv_bots/warbot/angar/convoy/convoynet/convoynet.go
  25. 1 2
      server/serv_bots/warbot/angar/death_match/battle_wait/battle_wait.go
  26. 2 3
      server/serv_bots/warbot/angar/death_match/death_worker/death_on/health/health.go
  27. 2 3
      server/serv_bots/warbot/angar/division/divwar/divwarnet/divwarnet.go
  28. 1 2
      server/serv_bots/warbot/angar/division/divwar/divwaron/divwarsound/divwarsound.go
  29. 1 2
      server/serv_bots/warbot/angar/masters/batmasnet/batmasnet.go
  30. 1 2
      server/serv_bots/warbot/angar/missions/missionsnet/missionsnet.go
  31. 2 3
      server/serv_bots/warbot/tank_stat/static_param/static_param.go
  32. BIN
      server/serv_bots/warbot/warbot_config/warbot_config.go
  33. BIN
      server/serv_bots/warbot/warbot_net/bot_net_conn/bot_net_conn.go
  34. 3 4
      server/serv_bots/warbot/warbot_net/warbot_net.go
  35. 2 3
      server/serv_desktop.zip
  36. 41 0
      server/server_stat/server_stat.go
  37. 0 169
      vendor/fyne.io/fyne/v2/app/app.go
  38. 0 60
      vendor/fyne.io/fyne/v2/app/app_darwin.go
  39. 0 61
      vendor/fyne.io/fyne/v2/app/app_darwin.m
  40. 0 8
      vendor/fyne.io/fyne/v2/app/app_debug.go
  41. 0 69
      vendor/fyne.io/fyne/v2/app/app_desktop_darwin.go
  42. 0 18
      vendor/fyne.io/fyne/v2/app/app_desktop_darwin.m
  43. 0 15
      vendor/fyne.io/fyne/v2/app/app_gl.go
  44. 0 19
      vendor/fyne.io/fyne/v2/app/app_goxjs.go
  45. 0 25
      vendor/fyne.io/fyne/v2/app/app_mobile.go
  46. 0 131
      vendor/fyne.io/fyne/v2/app/app_mobile_and.c
  47. 0 61
      vendor/fyne.io/fyne/v2/app/app_mobile_and.go
  48. 0 40
      vendor/fyne.io/fyne/v2/app/app_mobile_ios.go
  49. 0 16
      vendor/fyne.io/fyne/v2/app/app_mobile_ios.m
  50. 0 9
      vendor/fyne.io/fyne/v2/app/app_notlegacy_darwin.go
  51. 0 20
      vendor/fyne.io/fyne/v2/app/app_openurl_js.go
  52. 0 19
      vendor/fyne.io/fyne/v2/app/app_openurl_wasm.go
  53. 0 13
      vendor/fyne.io/fyne/v2/app/app_openurl_web.go
  54. 0 34
      vendor/fyne.io/fyne/v2/app/app_other.go
  55. 0 8
      vendor/fyne.io/fyne/v2/app/app_release.go
  56. 0 16
      vendor/fyne.io/fyne/v2/app/app_software.go
  57. 0 8
      vendor/fyne.io/fyne/v2/app/app_standard.go
  58. 0 29
      vendor/fyne.io/fyne/v2/app/app_theme_js.go
  59. 0 31
      vendor/fyne.io/fyne/v2/app/app_theme_wasm.go
  60. 0 13
      vendor/fyne.io/fyne/v2/app/app_theme_web.go
  61. 0 124
      vendor/fyne.io/fyne/v2/app/app_windows.go
  62. 0 202
      vendor/fyne.io/fyne/v2/app/app_xdg.go
  63. 0 47
      vendor/fyne.io/fyne/v2/app/cloud.go
  64. 0 28
      vendor/fyne.io/fyne/v2/app/meta.go
  65. 0 208
      vendor/fyne.io/fyne/v2/app/preferences.go
  66. 0 21
      vendor/fyne.io/fyne/v2/app/preferences_android.go
  67. 0 24
      vendor/fyne.io/fyne/v2/app/preferences_ios.go
  68. 0 20
      vendor/fyne.io/fyne/v2/app/preferences_mobile.go
  69. 0 29
      vendor/fyne.io/fyne/v2/app/preferences_other.go
  70. 0 168
      vendor/fyne.io/fyne/v2/app/settings.go
  71. 0 75
      vendor/fyne.io/fyne/v2/app/settings_desktop.go
  72. 0 35
      vendor/fyne.io/fyne/v2/app/settings_file.go
  73. 0 24
      vendor/fyne.io/fyne/v2/app/settings_goxjs.go
  74. 0 12
      vendor/fyne.io/fyne/v2/app/settings_mobile.go
  75. 0 8
      vendor/fyne.io/fyne/v2/app/settings_noanimation.go
  76. 0 27
      vendor/fyne.io/fyne/v2/app/storage.go
  77. 0 86
      vendor/fyne.io/fyne/v2/canvas/animation.go
  78. 0 100
      vendor/fyne.io/fyne/v2/canvas/base.go
  79. 0 29
      vendor/fyne.io/fyne/v2/canvas/canvas.go
  80. 0 90
      vendor/fyne.io/fyne/v2/canvas/circle.go
  81. 0 212
      vendor/fyne.io/fyne/v2/canvas/gradient.go
  82. 0 362
      vendor/fyne.io/fyne/v2/canvas/image.go
  83. 0 102
      vendor/fyne.io/fyne/v2/canvas/line.go
  84. 0 196
      vendor/fyne.io/fyne/v2/canvas/raster.go
  85. 0 64
      vendor/fyne.io/fyne/v2/canvas/rectangle.go
  86. 0 76
      vendor/fyne.io/fyne/v2/canvas/text.go
  87. 2 2
      vendor/fyne.io/fyne/v2/container.go
  88. 0 462
      vendor/fyne.io/fyne/v2/container/apptabs.go
  89. 0 20
      vendor/fyne.io/fyne/v2/container/container.go
  90. 0 496
      vendor/fyne.io/fyne/v2/container/doctabs.go
  91. 0 121
      vendor/fyne.io/fyne/v2/container/layouts.go
  92. 0 55
      vendor/fyne.io/fyne/v2/container/scroll.go
  93. 0 369
      vendor/fyne.io/fyne/v2/container/split.go
  94. 0 843
      vendor/fyne.io/fyne/v2/container/tabs.go
  95. 0 178
      vendor/fyne.io/fyne/v2/data/binding/binding.go
  96. 0 647
      vendor/fyne.io/fyne/v2/data/binding/binditems.go
  97. 0 1786
      vendor/fyne.io/fyne/v2/data/binding/bindlists.go
  98. 0 1816
      vendor/fyne.io/fyne/v2/data/binding/bindtrees.go
  99. 0 118
      vendor/fyne.io/fyne/v2/data/binding/bool.go
  100. 0 13
      vendor/fyne.io/fyne/v2/data/binding/comparator_helper.go

+ 58 - 0
.env

@@ -0,0 +1,58 @@
+// package main -- пускач для десктопа на лорке
+//
+// Профилирование:
+//
+//	go tool pprof http://localhost:29080/debug/pprof/profile?seconds=30
+package main
+
+import (
+	"log"
+	"net/http"
+	_ "net/http/pprof"
+	"os"
+	"time"
+
+	"wartank/desc_lorca"
+)
+
+func профилировать() {
+	порт := "29081"
+	стенд := os.Getenv("STAGE")
+	if стенд == "prod" {
+		порт = "29080"
+	}
+	for {
+		ош := http.ListenAndServe("0.0.0.0:"+порт, nil)
+		if ош != nil {
+			log.Printf("профилировать(): при запуске pprof, err=\n\t%v\n", ош)
+		}
+		time.Sleep(time.Second * 1)
+	}
+}
+
+var (
+	// Version -- версия тега хранилища
+	Version = ""
+	// Date -- дата релиза
+	Date = ""
+	// GoVersion -- версия компилятора
+	GoVersion = ""
+)
+
+func main() {
+	log.Printf("server/main():\n\tgo = %v\n\tvers = %v\n\tdate = %v\n", GoVersion, Version, Date)
+	go профилировать()
+	десктоп, ош := desc_lorca.НовДесктопЛорка()
+	if ош != nil {
+		log.Printf("main(): при создании ДесктопЛорка, ош=\n\t%v\n", ош)
+		os.Exit(1)
+	}
+	go func() {
+		time.Sleep(time.Minute * 20)
+		десктоп.Отменить()
+	}()
+	if ош = десктоп.Пуск(); ош != nil {
+		log.Printf("main(): при работе десктопа, ош=\n\t%v\n", ош)
+		os.Exit(2)
+	}
+}

+ 0 - 83
cmd/desk/main.go

@@ -1,83 +0,0 @@
-package main
-
-import (
-	"image/color"
-	"log"
-
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/app"
-	"fyne.io/fyne/v2/canvas"
-	"fyne.io/fyne/v2/container"
-	"fyne.io/fyne/v2/layout"
-	"fyne.io/fyne/v2/widget"
-	//"fyne.io/fyne/v2/layout"
-)
-
-var myApp fyne.App
-var winMain fyne.Window
-var botLogin string
-var botPass string
-var boxLeft *fyne.Container
-
-func main() {
-	myApp = app.New()
-	winMain = myApp.NewWindow("[Бото-ферма WarTank]")
-	winMain.Resize(fyne.NewSize(800, 600))
-	green := color.NRGBA{R: 0, G: 180, B: 0, A: 255}
-
-	text1 := canvas.NewText("Список ботов", green)
-	text2 := canvas.NewText("There", green)
-	text2.Move(fyne.NewPos(20, 20))
-	//content := container.NewWithoutLayout(text1, text2)
-	// content := container.New(layout.NewGridLayout(2), text1, text2)
-	boxLeft = container.NewVBox(text1, text2)
-	btnAddBot := widget.NewButton("Добавить бота", btnAddClick)
-	btnExit := widget.NewButton("Выход", btnExitClick)
-	boxDown := container.NewHBox(btnAddBot, layout.NewSpacer(), btnExit)
-	boxBorder := container.NewBorder(nil, nil, boxLeft, nil, boxLeft)
-	boxMain := container.NewBorder(nil, boxDown, nil, nil, boxBorder)
-
-	winMain.SetContent(boxMain)
-	winMain.Show()
-	myApp.Run()
-}
-
-func btnAddClick() {
-	log.Println("btnAddclick()")
-	winAddBot := myApp.NewWindow("Новый бот")
-	entLogin := widget.NewEntry()
-	entPass := widget.NewEntry()
-	form := &widget.Form{
-		Items: []*widget.FormItem{ // we can specify items in the constructor
-			{Text: "Логин", Widget: entLogin},
-			{Text: "Пароль", Widget: entPass},
-		},
-		OnSubmit: func() { // optional, handle form submission
-			botLogin = entLogin.Text
-			log.Println("Form submitted:", entLogin.Text)
-			botPass = entPass.Text
-			log.Println("multiline:", entPass.Text)
-			winAddBot.Close()
-			btnBot := widget.NewButton(botLogin, btnBotClick(botLogin, botPass))
-			boxLeft.Add(btnBot)
-			// winMain.Canvas().Refresh()
-		},
-	}
-	winAddBot.Resize(fyne.NewSize(640, 480))
-	winAddBot.SetContent(form)
-	winAddBot.Show()
-
-}
-
-func btnBotClick(botName, botPass string) func() {
-	_botName := botName
-	_botPass := botPass
-	return func() {
-		log.Printf("btnBotClick().fn(): botName=%q\tbotPass=%q\n", _botName, _botPass)
-	}
-}
-
-func btnExitClick() {
-	log.Println("btnExitClick()")
-	myApp.Quit()
-}

+ 1 - 2
cmd/server/main.go

@@ -14,7 +14,6 @@ import (
 	_ "net/http/pprof"
 	_ "net/http/pprof"
 	"os"
 	"os"
 	"time"
 	"time"
-
 	"wartank/server"
 	"wartank/server"
 )
 )
 
 
@@ -54,7 +53,7 @@ func main() {
 		time.Sleep(time.Minute * 20)
 		time.Sleep(time.Minute * 20)
 		serv.Отменить()
 		serv.Отменить()
 	}()
 	}()
-	if err := serv.Run(); err != nil {
+	if err := serv.Пуск(); err != nil {
 		log.Printf("main(): in run server, err=\n\t%v\n", err)
 		log.Printf("main(): in run server, err=\n\t%v\n", err)
 		os.Exit(2)
 		os.Exit(2)
 	}
 	}

+ 48 - 0
desc_lorca/desc_lorca.go

@@ -0,0 +1,48 @@
+// package desc_lorca -- главный тип десктопного приложения для lorca
+package desc_lorca
+
+import (
+	"fmt"
+	"log"
+	"wartank/desc_lorca/lorca_gui"
+	"wartank/server"
+)
+
+// ДесктопЛорка -- главный тип десктопного приложения для lorca
+type ДесктопЛорка struct {
+	сервер   *server.Сервер      // Сервер для взаимодействия с лоркой
+	гипЛорка *lorca_gui.ЛоркаГуи // ГИП десктопа на Лорке
+}
+
+// НовДесктопЛорка -- возвращает новый десктоп на Лорке
+func НовДесктопЛорка() (*ДесктопЛорка, error) {
+	гип, ош := lorca_gui.НовЛоркаГуи()
+	if ош != nil {
+		return nil, fmt.Errorf("НовДесктопЛорка(): при создании ЛоркаГуи, ош=\n\t%w", ош)
+	}
+	сам := &ДесктопЛорка{
+		гипЛорка: гип,
+	}
+	сам.сервер, ош = server.НовСервер()
+	if ош != nil {
+		return nil, fmt.Errorf("НовДесктопЛорка(): при создании ИСервер, ош=\n\t%w", ош)
+	}
+	return сам, nil
+}
+
+// Отменить -- отменяет работу десктопа
+func (сам *ДесктопЛорка) Отменить() {
+	сам.сервер.Отменить()
+}
+
+// Пуск -- запускает работу десктопа
+func (сам *ДесктопЛорка) Пуск() error {
+	go func() {
+		ош := сам.сервер.Пуск()
+		if ош != nil {
+			log.Printf("ДесктопЛорка.Пуск(): ош=\n\t%v\n", ош)
+		}
+	}()
+	сам.сервер.Wg().Wait()
+	return nil
+}

+ 36 - 0
desc_lorca/lorca_gui/lorca_gui.go

@@ -0,0 +1,36 @@
+// package lorca_gui -- тип десктопного приложения для lorca
+package lorca_gui
+
+import (
+	"fmt"
+
+	"github.com/zserge/lorca"
+)
+
+// ЛоркаГуи -- тип десктопного приложения для lorca
+type ЛоркаГуи struct{}
+
+// НовЛоркаГуи -- создание нового типа десктопного приложения для lorca
+func НовЛоркаГуи() (*ЛоркаГуи, error) {
+	ui, _ := lorca.New("", "", 480, 320)
+	defer ui.Close()
+
+	// Bind Go function to be available in JS. Go function may be long-running and
+	// blocking - in JS it's represented with a Promise.
+	ош := ui.Bind("add", func(a, b int) int { return a + b })
+	if ош != nil {
+		return nil, fmt.Errorf("НовЛоркаГуи(): ош=\n\t%w", ош)
+	}
+
+	// Call JS function from Go. Functions may be asynchronous, i.e. return promises
+	n := ui.Eval(`Math.random()`).Float()
+	fmt.Println(n)
+
+	// Call JS that calls Go and so on and so on...
+	m := ui.Eval(`add(2, 3)`).Int()
+	fmt.Println(m)
+
+	// Wait for the browser window to be closed
+	<-ui.Done()
+	return &ЛоркаГуи{}, nil
+}

+ 16 - 0
dev.cmd

@@ -0,0 +1,16 @@
+cls
+rm -rdf bin_dev
+mkdir -p bin_dev\web\static
+mkdir -p bin_dev\web\tmpl
+cp -r web bin_dev
+go fmt ./...
+go build -race -o bin_dev\wartank_dev.exe cmd\server\main.go
+
+
+
+set STAGE="local"
+
+
+cd bin_dev
+wartank_dev.exe
+cd ..

+ 21 - 43
doc/index.md

@@ -1,65 +1,43 @@
 module wartank
 module wartank
 
 
-go 1.21.4
+go 1.22.3
 
 
 require (
 require (
-	fyne.io/fyne/v2 v2.4.3
-	github.com/charmbracelet/bubbletea v0.25.0
-	github.com/gofiber/fiber/v2 v2.52.0
-	github.com/gofiber/template/html/v2 v2.1.0
+	fyne.io/fyne/v2 v2.4.5
+	github.com/charmbracelet/bubbletea v0.26.4
+	github.com/gofiber/fiber/v2 v2.52.4
+	github.com/gofiber/template/html/v2 v2.1.1
 	github.com/sirupsen/logrus v1.9.3
 	github.com/sirupsen/logrus v1.9.3
 	github.com/syndtr/goleveldb v1.0.0
 	github.com/syndtr/goleveldb v1.0.0
+	github.com/zserge/lorca v0.1.10
 )
 )
 
 
 require (
 require (
-	fyne.io/systray v1.10.1-0.20231115130155-104f5ef7839e // indirect
 	github.com/andybalholm/brotli v1.1.0 // indirect
 	github.com/andybalholm/brotli v1.1.0 // indirect
-	github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
-	github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
-	github.com/davecgh/go-spew v1.1.1 // indirect
-	github.com/fredbi/uri v1.1.0 // indirect
-	github.com/fsnotify/fsnotify v1.7.0 // indirect
-	github.com/fyne-io/gl-js v0.0.0-20230506162202-1fdaa286a934 // indirect
-	github.com/fyne-io/glfw-js v0.0.0-20240101223322-6e1efdc71b7a // indirect
-	github.com/fyne-io/image v0.0.0-20240121103648-c3c798e60e6b // indirect
-	github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 // indirect
-	github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240118000515-a250818d05e3 // indirect
-	github.com/go-text/render v0.0.0-20240122202426-67aad72d5803 // indirect
-	github.com/go-text/typesetting v0.1.0 // indirect
-	github.com/godbus/dbus/v5 v5.1.0 // indirect
-	github.com/gofiber/template v1.8.2 // indirect
+	github.com/charmbracelet/x/ansi v0.1.2 // indirect
+	github.com/charmbracelet/x/input v0.1.2 // indirect
+	github.com/charmbracelet/x/term v0.1.1 // indirect
+	github.com/charmbracelet/x/windows v0.1.2 // indirect
+	github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
+	github.com/gofiber/template v1.8.3 // indirect
 	github.com/gofiber/utils v1.1.0 // indirect
 	github.com/gofiber/utils v1.1.0 // indirect
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/google/uuid v1.6.0 // indirect
 	github.com/google/uuid v1.6.0 // indirect
-	github.com/gopherjs/gopherjs v1.17.2 // indirect
-	github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect
-	github.com/klauspost/compress v1.17.5 // indirect
-	github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
+	github.com/klauspost/compress v1.17.8 // indirect
 	github.com/mattn/go-colorable v0.1.13 // indirect
 	github.com/mattn/go-colorable v0.1.13 // indirect
 	github.com/mattn/go-isatty v0.0.20 // indirect
 	github.com/mattn/go-isatty v0.0.20 // indirect
 	github.com/mattn/go-localereader v0.0.1 // indirect
 	github.com/mattn/go-localereader v0.0.1 // indirect
 	github.com/mattn/go-runewidth v0.0.15 // indirect
 	github.com/mattn/go-runewidth v0.0.15 // indirect
 	github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
 	github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
 	github.com/muesli/cancelreader v0.2.2 // indirect
 	github.com/muesli/cancelreader v0.2.2 // indirect
-	github.com/muesli/reflow v0.3.0 // indirect
-	github.com/muesli/termenv v0.15.2 // indirect
-	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/rivo/uniseg v0.4.4 // 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/tevino/abool v1.2.0 // indirect
+	github.com/rivo/uniseg v0.4.7 // indirect
 	github.com/valyala/bytebufferpool v1.0.0 // indirect
 	github.com/valyala/bytebufferpool v1.0.0 // indirect
-	github.com/valyala/fasthttp v1.51.0 // indirect
+	github.com/valyala/fasthttp v1.54.0 // indirect
 	github.com/valyala/tcplisten v1.0.0 // indirect
 	github.com/valyala/tcplisten v1.0.0 // indirect
-	github.com/yuin/goldmark v1.6.0 // indirect
-	golang.org/x/image v0.15.0 // indirect
-	golang.org/x/mobile v0.0.0-20240112133503-c713f31d574b // indirect
-	golang.org/x/net v0.20.0 // indirect
-	golang.org/x/sync v0.6.0 // indirect
-	golang.org/x/sys v0.16.0 // indirect
-	golang.org/x/term v0.16.0 // indirect
-	golang.org/x/text v0.14.0 // indirect
-	gopkg.in/yaml.v3 v3.0.1 // indirect
-	honnef.co/go/js/dom v0.0.0-20231112215516-51f43a291193 // indirect
+	github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
+	golang.org/x/net v0.26.0 // indirect
+	golang.org/x/sync v0.7.0 // indirect
+	golang.org/x/sys v0.21.0 // indirect
+	golang.org/x/text v0.16.0 // indirect
+	gopkg.in/yaml.v2 v2.4.0 // indirect
 )
 )

+ 40 - 659
go.sum

@@ -1,730 +1,111 @@
-cloud.google.com/go v0.26.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.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 v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
-cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
-cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
-cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
-cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
-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/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
-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/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
-fyne.io/fyne/v2 v2.4.3 h1:v2wncjEAcwXZ8UNmTCWTGL9+sGyPc5RuzBvM96GcC78=
-fyne.io/fyne/v2 v2.4.3/go.mod h1:1h3BKxmQYRJlr2g+RGVxedzr6vLVQ/AJmFWcF9CJnoQ=
-fyne.io/systray v1.10.1-0.20231115130155-104f5ef7839e h1:Hvs+kW2VwCzNToF3FmnIAzmivNgrclwPgoUdVSrjkP8=
-fyne.io/systray v1.10.1-0.20231115130155-104f5ef7839e/go.mod h1:oM2AQqGJ1AMo4nNqZFYU8xYygSBZkW2hmdJ7n4yjedE=
-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=
+fyne.io/fyne/v2 v2.4.5 h1:W6jpAEmLoBbKyBB+EXqI7GMJ7kLgHQWCa0wZHUV2VfQ=
+fyne.io/fyne/v2 v2.4.5/go.mod h1:SlOgbca0y80cRObu/JOhxIJdIgtoW7aCyqUVlTMgs0Y=
 github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
 github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
 github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
 github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
-github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
-github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
-github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
-github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
-github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
-github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
-github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
-github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
-github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM=
-github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg=
-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-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
-github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
-github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
-github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/charmbracelet/bubbletea v0.26.4 h1:2gDkkzLZaTjMl/dQBpNVtnvcCxsh/FCkimep7FC9c40=
+github.com/charmbracelet/bubbletea v0.26.4/go.mod h1:P+r+RRA5qtI1DOHNFn0otoNwB4rn+zNAzSj/EXz6xU0=
+github.com/charmbracelet/x/ansi v0.1.2 h1:6+LR39uG8DE6zAmbu023YlqjJHkYXDF1z36ZwzO4xZY=
+github.com/charmbracelet/x/ansi v0.1.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
+github.com/charmbracelet/x/input v0.1.2 h1:QJAZr33eOhDowkkEQ24rsJy4Llxlm+fRDf/cQrmqJa0=
+github.com/charmbracelet/x/input v0.1.2/go.mod h1:LGBim0maUY4Pitjn/4fHnuXb4KirU3DODsyuHuXdOyA=
+github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI=
+github.com/charmbracelet/x/term v0.1.1/go.mod h1:wB1fHt5ECsu3mXYusyzcngVWWlu1KKUmmLhfgr/Flxw=
+github.com/charmbracelet/x/windows v0.1.2 h1:Iumiwq2G+BRmgoayww/qfcvof7W/3uLoelhxojXlRWg=
+github.com/charmbracelet/x/windows v0.1.2/go.mod h1:GLEO/l+lizvFDBPLIOk+49gdX49L9YWMB5t+DZd0jkQ=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 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=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-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.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
-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 v1.1.0 h1:OqLpTXtyRg9ABReqvDGdJPqZUxs8cyBDOMXBbskCaB8=
-github.com/fredbi/uri v1.1.0/go.mod h1:aYTUoAXBOq7BLfVJ8GnKmfcuURosB1xyHDIfWeC/iW4=
+github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
+github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
-github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
-github.com/fyne-io/gl-js v0.0.0-20230506162202-1fdaa286a934 h1:dZC5aKobSN07hf71oMivxUmAofFja5GrfPK2rBlttX4=
-github.com/fyne-io/gl-js v0.0.0-20230506162202-1fdaa286a934/go.mod h1:d4clgH0/GrRwWjRzJJQXxT/h1TyuNSfF/X64zb/3Ggg=
-github.com/fyne-io/glfw-js v0.0.0-20240101223322-6e1efdc71b7a h1:ybgRdYvAHTn93HW79bLiBiJwVL4jVeyGQRZMgImoeWs=
-github.com/fyne-io/glfw-js v0.0.0-20240101223322-6e1efdc71b7a/go.mod h1:gsGA2dotD4v0SR6PmPCYvS9JuOeMwAtmfvDE7mbYXMY=
-github.com/fyne-io/image v0.0.0-20240121103648-c3c798e60e6b h1:Fo9Q/ycIlYOhYJ28M+umawPvvcqvVDo/Zp4EZ5750UQ=
-github.com/fyne-io/image v0.0.0-20240121103648-c3c798e60e6b/go.mod h1:J9Uunu842kOcTjzQj4Eq8XIDmF55szvT1PTS1cUb1UE=
-github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
-github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 h1:5BVwOaUSBTlVZowGO6VZGw2H/zl9nrd3eCZfYV+NfQA=
-github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
-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-gl/glfw/v3.3/glfw v0.0.0-20240118000515-a250818d05e3 h1:nanQfMsOs3gnuKRm0E5jXWomedE/9YIFXdmHJNZYeqc=
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240118000515-a250818d05e3/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-text/render v0.0.0-20240122202426-67aad72d5803 h1:FLmwGPcxx/d3pJgrSOel1+xPP+igIcaFh8+frWKzusQ=
-github.com/go-text/render v0.0.0-20240122202426-67aad72d5803/go.mod h1:Yww7wr2yRAWo3zKRPO2rc155nccyXcE9FwyXXm9ys+w=
-github.com/go-text/typesetting v0.1.0 h1:vioSaLPYcHwPEPLT7gsjCGDCoYSbljxoHJzMnKwVvHw=
-github.com/go-text/typesetting v0.1.0/go.mod h1:d22AnmeKq/on0HNv73UFriMKc4Ez6EqZAofLhAzpSzI=
-github.com/go-text/typesetting-utils v0.0.0-20231211103740-d9332ae51f04 h1:zBx+p/W2aQYtNuyZNcTfinWvXBQwYtDfme051PR/lAY=
-github.com/go-text/typesetting-utils v0.0.0-20231211103740-d9332ae51f04/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o=
-github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
-github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/gofiber/fiber/v2 v2.52.0 h1:S+qXi7y+/Pgvqq4DrSmREGiFwtB7Bu6+QFLuIHYw/UE=
-github.com/gofiber/fiber/v2 v2.52.0/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
-github.com/gofiber/template v1.8.2 h1:PIv9s/7Uq6m+Fm2MDNd20pAFFKt5wWs7ZBd8iV9pWwk=
-github.com/gofiber/template v1.8.2/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8=
-github.com/gofiber/template/html/v2 v2.1.0 h1:FjwzqhhdJpnhyCvav60Z1ytnBqOUr5sGO/aTeob9/ng=
-github.com/gofiber/template/html/v2 v2.1.0/go.mod h1:txXsRQN/G7Fr2cqGfr6zhVHgreCfpsBS+9+DJyrddJc=
+github.com/gofiber/fiber/v2 v2.52.4 h1:P+T+4iK7VaqUsq2PALYEfBBo6bJZ4q3FP8cZ84EggTM=
+github.com/gofiber/fiber/v2 v2.52.4/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
+github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
+github.com/gofiber/template v1.8.3/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8=
+github.com/gofiber/template/html/v2 v2.1.1 h1:QEy3O3EBkvwDthy5bXVGUseOyO6ldJoiDxlF4+MJiV8=
+github.com/gofiber/template/html/v2 v2.1.1/go.mod h1:2G0GHHOUx70C1LDncoBpe4T6maQbNa4x1CVNFW0wju0=
 github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
 github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
 github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
 github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
-github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
-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/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.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 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.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
-github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-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.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.4/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/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/martian/v3 v3.1.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/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y=
-github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
-github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-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/gopherjs/gopherjs v0.0.0-20211219123610-ec9572f70e60/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI=
-github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
-github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
-github.com/goxjs/gl v0.0.0-20210104184919-e3fafc6f8f2a/go.mod h1:dy/f2gjY09hwVfIyATps4G2ai7/hLwLkc5TrPqONuXY=
-github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
-github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
-github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
-github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
-github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
-github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
-github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
-github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
-github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
-github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
-github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
-github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
-github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
-github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
-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/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
-github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
-github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
-github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
-github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
 github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
 github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
-github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-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/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 h1:YLvr1eE6cdCqjOe972w/cYF+FjW34v27+9Vo5106B4M=
-github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw=
-github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
-github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
-github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.17.5 h1:d4vBd+7CHydUqpFBgUEKkSdtSugf9YFmSkvUYPquI5E=
-github.com/klauspost/compress v1.17.5/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
-github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
-github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
-github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
-github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
-github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
+github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
 github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
 github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
 github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
 github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
-github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
 github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
 github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
 github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
 github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
 github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
-github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
 github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
 github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
 github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
-github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
-github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
-github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
-github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
-github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
-github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
-github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
 github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
 github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
 github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
 github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
 github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
 github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
 github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
-github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
-github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
-github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
-github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
-github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
-github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
 github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
 github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
 github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
-github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=
-github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo=
-github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
-github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
-github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
-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/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
-github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
-github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
-github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
-github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
-github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
+github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
+github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
 github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
 github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
 github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
 github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
-github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
-github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
-github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
-github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
-github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c h1:km8GpoQut05eY3GiYWEedbTT0qnSxrCjsVbb7yKY1KE=
-github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q=
-github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ=
-github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
 github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
 github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
 github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
-github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
 github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
 github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
 github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
 github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
-github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA=
-github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
-github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
+github.com/valyala/fasthttp v1.54.0 h1:cCL+ZZR3z3HPLMVfEYVUMtJqVaui0+gu7Lx63unHwS0=
+github.com/valyala/fasthttp v1.54.0/go.mod h1:6dt4/8olwq9QARP/TDuPmWyWcl4byhpvTJ4AAtcz+QM=
 github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
 github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
 github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
 github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
-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.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.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
-github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
-go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
-go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
-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.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
-go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
-go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
-go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
-golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
+github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
+github.com/zserge/lorca v0.1.10 h1:f/xBJ3D3ipcVRCcvN8XqZnpoKcOXV8I4vwqlFyw7ruc=
+github.com/zserge/lorca v0.1.10/go.mod h1:bVmnIbIRlOcoV285KIRSe4bUABKi7R7384Ycuum6e4A=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/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-20190820162420-60c769a6c586/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-20210711020723-a769d52b0f97/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-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
-golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
-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/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
-golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
-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/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/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/mobile v0.0.0-20211207041440-4e6c2922fdee/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ=
-golang.org/x/mobile v0.0.0-20240112133503-c713f31d574b h1:kfWLZgb8iUBHdE9WydD5V5dHIS/F6HjlBZNyJfn2bs4=
-golang.org/x/mobile v0.0.0-20240112133503-c713f31d574b/go.mod h1:4efzQnuA1nICq6h4kmZRMGzbPiP06lZvgADUu1VpJCE=
-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/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.2/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=
+golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
+golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/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-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-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-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
-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.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
-golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
-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/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-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
+golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
+golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 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/sync v0.0.0-20201207232520-09787c993a3a/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.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
-golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
-golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
+golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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-20181026203630-95b1ffbd15a5/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-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-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-20191005200804-aed5e4c7ecf9/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-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-20200905004654-be1d3432aa8f/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-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/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-20210630005230-0f9fa26af87c/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-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
-golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
-golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
-golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
+golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/text v0.3.0/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=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-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-20180917221912-90fa682c2a6e/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-20190328211700-ab21143f2384/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-20191112195655-aa38f8e97acc/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-20200619180055-7c47624df98f/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-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
-golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-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.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
-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=
-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/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
-google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
-google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
-google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
-google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
-google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
-google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
-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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-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-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
-google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
-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.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
-google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
-google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
-google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
-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/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
+golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 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/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 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.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-honnef.co/go/js/dom v0.0.0-20231112215516-51f43a291193 h1:BST3Y7yWfYPO8qqWhL2KtuqgRCbls6bIr4b4iFCg43I=
-honnef.co/go/js/dom v0.0.0-20231112215516-51f43a291193/go.mod h1:sUMDUKNB2ZcVjt92UnLy3cdGs+wDAcrPdV3JP6sVgA4=
-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=

+ 5 - 0
make.py

@@ -0,0 +1,5 @@
+cls
+go get -u ./...
+go mod tidy -compat=1.22.3
+go mod vendor
+go fmt ./...

+ 2 - 3
pkg/alias/alias.go

@@ -4,7 +4,6 @@ import (
 	"log"
 	"log"
 	"sync"
 	"sync"
 	"time"
 	"time"
-
 	"wartank/pkg/types"
 	"wartank/pkg/types"
 )
 )
 
 
@@ -40,7 +39,7 @@ func (сам *NetStat) makeTick() {
 	defer close(сам.chTick)
 	defer close(сам.chTick)
 	for {
 	for {
 		select {
 		select {
-		case <-сам.botNet.Кнт().Done():
+		case <-сам.botNet.Контекст().Done():
 			return
 			return
 		default:
 		default:
 			time.Sleep(time.Second * 5 * 60)
 			time.Sleep(time.Second * 5 * 60)
@@ -66,7 +65,7 @@ func (сам *NetStat) run() {
 	}
 	}
 	for range сам.chTick {
 	for range сам.chTick {
 		select {
 		select {
-		case <-сам.botNet.Кнт().Done():
+		case <-сам.botNet.Контекст().Done():
 			return
 			return
 		case <-сам.chTick:
 		case <-сам.chTick:
 			fnCalc()
 			fnCalc()

+ 1 - 2
pkg/components/scene_net/scene_web_worker/scene_web_worker.go

@@ -10,7 +10,6 @@ import (
 	"strings"
 	"strings"
 	"sync"
 	"sync"
 	"time"
 	"time"
-
 	"wartank/pkg/components/scene_net/netstat"
 	"wartank/pkg/components/scene_net/netstat"
 	"wartank/pkg/types"
 	"wartank/pkg/types"
 )
 )
@@ -40,7 +39,7 @@ func (сам *ВебВоркер) Получ(strLink string) ([]string, error) {
 	// if strLink == "https://wartank.ru/production/Mine" {
 	// if strLink == "https://wartank.ru/production/Mine" {
 	log.Printf("ВебВоркер.Получ(): link=%v\n", strLink)
 	log.Printf("ВебВоркер.Получ(): link=%v\n", strLink)
 	// }
 	// }
-	ctxCancel, fnCancel := context.WithTimeout(сам.botNet.Кнт(), time.Second*10)
+	ctxCancel, fnCancel := context.WithTimeout(сам.botNet.Контекст(), time.Second*10)
 	defer fnCancel()
 	defer fnCancel()
 	запрос, ош := http.NewRequestWithContext(ctxCancel, "GET", strLink, nil)
 	запрос, ош := http.NewRequestWithContext(ctxCancel, "GET", strLink, nil)
 	if ош != nil {
 	if ош != nil {

+ 1 - 2
pkg/components/sound/sound.go

@@ -4,7 +4,6 @@ package scene
 import (
 import (
 	"context"
 	"context"
 	"fmt"
 	"fmt"
-
 	"wartank/pkg/alias"
 	"wartank/pkg/alias"
 	"wartank/pkg/components/web_log"
 	"wartank/pkg/components/web_log"
 	"wartank/pkg/scene/scene_mode"
 	"wartank/pkg/scene/scene_mode"
@@ -28,7 +27,7 @@ func НовСцена(бот types.ИБот, сценаИмя alias.СценаИ
 	if сценаИмя == "" {
 	if сценаИмя == "" {
 		return nil, fmt.Errorf("НовСцена(): сценаИмя не задано")
 		return nil, fmt.Errorf("НовСцена(): сценаИмя не задано")
 	}
 	}
-	кнт, фнОтмена := context.WithCancel(бот.Кнт())
+	кнт, фнОтмена := context.WithCancel(бот.Контекст())
 	сам := &Сцена{
 	сам := &Сцена{
 		бот:      бот,
 		бот:      бот,
 		сценаИмя: сценаИмя,
 		сценаИмя: сценаИмя,

+ 0 - 0
pkg/scene/scene_mode/scene_mode.go → pkg/scene/scene_mode/scene_mode.go


+ 2 - 3
pkg/types/ibase.go

@@ -2,7 +2,6 @@ package types
 
 
 import (
 import (
 	"context"
 	"context"
-
 	"wartank/pkg/alias"
 	"wartank/pkg/alias"
 )
 )
 
 
@@ -32,8 +31,8 @@ type ИБот interface {
 	ЕслиПуск() bool
 	ЕслиПуск() bool
 	// Сервер -- возвращает ссылку на объект сервера
 	// Сервер -- возвращает ссылку на объект сервера
 	Сервер() ИСервер
 	Сервер() ИСервер
-	// Кнт -- возвращает контекст бота
-	Кнт() context.Context
+	// Контекст -- возвращает контекст бота
+	Контекст() context.Context
 	// Закончить -- отменяет контекст бота
 	// Закончить -- отменяет контекст бота
 	Закончить()
 	Закончить()
 }
 }

+ 1 - 1
pkg/types/ibot_cookie.go

@@ -7,7 +7,7 @@ import (
 // ИБотКуки -- куки серверного бота
 // ИБотКуки -- куки серверного бота
 type ИБотКуки interface {
 type ИБотКуки interface {
 	// Уст -- устанавливает куки бота
 	// Уст -- устанавливает куки бота
-	Уст(cook []*http.Cookie) error
+	Уст(куки []*http.Cookie) error
 	// Получ -- возвращает куки бота
 	// Получ -- возвращает куки бота
 	Получ() []*http.Cookie
 	Получ() []*http.Cookie
 }
 }

+ 1 - 2
pkg/types/ibot_net.go

@@ -2,7 +2,6 @@ package types
 
 
 import (
 import (
 	"context"
 	"context"
-
 	"wartank/pkg/components/safe_bool"
 	"wartank/pkg/components/safe_bool"
 )
 )
 
 
@@ -19,7 +18,7 @@ type ИБотСеть interface {
 	// ВебВоркер -- возвращает веб-воркер бота
 	// ВебВоркер -- возвращает веб-воркер бота
 	ВебВоркер() ИВебВоркер
 	ВебВоркер() ИВебВоркер
 	// Кнт -- контекст сетевого клиента
 	// Кнт -- контекст сетевого клиента
-	Кнт() context.Context
+	Контекст() context.Context
 	// Отмена -- вызывает отмену котекста сетевого клиента бота
 	// Отмена -- вызывает отмену котекста сетевого клиента бота
 	Отмена()
 	Отмена()
 	// Бот -- возвращает ссылку на бота
 	// Бот -- возвращает ссылку на бота

+ 2 - 2
pkg/types/iconvoy.go

@@ -7,8 +7,8 @@ package types
 // ИСервер -- интерфейс для приложения
 // ИСервер -- интерфейс для приложения
 type ИСервер interface {
 type ИСервер interface {
 	ИЯдро
 	ИЯдро
-	// Run -- запускает приложение в работу
-	Run() error
+	// Пуск -- запускает приложение в работу
+	Пуск() error
 	// ServBots -- словарь имеющихся ботов
 	// ServBots -- словарь имеющихся ботов
 	ServBots() ИБотоФерма
 	ServBots() ИБотоФерма
 	// Стат -- возвращает статистику сервера
 	// Стат -- возвращает статистику сервера

+ 3 - 5
pkg/types/iserver_stat.go

@@ -3,12 +3,10 @@ package angar
 import (
 import (
 	"fmt"
 	"fmt"
 	"log"
 	"log"
-	"sync"
-	"time"
-
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
-
+	"sync"
+	"time"
 	"wartank/pkg/section"
 	"wartank/pkg/section"
 	"wartank/pkg/types"
 	"wartank/pkg/types"
 	"wartank/server/serv_bots/warbot/angar/angarnet"
 	"wartank/server/serv_bots/warbot/angar/angarnet"
@@ -219,7 +217,7 @@ func (сам *Ангар) Пуск() error {
 		}
 		}
 		for {
 		for {
 			select {
 			select {
-			case <-сам.бот.Кнт().Done(): // Отмена контекста
+			case <-сам.бот.Контекст().Done(): // Отмена контекста
 				return
 				return
 			case <-сам.ВремяОстат().КаналСиг(): // Метка времени
 			case <-сам.ВремяОстат().КаналСиг(): // Метка времени
 				if !фнЦикл() {
 				if !фнЦикл() {

+ 1 - 2
server/serv_bots/warbot/angar/angarnet/angarnet.go

@@ -6,7 +6,6 @@ import (
 	"log"
 	"log"
 	"strings"
 	"strings"
 	"time"
 	"time"
-
 	"wartank/pkg/types"
 	"wartank/pkg/types"
 )
 )
 
 
@@ -36,7 +35,7 @@ func (сам *Лаборатория) пуск() {
 	time.Sleep(time.Millisecond * 4500)
 	time.Sleep(time.Millisecond * 4500)
 	for {
 	for {
 		select {
 		select {
-		case <-сам.бот.Кнт().Done():
+		case <-сам.бот.Контекст().Done():
 			return
 			return
 		default:
 		default:
 			сам.работать()
 			сам.работать()

+ 1 - 2
server/serv_bots/warbot/angar/base/market/market.go

@@ -7,7 +7,6 @@ import (
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
 	"time"
 	"time"
-
 	"wartank/pkg/alias"
 	"wartank/pkg/alias"
 	"wartank/pkg/section"
 	"wartank/pkg/section"
 	"wartank/pkg/types"
 	"wartank/pkg/types"
@@ -67,7 +66,7 @@ func (сам *Рынок) пуск() {
 	}
 	}
 	for {
 	for {
 		select {
 		select {
-		case <-сам.бот.Кнт().Done():
+		case <-сам.бот.Контекст().Done():
 			return
 			return
 		default:
 		default:
 			фнРабота()
 			фнРабота()

+ 1 - 2
server/serv_bots/warbot/angar/base/market/marketnet/marketnet.go

@@ -4,7 +4,6 @@ package battle
 import (
 import (
 	"fmt"
 	"fmt"
 	"time"
 	"time"
-
 	"wartank/pkg/section"
 	"wartank/pkg/section"
 	"wartank/pkg/types"
 	"wartank/pkg/types"
 	"wartank/server/serv_bots/warbot/angar/battle/battle_register"
 	"wartank/server/serv_bots/warbot/angar/battle/battle_register"
@@ -63,7 +62,7 @@ func (сам *Сражение) Пуск() error {
 func (сам *Сражение) пуск() {
 func (сам *Сражение) пуск() {
 	for {
 	for {
 		select {
 		select {
-		case <-сам.бот.Кнт().Done():
+		case <-сам.бот.Контекст().Done():
 			return
 			return
 		default:
 		default:
 			сам.регистрация.Зарегистрироваться()
 			сам.регистрация.Зарегистрироваться()

+ 1 - 2
server/serv_bots/warbot/angar/battle/battle_register/battle_register.go

@@ -4,7 +4,6 @@ import (
 	"context"
 	"context"
 	"fmt"
 	"fmt"
 	"time"
 	"time"
-
 	"wartank/pkg/components/scene_net"
 	"wartank/pkg/components/scene_net"
 	"wartank/pkg/section"
 	"wartank/pkg/section"
 	"wartank/pkg/types"
 	"wartank/pkg/types"
@@ -41,7 +40,7 @@ func НовСражениеДействие(бот types.ИБот) (*Сраже
 	}
 	}
 
 
 	// Ограничить время сражения бота
 	// Ограничить время сражения бота
-	кнтСражение, фнОтменить := context.WithTimeout(бот.Кнт(), time.Second*305)
+	кнтСражение, фнОтменить := context.WithTimeout(бот.Контекст(), time.Second*305)
 	сам := &СражениеДействие{
 	сам := &СражениеДействие{
 		Секция:      секция,
 		Секция:      секция,
 		бот:         бот,
 		бот:         бот,

+ 1 - 2
server/serv_bots/warbot/angar/battle/battle_worker/battleon/battlesound/battlesound.go

@@ -6,7 +6,6 @@ import (
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
 	"time"
 	"time"
-
 	"wartank/pkg/alias"
 	"wartank/pkg/alias"
 	"wartank/pkg/section"
 	"wartank/pkg/section"
 	"wartank/pkg/types"
 	"wartank/pkg/types"
@@ -76,7 +75,7 @@ func (сам *Конвой) пуск() {
 	}
 	}
 	for {
 	for {
 		select {
 		select {
-		case <-сам.бот.Кнт().Done():
+		case <-сам.бот.Контекст().Done():
 			return
 			return
 		default:
 		default:
 			фнЦикл()
 			фнЦикл()

+ 1 - 2
server/serv_bots/warbot/angar/convoy/convoynet/convoynet.go

@@ -4,7 +4,6 @@ package death_match
 import (
 import (
 	"fmt"
 	"fmt"
 	"time"
 	"time"
-
 	"wartank/pkg/section"
 	"wartank/pkg/section"
 	"wartank/pkg/types"
 	"wartank/pkg/types"
 	"wartank/server/serv_bots/warbot/angar/battle/battle_register"
 	"wartank/server/serv_bots/warbot/angar/battle/battle_register"
@@ -63,7 +62,7 @@ func (сам *Схватка) Пуск() error {
 func (сам *Схватка) пуск() {
 func (сам *Схватка) пуск() {
 	for {
 	for {
 		select {
 		select {
-		case <-сам.бот.Кнт().Done():
+		case <-сам.бот.Контекст().Done():
 			return
 			return
 		default:
 		default:
 			сам.регистрация.Зарегистрироваться()
 			сам.регистрация.Зарегистрироваться()

+ 1 - 2
server/serv_bots/warbot/angar/death_match/battle_wait/battle_wait.go

@@ -4,7 +4,6 @@ import (
 	"context"
 	"context"
 	"fmt"
 	"fmt"
 	"time"
 	"time"
-
 	"wartank/pkg/components/scene_net"
 	"wartank/pkg/components/scene_net"
 	"wartank/pkg/section"
 	"wartank/pkg/section"
 	"wartank/pkg/types"
 	"wartank/pkg/types"
@@ -41,7 +40,7 @@ func НовСхваткаДействие(бот types.ИБот) (*Схватк
 	}
 	}
 
 
 	// Ограничить время сражения бота
 	// Ограничить время сражения бота
-	кнтСражение, фнОтменить := context.WithTimeout(бот.Кнт(), time.Second*305)
+	кнтСражение, фнОтменить := context.WithTimeout(бот.Контекст(), time.Second*305)
 	сам := &СхваткаДействие{
 	сам := &СхваткаДействие{
 		Секция:      секция,
 		Секция:      секция,
 		бот:         бот,
 		бот:         бот,

+ 2 - 3
server/serv_bots/warbot/angar/death_match/death_worker/death_on/health/health.go

@@ -6,7 +6,6 @@ import (
 	"strings"
 	"strings"
 	"sync"
 	"sync"
 	"time"
 	"time"
-
 	"wartank/pkg/alias"
 	"wartank/pkg/alias"
 	"wartank/pkg/section"
 	"wartank/pkg/section"
 	"wartank/pkg/types"
 	"wartank/pkg/types"
@@ -77,7 +76,7 @@ func NewDivWar(bot types.ИБот) (*DivWar, error) {
 func (сам *DivWar) reservTick() {
 func (сам *DivWar) reservTick() {
 	for {
 	for {
 		select {
 		select {
-		case <-сам.bot.Кнт().Done():
+		case <-сам.bot.Контекст().Done():
 			return
 			return
 		default:
 		default:
 			ct0 := сам.ВремяОстат().ПолучМилСек()
 			ct0 := сам.ВремяОстат().ПолучМилСек()
@@ -99,7 +98,7 @@ func (сам *DivWar) run() {
 	сам.chDivWar <- 1
 	сам.chDivWar <- 1
 	for {
 	for {
 		select {
 		select {
-		case <-сам.bot.Кнт().Done():
+		case <-сам.bot.Контекст().Done():
 			return
 			return
 		case <-сам.ВремяОстат().КаналСиг(): // Время обновить данные по сражению
 		case <-сам.ВремяОстат().КаналСиг(): // Время обновить данные по сражению
 			сам.findTimeCount()
 			сам.findTimeCount()

+ 2 - 3
server/serv_bots/warbot/angar/division/divwar/divwarnet/divwarnet.go

@@ -5,7 +5,6 @@ import (
 	"fmt"
 	"fmt"
 	"strings"
 	"strings"
 	"time"
 	"time"
-
 	"wartank/pkg/components/safe_bool"
 	"wartank/pkg/components/safe_bool"
 	"wartank/pkg/components/scene_net"
 	"wartank/pkg/components/scene_net"
 	"wartank/pkg/section"
 	"wartank/pkg/section"
@@ -41,7 +40,7 @@ func NewDivWarOn(bot types.ИБот) (*DivWarOn, error) {
 	if bot == nil {
 	if bot == nil {
 		return nil, fmt.Errorf("NewDivWarOn(): IBot == nil")
 		return nil, fmt.Errorf("NewDivWarOn(): IBot == nil")
 	}
 	}
-	ctxDivWar, fnCancelDivWar := context.WithTimeout(bot.Кнт(), time.Second*305)
+	ctxDivWar, fnCancelDivWar := context.WithTimeout(bot.Контекст(), time.Second*305)
 	сам := &DivWarOn{
 	сам := &DivWarOn{
 		bot:            bot,
 		bot:            bot,
 		ctxDivWar:      ctxDivWar,
 		ctxDivWar:      ctxDivWar,
@@ -77,7 +76,7 @@ func (сам *DivWarOn) makeTick() {
 	}()
 	}()
 	for !сам.isEnd.Получ() {
 	for !сам.isEnd.Получ() {
 		select {
 		select {
-		case <-сам.bot.Кнт().Done(): // Отмена контекста приложения
+		case <-сам.bot.Контекст().Done(): // Отмена контекста приложения
 			return
 			return
 		case <-сам.ctxDivWar.Done(): // Битва закончилась
 		case <-сам.ctxDivWar.Done(): // Битва закончилась
 			return
 			return

+ 1 - 2
server/serv_bots/warbot/angar/division/divwar/divwaron/divwarsound/divwarsound.go

@@ -5,7 +5,6 @@ import (
 	"log"
 	"log"
 	"strings"
 	"strings"
 	"time"
 	"time"
-
 	"wartank/pkg/alias"
 	"wartank/pkg/alias"
 	"wartank/pkg/section"
 	"wartank/pkg/section"
 	"wartank/pkg/types"
 	"wartank/pkg/types"
@@ -57,7 +56,7 @@ func (сам *БитваМастеров) Run() error {
 		for {
 		for {
 			time.Sleep(time.Second * 10)
 			time.Sleep(time.Second * 10)
 			select {
 			select {
-			case <-сам.бот.Кнт().Done():
+			case <-сам.бот.Контекст().Done():
 				return
 				return
 			case <-сам.ВремяОстат().КаналСиг():
 			case <-сам.ВремяОстат().КаналСиг():
 				if !сам.goBatMas() { // Проверка на начало сражения
 				if !сам.goBatMas() { // Проверка на начало сражения

+ 1 - 2
server/serv_bots/warbot/angar/masters/batmasnet/batmasnet.go

@@ -5,7 +5,6 @@ import (
 	"log"
 	"log"
 	"strings"
 	"strings"
 	"time"
 	"time"
-
 	"wartank/pkg/section"
 	"wartank/pkg/section"
 	"wartank/pkg/types"
 	"wartank/pkg/types"
 	"wartank/server/serv_bots/warbot/angar/missions/missionsnet"
 	"wartank/server/serv_bots/warbot/angar/missions/missionsnet"
@@ -51,7 +50,7 @@ func (сам *Миссии) пуск() {
 	for { // Время истекло
 	for { // Время истекло
 		// time.Sleep(time.Minute * 1)
 		// time.Sleep(time.Minute * 1)
 		select {
 		select {
-		case <-сам.бот.Кнт().Done():
+		case <-сам.бот.Контекст().Done():
 			return
 			return
 		default:
 		default:
 			сам.проверНаграда()
 			сам.проверНаграда()

+ 1 - 2
server/serv_bots/warbot/angar/missions/missionsnet/missionsnet.go

@@ -7,7 +7,6 @@ import (
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
 	"time"
 	"time"
-
 	"wartank/pkg/types"
 	"wartank/pkg/types"
 )
 )
 
 
@@ -44,7 +43,7 @@ func (сам *ТанкПараметры) пуск() {
 	}
 	}
 	for {
 	for {
 		select {
 		select {
-		case <-сам.бот.Кнт().Done():
+		case <-сам.бот.Контекст().Done():
 			return
 			return
 		default:
 		default:
 			сам.работать()
 			сам.работать()

+ 2 - 3
server/serv_bots/warbot/tank_stat/static_param/static_param.go

@@ -7,7 +7,6 @@ import (
 	"log"
 	"log"
 	"strings"
 	"strings"
 	"time"
 	"time"
-
 	"wartank/pkg/alias"
 	"wartank/pkg/alias"
 	"wartank/pkg/components/safe_bool"
 	"wartank/pkg/components/safe_bool"
 	"wartank/pkg/types"
 	"wartank/pkg/types"
@@ -232,8 +231,8 @@ func (сам *ВарБот) сохрКонфиг() {
 	}
 	}
 }
 }
 
 
-// Кнт -- возвращает контекст бота
-func (сам *ВарБот) Кнт() context.Context {
+// Контекст -- возвращает контекст бота
+func (сам *ВарБот) Контекст() context.Context {
 	return сам.кнт
 	return сам.кнт
 }
 }
 
 

BIN
server/serv_bots/warbot/warbot_config/warbot_config.go


BIN
server/serv_bots/warbot/warbot_net/bot_net_conn/bot_net_conn.go


+ 3 - 4
server/serv_bots/warbot/warbot_net/warbot_net.go

@@ -4,7 +4,6 @@ import (
 	"context"
 	"context"
 	"fmt"
 	"fmt"
 	"log"
 	"log"
-
 	"wartank/pkg/components/safe_bool"
 	"wartank/pkg/components/safe_bool"
 	"wartank/pkg/components/scene_net/web_worker"
 	"wartank/pkg/components/scene_net/web_worker"
 	"wartank/pkg/types"
 	"wartank/pkg/types"
@@ -33,7 +32,7 @@ func НовВарБотСеть(бот types.ИБот) (types.ИБотСеть,
 		return nil, fmt.Errorf("НовВарБотСеть(): IBot == nil")
 		return nil, fmt.Errorf("НовВарБотСеть(): IBot == nil")
 	}
 	}
 	log.Printf("НовВарБотСеть(): имя=%q\n", бот.Имя())
 	log.Printf("НовВарБотСеть(): имя=%q\n", бот.Имя())
-	ctx, фнОтмена := context.WithCancel(бот.Кнт())
+	ctx, фнОтмена := context.WithCancel(бот.Контекст())
 	сам := &ВарБотСеть{
 	сам := &ВарБотСеть{
 		бот:        бот,
 		бот:        бот,
 		вебСокет:   bot_web_conn.НовБотВебСокет(),
 		вебСокет:   bot_web_conn.НовБотВебСокет(),
@@ -58,8 +57,8 @@ func (сам *ВарБотСеть) Бот() types.ИБот {
 	return сам.бот
 	return сам.бот
 }
 }
 
 
-// Кнт -- контекст сети бота
-func (сам *ВарБотСеть) Кнт() context.Context {
+// Контекст -- контекст сети бота
+func (сам *ВарБотСеть) Контекст() context.Context {
 	return сам.ctx
 	return сам.ctx
 }
 }
 
 

+ 2 - 3
server/serv_desktop.zip

@@ -3,7 +3,6 @@ package server
 
 
 import (
 import (
 	"fmt"
 	"fmt"
-
 	"wartank/pkg/components/kernel"
 	"wartank/pkg/components/kernel"
 	"wartank/pkg/types"
 	"wartank/pkg/types"
 	"wartank/server/serv_bots"
 	"wartank/server/serv_bots"
@@ -43,8 +42,8 @@ func НовСервер() (*Сервер, error) {
 	return сам, nil
 	return сам, nil
 }
 }
 
 
-// Run -- запускает сервер бота в работу
-func (сам *Сервер) Run() error {
+// Пуск -- запускает сервер бота в работу
+func (сам *Сервер) Пуск() error {
 	сам.сервВеб.Пуск()
 	сам.сервВеб.Пуск()
 	<-сам.Done()
 	<-сам.Done()
 	return nil
 	return nil

+ 41 - 0
server/server_stat/server_stat.go

@@ -3,6 +3,47 @@
 This file lists the main changes with each version of the Fyne toolkit.
 This file lists the main changes with each version of the Fyne toolkit.
 More detailed release notes can be found on the [releases page](https://github.com/fyne-io/fyne/releases). 
 More detailed release notes can be found on the [releases page](https://github.com/fyne-io/fyne/releases). 
 
 
+## 2.4.5 - 15 April 2024
+
+### Fixed
+
+* iOS files write would fail when over 16KB
+* storage.Delete not supported on Android/iOS (#2120)
+* layout.formLayout do not handle canvas.Text well in second column (#4665)
+* Fix building with ios17.4 (#4741)
+* Support template icon for system tray menu icons
+* Fix recognition of missing XDG user directories (#4650)
+* FileDialog.SetOnClosed not always working (#4651)
+* Upgrade GLFW for performance improvements and bug fixes
+* Multiple select popups can crash during background operations (#4730)
+* Controlling a negative slider with the left arrow key blocks after 8 steps (#4736)
+* cmd/fyne: command "get" is broken with Go 1.22 (#4684)
+* Race condition during system tray menu refresh (#4697)
+* Fyne release on Linux does not set Metadata().Release to true (#4711)
+* RichText leaks memory when replacing segments (#4723)
+
+
+## 2.4.4 - 13 February 2024
+
+### Fixed
+
+* Spaces could be appended to linux Exec command during packaging
+* Secondary mobile windows would not size correctly when padded
+* Setting Icon.Resource to nil will not clear rendering
+* Dismiss iOS keyboard if "Done" is tapped
+* Large speed improvement in Entry and GridWrap widgets
+* tests fail with macOS Assertion failure in NSMenu (#4572)
+* Fix image test failures on Apple Silicon
+* High CPU use when showing CustomDialogs (#4574)
+* Entry does not show the last (few) changes when updating a binding.String in a fast succession (#4082)
+* Calling Entry.SetText and then Entry.Bind immediately will ignore the bound value (#4235)
+* Changing theme while application is running doesn't change some parameters on some widgets (#4344)
+* Check widget: hovering/tapping to the right of the label area should not activate widget (#4527)
+* Calling entry.SetPlaceHolder inside of OnChanged callback freezes app (#4516)
+* Hyperlink enhancement: underline and tappable area shouldn't be wider than the text label (#3528)
+* Fix possible compile error from go-text/typesetting
+
+
 ## 2.4.3 - 23 December 2023
 ## 2.4.3 - 23 December 2023
 
 
 ### Fixed
 ### Fixed

+ 0 - 169
vendor/fyne.io/fyne/v2/app/app.go

@@ -1,169 +0,0 @@
-// Package app provides app implementations for working with Fyne graphical interfaces.
-// The fastest way to get started is to call app.New() which will normally load a new desktop application.
-// If the "ci" tag is passed to go (go run -tags ci myapp.go) it will run an in-memory application.
-package app // import "fyne.io/fyne/v2/app"
-
-import (
-	"os"
-	"strconv"
-	"sync/atomic"
-	"time"
-
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/internal"
-	"fyne.io/fyne/v2/internal/app"
-	intRepo "fyne.io/fyne/v2/internal/repository"
-	"fyne.io/fyne/v2/storage/repository"
-)
-
-// Declare conformity with App interface
-var _ fyne.App = (*fyneApp)(nil)
-
-type fyneApp struct {
-	driver   fyne.Driver
-	icon     fyne.Resource
-	uniqueID string
-
-	cloud     fyne.CloudProvider
-	lifecycle fyne.Lifecycle
-	settings  *settings
-	storage   fyne.Storage
-	prefs     fyne.Preferences
-
-	running uint32 // atomic, 1 == running, 0 == stopped
-}
-
-func (a *fyneApp) CloudProvider() fyne.CloudProvider {
-	return a.cloud
-}
-
-func (a *fyneApp) Icon() fyne.Resource {
-	if a.icon != nil {
-		return a.icon
-	}
-
-	return a.Metadata().Icon
-}
-
-func (a *fyneApp) SetIcon(icon fyne.Resource) {
-	a.icon = icon
-}
-
-func (a *fyneApp) UniqueID() string {
-	if a.uniqueID != "" {
-		return a.uniqueID
-	}
-	if a.Metadata().ID != "" {
-		return a.Metadata().ID
-	}
-
-	fyne.LogError("Preferences API requires a unique ID, use app.NewWithID() or the FyneApp.toml ID field", nil)
-	a.uniqueID = "missing-id-" + strconv.FormatInt(time.Now().Unix(), 10) // This is a fake unique - it just has to not be reused...
-	return a.uniqueID
-}
-
-func (a *fyneApp) NewWindow(title string) fyne.Window {
-	return a.driver.CreateWindow(title)
-}
-
-func (a *fyneApp) Run() {
-	if atomic.CompareAndSwapUint32(&a.running, 0, 1) {
-		a.driver.Run()
-	}
-}
-
-func (a *fyneApp) Quit() {
-	for _, window := range a.driver.AllWindows() {
-		window.Close()
-	}
-
-	a.driver.Quit()
-	a.settings.stopWatching()
-	atomic.StoreUint32(&a.running, 0)
-}
-
-func (a *fyneApp) Driver() fyne.Driver {
-	return a.driver
-}
-
-// Settings returns the application settings currently configured.
-func (a *fyneApp) Settings() fyne.Settings {
-	return a.settings
-}
-
-func (a *fyneApp) Storage() fyne.Storage {
-	return a.storage
-}
-
-func (a *fyneApp) Preferences() fyne.Preferences {
-	if a.UniqueID() == "" {
-		fyne.LogError("Preferences API requires a unique ID, use app.NewWithID() or the FyneApp.toml ID field", nil)
-	}
-	return a.prefs
-}
-
-func (a *fyneApp) Lifecycle() fyne.Lifecycle {
-	return a.lifecycle
-}
-
-func (a *fyneApp) newDefaultPreferences() *preferences {
-	p := newPreferences(a)
-	if a.uniqueID != "" {
-		p.load()
-	}
-	return p
-}
-
-// New returns a new application instance with the default driver and no unique ID (unless specified in FyneApp.toml)
-func New() fyne.App {
-	if meta.ID == "" {
-		internal.LogHint("Applications should be created with a unique ID using app.NewWithID()")
-	}
-	return NewWithID(meta.ID)
-}
-
-func makeStoreDocs(id string, s *store) *internal.Docs {
-	if id != "" {
-		err := os.MkdirAll(s.a.storageRoot(), 0755) // make the space before anyone can use it
-		if err != nil {
-			fyne.LogError("Failed to create app storage space", err)
-		}
-
-		root, _ := s.docRootURI()
-		return &internal.Docs{RootDocURI: root}
-	} else {
-		return &internal.Docs{} // an empty impl to avoid crashes
-	}
-}
-
-func newAppWithDriver(d fyne.Driver, id string) fyne.App {
-	newApp := &fyneApp{uniqueID: id, driver: d, lifecycle: &app.Lifecycle{}}
-	fyne.SetCurrentApp(newApp)
-
-	newApp.prefs = newApp.newDefaultPreferences()
-	newApp.lifecycle.(*app.Lifecycle).SetOnStoppedHookExecuted(func() {
-		if prefs, ok := newApp.prefs.(*preferences); ok {
-			prefs.forceImmediateSave()
-		}
-	})
-	newApp.settings = loadSettings()
-	store := &store{a: newApp}
-	store.Docs = makeStoreDocs(id, store)
-	newApp.storage = store
-
-	if !d.Device().IsMobile() {
-		newApp.settings.watchSettings()
-	}
-
-	httpHandler := intRepo.NewHTTPRepository()
-	repository.Register("http", httpHandler)
-	repository.Register("https", httpHandler)
-
-	return newApp
-}
-
-// marker interface to pass system tray to supporting drivers
-type systrayDriver interface {
-	SetSystemTrayMenu(*fyne.Menu)
-	SetSystemTrayIcon(resource fyne.Resource)
-}

+ 0 - 60
vendor/fyne.io/fyne/v2/app/app_darwin.go

@@ -1,60 +0,0 @@
-//go:build !ci && !js && !wasm && !test_web_driver
-// +build !ci,!js,!wasm,!test_web_driver
-
-package app
-
-/*
-#cgo CFLAGS: -x objective-c
-#cgo LDFLAGS: -framework Foundation
-
-#include <stdbool.h>
-#include <stdlib.h>
-
-bool isBundled();
-void sendNotification(char *title, char *content);
-*/
-import "C"
-import (
-	"fmt"
-	"strings"
-	"unsafe"
-
-	"fyne.io/fyne/v2"
-	"golang.org/x/sys/execabs"
-)
-
-func (a *fyneApp) SendNotification(n *fyne.Notification) {
-	if C.isBundled() {
-		titleStr := C.CString(n.Title)
-		defer C.free(unsafe.Pointer(titleStr))
-		contentStr := C.CString(n.Content)
-		defer C.free(unsafe.Pointer(contentStr))
-
-		C.sendNotification(titleStr, contentStr)
-		return
-	}
-
-	fallbackNotification(n.Title, n.Content)
-}
-
-func escapeNotificationString(in string) string {
-	noSlash := strings.ReplaceAll(in, "\\", "\\\\")
-	return strings.ReplaceAll(noSlash, "\"", "\\\"")
-}
-
-//export fallbackSend
-func fallbackSend(cTitle, cContent *C.char) {
-	title := C.GoString(cTitle)
-	content := C.GoString(cContent)
-	fallbackNotification(title, content)
-}
-
-func fallbackNotification(title, content string) {
-	template := `display notification "%s" with title "%s"`
-	script := fmt.Sprintf(template, escapeNotificationString(content), escapeNotificationString(title))
-
-	err := execabs.Command("osascript", "-e", script).Start()
-	if err != nil {
-		fyne.LogError("Failed to launch darwin notify script", err)
-	}
-}

+ 0 - 61
vendor/fyne.io/fyne/v2/app/app_darwin.m

@@ -1,61 +0,0 @@
-//go:build !ci
-// +build !ci
-
-#import <Foundation/Foundation.h>
-#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
-#import <UserNotifications/UserNotifications.h>
-#endif
-
-static int notifyNum = 0;
-
-extern void fallbackSend(char *cTitle, char *cBody);
-
-bool isBundled() {
-    return [[NSBundle mainBundle] bundleIdentifier] != nil;
-}
-
-#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
-void doSendNotification(UNUserNotificationCenter *center, NSString *title, NSString *body) {
-    UNMutableNotificationContent *content = [UNMutableNotificationContent new];
-    [content autorelease];
-    content.title = title;
-    content.body = body;
-
-    notifyNum++;
-    NSString *identifier = [NSString stringWithFormat:@"fyne-notify-%d", notifyNum];
-    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:identifier
-        content:content trigger:nil];
-
-    [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
-        if (error != nil) {
-            NSLog(@"Could not send notification: %@", error);
-        }
-    }];
-}
-
-void sendNotification(char *cTitle, char *cBody) {
-    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
-    NSString *title = [NSString stringWithUTF8String:cTitle];
-    NSString *body = [NSString stringWithUTF8String:cBody];
-
-    UNAuthorizationOptions options = UNAuthorizationOptionAlert;
-    [center requestAuthorizationWithOptions:options
-        completionHandler:^(BOOL granted, NSError *_Nullable error) {
-            if (!granted) {
-                if (error != NULL) {
-                    NSLog(@"Error asking for permission to send notifications %@", error);
-                    // this happens if our app was not signed, so do it the old way
-                    fallbackSend((char *)[title UTF8String], (char *)[body UTF8String]);
-                } else {
-                    NSLog(@"Unable to get permission to send notifications");
-                }
-            } else {
-                doSendNotification(center, title, body);
-            }
-        }];
-}
-#else
-void sendNotification(char *cTitle, char *cBody) {
-	fallbackSend(cTitle, cBody);
-}
-#endif

+ 0 - 8
vendor/fyne.io/fyne/v2/app/app_debug.go

@@ -1,8 +0,0 @@
-//go:build debug
-// +build debug
-
-package app
-
-import "fyne.io/fyne/v2"
-
-const buildMode = fyne.BuildDebug

+ 0 - 69
vendor/fyne.io/fyne/v2/app/app_desktop_darwin.go

@@ -1,69 +0,0 @@
-//go:build !ci && !ios && !js && !wasm && !test_web_driver
-// +build !ci,!ios,!js,!wasm,!test_web_driver
-
-package app
-
-/*
-#cgo CFLAGS: -x objective-c
-#cgo LDFLAGS: -framework Foundation
-
-#include <AppKit/AppKit.h>
-
-bool isBundled();
-bool isDarkMode();
-void watchTheme();
-*/
-import "C"
-import (
-	"net/url"
-	"os"
-	"path/filepath"
-
-	"golang.org/x/sys/execabs"
-
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/theme"
-)
-
-// SetSystemTrayMenu creates a system tray item and attaches the specified menu.
-// By default this will use the application icon.
-func (a *fyneApp) SetSystemTrayMenu(menu *fyne.Menu) {
-	if desk, ok := a.Driver().(systrayDriver); ok {
-		desk.SetSystemTrayMenu(menu)
-	}
-}
-
-// SetSystemTrayIcon sets a custom image for the system tray icon.
-// You should have previously called `SetSystemTrayMenu` to initialise the menu icon.
-func (a *fyneApp) SetSystemTrayIcon(icon fyne.Resource) {
-	a.Driver().(systrayDriver).SetSystemTrayIcon(icon)
-}
-
-func defaultVariant() fyne.ThemeVariant {
-	if C.isDarkMode() {
-		return theme.VariantDark
-	}
-	return theme.VariantLight
-}
-
-func rootConfigDir() string {
-	homeDir, _ := os.UserHomeDir()
-
-	desktopConfig := filepath.Join(filepath.Join(homeDir, "Library"), "Preferences")
-	return filepath.Join(desktopConfig, "fyne")
-}
-
-func (a *fyneApp) OpenURL(url *url.URL) error {
-	cmd := execabs.Command("open", url.String())
-	cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
-	return cmd.Run()
-}
-
-//export themeChanged
-func themeChanged() {
-	fyne.CurrentApp().Settings().(*settings).setupTheme()
-}
-
-func watchTheme() {
-	C.watchTheme()
-}

+ 0 - 18
vendor/fyne.io/fyne/v2/app/app_desktop_darwin.m

@@ -1,18 +0,0 @@
-//go:build !ci && !ios
-// +build !ci,!ios
-
-extern void themeChanged();
-
-#import <Foundation/Foundation.h>
-
-bool isDarkMode() {
-    NSString *style = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
-    return [@"Dark" isEqualToString:style];
-}
-
-void watchTheme() {
-    [[NSDistributedNotificationCenter defaultCenter] addObserverForName:@"AppleInterfaceThemeChangedNotification" object:nil queue:nil
-        usingBlock:^(NSNotification *note) {
-        themeChanged(); // calls back into Go
-    }];
-}

+ 0 - 15
vendor/fyne.io/fyne/v2/app/app_gl.go

@@ -1,15 +0,0 @@
-//go:build !ci && !android && !ios && !mobile
-// +build !ci,!android,!ios,!mobile
-
-package app
-
-import (
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/internal/driver/glfw"
-)
-
-// NewWithID returns a new app instance using the appropriate runtime driver.
-// The ID string should be globally unique to this app.
-func NewWithID(id string) fyne.App {
-	return newAppWithDriver(glfw.NewGLDriver(), id)
-}

+ 0 - 19
vendor/fyne.io/fyne/v2/app/app_goxjs.go

@@ -1,19 +0,0 @@
-//go:build !ci && (!android || !ios || !mobile) && (js || wasm || test_web_driver)
-// +build !ci
-// +build !android !ios !mobile
-// +build js wasm test_web_driver
-
-package app
-
-import (
-	"fyne.io/fyne/v2"
-)
-
-func (app *fyneApp) SendNotification(_ *fyne.Notification) {
-	// TODO #2735
-	fyne.LogError("Sending notification is not supported yet.", nil)
-}
-
-func rootConfigDir() string {
-	return "/data/"
-}

+ 0 - 25
vendor/fyne.io/fyne/v2/app/app_mobile.go

@@ -1,25 +0,0 @@
-//go:build !ci && (android || ios || mobile)
-// +build !ci
-// +build android ios mobile
-
-package app
-
-import (
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/internal/driver/mobile"
-)
-
-var systemTheme fyne.ThemeVariant
-
-// NewWithID returns a new app instance using the appropriate runtime driver.
-// The ID string should be globally unique to this app.
-func NewWithID(id string) fyne.App {
-	d := mobile.NewGoMobileDriver()
-	a := newAppWithDriver(d, id)
-	d.(mobile.ConfiguredDriver).SetOnConfigurationChanged(func(c *mobile.Configuration) {
-		systemTheme = c.SystemTheme
-
-		a.Settings().(*settings).setupTheme()
-	})
-	return a
-}

+ 0 - 131
vendor/fyne.io/fyne/v2/app/app_mobile_and.c

@@ -1,131 +0,0 @@
-//go:build !ci && android
-// +build !ci,android
-
-#include <android/log.h>
-#include <jni.h>
-#include <stdbool.h>
-#include <stdlib.h>
-
-#define LOG_FATAL(...) __android_log_print(ANDROID_LOG_FATAL, "Fyne", __VA_ARGS__)
-
-static jclass find_class(JNIEnv *env, const char *class_name) {
-	jclass clazz = (*env)->FindClass(env, class_name);
-	if (clazz == NULL) {
-		(*env)->ExceptionClear(env);
-		LOG_FATAL("cannot find %s", class_name);
-		return NULL;
-	}
-	return clazz;
-}
-
-static jmethodID find_method(JNIEnv *env, jclass clazz, const char *name, const char *sig) {
-	jmethodID m = (*env)->GetMethodID(env, clazz, name, sig);
-	if (m == 0) {
-		(*env)->ExceptionClear(env);
-		LOG_FATAL("cannot find method %s %s", name, sig);
-		return 0;
-	}
-	return m;
-}
-
-static jmethodID find_static_method(JNIEnv *env, jclass clazz, const char *name, const char *sig) {
-	jmethodID m = (*env)->GetStaticMethodID(env, clazz, name, sig);
-	if (m == 0) {
-		(*env)->ExceptionClear(env);
-		LOG_FATAL("cannot find method %s %s", name, sig);
-		return 0;
-	}
-	return m;
-}
-
-jobject getSystemService(uintptr_t jni_env, uintptr_t ctx, char *service) {
-	JNIEnv *env = (JNIEnv*)jni_env;
-	jstring serviceStr = (*env)->NewStringUTF(env, service);
-
-	jclass ctxClass = (*env)->GetObjectClass(env, (jobject)ctx);
-	jmethodID getSystemService = find_method(env, ctxClass, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
-
-	return (jobject)(*env)->CallObjectMethod(env, (jobject)ctx, getSystemService, serviceStr);
-}
-
-int nextId = 1;
-
-bool isOreoOrLater(JNIEnv *env) {
-    jclass versionClass = find_class(env, "android/os/Build$VERSION" );
-    jfieldID sdkIntFieldID = (*env)->GetStaticFieldID(env, versionClass, "SDK_INT", "I" );
-    int sdkVersion = (*env)->GetStaticIntField(env, versionClass, sdkIntFieldID );
-
-    return sdkVersion >= 26; // O = Oreo, will not be defined for older builds
-}
-
-jobject parseURL(uintptr_t jni_env, uintptr_t ctx, char* uriCstr) {
-	JNIEnv *env = (JNIEnv*)jni_env;
-
-	jstring uriStr = (*env)->NewStringUTF(env, uriCstr);
-	jclass uriClass = find_class(env, "android/net/Uri");
-	jmethodID parse = find_static_method(env, uriClass, "parse", "(Ljava/lang/String;)Landroid/net/Uri;");
-
-	return (jobject)(*env)->CallStaticObjectMethod(env, uriClass, parse, uriStr);
-}
-
-void openURL(uintptr_t java_vm, uintptr_t jni_env, uintptr_t ctx, char *url) {
-	JNIEnv *env = (JNIEnv*)jni_env;
-	jobject uri = parseURL(jni_env, ctx, url);
-
-	jclass intentClass = find_class(env, "android/content/Intent");
-	jfieldID viewFieldID = (*env)->GetStaticFieldID(env, intentClass, "ACTION_VIEW", "Ljava/lang/String;" );
-    jstring view = (*env)->GetStaticObjectField(env, intentClass, viewFieldID);
-
-	jmethodID constructor = find_method(env, intentClass, "<init>", "(Ljava/lang/String;Landroid/net/Uri;)V");
-	jobject intent = (*env)->NewObject(env, intentClass, constructor, view, uri);
-
-	jclass contextClass = find_class(env, "android/content/Context");
-	jmethodID start = find_method(env, contextClass, "startActivity", "(Landroid/content/Intent;)V");
-	(*env)->CallVoidMethod(env, (jobject)ctx, start, intent);
-}
-
-void sendNotification(uintptr_t java_vm, uintptr_t jni_env, uintptr_t ctx, char *title, char *body) {
-	JNIEnv *env = (JNIEnv*)jni_env;
-	jstring titleStr = (*env)->NewStringUTF(env, title);
-	jstring bodyStr = (*env)->NewStringUTF(env, body);
-
-	jclass cls = find_class(env, "android/app/Notification$Builder");
-	jmethodID constructor = find_method(env, cls, "<init>", "(Landroid/content/Context;)V");
-	jobject builder = (*env)->NewObject(env, cls, constructor, ctx);
-
-	jclass mgrCls = find_class(env, "android/app/NotificationManager");
-	jobject mgr = getSystemService((uintptr_t)env, ctx, "notification");
-
-	if (isOreoOrLater(env)) {
-		jstring channelId = (*env)->NewStringUTF(env, "fyne-notif");
-		jstring name = (*env)->NewStringUTF(env, "Fyne Notification");
-        int importance = 4; // IMPORTANCE_HIGH
-
-		jclass chanCls = find_class(env, "android/app/NotificationChannel");
-		jmethodID constructor = find_method(env, chanCls, "<init>", "(Ljava/lang/String;Ljava/lang/CharSequence;I)V");
-		jobject channel = (*env)->NewObject(env, chanCls, constructor, channelId, name, importance);
-
-		jmethodID createChannel = find_method(env, mgrCls, "createNotificationChannel", "(Landroid/app/NotificationChannel;)V");
-		(*env)->CallVoidMethod(env, mgr, createChannel, channel);
-
-		jmethodID setChannelId = find_method(env, cls, "setChannelId", "(Ljava/lang/String;)Landroid/app/Notification$Builder;");
-		(*env)->CallObjectMethod(env, builder, setChannelId, channelId);
-	}
-
-	jmethodID setContentTitle = find_method(env, cls, "setContentTitle", "(Ljava/lang/CharSequence;)Landroid/app/Notification$Builder;");
-	(*env)->CallObjectMethod(env, builder, setContentTitle, titleStr);
-
-	jmethodID setContentText = find_method(env, cls, "setContentText", "(Ljava/lang/CharSequence;)Landroid/app/Notification$Builder;");
-	(*env)->CallObjectMethod(env, builder, setContentText, bodyStr);
-
-	int iconID = 17629184; // constant of "unknown app icon"
-	jmethodID setSmallIcon = find_method(env, cls, "setSmallIcon", "(I)Landroid/app/Notification$Builder;");
-	(*env)->CallObjectMethod(env, builder, setSmallIcon, iconID);
-
-	jmethodID build = find_method(env, cls, "build", "()Landroid/app/Notification;");
-	jobject notif = (*env)->CallObjectMethod(env, builder, build);
-
-	jmethodID notify = find_method(env, mgrCls, "notify", "(ILandroid/app/Notification;)V");
-	(*env)->CallVoidMethod(env, mgr, notify, nextId, notif);
-	nextId++;
-}

+ 0 - 61
vendor/fyne.io/fyne/v2/app/app_mobile_and.go

@@ -1,61 +0,0 @@
-//go:build !ci && android
-// +build !ci,android
-
-package app
-
-/*
-#cgo LDFLAGS: -landroid -llog
-
-#include <stdlib.h>
-
-void openURL(uintptr_t java_vm, uintptr_t jni_env, uintptr_t ctx, char *url);
-void sendNotification(uintptr_t java_vm, uintptr_t jni_env, uintptr_t ctx, char *title, char *content);
-*/
-import "C"
-import (
-	"log"
-	"net/url"
-	"os"
-	"path/filepath"
-	"unsafe"
-
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/internal/driver/mobile/app"
-)
-
-func (a *fyneApp) OpenURL(url *url.URL) error {
-	urlStr := C.CString(url.String())
-	defer C.free(unsafe.Pointer(urlStr))
-
-	app.RunOnJVM(func(vm, env, ctx uintptr) error {
-		C.openURL(C.uintptr_t(vm), C.uintptr_t(env), C.uintptr_t(ctx), urlStr)
-		return nil
-	})
-	return nil
-}
-
-func (a *fyneApp) SendNotification(n *fyne.Notification) {
-	titleStr := C.CString(n.Title)
-	defer C.free(unsafe.Pointer(titleStr))
-	contentStr := C.CString(n.Content)
-	defer C.free(unsafe.Pointer(contentStr))
-
-	app.RunOnJVM(func(vm, env, ctx uintptr) error {
-		C.sendNotification(C.uintptr_t(vm), C.uintptr_t(env), C.uintptr_t(ctx), titleStr, contentStr)
-		return nil
-	})
-}
-
-func defaultVariant() fyne.ThemeVariant {
-	return systemTheme
-}
-
-func rootConfigDir() string {
-	filesDir := os.Getenv("FILESDIR")
-	if filesDir == "" {
-		log.Println("FILESDIR env was not set by android native code")
-		return "/data/data" // probably won't work, but we can't make a better guess
-	}
-
-	return filepath.Join(filesDir, "fyne")
-}

+ 0 - 40
vendor/fyne.io/fyne/v2/app/app_mobile_ios.go

@@ -1,40 +0,0 @@
-//go:build !ci && ios
-// +build !ci,ios
-
-package app
-
-/*
-#cgo CFLAGS: -x objective-c
-#cgo LDFLAGS: -framework Foundation -framework UIKit -framework UserNotifications
-
-#include <stdlib.h>
-
-char *documentsPath(void);
-void openURL(char *urlStr);
-void sendNotification(char *title, char *content);
-*/
-import "C"
-import (
-	"net/url"
-	"path/filepath"
-	"unsafe"
-
-	"fyne.io/fyne/v2"
-)
-
-func rootConfigDir() string {
-	root := C.documentsPath()
-	return filepath.Join(C.GoString(root), "fyne")
-}
-
-func (a *fyneApp) OpenURL(url *url.URL) error {
-	urlStr := C.CString(url.String())
-	C.openURL(urlStr)
-	C.free(unsafe.Pointer(urlStr))
-
-	return nil
-}
-
-func defaultVariant() fyne.ThemeVariant {
-	return systemTheme
-}

+ 0 - 16
vendor/fyne.io/fyne/v2/app/app_mobile_ios.m

@@ -1,16 +0,0 @@
-//go:build !ci && ios
-// +build !ci,ios
-
-#import <UIKit/UIKit.h>
-
-void openURL(char *urlStr) {
-    UIApplication *app = [UIApplication sharedApplication];
-    NSURL *url = [NSURL URLWithString:[NSString stringWithUTF8String:urlStr]];
-    [app openURL:url options:@{} completionHandler:nil];
-}
-
-char *documentsPath() {
-    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
-    NSString *path = paths.firstObject;
-    return [path UTF8String];
-}

+ 0 - 9
vendor/fyne.io/fyne/v2/app/app_notlegacy_darwin.go

@@ -1,9 +0,0 @@
-//go:build !ci && !legacy && !js && !wasm && !test_web_driver
-// +build !ci,!legacy,!js,!wasm,!test_web_driver
-
-package app
-
-/*
-#cgo LDFLAGS: -framework Foundation -framework UserNotifications
-*/
-import "C"

+ 0 - 20
vendor/fyne.io/fyne/v2/app/app_openurl_js.go

@@ -1,20 +0,0 @@
-//go:build !ci && js && !wasm
-// +build !ci,js,!wasm
-
-package app
-
-import (
-	"fmt"
-	"net/url"
-
-	"honnef.co/go/js/dom"
-)
-
-func (app *fyneApp) OpenURL(url *url.URL) error {
-	window := dom.GetWindow().Open(url.String(), "_blank", "")
-	if window == nil {
-		return fmt.Errorf("Unable to open a new window/tab for URL: %v.", url)
-	}
-	window.Focus()
-	return nil
-}

+ 0 - 19
vendor/fyne.io/fyne/v2/app/app_openurl_wasm.go

@@ -1,19 +0,0 @@
-//go:build !ci && wasm
-// +build !ci,wasm
-
-package app
-
-import (
-	"fmt"
-	"net/url"
-	"syscall/js"
-)
-
-func (app *fyneApp) OpenURL(url *url.URL) error {
-	window := js.Global().Call("open", url.String(), "_blank", "")
-	if window.Equal(js.Null()) {
-		return fmt.Errorf("Unable to open a new window/tab for URL: %v.", url)
-	}
-	window.Call("focus")
-	return nil
-}

+ 0 - 13
vendor/fyne.io/fyne/v2/app/app_openurl_web.go

@@ -1,13 +0,0 @@
-//go:build !ci && !js && !wasm && test_web_driver
-// +build !ci,!js,!wasm,test_web_driver
-
-package app
-
-import (
-	"errors"
-	"net/url"
-)
-
-func (app *fyneApp) OpenURL(url *url.URL) error {
-	return errors.New("OpenURL is not supported with the test web driver.")
-}

+ 0 - 34
vendor/fyne.io/fyne/v2/app/app_other.go

@@ -1,34 +0,0 @@
-//go:build ci || (!linux && !darwin && !windows && !freebsd && !openbsd && !netbsd && !js && !wasm && !test_web_driver)
-// +build ci !linux,!darwin,!windows,!freebsd,!openbsd,!netbsd,!js,!wasm,!test_web_driver
-
-package app
-
-import (
-	"errors"
-	"net/url"
-	"os"
-	"path/filepath"
-
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/theme"
-)
-
-func defaultVariant() fyne.ThemeVariant {
-	return theme.VariantDark
-}
-
-func rootConfigDir() string {
-	return filepath.Join(os.TempDir(), "fyne-test")
-}
-
-func (a *fyneApp) OpenURL(_ *url.URL) error {
-	return errors.New("Unable to open url for unknown operating system")
-}
-
-func (a *fyneApp) SendNotification(_ *fyne.Notification) {
-	fyne.LogError("Refusing to show notification for unknown operating system", nil)
-}
-
-func watchTheme() {
-	// no-op
-}

+ 0 - 8
vendor/fyne.io/fyne/v2/app/app_release.go

@@ -1,8 +0,0 @@
-//go:build release
-// +build release
-
-package app
-
-import "fyne.io/fyne/v2"
-
-const buildMode = fyne.BuildRelease

+ 0 - 16
vendor/fyne.io/fyne/v2/app/app_software.go

@@ -1,16 +0,0 @@
-//go:build ci
-// +build ci
-
-package app
-
-import (
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/internal/painter/software"
-	"fyne.io/fyne/v2/test"
-)
-
-// NewWithID returns a new app instance using the test (headless) driver.
-// The ID string should be globally unique to this app.
-func NewWithID(id string) fyne.App {
-	return newAppWithDriver(test.NewDriverWithPainter(software.NewPainter()), id)
-}

+ 0 - 8
vendor/fyne.io/fyne/v2/app/app_standard.go

@@ -1,8 +0,0 @@
-//go:build !debug && !release
-// +build !debug,!release
-
-package app
-
-import "fyne.io/fyne/v2"
-
-const buildMode = fyne.BuildStandard

+ 0 - 29
vendor/fyne.io/fyne/v2/app/app_theme_js.go

@@ -1,29 +0,0 @@
-//go:build !ci && js && !wasm
-// +build !ci,js,!wasm
-
-package app
-
-import (
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/theme"
-
-	"github.com/gopherjs/gopherjs/js"
-)
-
-func defaultVariant() fyne.ThemeVariant {
-	if matchMedia := js.Global.Call("matchMedia", "(prefers-color-scheme: dark)"); matchMedia != js.Undefined {
-		if matches := matchMedia.Get("matches"); matches != js.Undefined && matches.Bool() {
-			return theme.VariantDark
-		}
-		return theme.VariantLight
-	}
-	return theme.VariantDark
-}
-
-func init() {
-	if matchMedia := js.Global.Call("matchMedia", "(prefers-color-scheme: dark)"); matchMedia != js.Undefined {
-		matchMedia.Call("addEventListener", "change", func(o *js.Object) {
-			fyne.CurrentApp().Settings().(*settings).setupTheme()
-		})
-	}
-}

+ 0 - 31
vendor/fyne.io/fyne/v2/app/app_theme_wasm.go

@@ -1,31 +0,0 @@
-//go:build !ci && wasm
-// +build !ci,wasm
-
-package app
-
-import (
-	"syscall/js"
-
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/theme"
-)
-
-func defaultVariant() fyne.ThemeVariant {
-	matches := js.Global().Call("matchMedia", "(prefers-color-scheme: dark)")
-	if matches.Truthy() {
-		if matches.Get("matches").Bool() {
-			return theme.VariantDark
-		}
-		return theme.VariantLight
-	}
-	return theme.VariantDark
-}
-
-func init() {
-	if matchMedia := js.Global().Call("matchMedia", "(prefers-color-scheme: dark)"); matchMedia.Truthy() {
-		matchMedia.Call("addEventListener", "change", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
-			fyne.CurrentApp().Settings().(*settings).setupTheme()
-			return nil
-		}))
-	}
-}

+ 0 - 13
vendor/fyne.io/fyne/v2/app/app_theme_web.go

@@ -1,13 +0,0 @@
-//go:build !ci && !js && !wasm && test_web_driver
-// +build !ci,!js,!wasm,test_web_driver
-
-package app
-
-import (
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/theme"
-)
-
-func defaultVariant() fyne.ThemeVariant {
-	return theme.VariantDark
-}

+ 0 - 124
vendor/fyne.io/fyne/v2/app/app_windows.go

@@ -1,124 +0,0 @@
-//go:build !ci && !js && !android && !ios && !wasm && !test_web_driver
-// +build !ci,!js,!android,!ios,!wasm,!test_web_driver
-
-package app
-
-import (
-	"fmt"
-	"net/url"
-	"os"
-	"path/filepath"
-	"strings"
-	"syscall"
-
-	"golang.org/x/sys/execabs"
-	"golang.org/x/sys/windows/registry"
-
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/theme"
-)
-
-const notificationTemplate = `$title = "%s"
-$content = "%s"
-
-[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null
-$template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02)
-$toastXml = [xml] $template.GetXml()
-$toastXml.GetElementsByTagName("text")[0].AppendChild($toastXml.CreateTextNode($title)) > $null
-$toastXml.GetElementsByTagName("text")[1].AppendChild($toastXml.CreateTextNode($content)) > $null
-
-$xml = New-Object Windows.Data.Xml.Dom.XmlDocument
-$xml.LoadXml($toastXml.OuterXml)
-$toast = [Windows.UI.Notifications.ToastNotification]::new($xml)
-[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("%s").Show($toast);`
-
-func isDark() bool {
-	k, err := registry.OpenKey(registry.CURRENT_USER, `SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize`, registry.QUERY_VALUE)
-	if err != nil { // older version of Windows will not have this key
-		return false
-	}
-	defer k.Close()
-
-	useLight, _, err := k.GetIntegerValue("AppsUseLightTheme")
-	if err != nil { // older version of Windows will not have this value
-		return false
-	}
-
-	return useLight == 0
-}
-
-func defaultVariant() fyne.ThemeVariant {
-	if isDark() {
-		return theme.VariantDark
-	}
-	return theme.VariantLight
-}
-
-func rootConfigDir() string {
-	homeDir, _ := os.UserHomeDir()
-
-	desktopConfig := filepath.Join(filepath.Join(homeDir, "AppData"), "Roaming")
-	return filepath.Join(desktopConfig, "fyne")
-}
-
-func (a *fyneApp) OpenURL(url *url.URL) error {
-	cmd := execabs.Command("rundll32", "url.dll,FileProtocolHandler", url.String())
-	cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
-	return cmd.Run()
-}
-
-var scriptNum = 0
-
-func (a *fyneApp) SendNotification(n *fyne.Notification) {
-	title := escapeNotificationString(n.Title)
-	content := escapeNotificationString(n.Content)
-	appID := a.UniqueID()
-	if appID == "" || strings.Index(appID, "missing-id") == 0 {
-		appID = a.Metadata().Name
-	}
-
-	script := fmt.Sprintf(notificationTemplate, title, content, appID)
-	go runScript("notify", script)
-}
-
-// SetSystemTrayMenu creates a system tray item and attaches the specified menu.
-// By default this will use the application icon.
-func (a *fyneApp) SetSystemTrayMenu(menu *fyne.Menu) {
-	a.Driver().(systrayDriver).SetSystemTrayMenu(menu)
-}
-
-// SetSystemTrayIcon sets a custom image for the system tray icon.
-// You should have previously called `SetSystemTrayMenu` to initialise the menu icon.
-func (a *fyneApp) SetSystemTrayIcon(icon fyne.Resource) {
-	a.Driver().(systrayDriver).SetSystemTrayIcon(icon)
-}
-
-func escapeNotificationString(in string) string {
-	noSlash := strings.ReplaceAll(in, "`", "``")
-	return strings.ReplaceAll(noSlash, "\"", "`\"")
-}
-
-func runScript(name, script string) {
-	scriptNum++
-	appID := fyne.CurrentApp().UniqueID()
-	fileName := fmt.Sprintf("fyne-%s-%s-%d.ps1", appID, name, scriptNum)
-
-	tmpFilePath := filepath.Join(os.TempDir(), fileName)
-	err := os.WriteFile(tmpFilePath, []byte(script), 0600)
-	if err != nil {
-		fyne.LogError("Could not write script to show notification", err)
-		return
-	}
-	defer os.Remove(tmpFilePath)
-
-	launch := "(Get-Content -Encoding UTF8 -Path " + tmpFilePath + " -Raw) | Invoke-Expression"
-	cmd := execabs.Command("PowerShell", "-ExecutionPolicy", "Bypass", launch)
-	cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
-	err = cmd.Run()
-	if err != nil {
-		fyne.LogError("Failed to launch windows notify script", err)
-	}
-}
-func watchTheme() {
-	// TODO monitor the Windows theme
-}

+ 0 - 202
vendor/fyne.io/fyne/v2/app/app_xdg.go

@@ -1,202 +0,0 @@
-//go:build !ci && !js && !wasm && !test_web_driver && (linux || openbsd || freebsd || netbsd) && !android
-// +build !ci
-// +build !js
-// +build !wasm
-// +build !test_web_driver
-// +build linux openbsd freebsd netbsd
-// +build !android
-
-package app
-
-import (
-	"net/url"
-	"os"
-	"path/filepath"
-	"sync"
-
-	"github.com/godbus/dbus/v5"
-	"golang.org/x/sys/execabs"
-
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/theme"
-)
-
-var once sync.Once
-
-func defaultVariant() fyne.ThemeVariant {
-	return findFreedestktopColorScheme()
-}
-
-func (a *fyneApp) OpenURL(url *url.URL) error {
-	cmd := execabs.Command("xdg-open", url.String())
-	cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
-	return cmd.Start()
-}
-
-// fetch color variant from dbus portal desktop settings.
-func findFreedestktopColorScheme() fyne.ThemeVariant {
-	dbusConn, err := dbus.SessionBus()
-	if err != nil {
-		fyne.LogError("Unable to connect to session D-Bus", err)
-		return theme.VariantDark
-	}
-
-	dbusObj := dbusConn.Object("org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop")
-	call := dbusObj.Call(
-		"org.freedesktop.portal.Settings.Read",
-		dbus.FlagNoAutoStart,
-		"org.freedesktop.appearance",
-		"color-scheme",
-	)
-	if call.Err != nil {
-		// many desktops don't have this exported yet
-		return theme.VariantDark
-	}
-
-	var value uint8
-	if err = call.Store(&value); err != nil {
-		fyne.LogError("failed to read theme variant from D-Bus", err)
-		return theme.VariantDark
-	}
-
-	// See: https://github.com/flatpak/xdg-desktop-portal/blob/1.16.0/data/org.freedesktop.impl.portal.Settings.xml#L32-L46
-	// 0: No preference
-	// 1: Prefer dark appearance
-	// 2: Prefer light appearance
-	switch value {
-	case 2:
-		return theme.VariantLight
-	case 1:
-		return theme.VariantDark
-	default:
-		// Default to light theme to support Gnome's default see https://github.com/fyne-io/fyne/pull/3561
-		return theme.VariantLight
-	}
-}
-
-func (a *fyneApp) SendNotification(n *fyne.Notification) {
-	conn, err := dbus.SessionBus() // shared connection, don't close
-	if err != nil {
-		fyne.LogError("Unable to connect to session D-Bus", err)
-		return
-	}
-
-	appName := fyne.CurrentApp().UniqueID()
-	appIcon := a.cachedIconPath()
-	timeout := int32(0) // we don't support this yet
-
-	obj := conn.Object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")
-	call := obj.Call("org.freedesktop.Notifications.Notify", 0, appName, uint32(0),
-		appIcon, n.Title, n.Content, []string{}, map[string]dbus.Variant{}, timeout)
-	if call.Err != nil {
-		fyne.LogError("Failed to send message to bus", call.Err)
-	}
-}
-
-func (a *fyneApp) saveIconToCache(dirPath, filePath string) error {
-	err := os.MkdirAll(dirPath, 0700)
-	if err != nil {
-		fyne.LogError("Unable to create application cache directory", err)
-		return err
-	}
-
-	file, err := os.Create(filePath)
-	if err != nil {
-		fyne.LogError("Unable to create icon file", err)
-		return err
-	}
-
-	defer file.Close()
-
-	if icon := a.Icon(); icon != nil {
-		_, err = file.Write(icon.Content())
-		if err != nil {
-			fyne.LogError("Unable to write icon contents", err)
-			return err
-		}
-	}
-
-	return nil
-}
-
-func (a *fyneApp) cachedIconPath() string {
-	if a.Icon() == nil {
-		return ""
-	}
-
-	dirPath := filepath.Join(rootCacheDir(), a.UniqueID())
-	filePath := filepath.Join(dirPath, "icon.png")
-	once.Do(func() {
-		err := a.saveIconToCache(dirPath, filePath)
-		if err != nil {
-			filePath = ""
-		}
-	})
-
-	return filePath
-}
-
-// SetSystemTrayMenu creates a system tray item and attaches the specified menu.
-// By default this will use the application icon.
-func (a *fyneApp) SetSystemTrayMenu(menu *fyne.Menu) {
-	if desk, ok := a.Driver().(systrayDriver); ok { // don't use this on mobile tag
-		desk.SetSystemTrayMenu(menu)
-	}
-}
-
-// SetSystemTrayIcon sets a custom image for the system tray icon.
-// You should have previously called `SetSystemTrayMenu` to initialise the menu icon.
-func (a *fyneApp) SetSystemTrayIcon(icon fyne.Resource) {
-	if desk, ok := a.Driver().(systrayDriver); ok { // don't use this on mobile tag
-		desk.SetSystemTrayIcon(icon)
-	}
-}
-
-func rootConfigDir() string {
-	desktopConfig, _ := os.UserConfigDir()
-	return filepath.Join(desktopConfig, "fyne")
-}
-
-func rootCacheDir() string {
-	desktopCache, _ := os.UserCacheDir()
-	return filepath.Join(desktopCache, "fyne")
-}
-
-func watchTheme() {
-	go watchFreedekstopThemeChange()
-}
-
-func themeChanged() {
-	fyne.CurrentApp().Settings().(*settings).setupTheme()
-}
-
-// connect to dbus to detect color-schem theme changes in portal settings.
-func watchFreedekstopThemeChange() {
-	conn, err := dbus.SessionBus()
-	if err != nil {
-		fyne.LogError("Unable to connect to session D-Bus", err)
-		return
-	}
-
-	if err := conn.AddMatchSignal(
-		dbus.WithMatchObjectPath("/org/freedesktop/portal/desktop"),
-		dbus.WithMatchInterface("org.freedesktop.portal.Settings"),
-		dbus.WithMatchMember("SettingChanged"),
-	); err != nil {
-		fyne.LogError("D-Bus signal match failed", err)
-		return
-	}
-	defer conn.Close()
-
-	dbusChan := make(chan *dbus.Signal)
-	conn.Signal(dbusChan)
-
-	for sig := range dbusChan {
-		for _, v := range sig.Body {
-			if v == "color-scheme" {
-				themeChanged()
-				break
-			}
-		}
-	}
-}

+ 0 - 47
vendor/fyne.io/fyne/v2/app/cloud.go

@@ -1,47 +0,0 @@
-package app
-
-import "fyne.io/fyne/v2"
-
-func (a *fyneApp) SetCloudProvider(p fyne.CloudProvider) {
-	if p == nil {
-		a.cloud = nil
-		return
-	}
-
-	a.transitionCloud(p)
-}
-
-func (a *fyneApp) transitionCloud(p fyne.CloudProvider) {
-	if a.cloud != nil {
-		a.cloud.Cleanup(a)
-	}
-
-	err := p.Setup(a)
-	if err != nil {
-		fyne.LogError("Failed to set up cloud provider "+p.ProviderName(), err)
-		return
-	}
-	a.cloud = p
-
-	listeners := a.prefs.ChangeListeners()
-	if pp, ok := p.(fyne.CloudProviderPreferences); ok {
-		a.prefs = pp.CloudPreferences(a)
-	} else {
-		a.prefs = a.newDefaultPreferences()
-	}
-	if cloud, ok := p.(fyne.CloudProviderStorage); ok {
-		a.storage = cloud.CloudStorage(a)
-	} else {
-		store := &store{a: a}
-		store.Docs = makeStoreDocs(a.uniqueID, store)
-		a.storage = store
-	}
-
-	for _, l := range listeners {
-		a.prefs.AddChangeListener(l)
-		l() // assume that preferences have changed because we replaced the provider
-	}
-
-	// after transition ensure settings listener is fired
-	a.settings.apply()
-}

+ 0 - 28
vendor/fyne.io/fyne/v2/app/meta.go

@@ -1,28 +0,0 @@
-package app
-
-import (
-	"fyne.io/fyne/v2"
-)
-
-var meta = fyne.AppMetadata{
-	ID:      "",
-	Name:    "",
-	Version: "0.0.1",
-	Build:   1,
-	Release: false,
-	Custom:  map[string]string{},
-}
-
-// SetMetadata overrides the packaged application metadata.
-// This data can be used in many places like notifications and about screens.
-func SetMetadata(m fyne.AppMetadata) {
-	meta = m
-
-	if meta.Custom == nil {
-		meta.Custom = map[string]string{}
-	}
-}
-
-func (a *fyneApp) Metadata() fyne.AppMetadata {
-	return meta
-}

+ 0 - 208
vendor/fyne.io/fyne/v2/app/preferences.go

@@ -1,208 +0,0 @@
-package app
-
-import (
-	"encoding/json"
-	"os"
-	"path/filepath"
-	"sync"
-	"time"
-
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/internal"
-)
-
-type preferences struct {
-	*internal.InMemoryPreferences
-
-	prefLock            sync.RWMutex
-	loadingInProgress   bool
-	savedRecently       bool
-	changedDuringSaving bool
-
-	app                 *fyneApp
-	needsSaveBeforeExit bool
-}
-
-// Declare conformity with Preferences interface
-var _ fyne.Preferences = (*preferences)(nil)
-
-// forceImmediateSave writes preferences to file immediately, ignoring the debouncing
-// logic in the change listener. Does nothing if preferences are not backed with a file.
-func (p *preferences) forceImmediateSave() {
-	if !p.needsSaveBeforeExit {
-		return
-	}
-	err := p.save()
-	if err != nil {
-		fyne.LogError("Failed on force saving preferences", err)
-	}
-}
-
-func (p *preferences) resetSavedRecently() {
-	go func() {
-		time.Sleep(time.Millisecond * 100) // writes are not always atomic. 10ms worked, 100 is safer.
-		p.prefLock.Lock()
-		p.savedRecently = false
-		changedDuringSaving := p.changedDuringSaving
-		p.changedDuringSaving = false
-		p.prefLock.Unlock()
-
-		if changedDuringSaving {
-			p.save()
-		}
-	}()
-}
-
-func (p *preferences) save() error {
-	return p.saveToFile(p.storagePath())
-}
-
-func (p *preferences) saveToFile(path string) error {
-	p.prefLock.Lock()
-	p.savedRecently = true
-	p.prefLock.Unlock()
-	defer p.resetSavedRecently()
-	err := os.MkdirAll(filepath.Dir(path), 0700)
-	if err != nil { // this is not an exists error according to docs
-		return err
-	}
-
-	file, err := os.Create(path)
-	if err != nil {
-		if !os.IsExist(err) {
-			return err
-		}
-		file, err = os.Open(path) // #nosec
-		if err != nil {
-			return err
-		}
-	}
-	defer file.Close()
-	encode := json.NewEncoder(file)
-
-	p.InMemoryPreferences.ReadValues(func(values map[string]interface{}) {
-		err = encode.Encode(&values)
-	})
-
-	err2 := file.Sync()
-	if err == nil {
-		err = err2
-	}
-	return err
-}
-
-func (p *preferences) load() {
-	err := p.loadFromFile(p.storagePath())
-	if err != nil {
-		fyne.LogError("Preferences load error:", err)
-	}
-}
-
-func (p *preferences) loadFromFile(path string) (err error) {
-	file, err := os.Open(path) // #nosec
-	if err != nil {
-		if os.IsNotExist(err) {
-			if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {
-				return err
-			}
-			return nil
-		}
-		return err
-	}
-	defer func() {
-		if r := file.Close(); r != nil && err == nil {
-			err = r
-		}
-	}()
-	decode := json.NewDecoder(file)
-
-	p.prefLock.Lock()
-	p.loadingInProgress = true
-	p.prefLock.Unlock()
-
-	p.InMemoryPreferences.WriteValues(func(values map[string]interface{}) {
-		err = decode.Decode(&values)
-		if err != nil {
-			return
-		}
-		convertLists(values)
-	})
-
-	p.prefLock.Lock()
-	p.loadingInProgress = false
-	p.prefLock.Unlock()
-
-	return err
-}
-
-func newPreferences(app *fyneApp) *preferences {
-	p := &preferences{}
-	p.app = app
-	p.InMemoryPreferences = internal.NewInMemoryPreferences()
-
-	// don't load or watch if not setup
-	if app.uniqueID == "" && app.Metadata().ID == "" {
-		return p
-	}
-
-	p.needsSaveBeforeExit = true
-	p.AddChangeListener(func() {
-		if p != app.prefs {
-			return
-		}
-		p.prefLock.Lock()
-		shouldIgnoreChange := p.savedRecently || p.loadingInProgress
-		if p.savedRecently && !p.loadingInProgress {
-			p.changedDuringSaving = true
-		}
-		p.prefLock.Unlock()
-
-		if shouldIgnoreChange { // callback after loading file, or too many updates in a row
-			return
-		}
-
-		err := p.save()
-		if err != nil {
-			fyne.LogError("Failed on saving preferences", err)
-		}
-	})
-	p.watch()
-	return p
-}
-
-func convertLists(values map[string]interface{}) {
-	for k, v := range values {
-		if items, ok := v.([]interface{}); ok {
-			if len(items) == 0 {
-				continue
-			}
-
-			switch items[0].(type) {
-			case bool:
-				bools := make([]bool, len(items))
-				for i, item := range items {
-					bools[i] = item.(bool)
-				}
-				values[k] = bools
-			case float64:
-				floats := make([]float64, len(items))
-				for i, item := range items {
-					floats[i] = item.(float64)
-				}
-				values[k] = floats
-			case int:
-				ints := make([]int, len(items))
-				for i, item := range items {
-					ints[i] = item.(int)
-				}
-				values[k] = ints
-			case string:
-				strings := make([]string, len(items))
-				for i, item := range items {
-					strings[i] = item.(string)
-				}
-				values[k] = strings
-			}
-		}
-	}
-}

+ 0 - 21
vendor/fyne.io/fyne/v2/app/preferences_android.go

@@ -1,21 +0,0 @@
-//go:build android
-// +build android
-
-package app
-
-import "path/filepath"
-
-// storagePath returns the location of the settings storage
-func (p *preferences) storagePath() string {
-	// we have no global storage, use app global instead - rootConfigDir looks up in app_mobile_and.go
-	return filepath.Join(p.app.storageRoot(), "preferences.json")
-}
-
-// storageRoot returns the location of the app storage
-func (a *fyneApp) storageRoot() string {
-	return rootConfigDir() // we are in a sandbox, so no app ID added to this path
-}
-
-func (p *preferences) watch() {
-	// no-op on mobile
-}

+ 0 - 24
vendor/fyne.io/fyne/v2/app/preferences_ios.go

@@ -1,24 +0,0 @@
-//go:build ios
-// +build ios
-
-package app
-
-import (
-	"path/filepath"
-)
-import "C"
-
-// storagePath returns the location of the settings storage
-func (p *preferences) storagePath() string {
-	ret := filepath.Join(p.app.storageRoot(), "preferences.json")
-	return ret
-}
-
-// storageRoot returns the location of the app storage
-func (a *fyneApp) storageRoot() string {
-	return rootConfigDir() // we are in a sandbox, so no app ID added to this path
-}
-
-func (p *preferences) watch() {
-	// no-op on mobile
-}

+ 0 - 20
vendor/fyne.io/fyne/v2/app/preferences_mobile.go

@@ -1,20 +0,0 @@
-//go:build mobile
-// +build mobile
-
-package app
-
-import "path/filepath"
-
-// storagePath returns the location of the settings storage
-func (p *preferences) storagePath() string {
-	return filepath.Join(p.app.storageRoot(), "preferences.json")
-}
-
-// storageRoot returns the location of the app storage
-func (a *fyneApp) storageRoot() string {
-	return filepath.Join(rootConfigDir(), a.UniqueID())
-}
-
-func (p *preferences) watch() {
-	// no-op as we are in mobile simulation mode
-}

+ 0 - 29
vendor/fyne.io/fyne/v2/app/preferences_other.go

@@ -1,29 +0,0 @@
-//go:build !ios && !android && !mobile
-// +build !ios,!android,!mobile
-
-package app
-
-import "path/filepath"
-
-// storagePath returns the location of the settings storage
-func (p *preferences) storagePath() string {
-	return filepath.Join(p.app.storageRoot(), "preferences.json")
-}
-
-// storageRoot returns the location of the app storage
-func (a *fyneApp) storageRoot() string {
-	return filepath.Join(rootConfigDir(), a.UniqueID())
-}
-
-func (p *preferences) watch() {
-	watchFile(p.storagePath(), func() {
-		p.prefLock.RLock()
-		shouldIgnoreChange := p.savedRecently
-		p.prefLock.RUnlock()
-		if shouldIgnoreChange {
-			return
-		}
-
-		p.load()
-	})
-}

+ 0 - 168
vendor/fyne.io/fyne/v2/app/settings.go

@@ -1,168 +0,0 @@
-package app
-
-import (
-	"bytes"
-	"os"
-	"path/filepath"
-	"sync"
-
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/theme"
-)
-
-var noAnimations bool // set to true at compile time if no_animations tag is passed
-
-// SettingsSchema is used for loading and storing global settings
-type SettingsSchema struct {
-	// these items are used for global settings load
-	ThemeName         string  `json:"theme"`
-	Scale             float32 `json:"scale"`
-	PrimaryColor      string  `json:"primary_color"`
-	CloudName         string  `json:"cloud_name"`
-	CloudConfig       string  `json:"cloud_config"`
-	DisableAnimations bool    `json:"no_animations"`
-}
-
-// StoragePath returns the location of the settings storage
-func (sc *SettingsSchema) StoragePath() string {
-	return filepath.Join(rootConfigDir(), "settings.json")
-}
-
-// Declare conformity with Settings interface
-var _ fyne.Settings = (*settings)(nil)
-
-type settings struct {
-	propertyLock   sync.RWMutex
-	theme          fyne.Theme
-	themeSpecified bool
-	variant        fyne.ThemeVariant
-
-	changeListeners sync.Map    // map[chan fyne.Settings]bool
-	watcher         interface{} // normally *fsnotify.Watcher or nil - avoid import in this file
-
-	schema SettingsSchema
-}
-
-func (s *settings) BuildType() fyne.BuildType {
-	return buildMode
-}
-
-func (s *settings) PrimaryColor() string {
-	s.propertyLock.RLock()
-	defer s.propertyLock.RUnlock()
-	return s.schema.PrimaryColor
-}
-
-// OverrideTheme allows the settings app to temporarily preview different theme details.
-// Please make sure that you remember the original settings and call this again to revert the change.
-func (s *settings) OverrideTheme(theme fyne.Theme, name string) {
-	s.propertyLock.Lock()
-	defer s.propertyLock.Unlock()
-	s.schema.PrimaryColor = name
-	s.theme = theme
-}
-
-func (s *settings) Theme() fyne.Theme {
-	s.propertyLock.RLock()
-	defer s.propertyLock.RUnlock()
-	return s.theme
-}
-
-func (s *settings) SetTheme(theme fyne.Theme) {
-	s.themeSpecified = true
-	s.applyTheme(theme, s.variant)
-}
-
-func (s *settings) ShowAnimations() bool {
-	return !s.schema.DisableAnimations && !noAnimations
-}
-
-func (s *settings) ThemeVariant() fyne.ThemeVariant {
-	return s.variant
-}
-
-func (s *settings) applyTheme(theme fyne.Theme, variant fyne.ThemeVariant) {
-	s.propertyLock.Lock()
-	defer s.propertyLock.Unlock()
-	s.variant = variant
-	s.theme = theme
-	s.apply()
-}
-
-func (s *settings) Scale() float32 {
-	s.propertyLock.RLock()
-	defer s.propertyLock.RUnlock()
-	if s.schema.Scale < 0.0 {
-		return 1.0 // catching any really old data still using the `-1`  value for "auto" scale
-	}
-	return s.schema.Scale
-}
-
-func (s *settings) AddChangeListener(listener chan fyne.Settings) {
-	s.changeListeners.Store(listener, true) // the boolean is just a dummy value here.
-}
-
-func (s *settings) apply() {
-	s.changeListeners.Range(func(key, _ interface{}) bool {
-		listener := key.(chan fyne.Settings)
-		select {
-		case listener <- s:
-		default:
-			l := listener
-			go func() { l <- s }()
-		}
-		return true
-	})
-}
-
-func (s *settings) fileChanged() {
-	s.load()
-	s.apply()
-}
-
-func (s *settings) loadSystemTheme() fyne.Theme {
-	path := filepath.Join(rootConfigDir(), "theme.json")
-	data, err := fyne.LoadResourceFromPath(path)
-	if err != nil {
-		if !os.IsNotExist(err) {
-			fyne.LogError("Failed to load user theme file: "+path, err)
-		}
-		return theme.DefaultTheme()
-	}
-	if data != nil && data.Content() != nil {
-		th, err := theme.FromJSONReader(bytes.NewReader(data.Content()))
-		if err == nil {
-			return th
-		}
-		fyne.LogError("Failed to parse user theme file: "+path, err)
-	}
-	return theme.DefaultTheme()
-}
-
-func (s *settings) setupTheme() {
-	name := s.schema.ThemeName
-	if env := os.Getenv("FYNE_THEME"); env != "" {
-		name = env
-	}
-
-	variant := defaultVariant()
-	effectiveTheme := s.theme
-	if !s.themeSpecified {
-		effectiveTheme = s.loadSystemTheme()
-	}
-	switch name {
-	case "light":
-		variant = theme.VariantLight
-	case "dark":
-		variant = theme.VariantDark
-	}
-
-	s.applyTheme(effectiveTheme, variant)
-}
-
-func loadSettings() *settings {
-	s := &settings{}
-	s.load()
-
-	return s
-}

+ 0 - 75
vendor/fyne.io/fyne/v2/app/settings_desktop.go

@@ -1,75 +0,0 @@
-//go:build !android && !ios && !mobile && !js && !wasm && !test_web_driver
-// +build !android,!ios,!mobile,!js,!wasm,!test_web_driver
-
-package app
-
-import (
-	"os"
-	"path/filepath"
-
-	"fyne.io/fyne/v2"
-	"github.com/fsnotify/fsnotify"
-)
-
-func watchFileAddTarget(watcher *fsnotify.Watcher, path string) {
-	dir := filepath.Dir(path)
-	ensureDirExists(dir)
-
-	err := watcher.Add(dir)
-	if err != nil {
-		fyne.LogError("Settings watch error:", err)
-	}
-}
-
-func ensureDirExists(dir string) {
-	if stat, err := os.Stat(dir); err == nil && stat.IsDir() {
-		return
-	}
-
-	err := os.MkdirAll(dir, 0700)
-	if err != nil {
-		fyne.LogError("Unable to create settings storage:", err)
-	}
-}
-
-func watchFile(path string, callback func()) *fsnotify.Watcher {
-	watcher, err := fsnotify.NewWatcher()
-	if err != nil {
-		fyne.LogError("Failed to watch settings file:", err)
-		return nil
-	}
-
-	go func() {
-		for event := range watcher.Events {
-			if event.Op.Has(fsnotify.Remove) { // if it was deleted then watch again
-				watcher.Remove(path) // fsnotify returns false positives, see https://github.com/fsnotify/fsnotify/issues/268
-
-				watchFileAddTarget(watcher, path)
-			} else {
-				callback()
-			}
-		}
-
-		err = watcher.Close()
-		if err != nil {
-			fyne.LogError("Settings un-watch error:", err)
-		}
-	}()
-
-	watchFileAddTarget(watcher, path)
-	return watcher
-}
-
-func (s *settings) watchSettings() {
-	s.watcher = watchFile(s.schema.StoragePath(), s.fileChanged)
-
-	watchTheme()
-}
-
-func (s *settings) stopWatching() {
-	if s.watcher == nil {
-		return
-	}
-
-	s.watcher.(*fsnotify.Watcher).Close() // fsnotify returns false positives, see https://github.com/fsnotify/fsnotify/issues/268
-}

+ 0 - 35
vendor/fyne.io/fyne/v2/app/settings_file.go

@@ -1,35 +0,0 @@
-//go:build !js && !wasm && !test_web_driver
-// +build !js,!wasm,!test_web_driver
-
-package app
-
-import (
-	"encoding/json"
-	"io"
-	"os"
-
-	"fyne.io/fyne/v2"
-)
-
-func (s *settings) load() {
-	err := s.loadFromFile(s.schema.StoragePath())
-	if err != nil && err != io.EOF { // we can get an EOF in windows settings writes
-		fyne.LogError("Settings load error:", err)
-	}
-
-	s.setupTheme()
-}
-
-func (s *settings) loadFromFile(path string) error {
-	file, err := os.Open(path) // #nosec
-	if err != nil {
-		if os.IsNotExist(err) {
-			return nil
-		}
-		return err
-	}
-	defer file.Close()
-	decode := json.NewDecoder(file)
-
-	return decode.Decode(&s.schema)
-}

+ 0 - 24
vendor/fyne.io/fyne/v2/app/settings_goxjs.go

@@ -1,24 +0,0 @@
-//go:build js || wasm || test_web_driver
-// +build js wasm test_web_driver
-
-package app
-
-// TODO: #2734
-
-func (s *settings) load() {
-	s.setupTheme()
-	s.schema.Scale = 1
-}
-
-func (s *settings) loadFromFile(path string) error {
-	return nil
-}
-
-func watchFile(path string, callback func()) {
-}
-
-func (s *settings) watchSettings() {
-}
-
-func (s *settings) stopWatching() {
-}

+ 0 - 12
vendor/fyne.io/fyne/v2/app/settings_mobile.go

@@ -1,12 +0,0 @@
-//go:build android || ios || mobile
-// +build android ios mobile
-
-package app
-
-func (s *settings) watchSettings() {
-	// no-op on mobile
-}
-
-func (s *settings) stopWatching() {
-	// no-op on mobile
-}

+ 0 - 8
vendor/fyne.io/fyne/v2/app/settings_noanimation.go

@@ -1,8 +0,0 @@
-//go:build no_animations
-// +build no_animations
-
-package app
-
-func init() {
-	noAnimations = true
-}

+ 0 - 27
vendor/fyne.io/fyne/v2/app/storage.go

@@ -1,27 +0,0 @@
-package app
-
-import (
-	"os"
-
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/internal"
-	"fyne.io/fyne/v2/storage"
-)
-
-type store struct {
-	*internal.Docs
-	a *fyneApp
-}
-
-func (s *store) RootURI() fyne.URI {
-	if s.a.UniqueID() == "" {
-		fyne.LogError("Storage API requires a unique ID, use app.NewWithID()", nil)
-		return storage.NewFileURI(os.TempDir())
-	}
-
-	return storage.NewFileURI(s.a.storageRoot())
-}
-
-func (s *store) docRootURI() (fyne.URI, error) {
-	return storage.Child(s.RootURI(), "Documents")
-}

+ 0 - 86
vendor/fyne.io/fyne/v2/canvas/animation.go

@@ -1,86 +0,0 @@
-package canvas
-
-import (
-	"image/color"
-	"time"
-
-	"fyne.io/fyne/v2"
-)
-
-const (
-	// DurationStandard is the time a standard interface animation will run.
-	//
-	// Since: 2.0
-	DurationStandard = time.Millisecond * 300
-	// DurationShort is the time a subtle or small transition should use.
-	//
-	// Since: 2.0
-	DurationShort = time.Millisecond * 150
-)
-
-// NewColorRGBAAnimation sets up a new animation that will transition from the start to stop Color over
-// the specified Duration. The colour transition will move linearly through the RGB colour space.
-// The content of fn should apply the color values to an object and refresh it.
-// You should call Start() on the returned animation to start it.
-//
-// Since: 2.0
-func NewColorRGBAAnimation(start, stop color.Color, d time.Duration, fn func(color.Color)) *fyne.Animation {
-	r1, g1, b1, a1 := start.RGBA()
-	r2, g2, b2, a2 := stop.RGBA()
-
-	rStart := int(r1 >> 8)
-	gStart := int(g1 >> 8)
-	bStart := int(b1 >> 8)
-	aStart := int(a1 >> 8)
-	rDelta := float32(int(r2>>8) - rStart)
-	gDelta := float32(int(g2>>8) - gStart)
-	bDelta := float32(int(b2>>8) - bStart)
-	aDelta := float32(int(a2>>8) - aStart)
-
-	return &fyne.Animation{
-		Duration: d,
-		Tick: func(done float32) {
-			fn(color.RGBA{R: scaleChannel(rStart, rDelta, done), G: scaleChannel(gStart, gDelta, done),
-				B: scaleChannel(bStart, bDelta, done), A: scaleChannel(aStart, aDelta, done)})
-		}}
-}
-
-// NewPositionAnimation sets up a new animation that will transition from the start to stop Position over
-// the specified Duration. The content of fn should apply the position value to an object for the change
-// to be visible. You should call Start() on the returned animation to start it.
-//
-// Since: 2.0
-func NewPositionAnimation(start, stop fyne.Position, d time.Duration, fn func(fyne.Position)) *fyne.Animation {
-	xDelta := float32(stop.X - start.X)
-	yDelta := float32(stop.Y - start.Y)
-
-	return &fyne.Animation{
-		Duration: d,
-		Tick: func(done float32) {
-			fn(fyne.NewPos(scaleVal(start.X, xDelta, done), scaleVal(start.Y, yDelta, done)))
-		}}
-}
-
-// NewSizeAnimation sets up a new animation that will transition from the start to stop Size over
-// the specified Duration. The content of fn should apply the size value to an object for the change
-// to be visible. You should call Start() on the returned animation to start it.
-//
-// Since: 2.0
-func NewSizeAnimation(start, stop fyne.Size, d time.Duration, fn func(fyne.Size)) *fyne.Animation {
-	widthDelta := float32(stop.Width - start.Width)
-	heightDelta := float32(stop.Height - start.Height)
-
-	return &fyne.Animation{
-		Duration: d,
-		Tick: func(done float32) {
-			fn(fyne.NewSize(scaleVal(start.Width, widthDelta, done), scaleVal(start.Height, heightDelta, done)))
-		}}
-}
-
-func scaleChannel(start int, diff, done float32) uint8 {
-	return uint8(start + int(diff*done))
-}
-
-func scaleVal(start float32, delta, done float32) float32 {
-	return start + delta*done
-}

+ 0 - 100
vendor/fyne.io/fyne/v2/canvas/base.go

@@ -1,100 +0,0 @@
-// Package canvas contains all of the primitive CanvasObjects that make up a Fyne GUI.
-//
-// The types implemented in this package are used as building blocks in order
-// to build higher order functionality. These types are designed to be
-// non-interactive, by design. If additional functionality is required,
-// it's usually a sign that this type should be used as part of a custom
-// widget.
-package canvas // import "fyne.io/fyne/v2/canvas"
-
-import (
-	"sync"
-
-	"fyne.io/fyne/v2"
-)
-
-type baseObject struct {
-	size     fyne.Size     // The current size of the canvas object
-	position fyne.Position // The current position of the object
-	Hidden   bool          // Is this object currently hidden
-
-	min fyne.Size // The minimum size this object can be
-
-	propertyLock sync.RWMutex
-}
-
-// Hide will set this object to not be visible.
-func (o *baseObject) Hide() {
-	o.propertyLock.Lock()
-	defer o.propertyLock.Unlock()
-
-	o.Hidden = true
-}
-
-// MinSize returns the specified minimum size, if set, or {1, 1} otherwise.
-func (o *baseObject) MinSize() fyne.Size {
-	o.propertyLock.RLock()
-	defer o.propertyLock.RUnlock()
-
-	if o.min.Width == 0 && o.min.Height == 0 {
-		return fyne.NewSize(1, 1)
-	}
-
-	return o.min
-}
-
-// Move the object to a new position, relative to its parent.
-func (o *baseObject) Move(pos fyne.Position) {
-	o.propertyLock.Lock()
-	defer o.propertyLock.Unlock()
-
-	o.position = pos
-}
-
-// Position gets the current position of this canvas object, relative to its parent.
-func (o *baseObject) Position() fyne.Position {
-	o.propertyLock.RLock()
-	defer o.propertyLock.RUnlock()
-
-	return o.position
-}
-
-// Resize sets a new size for the canvas object.
-func (o *baseObject) Resize(size fyne.Size) {
-	o.propertyLock.Lock()
-	defer o.propertyLock.Unlock()
-
-	o.size = size
-}
-
-// SetMinSize specifies the smallest size this object should be.
-func (o *baseObject) SetMinSize(size fyne.Size) {
-	o.propertyLock.Lock()
-	defer o.propertyLock.Unlock()
-
-	o.min = size
-}
-
-// Show will set this object to be visible.
-func (o *baseObject) Show() {
-	o.propertyLock.Lock()
-	defer o.propertyLock.Unlock()
-
-	o.Hidden = false
-}
-
-// Size returns the current size of this canvas object.
-func (o *baseObject) Size() fyne.Size {
-	o.propertyLock.RLock()
-	defer o.propertyLock.RUnlock()
-
-	return o.size
-}
-
-// Visible returns true if this object is visible, false otherwise.
-func (o *baseObject) Visible() bool {
-	o.propertyLock.RLock()
-	defer o.propertyLock.RUnlock()
-
-	return !o.Hidden
-}

+ 0 - 29
vendor/fyne.io/fyne/v2/canvas/canvas.go

@@ -1,29 +0,0 @@
-package canvas
-
-import "fyne.io/fyne/v2"
-
-// Refresh instructs the containing canvas to refresh the specified obj.
-func Refresh(obj fyne.CanvasObject) {
-	if fyne.CurrentApp() == nil || fyne.CurrentApp().Driver() == nil {
-		return
-	}
-
-	c := fyne.CurrentApp().Driver().CanvasForObject(obj)
-	if c != nil {
-		c.Refresh(obj)
-	}
-}
-
-// repaint instructs the containing canvas to redraw, even if nothing changed.
-func repaint(obj fyne.CanvasObject) {
-	if fyne.CurrentApp() == nil || fyne.CurrentApp().Driver() == nil {
-		return
-	}
-
-	c := fyne.CurrentApp().Driver().CanvasForObject(obj)
-	if c != nil {
-		if paint, ok := c.(interface{ SetDirty() }); ok {
-			paint.SetDirty()
-		}
-	}
-}

+ 0 - 90
vendor/fyne.io/fyne/v2/canvas/circle.go

@@ -1,90 +0,0 @@
-package canvas
-
-import (
-	"image/color"
-	"math"
-
-	"fyne.io/fyne/v2"
-)
-
-// Declare conformity with CanvasObject interface
-var _ fyne.CanvasObject = (*Circle)(nil)
-
-// Circle describes a colored circle primitive in a Fyne canvas
-type Circle struct {
-	Position1 fyne.Position // The current top-left position of the Circle
-	Position2 fyne.Position // The current bottomright position of the Circle
-	Hidden    bool          // Is this circle currently hidden
-
-	FillColor   color.Color // The circle fill color
-	StrokeColor color.Color // The circle stroke color
-	StrokeWidth float32     // The stroke width of the circle
-}
-
-// NewCircle returns a new Circle instance
-func NewCircle(color color.Color) *Circle {
-	return &Circle{
-		FillColor: color,
-	}
-}
-
-// Hide will set this circle to not be visible
-func (c *Circle) Hide() {
-	c.Hidden = true
-
-	repaint(c)
-}
-
-// MinSize for a Circle simply returns Size{1, 1} as there is no
-// explicit content
-func (c *Circle) MinSize() fyne.Size {
-	return fyne.NewSize(1, 1)
-}
-
-// Move the circle object to a new position, relative to its parent / canvas
-func (c *Circle) Move(pos fyne.Position) {
-	size := c.Size()
-	c.Position1 = pos
-	c.Position2 = fyne.NewPos(c.Position1.X+size.Width, c.Position1.Y+size.Height)
-	repaint(c)
-}
-
-// Position gets the current top-left position of this circle object, relative to its parent / canvas
-func (c *Circle) Position() fyne.Position {
-	return c.Position1
-}
-
-// Refresh causes this object to be redrawn with its configured state.
-func (c *Circle) Refresh() {
-	Refresh(c)
-}
-
-// Resize sets a new bottom-right position for the circle object
-// If it has a stroke width this will cause it to Refresh.
-func (c *Circle) Resize(size fyne.Size) {
-	if size == c.Size() {
-		return
-	}
-
-	c.Position2 = fyne.NewPos(c.Position1.X+size.Width, c.Position1.Y+size.Height)
-
-	Refresh(c)
-}
-
-// Show will set this circle to be visible
-func (c *Circle) Show() {
-	c.Hidden = false
-
-	c.Refresh()
-}
-
-// Size returns the current size of bounding box for this circle object
-func (c *Circle) Size() fyne.Size {
-	return fyne.NewSize(float32(math.Abs(float64(c.Position2.X)-float64(c.Position1.X))),
-		float32(math.Abs(float64(c.Position2.Y)-float64(c.Position1.Y))))
-}
-
-// Visible returns true if this circle is visible, false otherwise
-func (c *Circle) Visible() bool {
-	return !c.Hidden
-}

+ 0 - 212
vendor/fyne.io/fyne/v2/canvas/gradient.go

@@ -1,212 +0,0 @@
-package canvas
-
-import (
-	"image"
-	"image/color"
-	"math"
-
-	"fyne.io/fyne/v2"
-)
-
-// LinearGradient defines a Gradient travelling straight at a given angle.
-// The only supported values for the angle are `0.0` (vertical) and `90.0` (horizontal), currently.
-type LinearGradient struct {
-	baseObject
-
-	StartColor color.Color // The beginning color of the gradient
-	EndColor   color.Color // The end color of the gradient
-	Angle      float64     // The angle of the gradient (0/180 for vertical; 90/270 for horizontal)
-}
-
-// Generate calculates an image of the gradient with the specified width and height.
-func (g *LinearGradient) Generate(iw, ih int) image.Image {
-	w, h := float64(iw), float64(ih)
-	var generator func(x, y float64) float64
-	switch g.Angle {
-	case 90: // horizontal flipped
-		generator = func(x, _ float64) float64 {
-			return (w - x) / w
-		}
-	case 270: // horizontal
-		generator = func(x, _ float64) float64 {
-			return x / w
-		}
-	case 45: // diagonal negative flipped
-		generator = func(x, y float64) float64 {
-			return math.Abs((w - x + y) / (w + h)) // ((w+h)-(x+h-y)) / (w+h)
-		}
-	case 225: // diagonal negative
-		generator = func(x, y float64) float64 {
-			return math.Abs((x + h - y) / (w + h))
-		}
-	case 135: // diagonal positive flipped
-		generator = func(x, y float64) float64 {
-			return math.Abs((w + h - (x + y)) / (w + h))
-		}
-	case 315: // diagonal positive
-		generator = func(x, y float64) float64 {
-			return math.Abs((x + y) / (w + h))
-		}
-	case 180: // vertical flipped
-		generator = func(_, y float64) float64 {
-			return (h - y) / h
-		}
-	default: // vertical
-		generator = func(_, y float64) float64 {
-			return y / h
-		}
-	}
-	return computeGradient(generator, iw, ih, g.StartColor, g.EndColor)
-}
-
-// Hide will set this gradient to not be visible
-func (g *LinearGradient) Hide() {
-	g.baseObject.Hide()
-
-	repaint(g)
-}
-
-// Move the gradient to a new position, relative to its parent / canvas
-func (g *LinearGradient) Move(pos fyne.Position) {
-	g.baseObject.Move(pos)
-
-	repaint(g)
-}
-
-// Refresh causes this gradient to be redrawn with its configured state.
-func (g *LinearGradient) Refresh() {
-	Refresh(g)
-}
-
-// RadialGradient defines a Gradient travelling radially from a center point outward.
-type RadialGradient struct {
-	baseObject
-
-	StartColor color.Color // The beginning color of the gradient
-	EndColor   color.Color // The end color of the gradient
-	// The offset of the center for generation of the gradient.
-	// This is not a DP measure but relates to the width/height.
-	// A value of 0.5 would move the center by the half width/height.
-	CenterOffsetX, CenterOffsetY float64
-}
-
-// Generate calculates an image of the gradient with the specified width and height.
-func (g *RadialGradient) Generate(iw, ih int) image.Image {
-	w, h := float64(iw), float64(ih)
-	// define center plus offset
-	centerX := w/2 + w*g.CenterOffsetX
-	centerY := h/2 + h*g.CenterOffsetY
-
-	// handle negative offsets
-	var a, b float64
-	if g.CenterOffsetX < 0 {
-		a = w - centerX
-	} else {
-		a = centerX
-	}
-	if g.CenterOffsetY < 0 {
-		b = h - centerY
-	} else {
-		b = centerY
-	}
-
-	generator := func(x, y float64) float64 {
-		// calculate distance from center for gradient multiplier
-		dx, dy := centerX-x, centerY-y
-		da := math.Sqrt(dx*dx + dy*dy*a*a/b/b)
-		if da > a {
-			return 1
-		}
-		return da / a
-	}
-	return computeGradient(generator, iw, ih, g.StartColor, g.EndColor)
-}
-
-// Hide will set this gradient to not be visible
-func (g *RadialGradient) Hide() {
-	g.baseObject.Hide()
-
-	repaint(g)
-}
-
-// Move the gradient to a new position, relative to its parent / canvas
-func (g *RadialGradient) Move(pos fyne.Position) {
-	g.baseObject.Move(pos)
-
-	repaint(g)
-}
-
-// Refresh causes this gradient to be redrawn with its configured state.
-func (g *RadialGradient) Refresh() {
-	Refresh(g)
-}
-
-func calculatePixel(d float64, startColor, endColor color.Color) color.Color {
-	// fetch RGBA values
-	aR, aG, aB, aA := startColor.RGBA()
-	bR, bG, bB, bA := endColor.RGBA()
-
-	// Get difference
-	dR := float64(bR) - float64(aR)
-	dG := float64(bG) - float64(aG)
-	dB := float64(bB) - float64(aB)
-	dA := float64(bA) - float64(aA)
-
-	// Apply gradations
-	pixel := &color.RGBA64{
-		R: uint16(float64(aR) + d*dR),
-		B: uint16(float64(aB) + d*dB),
-		G: uint16(float64(aG) + d*dG),
-		A: uint16(float64(aA) + d*dA),
-	}
-
-	return pixel
-}
-
-func computeGradient(generator func(x, y float64) float64, w, h int, startColor, endColor color.Color) image.Image {
-	img := image.NewNRGBA(image.Rect(0, 0, w, h))
-
-	if startColor == nil && endColor == nil {
-		return img
-	} else if startColor == nil {
-		startColor = color.Transparent
-	} else if endColor == nil {
-		endColor = color.Transparent
-	}
-
-	for x := 0; x < w; x++ {
-		for y := 0; y < h; y++ {
-			distance := generator(float64(x)+0.5, float64(y)+0.5)
-			img.Set(x, y, calculatePixel(distance, startColor, endColor))
-		}
-	}
-	return img
-}
-
-// NewHorizontalGradient creates a new horizontally travelling linear gradient.
-// The start color will be at the left of the gradient and the end color will be at the right.
-func NewHorizontalGradient(start, end color.Color) *LinearGradient {
-	g := &LinearGradient{StartColor: start, EndColor: end}
-	g.Angle = 270
-	return g
-}
-
-// NewLinearGradient creates a linear gradient at the specified angle.
-// The angle parameter is the degree angle along which the gradient is calculated.
-// A NewHorizontalGradient uses 270 degrees and NewVerticalGradient is 0 degrees.
-func NewLinearGradient(start, end color.Color, angle float64) *LinearGradient {
-	g := &LinearGradient{StartColor: start, EndColor: end}
-	g.Angle = angle
-	return g
-}
-
-// NewRadialGradient creates a new radial gradient.
-func NewRadialGradient(start, end color.Color) *RadialGradient {
-	return &RadialGradient{StartColor: start, EndColor: end}
-}
-
-// NewVerticalGradient creates a new vertically travelling linear gradient.
-// The start color will be at the top of the gradient and the end color will be at the bottom.
-func NewVerticalGradient(start color.Color, end color.Color) *LinearGradient {
-	return &LinearGradient{StartColor: start, EndColor: end}
-}

+ 0 - 362
vendor/fyne.io/fyne/v2/canvas/image.go

@@ -1,362 +0,0 @@
-package canvas
-
-import (
-	"bytes"
-	"errors"
-	"image"
-	_ "image/jpeg" // avoid users having to import when using image widget
-	_ "image/png"  // avoid the same for PNG images
-	"io"
-	"os"
-	"path/filepath"
-	"sync"
-
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/internal/cache"
-	"fyne.io/fyne/v2/internal/scale"
-	"fyne.io/fyne/v2/internal/svg"
-	"fyne.io/fyne/v2/storage"
-)
-
-// ImageFill defines the different type of ways an image can stretch to fill its space.
-type ImageFill int
-
-const (
-	// ImageFillStretch will scale the image to match the Size() values.
-	// This is the default and does not maintain aspect ratio.
-	ImageFillStretch ImageFill = iota
-	// ImageFillContain makes the image fit within the object Size(),
-	// centrally and maintaining aspect ratio.
-	// There may be transparent sections top and bottom or left and right.
-	ImageFillContain // (Fit)
-	// ImageFillOriginal ensures that the container grows to the pixel dimensions
-	// required to fit the original image. The aspect of the image will be maintained so,
-	// as with ImageFillContain there may be transparent areas around the image.
-	// Note that the minSize may be smaller than the image dimensions if scale > 1.
-	ImageFillOriginal
-)
-
-// ImageScale defines the different scaling filters used to scaling images
-type ImageScale int32
-
-const (
-	// ImageScaleSmooth will scale the image using ApproxBiLinear filter (or GL equivalent)
-	ImageScaleSmooth ImageScale = iota
-	// ImageScalePixels will scale the image using NearestNeighbor filter (or GL equivalent)
-	ImageScalePixels
-	// ImageScaleFastest will scale the image using hardware GPU if available
-	//
-	// Since: 2.0
-	ImageScaleFastest
-)
-
-// Declare conformity with CanvasObject interface
-var _ fyne.CanvasObject = (*Image)(nil)
-
-// Image describes a drawable image area that can render in a Fyne canvas
-// The image may be a vector or a bitmap representation, it will fill the area.
-// The fill mode can be changed by setting FillMode to a different ImageFill.
-type Image struct {
-	baseObject
-
-	aspect float32
-	icon   *svg.Decoder
-	isSVG  bool
-	lock   sync.Mutex
-
-	// one of the following sources will provide our image data
-	File     string        // Load the image from a file
-	Resource fyne.Resource // Load the image from an in-memory resource
-	Image    image.Image   // Specify a loaded image to use in this canvas object
-
-	Translucency float64    // Set a translucency value > 0.0 to fade the image
-	FillMode     ImageFill  // Specify how the image should expand to fill or fit the available space
-	ScaleMode    ImageScale // Specify the type of scaling interpolation applied to the image
-}
-
-// Alpha is a convenience function that returns the alpha value for an image
-// based on its Translucency value. The result is 1.0 - Translucency.
-func (i *Image) Alpha() float64 {
-	return 1.0 - i.Translucency
-}
-
-// Aspect will return the original content aspect after it was last refreshed.
-//
-// Since: 2.4
-func (i *Image) Aspect() float32 {
-	if i.aspect == 0 {
-		i.Refresh()
-	}
-	return i.aspect
-}
-
-// Hide will set this image to not be visible
-func (i *Image) Hide() {
-	i.baseObject.Hide()
-
-	repaint(i)
-}
-
-// MinSize returns the specified minimum size, if set, or {1, 1} otherwise.
-func (i *Image) MinSize() fyne.Size {
-	if i.Image == nil || i.aspect == 0 {
-		i.Refresh()
-	}
-	return i.baseObject.MinSize()
-}
-
-// Move the image object to a new position, relative to its parent top, left corner.
-func (i *Image) Move(pos fyne.Position) {
-	i.baseObject.Move(pos)
-
-	repaint(i)
-}
-
-// Refresh causes this image to be redrawn with its configured state.
-func (i *Image) Refresh() {
-	i.lock.Lock()
-	defer i.lock.Unlock()
-
-	rc, err := i.updateReader()
-	if err != nil {
-		fyne.LogError("Failed to load image", err)
-		return
-	}
-	if rc != nil {
-		rcMem := rc
-		defer rcMem.Close()
-	}
-
-	if i.File != "" || i.Resource != nil || i.Image != nil {
-		r, err := i.updateAspectAndMinSize(rc)
-		if err != nil {
-			fyne.LogError("Failed to load image", err)
-			return
-		}
-		rc = io.NopCloser(r)
-	}
-
-	if i.File != "" || i.Resource != nil {
-		size := i.Size()
-		width := size.Width
-		height := size.Height
-
-		if width == 0 || height == 0 {
-			return
-		}
-
-		if i.isSVG {
-			tex, err := i.renderSVG(width, height)
-			if err != nil {
-				fyne.LogError("Failed to render SVG", err)
-				return
-			}
-			i.Image = tex
-		} else {
-			if rc == nil {
-				return
-			}
-
-			img, _, err := image.Decode(rc)
-			if err != nil {
-				fyne.LogError("Failed to render image", err)
-				return
-			}
-			i.Image = img
-		}
-	}
-
-	Refresh(i)
-}
-
-// Resize on an image will scale the content or reposition it according to FillMode.
-// It will normally cause a Refresh to ensure the pixels are recalculated.
-func (i *Image) Resize(s fyne.Size) {
-	if s == i.Size() {
-		return
-	}
-	i.baseObject.Resize(s)
-	if i.FillMode == ImageFillOriginal && i.size.Height > 2 { // we can just ask for a GPU redraw to align
-		Refresh(i)
-		return
-	}
-
-	i.baseObject.Resize(s)
-	if i.isSVG || i.Image == nil {
-		i.Refresh() // we need to rasterise at the new size
-	} else {
-		Refresh(i) // just re-size using GPU scaling
-	}
-}
-
-// NewImageFromFile creates a new image from a local file.
-// Images returned from this method will scale to fit the canvas object.
-// The method for scaling can be set using the Fill field.
-func NewImageFromFile(file string) *Image {
-	return &Image{File: file}
-}
-
-// NewImageFromURI creates a new image from named resource.
-// File URIs will read the file path and other schemes will download the data into a resource.
-// HTTP and HTTPs URIs will use the GET method by default to request the resource.
-// Images returned from this method will scale to fit the canvas object.
-// The method for scaling can be set using the Fill field.
-//
-// Since: 2.0
-func NewImageFromURI(uri fyne.URI) *Image {
-	if uri.Scheme() == "file" && len(uri.String()) > 7 {
-		return NewImageFromFile(uri.Path())
-	}
-
-	var read io.ReadCloser
-
-	read, err := storage.Reader(uri) // attempt unknown / http file type
-	if err != nil {
-		fyne.LogError("Failed to open image URI", err)
-		return &Image{}
-	}
-
-	defer read.Close()
-	return NewImageFromReader(read, filepath.Base(uri.String()))
-}
-
-// NewImageFromReader creates a new image from a data stream.
-// The name parameter is required to uniquely identify this image (for caching etc.).
-// If the image in this io.Reader is an SVG, the name should end ".svg".
-// Images returned from this method will scale to fit the canvas object.
-// The method for scaling can be set using the Fill field.
-//
-// Since: 2.0
-func NewImageFromReader(read io.Reader, name string) *Image {
-	data, err := io.ReadAll(read)
-	if err != nil {
-		fyne.LogError("Unable to read image data", err)
-		return nil
-	}
-
-	res := &fyne.StaticResource{
-		StaticName:    name,
-		StaticContent: data,
-	}
-
-	return NewImageFromResource(res)
-}
-
-// NewImageFromResource creates a new image by loading the specified resource.
-// Images returned from this method will scale to fit the canvas object.
-// The method for scaling can be set using the Fill field.
-func NewImageFromResource(res fyne.Resource) *Image {
-	return &Image{Resource: res}
-}
-
-// NewImageFromImage returns a new Image instance that is rendered from the Go
-// image.Image passed in.
-// Images returned from this method will scale to fit the canvas object.
-// The method for scaling can be set using the Fill field.
-func NewImageFromImage(img image.Image) *Image {
-	return &Image{Image: img}
-}
-
-func (i *Image) name() string {
-	if i.Resource != nil {
-		return i.Resource.Name()
-	} else if i.File != "" {
-		return i.File
-	}
-	return ""
-}
-
-func (i *Image) updateReader() (io.ReadCloser, error) {
-	i.isSVG = false
-	if i.Resource != nil {
-		i.isSVG = svg.IsResourceSVG(i.Resource)
-		return io.NopCloser(bytes.NewReader(i.Resource.Content())), nil
-	} else if i.File != "" {
-		var err error
-
-		fd, err := os.Open(i.File)
-		if err != nil {
-			return nil, err
-		}
-		i.isSVG = svg.IsFileSVG(i.File)
-		return fd, nil
-	}
-	return nil, nil
-}
-
-func (i *Image) updateAspectAndMinSize(reader io.Reader) (io.Reader, error) {
-	var pixWidth, pixHeight int
-
-	if reader != nil {
-		r, width, height, aspect, err := i.imageDetailsFromReader(reader)
-		if err != nil {
-			return nil, err
-		}
-		reader = r
-		i.aspect = aspect
-		pixWidth, pixHeight = width, height
-	} else if i.Image != nil {
-		original := i.Image.Bounds().Size()
-		i.aspect = float32(original.X) / float32(original.Y)
-		pixWidth, pixHeight = original.X, original.Y
-	} else {
-		return nil, errors.New("no matching image source")
-	}
-
-	if i.FillMode == ImageFillOriginal {
-		i.SetMinSize(scale.ToFyneSize(i, pixWidth, pixHeight))
-	}
-	return reader, nil
-}
-
-func (i *Image) imageDetailsFromReader(source io.Reader) (reader io.Reader, width, height int, aspect float32, err error) {
-	if source == nil {
-		return nil, 0, 0, 0, errors.New("no matching reading reader")
-	}
-
-	if i.isSVG {
-		var err error
-
-		i.icon, err = svg.NewDecoder(source)
-		if err != nil {
-			return nil, 0, 0, 0, err
-		}
-		config := i.icon.Config()
-		width, height = config.Width, config.Height
-		aspect = config.Aspect
-	} else {
-		var buf bytes.Buffer
-		tee := io.TeeReader(source, &buf)
-		reader = io.MultiReader(&buf, source)
-
-		config, _, err := image.DecodeConfig(tee)
-		if err != nil {
-			return nil, 0, 0, 0, err
-		}
-		width, height = config.Width, config.Height
-		aspect = float32(width) / float32(height)
-	}
-	return
-}
-
-func (i *Image) renderSVG(width, height float32) (image.Image, error) {
-	c := fyne.CurrentApp().Driver().CanvasForObject(i)
-	screenWidth, screenHeight := int(width), int(height)
-	if c != nil {
-		// We want real output pixel count not just the screen coordinate space (i.e. macOS Retina)
-		screenWidth, screenHeight = c.PixelCoordinateForPosition(fyne.Position{X: width, Y: height})
-	}
-
-	tex := cache.GetSvg(i.name(), screenWidth, screenHeight)
-	if tex != nil {
-		return tex, nil
-	}
-
-	var err error
-	tex, err = i.icon.Draw(screenWidth, screenHeight)
-	if err != nil {
-		return nil, err
-	}
-	cache.SetSvg(i.name(), tex, screenWidth, screenHeight)
-	return tex, nil
-}

+ 0 - 102
vendor/fyne.io/fyne/v2/canvas/line.go

@@ -1,102 +0,0 @@
-package canvas
-
-import (
-	"image/color"
-	"math"
-
-	"fyne.io/fyne/v2"
-)
-
-// Declare conformity with CanvasObject interface
-var _ fyne.CanvasObject = (*Line)(nil)
-
-// Line describes a colored line primitive in a Fyne canvas.
-// Lines are special as they can have a negative width or height to indicate
-// an inverse slope (i.e. slope up vs down).
-type Line struct {
-	Position1 fyne.Position // The current top-left position of the Line
-	Position2 fyne.Position // The current bottom-right position of the Line
-	Hidden    bool          // Is this Line currently hidden
-
-	StrokeColor color.Color // The line stroke color
-	StrokeWidth float32     // The stroke width of the line
-}
-
-// Size returns the current size of bounding box for this line object
-func (l *Line) Size() fyne.Size {
-	return fyne.NewSize(float32(math.Abs(float64(l.Position2.X)-float64(l.Position1.X))),
-		float32(math.Abs(float64(l.Position2.Y)-float64(l.Position1.Y))))
-}
-
-// Resize sets a new bottom-right position for the line object, then it will then be refreshed.
-func (l *Line) Resize(size fyne.Size) {
-	if size == l.Size() {
-		return
-	}
-
-	if l.Position1.X <= l.Position2.X {
-		l.Position2.X = l.Position1.X + size.Width
-	} else {
-		l.Position1.X = l.Position2.X + size.Width
-	}
-	if l.Position1.Y <= l.Position2.Y {
-		l.Position2.Y = l.Position1.Y + size.Height
-	} else {
-		l.Position1.Y = l.Position2.Y + size.Height
-	}
-	Refresh(l)
-}
-
-// Position gets the current top-left position of this line object, relative to its parent / canvas
-func (l *Line) Position() fyne.Position {
-	return fyne.NewPos(fyne.Min(l.Position1.X, l.Position2.X), fyne.Min(l.Position1.Y, l.Position2.Y))
-}
-
-// Move the line object to a new position, relative to its parent / canvas
-func (l *Line) Move(pos fyne.Position) {
-	oldPos := l.Position()
-	deltaX := pos.X - oldPos.X
-	deltaY := pos.Y - oldPos.Y
-
-	l.Position1 = l.Position1.Add(fyne.NewPos(deltaX, deltaY))
-	l.Position2 = l.Position2.Add(fyne.NewPos(deltaX, deltaY))
-	repaint(l)
-}
-
-// MinSize for a Line simply returns Size{1, 1} as there is no
-// explicit content
-func (l *Line) MinSize() fyne.Size {
-	return fyne.NewSize(1, 1)
-}
-
-// Visible returns true if this line// Show will set this circle to be visible is visible, false otherwise
-func (l *Line) Visible() bool {
-	return !l.Hidden
-}
-
-// Show will set this line to be visible
-func (l *Line) Show() {
-	l.Hidden = false
-
-	l.Refresh()
-}
-
-// Hide will set this line to not be visible
-func (l *Line) Hide() {
-	l.Hidden = true
-
-	repaint(l)
-}
-
-// Refresh causes this line to be redrawn with its configured state.
-func (l *Line) Refresh() {
-	Refresh(l)
-}
-
-// NewLine returns a new Line instance
-func NewLine(color color.Color) *Line {
-	return &Line{
-		StrokeColor: color,
-		StrokeWidth: 1,
-	}
-}

+ 0 - 196
vendor/fyne.io/fyne/v2/canvas/raster.go

@@ -1,196 +0,0 @@
-package canvas
-
-import (
-	"image"
-	"image/color"
-	"image/draw"
-
-	"fyne.io/fyne/v2"
-)
-
-// Declare conformity with CanvasObject interface
-var _ fyne.CanvasObject = (*Raster)(nil)
-
-// Raster describes a raster image area that can render in a Fyne canvas
-type Raster struct {
-	baseObject
-
-	// Render the raster image from code
-	Generator func(w, h int) image.Image
-
-	// Set a translucency value > 0.0 to fade the raster
-	Translucency float64
-	// Specify the type of scaling interpolation applied to the raster if it is not full-size
-	// Since: 1.4.1
-	ScaleMode ImageScale
-}
-
-// Alpha is a convenience function that returns the alpha value for a raster
-// based on its Translucency value. The result is 1.0 - Translucency.
-func (r *Raster) Alpha() float64 {
-	return 1.0 - r.Translucency
-}
-
-// Hide will set this raster to not be visible
-func (r *Raster) Hide() {
-	r.baseObject.Hide()
-
-	repaint(r)
-}
-
-// Move the raster to a new position, relative to its parent / canvas
-func (r *Raster) Move(pos fyne.Position) {
-	r.baseObject.Move(pos)
-
-	repaint(r)
-}
-
-// Resize on a raster image causes the new size to be set and then calls Refresh.
-// This causes the underlying data to be recalculated and a new output to be drawn.
-func (r *Raster) Resize(s fyne.Size) {
-	if s == r.Size() {
-		return
-	}
-
-	r.baseObject.Resize(s)
-	Refresh(r)
-}
-
-// Refresh causes this raster to be redrawn with its configured state.
-func (r *Raster) Refresh() {
-	Refresh(r)
-}
-
-// NewRaster returns a new Image instance that is rendered dynamically using
-// the specified generate function.
-// Images returned from this method should draw dynamically to fill the width
-// and height parameters passed to pixelColor.
-func NewRaster(generate func(w, h int) image.Image) *Raster {
-	return &Raster{Generator: generate}
-}
-
-type pixelRaster struct {
-	r *Raster
-
-	img draw.Image
-}
-
-// NewRasterWithPixels returns a new Image instance that is rendered dynamically
-// by iterating over the specified pixelColor function for each x, y pixel.
-// Images returned from this method should draw dynamically to fill the width
-// and height parameters passed to pixelColor.
-func NewRasterWithPixels(pixelColor func(x, y, w, h int) color.Color) *Raster {
-	pix := &pixelRaster{}
-	pix.r = &Raster{
-		Generator: func(w, h int) image.Image {
-			if pix.img == nil || pix.img.Bounds().Size().X != w || pix.img.Bounds().Size().Y != h {
-				// raster first pixel, figure out color type
-				var dst draw.Image
-				rect := image.Rect(0, 0, w, h)
-				switch pixelColor(0, 0, w, h).(type) {
-				case color.Alpha:
-					dst = image.NewAlpha(rect)
-				case color.Alpha16:
-					dst = image.NewAlpha16(rect)
-				case color.CMYK:
-					dst = image.NewCMYK(rect)
-				case color.Gray:
-					dst = image.NewGray(rect)
-				case color.Gray16:
-					dst = image.NewGray16(rect)
-				case color.NRGBA:
-					dst = image.NewNRGBA(rect)
-				case color.NRGBA64:
-					dst = image.NewNRGBA64(rect)
-				case color.RGBA:
-					dst = image.NewRGBA(rect)
-				case color.RGBA64:
-					dst = image.NewRGBA64(rect)
-				default:
-					dst = image.NewRGBA(rect)
-				}
-				pix.img = dst
-			}
-
-			for y := 0; y < h; y++ {
-				for x := 0; x < w; x++ {
-					pix.img.Set(x, y, pixelColor(x, y, w, h))
-				}
-			}
-
-			return pix.img
-		},
-	}
-	return pix.r
-}
-
-type subImg interface {
-	SubImage(r image.Rectangle) image.Image
-}
-
-// NewRasterFromImage returns a new Raster instance that is rendered from the Go
-// image.Image passed in.
-// Rasters returned from this method will map pixel for pixel to the screen
-// starting img.Bounds().Min pixels from the top left of the canvas object.
-// Truncates rather than scales the image.
-// If smaller than the target space, the image will be padded with zero-pixels to the target size.
-func NewRasterFromImage(img image.Image) *Raster {
-	return &Raster{
-		Generator: func(w int, h int) image.Image {
-			bounds := img.Bounds()
-
-			rect := image.Rect(0, 0, w, h)
-
-			switch {
-			case w == bounds.Max.X && h == bounds.Max.Y:
-				return img
-			case w >= bounds.Max.X && h >= bounds.Max.Y:
-				// try quickly truncating
-				if sub, ok := img.(subImg); ok {
-					return sub.SubImage(image.Rectangle{
-						Min: bounds.Min,
-						Max: image.Point{
-							X: bounds.Min.X + w,
-							Y: bounds.Min.Y + h,
-						},
-					})
-				}
-			default:
-				if !rect.Overlaps(bounds) {
-					return image.NewUniform(color.RGBA{})
-				}
-				bounds = bounds.Intersect(rect)
-			}
-
-			// respect the user's pixel format (if possible)
-			var dst draw.Image
-			switch i := img.(type) {
-			case *image.Alpha:
-				dst = image.NewAlpha(rect)
-			case *image.Alpha16:
-				dst = image.NewAlpha16(rect)
-			case *image.CMYK:
-				dst = image.NewCMYK(rect)
-			case *image.Gray:
-				dst = image.NewGray(rect)
-			case *image.Gray16:
-				dst = image.NewGray16(rect)
-			case *image.NRGBA:
-				dst = image.NewNRGBA(rect)
-			case *image.NRGBA64:
-				dst = image.NewNRGBA64(rect)
-			case *image.Paletted:
-				dst = image.NewPaletted(rect, i.Palette)
-			case *image.RGBA:
-				dst = image.NewRGBA(rect)
-			case *image.RGBA64:
-				dst = image.NewRGBA64(rect)
-			default:
-				dst = image.NewRGBA(rect)
-			}
-
-			draw.Draw(dst, bounds, img, bounds.Min, draw.Over)
-			return dst
-		},
-	}
-}

+ 0 - 64
vendor/fyne.io/fyne/v2/canvas/rectangle.go

@@ -1,64 +0,0 @@
-package canvas
-
-import (
-	"image/color"
-
-	"fyne.io/fyne/v2"
-)
-
-// Declare conformity with CanvasObject interface
-var _ fyne.CanvasObject = (*Rectangle)(nil)
-
-// Rectangle describes a colored rectangle primitive in a Fyne canvas
-type Rectangle struct {
-	baseObject
-
-	FillColor   color.Color // The rectangle fill color
-	StrokeColor color.Color // The rectangle stroke color
-	StrokeWidth float32     // The stroke width of the rectangle
-	// The radius of the rectangle corners
-	//
-	// Since: 2.4
-	CornerRadius float32
-}
-
-// Hide will set this rectangle to not be visible
-func (r *Rectangle) Hide() {
-	r.baseObject.Hide()
-
-	repaint(r)
-}
-
-// Move the rectangle to a new position, relative to its parent / canvas
-func (r *Rectangle) Move(pos fyne.Position) {
-	r.baseObject.Move(pos)
-
-	repaint(r)
-}
-
-// Refresh causes this rectangle to be redrawn with its configured state.
-func (r *Rectangle) Refresh() {
-	Refresh(r)
-}
-
-// Resize on a rectangle updates the new size of this object.
-// If it has a stroke width this will cause it to Refresh.
-func (r *Rectangle) Resize(s fyne.Size) {
-	if s == r.Size() {
-		return
-	}
-
-	r.baseObject.Resize(s)
-	if r.StrokeWidth == 0 {
-		return
-	}
-
-	Refresh(r)
-}
-
-// NewRectangle returns a new Rectangle instance
-func NewRectangle(color color.Color) *Rectangle {
-	return &Rectangle{
-		FillColor: color,
-	}
-}

+ 0 - 76
vendor/fyne.io/fyne/v2/canvas/text.go

@@ -1,76 +0,0 @@
-package canvas
-
-import (
-	"image/color"
-
-	"fyne.io/fyne/v2"
-)
-
-// Declare conformity with CanvasObject interface
-var _ fyne.CanvasObject = (*Text)(nil)
-
-// Text describes a text primitive in a Fyne canvas.
-// A text object can have a style set which will apply to the whole string.
-// No formatting or text parsing will be performed
-type Text struct {
-	baseObject
-	Alignment fyne.TextAlign // The alignment of the text content
-
-	Color     color.Color    // The main text draw color
-	Text      string         // The string content of this Text
-	TextSize  float32        // Size of the text - if the Canvas scale is 1.0 this will be equivalent to point size
-	TextStyle fyne.TextStyle // The style of the text content
-}
-
-// Hide will set this text to not be visible
-func (t *Text) Hide() {
-	t.baseObject.Hide()
-
-	repaint(t)
-}
-
-// MinSize returns the minimum size of this text object based on its font size and content.
-// This is normally determined by the render implementation.
-func (t *Text) MinSize() fyne.Size {
-	return fyne.MeasureText(t.Text, t.TextSize, t.TextStyle)
-}
-
-// Move the text to a new position, relative to its parent / canvas
-func (t *Text) Move(pos fyne.Position) {
-	t.baseObject.Move(pos)
-
-	repaint(t)
-}
-
-// Resize on a text updates the new size of this object, which may not result in a visual change, depending on alignment.
-func (t *Text) Resize(s fyne.Size) {
-	if s == t.Size() {
-		return
-	}
-
-	t.baseObject.Resize(s)
-	Refresh(t)
-}
-
-// SetMinSize has no effect as the smallest size this canvas object can be is based on its font size and content.
-func (t *Text) SetMinSize(fyne.Size) {
-	// no-op
-}
-
-// Refresh causes this text to be redrawn with its configured state.
-func (t *Text) Refresh() {
-	Refresh(t)
-}
-
-// NewText returns a new Text implementation
-func NewText(text string, color color.Color) *Text {
-	size := float32(0)
-	if fyne.CurrentApp() != nil { // nil app possible if app not started
-		size = fyne.CurrentApp().Settings().Theme().Size("text") // manually name the size to avoid import loop
-	}
-	return &Text{
-		Color:    color,
-		Text:     text,
-		TextSize: size,
-	}
-}

+ 2 - 2
vendor/fyne.io/fyne/v2/container.go

@@ -129,12 +129,12 @@ func (c *Container) Refresh() {
 // This method is not intended to be used inside a loop, to remove all the elements.
 // This method is not intended to be used inside a loop, to remove all the elements.
 // It is much more efficient to call RemoveAll() instead.
 // It is much more efficient to call RemoveAll() instead.
 func (c *Container) Remove(rem CanvasObject) {
 func (c *Container) Remove(rem CanvasObject) {
+	c.lock.Lock()
+	defer c.lock.Unlock()
 	if len(c.Objects) == 0 {
 	if len(c.Objects) == 0 {
 		return
 		return
 	}
 	}
 
 
-	c.lock.Lock()
-	defer c.lock.Unlock()
 	for i, o := range c.Objects {
 	for i, o := range c.Objects {
 		if o != rem {
 		if o != rem {
 			continue
 			continue

+ 0 - 462
vendor/fyne.io/fyne/v2/container/apptabs.go

@@ -1,462 +0,0 @@
-package container
-
-import (
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/canvas"
-	"fyne.io/fyne/v2/layout"
-	"fyne.io/fyne/v2/theme"
-	"fyne.io/fyne/v2/widget"
-)
-
-// Declare conformity with Widget interface.
-var _ fyne.Widget = (*AppTabs)(nil)
-
-// AppTabs container is used to split your application into various different areas identified by tabs.
-// The tabs contain text and/or an icon and allow the user to switch between the content specified in each TabItem.
-// Each item is represented by a button at the edge of the container.
-//
-// Since: 1.4
-type AppTabs struct {
-	widget.BaseWidget
-
-	Items []*TabItem
-
-	// Deprecated: Use `OnSelected func(*TabItem)` instead.
-	OnChanged    func(*TabItem)
-	OnSelected   func(*TabItem)
-	OnUnselected func(*TabItem)
-
-	current         int
-	location        TabLocation
-	isTransitioning bool
-
-	popUpMenu *widget.PopUpMenu
-}
-
-// NewAppTabs creates a new tab container that allows the user to choose between different areas of an app.
-//
-// Since: 1.4
-func NewAppTabs(items ...*TabItem) *AppTabs {
-	tabs := &AppTabs{}
-	tabs.BaseWidget.ExtendBaseWidget(tabs)
-	tabs.SetItems(items)
-	return tabs
-}
-
-// CreateRenderer is a private method to Fyne which links this widget to its renderer
-//
-// Implements: fyne.Widget
-func (t *AppTabs) CreateRenderer() fyne.WidgetRenderer {
-	t.BaseWidget.ExtendBaseWidget(t)
-	r := &appTabsRenderer{
-		baseTabsRenderer: baseTabsRenderer{
-			bar:       &fyne.Container{},
-			divider:   canvas.NewRectangle(theme.ShadowColor()),
-			indicator: canvas.NewRectangle(theme.PrimaryColor()),
-		},
-		appTabs: t,
-	}
-	r.action = r.buildOverflowTabsButton()
-
-	// Initially setup the tab bar to only show one tab, all others will be in overflow.
-	// When the widget is laid out, and we know the size, the tab bar will be updated to show as many as can fit.
-	r.updateTabs(1)
-	r.updateIndicator(false)
-	r.applyTheme(t)
-	return r
-}
-
-// Append adds a new TabItem to the end of the tab bar.
-func (t *AppTabs) Append(item *TabItem) {
-	t.SetItems(append(t.Items, item))
-}
-
-// CurrentTab returns the currently selected TabItem.
-//
-// Deprecated: Use `AppTabs.Selected() *TabItem` instead.
-func (t *AppTabs) CurrentTab() *TabItem {
-	if t.current < 0 || t.current >= len(t.Items) {
-		return nil
-	}
-	return t.Items[t.current]
-}
-
-// CurrentTabIndex returns the index of the currently selected TabItem.
-//
-// Deprecated: Use `AppTabs.SelectedIndex() int` instead.
-func (t *AppTabs) CurrentTabIndex() int {
-	return t.current
-}
-
-// DisableIndex disables the TabItem at the specified index.
-//
-// Since: 2.3
-func (t *AppTabs) DisableIndex(i int) {
-	disableIndex(t, i)
-}
-
-// DisableItem disables the specified TabItem.
-//
-// Since: 2.3
-func (t *AppTabs) DisableItem(item *TabItem) {
-	disableItem(t, item)
-}
-
-// EnableIndex enables the TabItem at the specified index.
-//
-// Since: 2.3
-func (t *AppTabs) EnableIndex(i int) {
-	enableIndex(t, i)
-}
-
-// EnableItem enables the specified TabItem.
-//
-// Since: 2.3
-func (t *AppTabs) EnableItem(item *TabItem) {
-	enableItem(t, item)
-}
-
-// ExtendBaseWidget is used by an extending widget to make use of BaseWidget functionality.
-//
-// Deprecated: Support for extending containers is being removed
-func (t *AppTabs) ExtendBaseWidget(wid fyne.Widget) {
-	t.BaseWidget.ExtendBaseWidget(wid)
-}
-
-// Hide hides the widget.
-//
-// Implements: fyne.CanvasObject
-func (t *AppTabs) Hide() {
-	if t.popUpMenu != nil {
-		t.popUpMenu.Hide()
-		t.popUpMenu = nil
-	}
-	t.BaseWidget.Hide()
-}
-
-// MinSize returns the size that this widget should not shrink below
-//
-// Implements: fyne.CanvasObject
-func (t *AppTabs) MinSize() fyne.Size {
-	t.BaseWidget.ExtendBaseWidget(t)
-	return t.BaseWidget.MinSize()
-}
-
-// Remove tab by value.
-func (t *AppTabs) Remove(item *TabItem) {
-	removeItem(t, item)
-	t.Refresh()
-}
-
-// RemoveIndex removes tab by index.
-func (t *AppTabs) RemoveIndex(index int) {
-	removeIndex(t, index)
-	t.Refresh()
-}
-
-// Select sets the specified TabItem to be selected and its content visible.
-func (t *AppTabs) Select(item *TabItem) {
-	selectItem(t, item)
-	t.Refresh()
-}
-
-// SelectIndex sets the TabItem at the specific index to be selected and its content visible.
-func (t *AppTabs) SelectIndex(index int) {
-	selectIndex(t, index)
-	t.Refresh()
-}
-
-// SelectTab sets the specified TabItem to be selected and its content visible.
-//
-// Deprecated: Use `AppTabs.Select(*TabItem)` instead.
-func (t *AppTabs) SelectTab(item *TabItem) {
-	for i, child := range t.Items {
-		if child == item {
-			t.SelectTabIndex(i)
-			return
-		}
-	}
-}
-
-// SelectTabIndex sets the TabItem at the specific index to be selected and its content visible.
-//
-// Deprecated: Use `AppTabs.SelectIndex(int)` instead.
-func (t *AppTabs) SelectTabIndex(index int) {
-	if index < 0 || index >= len(t.Items) || t.current == index {
-		return
-	}
-	t.current = index
-	t.Refresh()
-
-	if t.OnChanged != nil {
-		t.OnChanged(t.Items[t.current])
-	}
-}
-
-// Selected returns the currently selected TabItem.
-func (t *AppTabs) Selected() *TabItem {
-	return selected(t)
-}
-
-// SelectedIndex returns the index of the currently selected TabItem.
-func (t *AppTabs) SelectedIndex() int {
-	return t.current
-}
-
-// SetItems sets the containers items and refreshes.
-func (t *AppTabs) SetItems(items []*TabItem) {
-	setItems(t, items)
-	t.Refresh()
-}
-
-// SetTabLocation sets the location of the tab bar
-func (t *AppTabs) SetTabLocation(l TabLocation) {
-	t.location = tabsAdjustedLocation(l)
-	t.Refresh()
-}
-
-// Show this widget, if it was previously hidden
-//
-// Implements: fyne.CanvasObject
-func (t *AppTabs) Show() {
-	t.BaseWidget.Show()
-	t.SelectIndex(t.current)
-}
-
-func (t *AppTabs) onUnselected() func(*TabItem) {
-	return t.OnUnselected
-}
-
-func (t *AppTabs) onSelected() func(*TabItem) {
-	return func(tab *TabItem) {
-		if f := t.OnChanged; f != nil {
-			f(tab)
-		}
-		if f := t.OnSelected; f != nil {
-			f(tab)
-		}
-	}
-}
-
-func (t *AppTabs) items() []*TabItem {
-	return t.Items
-}
-
-func (t *AppTabs) selected() int {
-	return t.current
-}
-
-func (t *AppTabs) setItems(items []*TabItem) {
-	t.Items = items
-}
-
-func (t *AppTabs) setSelected(selected int) {
-	t.current = selected
-}
-
-func (t *AppTabs) setTransitioning(transitioning bool) {
-	t.isTransitioning = transitioning
-}
-
-func (t *AppTabs) tabLocation() TabLocation {
-	return t.location
-}
-
-func (t *AppTabs) transitioning() bool {
-	return t.isTransitioning
-}
-
-// Declare conformity with WidgetRenderer interface.
-var _ fyne.WidgetRenderer = (*appTabsRenderer)(nil)
-
-type appTabsRenderer struct {
-	baseTabsRenderer
-	appTabs *AppTabs
-}
-
-func (r *appTabsRenderer) Layout(size fyne.Size) {
-	// Try render as many tabs as will fit, others will appear in the overflow
-	if len(r.appTabs.Items) == 0 {
-		r.updateTabs(0)
-	} else {
-		for i := len(r.appTabs.Items); i > 0; i-- {
-			r.updateTabs(i)
-			barMin := r.bar.MinSize()
-			if r.appTabs.location == TabLocationLeading || r.appTabs.location == TabLocationTrailing {
-				if barMin.Height <= size.Height {
-					// Tab bar is short enough to fit
-					break
-				}
-			} else {
-				if barMin.Width <= size.Width {
-					// Tab bar is thin enough to fit
-					break
-				}
-			}
-		}
-	}
-
-	r.layout(r.appTabs, size)
-	r.updateIndicator(r.appTabs.transitioning())
-	if r.appTabs.transitioning() {
-		r.appTabs.setTransitioning(false)
-	}
-}
-
-func (r *appTabsRenderer) MinSize() fyne.Size {
-	return r.minSize(r.appTabs)
-}
-
-func (r *appTabsRenderer) Objects() []fyne.CanvasObject {
-	return r.objects(r.appTabs)
-}
-
-func (r *appTabsRenderer) Refresh() {
-	r.Layout(r.appTabs.Size())
-
-	r.refresh(r.appTabs)
-
-	canvas.Refresh(r.appTabs)
-}
-
-func (r *appTabsRenderer) buildOverflowTabsButton() (overflow *widget.Button) {
-	overflow = &widget.Button{Icon: moreIcon(r.appTabs), Importance: widget.LowImportance, OnTapped: func() {
-		// Show pop up containing all tabs which did not fit in the tab bar
-
-		itemLen, objLen := len(r.appTabs.Items), len(r.bar.Objects[0].(*fyne.Container).Objects)
-		items := make([]*fyne.MenuItem, 0, itemLen-objLen)
-		for i := objLen; i < itemLen; i++ {
-			index := i // capture
-			// FIXME MenuItem doesn't support icons (#1752)
-			// FIXME MenuItem can't show if it is the currently selected tab (#1753)
-			items = append(items, fyne.NewMenuItem(r.appTabs.Items[i].Text, func() {
-				r.appTabs.SelectIndex(index)
-				if r.appTabs.popUpMenu != nil {
-					r.appTabs.popUpMenu.Hide()
-					r.appTabs.popUpMenu = nil
-				}
-			}))
-		}
-
-		r.appTabs.popUpMenu = buildPopUpMenu(r.appTabs, overflow, items)
-	}}
-
-	return overflow
-}
-
-func (r *appTabsRenderer) buildTabButtons(count int) *fyne.Container {
-	buttons := &fyne.Container{}
-
-	var iconPos buttonIconPosition
-	if fyne.CurrentDevice().IsMobile() {
-		cells := count
-		if cells == 0 {
-			cells = 1
-		}
-		if r.appTabs.location == TabLocationTop || r.appTabs.location == TabLocationBottom {
-			buttons.Layout = layout.NewGridLayoutWithColumns(cells)
-		} else {
-			buttons.Layout = layout.NewGridLayoutWithRows(cells)
-		}
-		iconPos = buttonIconTop
-	} else if r.appTabs.location == TabLocationLeading || r.appTabs.location == TabLocationTrailing {
-		buttons.Layout = layout.NewVBoxLayout()
-		iconPos = buttonIconTop
-	} else {
-		buttons.Layout = layout.NewHBoxLayout()
-		iconPos = buttonIconInline
-	}
-
-	for i := 0; i < count; i++ {
-		item := r.appTabs.Items[i]
-		if item.button == nil {
-			item.button = &tabButton{
-				onTapped: func() { r.appTabs.Select(item) },
-			}
-		}
-		button := item.button
-		button.icon = item.Icon
-		button.iconPosition = iconPos
-		if i == r.appTabs.current {
-			button.importance = widget.HighImportance
-		} else {
-			button.importance = widget.MediumImportance
-		}
-		button.text = item.Text
-		button.textAlignment = fyne.TextAlignCenter
-		button.Refresh()
-		buttons.Objects = append(buttons.Objects, button)
-	}
-	return buttons
-}
-
-func (r *appTabsRenderer) updateIndicator(animate bool) {
-	if r.appTabs.current < 0 {
-		r.indicator.Hide()
-		return
-	}
-
-	var selectedPos fyne.Position
-	var selectedSize fyne.Size
-
-	buttons := r.bar.Objects[0].(*fyne.Container).Objects
-	if r.appTabs.current >= len(buttons) {
-		if a := r.action; a != nil {
-			selectedPos = a.Position()
-			selectedSize = a.Size()
-		}
-	} else {
-		selected := buttons[r.appTabs.current]
-		selectedPos = selected.Position()
-		selectedSize = selected.Size()
-	}
-
-	var indicatorPos fyne.Position
-	var indicatorSize fyne.Size
-
-	switch r.appTabs.location {
-	case TabLocationTop:
-		indicatorPos = fyne.NewPos(selectedPos.X, r.bar.MinSize().Height)
-		indicatorSize = fyne.NewSize(selectedSize.Width, theme.Padding())
-	case TabLocationLeading:
-		indicatorPos = fyne.NewPos(r.bar.MinSize().Width, selectedPos.Y)
-		indicatorSize = fyne.NewSize(theme.Padding(), selectedSize.Height)
-	case TabLocationBottom:
-		indicatorPos = fyne.NewPos(selectedPos.X, r.bar.Position().Y-theme.Padding())
-		indicatorSize = fyne.NewSize(selectedSize.Width, theme.Padding())
-	case TabLocationTrailing:
-		indicatorPos = fyne.NewPos(r.bar.Position().X-theme.Padding(), selectedPos.Y)
-		indicatorSize = fyne.NewSize(theme.Padding(), selectedSize.Height)
-	}
-
-	r.moveIndicator(indicatorPos, indicatorSize, animate)
-}
-
-func (r *appTabsRenderer) updateTabs(max int) {
-	tabCount := len(r.appTabs.Items)
-
-	// Set overflow action
-	if tabCount <= max {
-		r.action.Hide()
-		r.bar.Layout = layout.NewStackLayout()
-	} else {
-		tabCount = max
-		r.action.Show()
-
-		// Set layout of tab bar containing tab buttons and overflow action
-		if r.appTabs.location == TabLocationLeading || r.appTabs.location == TabLocationTrailing {
-			r.bar.Layout = layout.NewBorderLayout(nil, r.action, nil, nil)
-		} else {
-			r.bar.Layout = layout.NewBorderLayout(nil, nil, nil, r.action)
-		}
-	}
-
-	buttons := r.buildTabButtons(tabCount)
-
-	r.bar.Objects = []fyne.CanvasObject{buttons}
-	if a := r.action; a != nil {
-		r.bar.Objects = append(r.bar.Objects, a)
-	}
-
-	r.bar.Refresh()
-}

+ 0 - 20
vendor/fyne.io/fyne/v2/container/container.go

@@ -1,20 +0,0 @@
-// Package container provides containers that are used to lay out and organise applications.
-package container
-
-import (
-	"fyne.io/fyne/v2"
-)
-
-// New returns a new Container instance holding the specified CanvasObjects which will be laid out according to the specified Layout.
-//
-// Since: 2.0
-func New(layout fyne.Layout, objects ...fyne.CanvasObject) *fyne.Container {
-	return &fyne.Container{Layout: layout, Objects: objects}
-}
-
-// NewWithoutLayout returns a new Container instance holding the specified CanvasObjects that are manually arranged.
-//
-// Since: 2.0
-func NewWithoutLayout(objects ...fyne.CanvasObject) *fyne.Container {
-	return &fyne.Container{Objects: objects}
-}

+ 0 - 496
vendor/fyne.io/fyne/v2/container/doctabs.go

@@ -1,496 +0,0 @@
-package container
-
-import (
-	"image/color"
-
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/canvas"
-	"fyne.io/fyne/v2/layout"
-	"fyne.io/fyne/v2/theme"
-	"fyne.io/fyne/v2/widget"
-)
-
-// Declare conformity with Widget interface.
-var _ fyne.Widget = (*DocTabs)(nil)
-
-// DocTabs container is used to display various pieces of content identified by tabs.
-// The tabs contain text and/or an icon and allow the user to switch between the content specified in each TabItem.
-// Each item is represented by a button at the edge of the container.
-//
-// Since: 2.1
-type DocTabs struct {
-	widget.BaseWidget
-
-	Items []*TabItem
-
-	CreateTab      func() *TabItem
-	CloseIntercept func(*TabItem)
-	OnClosed       func(*TabItem)
-	OnSelected     func(*TabItem)
-	OnUnselected   func(*TabItem)
-
-	current         int
-	location        TabLocation
-	isTransitioning bool
-
-	popUpMenu *widget.PopUpMenu
-}
-
-// NewDocTabs creates a new tab container that allows the user to choose between various pieces of content.
-//
-// Since: 2.1
-func NewDocTabs(items ...*TabItem) *DocTabs {
-	tabs := &DocTabs{}
-	tabs.ExtendBaseWidget(tabs)
-	tabs.SetItems(items)
-	return tabs
-}
-
-// Append adds a new TabItem to the end of the tab bar.
-func (t *DocTabs) Append(item *TabItem) {
-	t.SetItems(append(t.Items, item))
-}
-
-// CreateRenderer is a private method to Fyne which links this widget to its renderer
-//
-// Implements: fyne.Widget
-func (t *DocTabs) CreateRenderer() fyne.WidgetRenderer {
-	t.ExtendBaseWidget(t)
-	r := &docTabsRenderer{
-		baseTabsRenderer: baseTabsRenderer{
-			bar:       &fyne.Container{},
-			divider:   canvas.NewRectangle(theme.ShadowColor()),
-			indicator: canvas.NewRectangle(theme.PrimaryColor()),
-		},
-		docTabs:  t,
-		scroller: NewScroll(&fyne.Container{}),
-	}
-	r.action = r.buildAllTabsButton()
-	r.create = r.buildCreateTabsButton()
-	r.box = NewHBox(r.create, r.action)
-	r.scroller.OnScrolled = func(offset fyne.Position) {
-		r.updateIndicator(false)
-	}
-	r.updateAllTabs()
-	r.updateCreateTab()
-	r.updateTabs()
-	r.updateIndicator(false)
-	r.applyTheme(t)
-	return r
-}
-
-// DisableIndex disables the TabItem at the specified index.
-//
-// Since: 2.3
-func (t *DocTabs) DisableIndex(i int) {
-	disableIndex(t, i)
-}
-
-// DisableItem disables the specified TabItem.
-//
-// Since: 2.3
-func (t *DocTabs) DisableItem(item *TabItem) {
-	disableItem(t, item)
-}
-
-// EnableIndex enables the TabItem at the specified index.
-//
-// Since: 2.3
-func (t *DocTabs) EnableIndex(i int) {
-	enableIndex(t, i)
-}
-
-// EnableItem enables the specified TabItem.
-//
-// Since: 2.3
-func (t *DocTabs) EnableItem(item *TabItem) {
-	enableItem(t, item)
-}
-
-// Hide hides the widget.
-//
-// Implements: fyne.CanvasObject
-func (t *DocTabs) Hide() {
-	if t.popUpMenu != nil {
-		t.popUpMenu.Hide()
-		t.popUpMenu = nil
-	}
-	t.BaseWidget.Hide()
-}
-
-// MinSize returns the size that this widget should not shrink below
-//
-// Implements: fyne.CanvasObject
-func (t *DocTabs) MinSize() fyne.Size {
-	t.ExtendBaseWidget(t)
-	return t.BaseWidget.MinSize()
-}
-
-// Remove tab by value.
-func (t *DocTabs) Remove(item *TabItem) {
-	removeItem(t, item)
-	t.Refresh()
-}
-
-// RemoveIndex removes tab by index.
-func (t *DocTabs) RemoveIndex(index int) {
-	removeIndex(t, index)
-	t.Refresh()
-}
-
-// Select sets the specified TabItem to be selected and its content visible.
-func (t *DocTabs) Select(item *TabItem) {
-	selectItem(t, item)
-	t.Refresh()
-}
-
-// SelectIndex sets the TabItem at the specific index to be selected and its content visible.
-func (t *DocTabs) SelectIndex(index int) {
-	selectIndex(t, index)
-	t.Refresh()
-}
-
-// Selected returns the currently selected TabItem.
-func (t *DocTabs) Selected() *TabItem {
-	return selected(t)
-}
-
-// SelectedIndex returns the index of the currently selected TabItem.
-func (t *DocTabs) SelectedIndex() int {
-	return t.current
-}
-
-// SetItems sets the containers items and refreshes.
-func (t *DocTabs) SetItems(items []*TabItem) {
-	setItems(t, items)
-	t.Refresh()
-}
-
-// SetTabLocation sets the location of the tab bar
-func (t *DocTabs) SetTabLocation(l TabLocation) {
-	t.location = tabsAdjustedLocation(l)
-	t.Refresh()
-}
-
-// Show this widget, if it was previously hidden
-//
-// Implements: fyne.CanvasObject
-func (t *DocTabs) Show() {
-	t.BaseWidget.Show()
-	t.SelectIndex(t.current)
-}
-
-func (t *DocTabs) close(item *TabItem) {
-	if f := t.CloseIntercept; f != nil {
-		f(item)
-	} else {
-		t.Remove(item)
-		if f := t.OnClosed; f != nil {
-			f(item)
-		}
-	}
-}
-
-func (t *DocTabs) onUnselected() func(*TabItem) {
-	return t.OnUnselected
-}
-
-func (t *DocTabs) onSelected() func(*TabItem) {
-	return t.OnSelected
-}
-
-func (t *DocTabs) items() []*TabItem {
-	return t.Items
-}
-
-func (t *DocTabs) selected() int {
-	return t.current
-}
-
-func (t *DocTabs) setItems(items []*TabItem) {
-	t.Items = items
-}
-
-func (t *DocTabs) setSelected(selected int) {
-	t.current = selected
-}
-
-func (t *DocTabs) setTransitioning(transitioning bool) {
-	t.isTransitioning = transitioning
-}
-
-func (t *DocTabs) tabLocation() TabLocation {
-	return t.location
-}
-
-func (t *DocTabs) transitioning() bool {
-	return t.isTransitioning
-}
-
-// Declare conformity with WidgetRenderer interface.
-var _ fyne.WidgetRenderer = (*docTabsRenderer)(nil)
-
-type docTabsRenderer struct {
-	baseTabsRenderer
-	docTabs      *DocTabs
-	scroller     *Scroll
-	box          *fyne.Container
-	create       *widget.Button
-	lastSelected int
-}
-
-func (r *docTabsRenderer) Layout(size fyne.Size) {
-	r.updateAllTabs()
-	r.updateCreateTab()
-	r.updateTabs()
-	r.layout(r.docTabs, size)
-
-	// lay out buttons before updating indicator, which is relative to their position
-	buttons := r.scroller.Content.(*fyne.Container)
-	buttons.Layout.Layout(buttons.Objects, buttons.Size())
-	r.updateIndicator(r.docTabs.transitioning())
-
-	if r.docTabs.transitioning() {
-		r.docTabs.setTransitioning(false)
-	}
-}
-
-func (r *docTabsRenderer) MinSize() fyne.Size {
-	return r.minSize(r.docTabs)
-}
-
-func (r *docTabsRenderer) Objects() []fyne.CanvasObject {
-	return r.objects(r.docTabs)
-}
-
-func (r *docTabsRenderer) Refresh() {
-	r.Layout(r.docTabs.Size())
-
-	if c := r.docTabs.current; c != r.lastSelected {
-		if c >= 0 && c < len(r.docTabs.Items) {
-			r.scrollToSelected()
-		}
-		r.lastSelected = c
-	}
-
-	r.refresh(r.docTabs)
-
-	canvas.Refresh(r.docTabs)
-}
-
-func (r *docTabsRenderer) buildAllTabsButton() (all *widget.Button) {
-	all = &widget.Button{Importance: widget.LowImportance, OnTapped: func() {
-		// Show pop up containing all tabs
-
-		items := make([]*fyne.MenuItem, len(r.docTabs.Items))
-		for i := 0; i < len(r.docTabs.Items); i++ {
-			index := i // capture
-			// FIXME MenuItem doesn't support icons (#1752)
-			items[i] = fyne.NewMenuItem(r.docTabs.Items[i].Text, func() {
-				r.docTabs.SelectIndex(index)
-				if r.docTabs.popUpMenu != nil {
-					r.docTabs.popUpMenu.Hide()
-					r.docTabs.popUpMenu = nil
-				}
-			})
-			items[i].Checked = index == r.docTabs.current
-		}
-
-		r.docTabs.popUpMenu = buildPopUpMenu(r.docTabs, all, items)
-	}}
-
-	return all
-}
-
-func (r *docTabsRenderer) buildCreateTabsButton() *widget.Button {
-	create := widget.NewButton("", func() {
-		if f := r.docTabs.CreateTab; f != nil {
-			if tab := f(); tab != nil {
-				r.docTabs.Append(tab)
-				r.docTabs.SelectIndex(len(r.docTabs.Items) - 1)
-			}
-		}
-	})
-	create.Importance = widget.LowImportance
-	return create
-}
-
-func (r *docTabsRenderer) buildTabButtons(count int, buttons *fyne.Container) {
-	buttons.Objects = nil
-
-	var iconPos buttonIconPosition
-	if fyne.CurrentDevice().IsMobile() {
-		cells := count
-		if cells == 0 {
-			cells = 1
-		}
-		if r.docTabs.location == TabLocationTop || r.docTabs.location == TabLocationBottom {
-			buttons.Layout = layout.NewGridLayoutWithColumns(cells)
-		} else {
-			buttons.Layout = layout.NewGridLayoutWithRows(cells)
-		}
-		iconPos = buttonIconTop
-	} else if r.docTabs.location == TabLocationLeading || r.docTabs.location == TabLocationTrailing {
-		buttons.Layout = layout.NewVBoxLayout()
-		iconPos = buttonIconTop
-	} else {
-		buttons.Layout = layout.NewHBoxLayout()
-		iconPos = buttonIconInline
-	}
-
-	for i := 0; i < count; i++ {
-		item := r.docTabs.Items[i]
-		if item.button == nil {
-			item.button = &tabButton{
-				onTapped: func() { r.docTabs.Select(item) },
-				onClosed: func() { r.docTabs.close(item) },
-			}
-		}
-		button := item.button
-		button.icon = item.Icon
-		button.iconPosition = iconPos
-		if i == r.docTabs.current {
-			button.importance = widget.HighImportance
-		} else {
-			button.importance = widget.MediumImportance
-		}
-		button.text = item.Text
-		button.textAlignment = fyne.TextAlignLeading
-		button.Refresh()
-		buttons.Objects = append(buttons.Objects, button)
-	}
-}
-
-func (r *docTabsRenderer) scrollToSelected() {
-	buttons := r.scroller.Content.(*fyne.Container)
-
-	// https://github.com/fyne-io/fyne/issues/3909
-	// very dirty temporary fix to this crash!
-	if r.docTabs.current < 0 || r.docTabs.current >= len(buttons.Objects) {
-		return
-	}
-
-	button := buttons.Objects[r.docTabs.current]
-	pos := button.Position()
-	size := button.Size()
-	offset := r.scroller.Offset
-	viewport := r.scroller.Size()
-	if r.docTabs.location == TabLocationLeading || r.docTabs.location == TabLocationTrailing {
-		if pos.Y < offset.Y {
-			offset.Y = pos.Y
-		} else if pos.Y+size.Height > offset.Y+viewport.Height {
-			offset.Y = pos.Y + size.Height - viewport.Height
-		}
-	} else {
-		if pos.X < offset.X {
-			offset.X = pos.X
-		} else if pos.X+size.Width > offset.X+viewport.Width {
-			offset.X = pos.X + size.Width - viewport.Width
-		}
-	}
-	r.scroller.Offset = offset
-	r.updateIndicator(false)
-}
-
-func (r *docTabsRenderer) updateIndicator(animate bool) {
-	if r.docTabs.current < 0 {
-		r.indicator.FillColor = color.Transparent
-		r.moveIndicator(fyne.NewPos(0, 0), fyne.NewSize(0, 0), animate)
-		return
-	}
-
-	var selectedPos fyne.Position
-	var selectedSize fyne.Size
-
-	buttons := r.scroller.Content.(*fyne.Container).Objects
-
-	if r.docTabs.current >= len(buttons) {
-		if a := r.action; a != nil {
-			selectedPos = a.Position()
-			selectedSize = a.Size()
-			minSize := a.MinSize()
-			if minSize.Width > selectedSize.Width {
-				selectedSize = minSize
-			}
-		}
-	} else {
-		selected := buttons[r.docTabs.current]
-		selectedPos = selected.Position()
-		selectedSize = selected.Size()
-		minSize := selected.MinSize()
-		if minSize.Width > selectedSize.Width {
-			selectedSize = minSize
-		}
-	}
-
-	scrollOffset := r.scroller.Offset
-	scrollSize := r.scroller.Size()
-
-	var indicatorPos fyne.Position
-	var indicatorSize fyne.Size
-
-	switch r.docTabs.location {
-	case TabLocationTop:
-		indicatorPos = fyne.NewPos(selectedPos.X-scrollOffset.X, r.bar.MinSize().Height)
-		indicatorSize = fyne.NewSize(fyne.Min(selectedSize.Width, scrollSize.Width-indicatorPos.X), theme.Padding())
-	case TabLocationLeading:
-		indicatorPos = fyne.NewPos(r.bar.MinSize().Width, selectedPos.Y-scrollOffset.Y)
-		indicatorSize = fyne.NewSize(theme.Padding(), fyne.Min(selectedSize.Height, scrollSize.Height-indicatorPos.Y))
-	case TabLocationBottom:
-		indicatorPos = fyne.NewPos(selectedPos.X-scrollOffset.X, r.bar.Position().Y-theme.Padding())
-		indicatorSize = fyne.NewSize(fyne.Min(selectedSize.Width, scrollSize.Width-indicatorPos.X), theme.Padding())
-	case TabLocationTrailing:
-		indicatorPos = fyne.NewPos(r.bar.Position().X-theme.Padding(), selectedPos.Y-scrollOffset.Y)
-		indicatorSize = fyne.NewSize(theme.Padding(), fyne.Min(selectedSize.Height, scrollSize.Height-indicatorPos.Y))
-	}
-
-	if indicatorPos.X < 0 {
-		indicatorSize.Width = indicatorSize.Width + indicatorPos.X
-		indicatorPos.X = 0
-	}
-	if indicatorPos.Y < 0 {
-		indicatorSize.Height = indicatorSize.Height + indicatorPos.Y
-		indicatorPos.Y = 0
-	}
-	if indicatorSize.Width < 0 || indicatorSize.Height < 0 {
-		r.indicator.FillColor = color.Transparent
-		r.indicator.Refresh()
-		return
-	}
-
-	r.moveIndicator(indicatorPos, indicatorSize, animate)
-}
-
-func (r *docTabsRenderer) updateAllTabs() {
-	if len(r.docTabs.Items) > 0 {
-		r.action.Show()
-	} else {
-		r.action.Hide()
-	}
-}
-
-func (r *docTabsRenderer) updateCreateTab() {
-	if r.docTabs.CreateTab != nil {
-		r.create.SetIcon(theme.ContentAddIcon())
-		r.create.Show()
-	} else {
-		r.create.Hide()
-	}
-}
-
-func (r *docTabsRenderer) updateTabs() {
-	tabCount := len(r.docTabs.Items)
-	r.buildTabButtons(tabCount, r.scroller.Content.(*fyne.Container))
-
-	// Set layout of tab bar containing tab buttons and overflow action
-	if r.docTabs.location == TabLocationLeading || r.docTabs.location == TabLocationTrailing {
-		r.bar.Layout = layout.NewBorderLayout(nil, r.box, nil, nil)
-		r.scroller.Direction = ScrollVerticalOnly
-	} else {
-		r.bar.Layout = layout.NewBorderLayout(nil, nil, nil, r.box)
-		r.scroller.Direction = ScrollHorizontalOnly
-	}
-
-	r.bar.Objects = []fyne.CanvasObject{r.scroller, r.box}
-	r.bar.Refresh()
-}

+ 0 - 121
vendor/fyne.io/fyne/v2/container/layouts.go

@@ -1,121 +0,0 @@
-package container // import "fyne.io/fyne/v2/container"
-
-import (
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/internal"
-	"fyne.io/fyne/v2/layout"
-)
-
-// NewAdaptiveGrid creates a new container with the specified objects and using the grid layout.
-// When in a horizontal arrangement the rowcols parameter will specify the column count, when in vertical
-// it will specify the rows. On mobile this will dynamically refresh when device is rotated.
-//
-// Since: 1.4
-func NewAdaptiveGrid(rowcols int, objects ...fyne.CanvasObject) *fyne.Container {
-	return New(layout.NewAdaptiveGridLayout(rowcols), objects...)
-}
-
-// NewBorder creates a new container with the specified objects and using the border layout.
-// The top, bottom, left and right parameters specify the items that should be placed around edges,
-// the remaining elements will be in the center. Nil can be used to an edge if it should not be filled.
-//
-// Since: 1.4
-func NewBorder(top, bottom, left, right fyne.CanvasObject, objects ...fyne.CanvasObject) *fyne.Container {
-	all := objects
-	if top != nil {
-		all = append(all, top)
-	}
-	if bottom != nil {
-		all = append(all, bottom)
-	}
-	if left != nil {
-		all = append(all, left)
-	}
-	if right != nil {
-		all = append(all, right)
-	}
-
-	if len(objects) == 1 && objects[0] == nil {
-		internal.LogHint("Border layout requires only 4 parameters, optional items cannot be nil")
-		all = all[1:]
-	}
-	return New(layout.NewBorderLayout(top, bottom, left, right), all...)
-}
-
-// NewCenter creates a new container with the specified objects centered in the available space.
-//
-// Since: 1.4
-func NewCenter(objects ...fyne.CanvasObject) *fyne.Container {
-	return New(layout.NewCenterLayout(), objects...)
-}
-
-// NewGridWithColumns creates a new container with the specified objects and using the grid layout with
-// a specified number of columns. The number of rows will depend on how many children are in the container.
-//
-// Since: 1.4
-func NewGridWithColumns(cols int, objects ...fyne.CanvasObject) *fyne.Container {
-	return New(layout.NewGridLayoutWithColumns(cols), objects...)
-}
-
-// NewGridWithRows creates a new container with the specified objects and using the grid layout with
-// a specified number of rows. The number of columns will depend on how many children are in the container.
-//
-// Since: 1.4
-func NewGridWithRows(rows int, objects ...fyne.CanvasObject) *fyne.Container {
-	return New(layout.NewGridLayoutWithRows(rows), objects...)
-}
-
-// NewGridWrap creates a new container with the specified objects and using the gridwrap layout.
-// Every element will be resized to the size parameter and the content will arrange along a row and flow to a
-// new row if the elements don't fit.
-//
-// Since: 1.4
-func NewGridWrap(size fyne.Size, objects ...fyne.CanvasObject) *fyne.Container {
-	return New(layout.NewGridWrapLayout(size), objects...)
-}
-
-// NewHBox creates a new container with the specified objects and using the HBox layout.
-// The objects will be placed in the container from left to right and always displayed
-// at their horizontal MinSize. Use a different layout if the objects are intended
-// to be larger then their horizontal MinSize.
-//
-// Since: 1.4
-func NewHBox(objects ...fyne.CanvasObject) *fyne.Container {
-	return New(layout.NewHBoxLayout(), objects...)
-}
-
-// NewMax creates a new container with the specified objects filling the available space.
-//
-// Since: 1.4
-//
-// Deprecated: Use container.NewStack() instead.
-func NewMax(objects ...fyne.CanvasObject) *fyne.Container {
-	return NewStack(objects...)
-}
-
-// NewPadded creates a new container with the specified objects inset by standard padding size.
-//
-// Since: 1.4
-func NewPadded(objects ...fyne.CanvasObject) *fyne.Container {
-	return New(layout.NewPaddedLayout(), objects...)
-}
-
-// NewStack returns a new container that stacks objects on top of each other.
-// Objects at the end of the container will be stacked on top of objects before.
-// Having only a single object has no impact as CanvasObjects will
-// fill the available space even without a Stack.
-//
-// Since: 2.4
-func NewStack(objects ...fyne.CanvasObject) *fyne.Container {
-	return New(layout.NewStackLayout(), objects...)
-}
-
-// NewVBox creates a new container with the specified objects and using the VBox layout.
-// The objects will be stacked in the container from top to bottom and always displayed
-// at their vertical MinSize. Use a different layout if the objects are intended
-// to be larger then their vertical MinSize.
-//
-// Since: 1.4
-func NewVBox(objects ...fyne.CanvasObject) *fyne.Container {
-	return New(layout.NewVBoxLayout(), objects...)
-}

+ 0 - 55
vendor/fyne.io/fyne/v2/container/scroll.go

@@ -1,55 +0,0 @@
-package container
-
-import (
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/internal/widget"
-)
-
-// Scroll defines a container that is smaller than the Content.
-// The Offset is used to determine the position of the child widgets within the container.
-//
-// Since: 1.4
-type Scroll = widget.Scroll
-
-// ScrollDirection represents the directions in which a Scroll container can scroll its child content.
-//
-// Since: 1.4
-type ScrollDirection = widget.ScrollDirection
-
-// Constants for valid values of ScrollDirection.
-const (
-	// ScrollBoth supports horizontal and vertical scrolling.
-	ScrollBoth ScrollDirection = widget.ScrollBoth
-	// ScrollHorizontalOnly specifies the scrolling should only happen left to right.
-	ScrollHorizontalOnly = widget.ScrollHorizontalOnly
-	// ScrollVerticalOnly specifies the scrolling should only happen top to bottom.
-	ScrollVerticalOnly = widget.ScrollVerticalOnly
-	// ScrollNone turns off scrolling for this container.
-	//
-	// Since: 2.1
-	ScrollNone = widget.ScrollNone
-)
-
-// NewScroll creates a scrollable parent wrapping the specified content.
-// Note that this may cause the MinSize to be smaller than that of the passed object.
-//
-// Since: 1.4
-func NewScroll(content fyne.CanvasObject) *Scroll {
-	return widget.NewScroll(content)
-}
-
-// NewHScroll create a scrollable parent wrapping the specified content.
-// Note that this may cause the MinSize.Width to be smaller than that of the passed object.
-//
-// Since: 1.4
-func NewHScroll(content fyne.CanvasObject) *Scroll {
-	return widget.NewHScroll(content)
-}
-
-// NewVScroll a scrollable parent wrapping the specified content.
-// Note that this may cause the MinSize.Height to be smaller than that of the passed object.
-//
-// Since: 1.4
-func NewVScroll(content fyne.CanvasObject) *Scroll {
-	return widget.NewVScroll(content)
-}

+ 0 - 369
vendor/fyne.io/fyne/v2/container/split.go

@@ -1,369 +0,0 @@
-package container
-
-import (
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/canvas"
-	"fyne.io/fyne/v2/driver/desktop"
-	"fyne.io/fyne/v2/theme"
-	"fyne.io/fyne/v2/widget"
-)
-
-// Declare conformity with CanvasObject interface
-var _ fyne.CanvasObject = (*Split)(nil)
-
-// Split defines a container whose size is split between two children.
-//
-// Since: 1.4
-type Split struct {
-	widget.BaseWidget
-	Offset     float64
-	Horizontal bool
-	Leading    fyne.CanvasObject
-	Trailing   fyne.CanvasObject
-}
-
-// NewHSplit creates a horizontally arranged container with the specified leading and trailing elements.
-// A vertical split bar that can be dragged will be added between the elements.
-//
-// Since: 1.4
-func NewHSplit(leading, trailing fyne.CanvasObject) *Split {
-	return newSplitContainer(true, leading, trailing)
-}
-
-// NewVSplit creates a vertically arranged container with the specified top and bottom elements.
-// A horizontal split bar that can be dragged will be added between the elements.
-//
-// Since: 1.4
-func NewVSplit(top, bottom fyne.CanvasObject) *Split {
-	return newSplitContainer(false, top, bottom)
-}
-
-func newSplitContainer(horizontal bool, leading, trailing fyne.CanvasObject) *Split {
-	s := &Split{
-		Offset:     0.5, // Sensible default, can be overridden with SetOffset
-		Horizontal: horizontal,
-		Leading:    leading,
-		Trailing:   trailing,
-	}
-	s.BaseWidget.ExtendBaseWidget(s)
-	return s
-}
-
-// CreateRenderer is a private method to Fyne which links this widget to its renderer
-func (s *Split) CreateRenderer() fyne.WidgetRenderer {
-	s.BaseWidget.ExtendBaseWidget(s)
-	d := newDivider(s)
-	return &splitContainerRenderer{
-		split:   s,
-		divider: d,
-		objects: []fyne.CanvasObject{s.Leading, d, s.Trailing},
-	}
-}
-
-// ExtendBaseWidget is used by an extending widget to make use of BaseWidget functionality.
-//
-// Deprecated: Support for extending containers is being removed
-func (s *Split) ExtendBaseWidget(wid fyne.Widget) {
-	s.BaseWidget.ExtendBaseWidget(wid)
-}
-
-// SetOffset sets the offset (0.0 to 1.0) of the Split divider.
-// 0.0 - Leading is min size, Trailing uses all remaining space.
-// 0.5 - Leading & Trailing equally share the available space.
-// 1.0 - Trailing is min size, Leading uses all remaining space.
-func (s *Split) SetOffset(offset float64) {
-	if s.Offset == offset {
-		return
-	}
-	s.Offset = offset
-	s.Refresh()
-}
-
-var _ fyne.WidgetRenderer = (*splitContainerRenderer)(nil)
-
-type splitContainerRenderer struct {
-	split   *Split
-	divider *divider
-	objects []fyne.CanvasObject
-}
-
-func (r *splitContainerRenderer) Destroy() {
-}
-
-func (r *splitContainerRenderer) Layout(size fyne.Size) {
-	var dividerPos, leadingPos, trailingPos fyne.Position
-	var dividerSize, leadingSize, trailingSize fyne.Size
-
-	if r.split.Horizontal {
-		lw, tw := r.computeSplitLengths(size.Width, r.minLeadingWidth(), r.minTrailingWidth())
-		leadingPos.X = 0
-		leadingSize.Width = lw
-		leadingSize.Height = size.Height
-		dividerPos.X = lw
-		dividerSize.Width = dividerThickness()
-		dividerSize.Height = size.Height
-		trailingPos.X = lw + dividerSize.Width
-		trailingSize.Width = tw
-		trailingSize.Height = size.Height
-	} else {
-		lh, th := r.computeSplitLengths(size.Height, r.minLeadingHeight(), r.minTrailingHeight())
-		leadingPos.Y = 0
-		leadingSize.Width = size.Width
-		leadingSize.Height = lh
-		dividerPos.Y = lh
-		dividerSize.Width = size.Width
-		dividerSize.Height = dividerThickness()
-		trailingPos.Y = lh + dividerSize.Height
-		trailingSize.Width = size.Width
-		trailingSize.Height = th
-	}
-
-	r.divider.Move(dividerPos)
-	r.divider.Resize(dividerSize)
-	r.split.Leading.Move(leadingPos)
-	r.split.Leading.Resize(leadingSize)
-	r.split.Trailing.Move(trailingPos)
-	r.split.Trailing.Resize(trailingSize)
-	canvas.Refresh(r.divider)
-}
-
-func (r *splitContainerRenderer) MinSize() fyne.Size {
-	s := fyne.NewSize(0, 0)
-	for _, o := range r.objects {
-		min := o.MinSize()
-		if r.split.Horizontal {
-			s.Width += min.Width
-			s.Height = fyne.Max(s.Height, min.Height)
-		} else {
-			s.Width = fyne.Max(s.Width, min.Width)
-			s.Height += min.Height
-		}
-	}
-	return s
-}
-
-func (r *splitContainerRenderer) Objects() []fyne.CanvasObject {
-	return r.objects
-}
-
-func (r *splitContainerRenderer) Refresh() {
-	r.objects[0] = r.split.Leading
-	// [1] is divider which doesn't change
-	r.objects[2] = r.split.Trailing
-	r.Layout(r.split.Size())
-	canvas.Refresh(r.split)
-}
-
-func (r *splitContainerRenderer) computeSplitLengths(total, lMin, tMin float32) (float32, float32) {
-	available := float64(total - dividerThickness())
-	if available <= 0 {
-		return 0, 0
-	}
-	ld := float64(lMin)
-	tr := float64(tMin)
-	offset := r.split.Offset
-
-	min := ld / available
-	max := 1 - tr/available
-	if min <= max {
-		if offset < min {
-			offset = min
-		}
-		if offset > max {
-			offset = max
-		}
-	} else {
-		offset = ld / (ld + tr)
-	}
-
-	ld = offset * available
-	tr = available - ld
-	return float32(ld), float32(tr)
-}
-
-func (r *splitContainerRenderer) minLeadingWidth() float32 {
-	if r.split.Leading.Visible() {
-		return r.split.Leading.MinSize().Width
-	}
-	return 0
-}
-
-func (r *splitContainerRenderer) minLeadingHeight() float32 {
-	if r.split.Leading.Visible() {
-		return r.split.Leading.MinSize().Height
-	}
-	return 0
-}
-
-func (r *splitContainerRenderer) minTrailingWidth() float32 {
-	if r.split.Trailing.Visible() {
-		return r.split.Trailing.MinSize().Width
-	}
-	return 0
-}
-
-func (r *splitContainerRenderer) minTrailingHeight() float32 {
-	if r.split.Trailing.Visible() {
-		return r.split.Trailing.MinSize().Height
-	}
-	return 0
-}
-
-// Declare conformity with interfaces
-var _ fyne.CanvasObject = (*divider)(nil)
-var _ fyne.Draggable = (*divider)(nil)
-var _ desktop.Cursorable = (*divider)(nil)
-var _ desktop.Hoverable = (*divider)(nil)
-
-type divider struct {
-	widget.BaseWidget
-	split          *Split
-	hovered        bool
-	startDragOff   *fyne.Position
-	currentDragPos fyne.Position
-}
-
-func newDivider(split *Split) *divider {
-	d := &divider{
-		split: split,
-	}
-	d.ExtendBaseWidget(d)
-	return d
-}
-
-// CreateRenderer is a private method to Fyne which links this widget to its renderer
-func (d *divider) CreateRenderer() fyne.WidgetRenderer {
-	d.ExtendBaseWidget(d)
-	background := canvas.NewRectangle(theme.ShadowColor())
-	foreground := canvas.NewRectangle(theme.ForegroundColor())
-	return &dividerRenderer{
-		divider:    d,
-		background: background,
-		foreground: foreground,
-		objects:    []fyne.CanvasObject{background, foreground},
-	}
-}
-
-func (d *divider) Cursor() desktop.Cursor {
-	if d.split.Horizontal {
-		return desktop.HResizeCursor
-	}
-	return desktop.VResizeCursor
-}
-
-func (d *divider) DragEnd() {
-	d.startDragOff = nil
-}
-
-func (d *divider) Dragged(e *fyne.DragEvent) {
-	if d.startDragOff == nil {
-		d.currentDragPos = d.Position().Add(e.Position)
-		start := e.Position.Subtract(e.Dragged)
-		d.startDragOff = &start
-	} else {
-		d.currentDragPos = d.currentDragPos.Add(e.Dragged)
-	}
-
-	x, y := d.currentDragPos.Components()
-	var offset, leadingRatio, trailingRatio float64
-	if d.split.Horizontal {
-		widthFree := float64(d.split.Size().Width - dividerThickness())
-		leadingRatio = float64(d.split.Leading.MinSize().Width) / widthFree
-		trailingRatio = 1. - (float64(d.split.Trailing.MinSize().Width) / widthFree)
-		offset = float64(x-d.startDragOff.X) / widthFree
-	} else {
-		heightFree := float64(d.split.Size().Height - dividerThickness())
-		leadingRatio = float64(d.split.Leading.MinSize().Height) / heightFree
-		trailingRatio = 1. - (float64(d.split.Trailing.MinSize().Height) / heightFree)
-		offset = float64(y-d.startDragOff.Y) / heightFree
-	}
-
-	if offset < leadingRatio {
-		offset = leadingRatio
-	}
-	if offset > trailingRatio {
-		offset = trailingRatio
-	}
-	d.split.SetOffset(offset)
-}
-
-func (d *divider) MouseIn(event *desktop.MouseEvent) {
-	d.hovered = true
-	d.split.Refresh()
-}
-
-func (d *divider) MouseMoved(event *desktop.MouseEvent) {}
-
-func (d *divider) MouseOut() {
-	d.hovered = false
-	d.split.Refresh()
-}
-
-var _ fyne.WidgetRenderer = (*dividerRenderer)(nil)
-
-type dividerRenderer struct {
-	divider    *divider
-	background *canvas.Rectangle
-	foreground *canvas.Rectangle
-	objects    []fyne.CanvasObject
-}
-
-func (r *dividerRenderer) Destroy() {
-}
-
-func (r *dividerRenderer) Layout(size fyne.Size) {
-	r.background.Resize(size)
-	var x, y, w, h float32
-	if r.divider.split.Horizontal {
-		x = (dividerThickness() - handleThickness()) / 2
-		y = (size.Height - handleLength()) / 2
-		w = handleThickness()
-		h = handleLength()
-	} else {
-		x = (size.Width - handleLength()) / 2
-		y = (dividerThickness() - handleThickness()) / 2
-		w = handleLength()
-		h = handleThickness()
-	}
-	r.foreground.Move(fyne.NewPos(x, y))
-	r.foreground.Resize(fyne.NewSize(w, h))
-}
-
-func (r *dividerRenderer) MinSize() fyne.Size {
-	if r.divider.split.Horizontal {
-		return fyne.NewSize(dividerThickness(), dividerLength())
-	}
-	return fyne.NewSize(dividerLength(), dividerThickness())
-}
-
-func (r *dividerRenderer) Objects() []fyne.CanvasObject {
-	return r.objects
-}
-
-func (r *dividerRenderer) Refresh() {
-	if r.divider.hovered {
-		r.background.FillColor = theme.HoverColor()
-	} else {
-		r.background.FillColor = theme.ShadowColor()
-	}
-	r.background.Refresh()
-	r.foreground.FillColor = theme.ForegroundColor()
-	r.foreground.Refresh()
-	r.Layout(r.divider.Size())
-}
-
-func dividerThickness() float32 {
-	return theme.Padding() * 2
-}
-
-func dividerLength() float32 {
-	return theme.Padding() * 6
-}
-
-func handleThickness() float32 {
-	return theme.Padding() / 2
-}
-
-func handleLength() float32 {
-	return theme.Padding() * 4
-}

+ 0 - 843
vendor/fyne.io/fyne/v2/container/tabs.go

@@ -1,843 +0,0 @@
-package container
-
-import (
-	"sync"
-
-	"fyne.io/fyne/v2"
-	"fyne.io/fyne/v2/canvas"
-	"fyne.io/fyne/v2/driver/desktop"
-	"fyne.io/fyne/v2/internal"
-	"fyne.io/fyne/v2/theme"
-	"fyne.io/fyne/v2/widget"
-)
-
-// TabItem represents a single view in a tab view.
-// The Text and Icon are used for the tab button and the Content is shown when the corresponding tab is active.
-//
-// Since: 1.4
-type TabItem struct {
-	Text    string
-	Icon    fyne.Resource
-	Content fyne.CanvasObject
-
-	button *tabButton
-}
-
-// Disabled returns whether or not the TabItem is disabled.
-//
-// Since: 2.3
-func (ti *TabItem) Disabled() bool {
-	if ti.button != nil {
-		return ti.button.Disabled()
-	}
-	return false
-}
-
-func (ti *TabItem) disable() {
-	if ti.button != nil {
-		ti.button.Disable()
-	}
-}
-
-func (ti *TabItem) enable() {
-	if ti.button != nil {
-		ti.button.Enable()
-	}
-}
-
-// TabLocation is the location where the tabs of a tab container should be rendered
-//
-// Since: 1.4
-type TabLocation int
-
-// TabLocation values
-const (
-	TabLocationTop TabLocation = iota
-	TabLocationLeading
-	TabLocationBottom
-	TabLocationTrailing
-)
-
-// NewTabItem creates a new item for a tabbed widget - each item specifies the content and a label for its tab.
-//
-// Since: 1.4
-func NewTabItem(text string, content fyne.CanvasObject) *TabItem {
-	return &TabItem{Text: text, Content: content}
-}
-
-// NewTabItemWithIcon creates a new item for a tabbed widget - each item specifies the content and a label with an icon for its tab.
-//
-// Since: 1.4
-func NewTabItemWithIcon(text string, icon fyne.Resource, content fyne.CanvasObject) *TabItem {
-	return &TabItem{Text: text, Icon: icon, Content: content}
-}
-
-type baseTabs interface {
-	onUnselected() func(*TabItem)
-	onSelected() func(*TabItem)
-
-	items() []*TabItem
-	setItems([]*TabItem)
-
-	selected() int
-	setSelected(int)
-
-	tabLocation() TabLocation
-
-	transitioning() bool
-	setTransitioning(bool)
-}
-
-func tabsAdjustedLocation(l TabLocation) TabLocation {
-	// Mobile has limited screen space, so don't put app tab bar on long edges
-	if d := fyne.CurrentDevice(); d.IsMobile() {
-		if o := d.Orientation(); fyne.IsVertical(o) {
-			if l == TabLocationLeading {
-				return TabLocationTop
-			} else if l == TabLocationTrailing {
-				return TabLocationBottom
-			}
-		} else {
-			if l == TabLocationTop {
-				return TabLocationLeading
-			} else if l == TabLocationBottom {
-				return TabLocationTrailing
-			}
-		}
-	}
-
-	return l
-}
-
-func buildPopUpMenu(t baseTabs, button *widget.Button, items []*fyne.MenuItem) *widget.PopUpMenu {
-	d := fyne.CurrentApp().Driver()
-	c := d.CanvasForObject(button)
-	popUpMenu := widget.NewPopUpMenu(fyne.NewMenu("", items...), c)
-	buttonPos := d.AbsolutePositionForObject(button)
-	buttonSize := button.Size()
-	popUpMin := popUpMenu.MinSize()
-	var popUpPos fyne.Position
-	switch t.tabLocation() {
-	case TabLocationLeading:
-		popUpPos.X = buttonPos.X + buttonSize.Width
-		popUpPos.Y = buttonPos.Y + buttonSize.Height - popUpMin.Height
-	case TabLocationTrailing:
-		popUpPos.X = buttonPos.X - popUpMin.Width
-		popUpPos.Y = buttonPos.Y + buttonSize.Height - popUpMin.Height
-	case TabLocationTop:
-		popUpPos.X = buttonPos.X + buttonSize.Width - popUpMin.Width
-		popUpPos.Y = buttonPos.Y + buttonSize.Height
-	case TabLocationBottom:
-		popUpPos.X = buttonPos.X + buttonSize.Width - popUpMin.Width
-		popUpPos.Y = buttonPos.Y - popUpMin.Height
-	}
-	if popUpPos.X < 0 {
-		popUpPos.X = 0
-	}
-	if popUpPos.Y < 0 {
-		popUpPos.Y = 0
-	}
-	popUpMenu.ShowAtPosition(popUpPos)
-	return popUpMenu
-}
-
-func removeIndex(t baseTabs, index int) {
-	items := t.items()
-	if index < 0 || index >= len(items) {
-		return
-	}
-	setItems(t, append(items[:index], items[index+1:]...))
-	if s := t.selected(); index < s {
-		t.setSelected(s - 1)
-	}
-}
-
-func removeItem(t baseTabs, item *TabItem) {
-	for index, existingItem := range t.items() {
-		if existingItem == item {
-			removeIndex(t, index)
-			break
-		}
-	}
-}
-
-func selected(t baseTabs) *TabItem {
-	selected := t.selected()
-	items := t.items()
-	if selected < 0 || selected >= len(items) {
-		return nil
-	}
-	return items[selected]
-}
-
-func selectIndex(t baseTabs, index int) {
-	selected := t.selected()
-
-	if selected == index {
-		// No change, so do nothing
-		return
-	}
-
-	items := t.items()
-
-	if f := t.onUnselected(); f != nil && selected >= 0 && selected < len(items) {
-		// Notification of unselected
-		f(items[selected])
-	}
-
-	if index < 0 || index >= len(items) {
-		// Out of bounds, so do nothing
-		return
-	}
-
-	t.setTransitioning(true)
-	t.setSelected(index)
-
-	if f := t.onSelected(); f != nil {
-		// Notification of selected
-		f(items[index])
-	}
-}
-
-func selectItem(t baseTabs, item *TabItem) {
-	for i, child := range t.items() {
-		if child == item {
-			selectIndex(t, i)
-			return
-		}
-	}
-}
-
-func setItems(t baseTabs, items []*TabItem) {
-	if internal.HintsEnabled && mismatchedTabItems(items) {
-		internal.LogHint("Tab items should all have the same type of content (text, icons or both)")
-	}
-	t.setItems(items)
-	selected := t.selected()
-	count := len(items)
-	switch {
-	case count == 0:
-		// No items available to be selected
-		selectIndex(t, -1) // Unsure OnUnselected gets called if applicable
-		t.setSelected(-1)
-	case selected < 0:
-		// Current is first tab item
-		selectIndex(t, 0)
-	case selected >= count:
-		// Current doesn't exist, select last tab
-		selectIndex(t, count-1)
-	}
-}
-
-func disableIndex(t baseTabs, index int) {
-	items := t.items()
-	if index < 0 || index >= len(items) {
-		return
-	}
-
-	item := items[index]
-	item.disable()
-
-	if selected(t) == item {
-		// the disabled tab is currently selected, so select the first enabled tab
-		for i, it := range items {
-			if !it.Disabled() {
-				selectIndex(t, i)
-				break
-			}
-		}
-	}
-
-	if selected(t) == item {
-		selectIndex(t, -1) // no other tab is able to be selected
-	}
-}
-
-func disableItem(t baseTabs, item *TabItem) {
-	for i, it := range t.items() {
-		if it == item {
-			disableIndex(t, i)
-			return
-		}
-	}
-}
-
-func enableIndex(t baseTabs, index int) {
-	items := t.items()
-	if index < 0 || index >= len(items) {
-		return
-	}
-
-	item := items[index]
-	item.enable()
-}
-
-func enableItem(t baseTabs, item *TabItem) {
-	for i, it := range t.items() {
-		if it == item {
-			enableIndex(t, i)
-			return
-		}
-	}
-}
-
-type baseTabsRenderer struct {
-	positionAnimation, sizeAnimation *fyne.Animation
-
-	lastIndicatorMutex  sync.RWMutex
-	lastIndicatorPos    fyne.Position
-	lastIndicatorSize   fyne.Size
-	lastIndicatorHidden bool
-
-	action             *widget.Button
-	bar                *fyne.Container
-	divider, indicator *canvas.Rectangle
-}
-
-func (r *baseTabsRenderer) Destroy() {
-}
-
-func (r *baseTabsRenderer) applyTheme(t baseTabs) {
-	if r.action != nil {
-		r.action.SetIcon(moreIcon(t))
-	}
-	r.divider.FillColor = theme.ShadowColor()
-	r.indicator.FillColor = theme.PrimaryColor()
-	r.indicator.CornerRadius = theme.SelectionRadiusSize()
-}
-
-func (r *baseTabsRenderer) layout(t baseTabs, size fyne.Size) {
-	var (
-		barPos, dividerPos, contentPos    fyne.Position
-		barSize, dividerSize, contentSize fyne.Size
-	)
-
-	barMin := r.bar.MinSize()
-
-	padding := theme.Padding()
-	switch t.tabLocation() {
-	case TabLocationTop:
-		barHeight := barMin.Height
-		barPos = fyne.NewPos(0, 0)
-		barSize = fyne.NewSize(size.Width, barHeight)
-		dividerPos = fyne.NewPos(0, barHeight)
-		dividerSize = fyne.NewSize(size.Width, padding)
-		contentPos = fyne.NewPos(0, barHeight+padding)
-		contentSize = fyne.NewSize(size.Width, size.Height-barHeight-padding)
-	case TabLocationLeading:
-		barWidth := barMin.Width
-		barPos = fyne.NewPos(0, 0)
-		barSize = fyne.NewSize(barWidth, size.Height)
-		dividerPos = fyne.NewPos(barWidth, 0)
-		dividerSize = fyne.NewSize(padding, size.Height)
-		contentPos = fyne.NewPos(barWidth+theme.Padding(), 0)
-		contentSize = fyne.NewSize(size.Width-barWidth-padding, size.Height)
-	case TabLocationBottom:
-		barHeight := barMin.Height
-		barPos = fyne.NewPos(0, size.Height-barHeight)
-		barSize = fyne.NewSize(size.Width, barHeight)
-		dividerPos = fyne.NewPos(0, size.Height-barHeight-padding)
-		dividerSize = fyne.NewSize(size.Width, padding)
-		contentPos = fyne.NewPos(0, 0)
-		contentSize = fyne.NewSize(size.Width, size.Height-barHeight-padding)
-	case TabLocationTrailing:
-		barWidth := barMin.Width
-		barPos = fyne.NewPos(size.Width-barWidth, 0)
-		barSize = fyne.NewSize(barWidth, size.Height)
-		dividerPos = fyne.NewPos(size.Width-barWidth-padding, 0)
-		dividerSize = fyne.NewSize(padding, size.Height)
-		contentPos = fyne.NewPos(0, 0)
-		contentSize = fyne.NewSize(size.Width-barWidth-padding, size.Height)
-	}
-
-	r.bar.Move(barPos)
-	r.bar.Resize(barSize)
-	r.divider.Move(dividerPos)
-	r.divider.Resize(dividerSize)
-	selected := t.selected()
-	for i, ti := range t.items() {
-		if i == selected {
-			ti.Content.Move(contentPos)
-			ti.Content.Resize(contentSize)
-			ti.Content.Show()
-		} else {
-			ti.Content.Hide()
-		}
-	}
-}
-
-func (r *baseTabsRenderer) minSize(t baseTabs) fyne.Size {
-	pad := theme.Padding()
-	buttonPad := pad
-	barMin := r.bar.MinSize()
-	tabsMin := r.bar.Objects[0].MinSize()
-	accessory := r.bar.Objects[1]
-	accessoryMin := accessory.MinSize()
-	if scroll, ok := r.bar.Objects[0].(*Scroll); ok && len(scroll.Content.(*fyne.Container).Objects) == 0 {
-		tabsMin = fyne.Size{} // scroller forces 32 where we don't need any space
-		buttonPad = 0
-	} else if group, ok := r.bar.Objects[0].(*fyne.Container); ok && len(group.Objects) > 0 {
-		tabsMin = group.Objects[0].MinSize()
-		buttonPad = 0
-	}
-	if !accessory.Visible() || accessoryMin.Width == 0 {
-		buttonPad = 0
-		accessoryMin = fyne.Size{}
-	}
-
-	contentMin := fyne.NewSize(0, 0)
-	for _, content := range t.items() {
-		contentMin = contentMin.Max(content.Content.MinSize())
-	}
-
-	switch t.tabLocation() {
-	case TabLocationLeading, TabLocationTrailing:
-		return fyne.NewSize(barMin.Width+contentMin.Width+pad,
-			fyne.Max(contentMin.Height, accessoryMin.Height+buttonPad+tabsMin.Height))
-	default:
-		return fyne.NewSize(fyne.Max(contentMin.Width, accessoryMin.Width+buttonPad+tabsMin.Width),
-			barMin.Height+contentMin.Height+pad)
-	}
-}
-
-func (r *baseTabsRenderer) moveIndicator(pos fyne.Position, siz fyne.Size, animate bool) {
-	r.lastIndicatorMutex.RLock()
-	isSameState := r.lastIndicatorPos.Subtract(pos).IsZero() && r.lastIndicatorSize.Subtract(siz).IsZero() &&
-		r.lastIndicatorHidden == r.indicator.Hidden
-	r.lastIndicatorMutex.RUnlock()
-	if isSameState {
-		return
-	}
-
-	if r.positionAnimation != nil {
-		r.positionAnimation.Stop()
-		r.positionAnimation = nil
-	}
-	if r.sizeAnimation != nil {
-		r.sizeAnimation.Stop()
-		r.sizeAnimation = nil
-	}
-
-	r.indicator.FillColor = theme.PrimaryColor()
-	if r.indicator.Position().IsZero() {
-		r.indicator.Move(pos)
-		r.indicator.Resize(siz)
-		r.indicator.Refresh()
-		return
-	}
-
-	r.lastIndicatorMutex.Lock()
-	r.lastIndicatorPos = pos
-	r.lastIndicatorSize = siz
-	r.lastIndicatorHidden = r.indicator.Hidden
-	r.lastIndicatorMutex.Unlock()
-
-	if animate && fyne.CurrentApp().Settings().ShowAnimations() {
-		r.positionAnimation = canvas.NewPositionAnimation(r.indicator.Position(), pos, canvas.DurationShort, func(p fyne.Position) {
-			r.indicator.Move(p)
-			r.indicator.Refresh()
-			if pos == p {
-				r.positionAnimation.Stop()
-				r.positionAnimation = nil
-			}
-		})
-		r.sizeAnimation = canvas.NewSizeAnimation(r.indicator.Size(), siz, canvas.DurationShort, func(s fyne.Size) {
-			r.indicator.Resize(s)
-			r.indicator.Refresh()
-			if siz == s {
-				r.sizeAnimation.Stop()
-				r.sizeAnimation = nil
-			}
-		})
-
-		r.positionAnimation.Start()
-		r.sizeAnimation.Start()
-	} else {
-		r.indicator.Move(pos)
-		r.indicator.Resize(siz)
-		r.indicator.Refresh()
-	}
-}
-
-func (r *baseTabsRenderer) objects(t baseTabs) []fyne.CanvasObject {
-	objects := []fyne.CanvasObject{r.bar, r.divider, r.indicator}
-	if i, is := t.selected(), t.items(); i >= 0 && i < len(is) {
-		objects = append(objects, is[i].Content)
-	}
-	return objects
-}
-
-func (r *baseTabsRenderer) refresh(t baseTabs) {
-	r.applyTheme(t)
-
-	r.bar.Refresh()
-	r.divider.Refresh()
-	r.indicator.Refresh()
-}
-
-type buttonIconPosition int
-
-const (
-	buttonIconInline buttonIconPosition = iota
-	buttonIconTop
-)
-
-var _ fyne.Widget = (*tabButton)(nil)
-var _ fyne.Tappable = (*tabButton)(nil)
-var _ desktop.Hoverable = (*tabButton)(nil)
-
-type tabButton struct {
-	widget.DisableableWidget
-	hovered       bool
-	icon          fyne.Resource
-	iconPosition  buttonIconPosition
-	importance    widget.Importance
-	onTapped      func()
-	onClosed      func()
-	text          string
-	textAlignment fyne.TextAlign
-}
-
-func (b *tabButton) CreateRenderer() fyne.WidgetRenderer {
-	b.ExtendBaseWidget(b)
-	background := canvas.NewRectangle(theme.HoverColor())
-	background.CornerRadius = theme.SelectionRadiusSize()
-	background.Hide()
-	icon := canvas.NewImageFromResource(b.icon)
-	if b.icon == nil {
-		icon.Hide()
-	}
-
-	label := canvas.NewText(b.text, theme.ForegroundColor())
-	label.TextStyle.Bold = true
-
-	close := &tabCloseButton{
-		parent: b,
-		onTapped: func() {
-			if f := b.onClosed; f != nil {
-				f()
-			}
-		},
-	}
-	close.ExtendBaseWidget(close)
-	close.Hide()
-
-	objects := []fyne.CanvasObject{background, label, close, icon}
-	r := &tabButtonRenderer{
-		button:     b,
-		background: background,
-		icon:       icon,
-		label:      label,
-		close:      close,
-		objects:    objects,
-	}
-	r.Refresh()
-	return r
-}
-
-func (b *tabButton) MinSize() fyne.Size {
-	b.ExtendBaseWidget(b)
-	return b.BaseWidget.MinSize()
-}
-
-func (b *tabButton) MouseIn(*desktop.MouseEvent) {
-	b.hovered = true
-	b.Refresh()
-}
-
-func (b *tabButton) MouseMoved(*desktop.MouseEvent) {
-}
-
-func (b *tabButton) MouseOut() {
-	b.hovered = false
-	b.Refresh()
-}
-
-func (b *tabButton) Tapped(*fyne.PointEvent) {
-	if b.Disabled() {
-		return
-	}
-
-	b.onTapped()
-}
-
-type tabButtonRenderer struct {
-	button     *tabButton
-	background *canvas.Rectangle
-	icon       *canvas.Image
-	label      *canvas.Text
-	close      *tabCloseButton
-	objects    []fyne.CanvasObject
-}
-
-func (r *tabButtonRenderer) Destroy() {
-}
-
-func (r *tabButtonRenderer) Layout(size fyne.Size) {
-	r.background.Resize(size)
-	padding := r.padding()
-	innerSize := size.Subtract(padding)
-	innerOffset := fyne.NewPos(padding.Width/2, padding.Height/2)
-	labelShift := float32(0)
-	if r.icon.Visible() {
-		iconSize := r.iconSize()
-		var iconOffset fyne.Position
-		if r.button.iconPosition == buttonIconTop {
-			iconOffset = fyne.NewPos((innerSize.Width-iconSize)/2, 0)
-		} else {
-			iconOffset = fyne.NewPos(0, (innerSize.Height-iconSize)/2)
-		}
-		r.icon.Resize(fyne.NewSquareSize(iconSize))
-		r.icon.Move(innerOffset.Add(iconOffset))
-		labelShift = iconSize + theme.Padding()
-	}
-	if r.label.Text != "" {
-		var labelOffset fyne.Position
-		var labelSize fyne.Size
-		if r.button.iconPosition == buttonIconTop {
-			labelOffset = fyne.NewPos(0, labelShift)
-			labelSize = fyne.NewSize(innerSize.Width, r.label.MinSize().Height)
-		} else {
-			labelOffset = fyne.NewPos(labelShift, 0)
-			labelSize = fyne.NewSize(innerSize.Width-labelShift, innerSize.Height)
-		}
-		r.label.Resize(labelSize)
-		r.label.Move(innerOffset.Add(labelOffset))
-	}
-	inlineIconSize := theme.IconInlineSize()
-	r.close.Move(fyne.NewPos(size.Width-inlineIconSize-theme.Padding(), (size.Height-inlineIconSize)/2))
-	r.close.Resize(fyne.NewSquareSize(inlineIconSize))
-}
-
-func (r *tabButtonRenderer) MinSize() fyne.Size {
-	var contentWidth, contentHeight float32
-	textSize := r.label.MinSize()
-	iconSize := r.iconSize()
-	padding := theme.Padding()
-	if r.button.iconPosition == buttonIconTop {
-		contentWidth = fyne.Max(textSize.Width, iconSize)
-		if r.icon.Visible() {
-			contentHeight += iconSize
-		}
-		if r.label.Text != "" {
-			if r.icon.Visible() {
-				contentHeight += padding
-			}
-			contentHeight += textSize.Height
-		}
-	} else {
-		contentHeight = fyne.Max(textSize.Height, iconSize)
-		if r.icon.Visible() {
-			contentWidth += iconSize
-		}
-		if r.label.Text != "" {
-			if r.icon.Visible() {
-				contentWidth += padding
-			}
-			contentWidth += textSize.Width
-		}
-	}
-	if r.button.onClosed != nil {
-		inlineIconSize := theme.IconInlineSize()
-		contentWidth += inlineIconSize + padding
-		contentHeight = fyne.Max(contentHeight, inlineIconSize)
-	}
-	return fyne.NewSize(contentWidth, contentHeight).Add(r.padding())
-}
-
-func (r *tabButtonRenderer) Objects() []fyne.CanvasObject {
-	return r.objects
-}
-
-func (r *tabButtonRenderer) Refresh() {
-	if r.button.hovered && !r.button.Disabled() {
-		r.background.FillColor = theme.HoverColor()
-		r.background.CornerRadius = theme.SelectionRadiusSize()
-		r.background.Show()
-	} else {
-		r.background.Hide()
-	}
-	r.background.Refresh()
-
-	r.label.Text = r.button.text
-	r.label.Alignment = r.button.textAlignment
-	if !r.button.Disabled() {
-		if r.button.importance == widget.HighImportance {
-			r.label.Color = theme.PrimaryColor()
-		} else {
-			r.label.Color = theme.ForegroundColor()
-		}
-	} else {
-		r.label.Color = theme.DisabledColor()
-	}
-	r.label.TextSize = theme.TextSize()
-	if r.button.text == "" {
-		r.label.Hide()
-	} else {
-		r.label.Show()
-	}
-
-	r.icon.Resource = r.button.icon
-	if r.icon.Resource != nil {
-		r.icon.Show()
-		switch res := r.icon.Resource.(type) {
-		case *theme.ThemedResource:
-			if r.button.importance == widget.HighImportance {
-				r.icon.Resource = theme.NewPrimaryThemedResource(res)
-				r.icon.Refresh()
-			}
-		case *theme.PrimaryThemedResource:
-			if r.button.importance != widget.HighImportance {
-				r.icon.Resource = res.Original()
-				r.icon.Refresh()
-			}
-		}
-	} else {
-		r.icon.Hide()
-	}
-
-	if d := fyne.CurrentDevice(); r.button.onClosed != nil && (d.IsMobile() || r.button.hovered || r.close.hovered) {
-		r.close.Show()
-	} else {
-		r.close.Hide()
-	}
-	r.close.Refresh()
-
-	canvas.Refresh(r.button)
-}
-
-func (r *tabButtonRenderer) iconSize() float32 {
-	if r.button.iconPosition == buttonIconTop {
-		return 2 * theme.IconInlineSize()
-	}
-
-	return theme.IconInlineSize()
-}
-
-func (r *tabButtonRenderer) padding() fyne.Size {
-	padding := theme.InnerPadding()
-	if r.label.Text != "" && r.button.iconPosition == buttonIconInline {
-		return fyne.NewSquareSize(padding * 2)
-	}
-	return fyne.NewSize(padding, padding*2)
-}
-
-var _ fyne.Widget = (*tabCloseButton)(nil)
-var _ fyne.Tappable = (*tabCloseButton)(nil)
-var _ desktop.Hoverable = (*tabCloseButton)(nil)
-
-type tabCloseButton struct {
-	widget.BaseWidget
-	parent   *tabButton
-	hovered  bool
-	onTapped func()
-}
-
-func (b *tabCloseButton) CreateRenderer() fyne.WidgetRenderer {
-	b.ExtendBaseWidget(b)
-	background := canvas.NewRectangle(theme.HoverColor())
-	background.CornerRadius = theme.SelectionRadiusSize()
-	background.Hide()
-	icon := canvas.NewImageFromResource(theme.CancelIcon())
-
-	r := &tabCloseButtonRenderer{
-		button:     b,
-		background: background,
-		icon:       icon,
-		objects:    []fyne.CanvasObject{background, icon},
-	}
-	r.Refresh()
-	return r
-}
-
-func (b *tabCloseButton) MinSize() fyne.Size {
-	b.ExtendBaseWidget(b)
-	return b.BaseWidget.MinSize()
-}
-
-func (b *tabCloseButton) MouseIn(*desktop.MouseEvent) {
-	b.hovered = true
-	b.parent.Refresh()
-}
-
-func (b *tabCloseButton) MouseMoved(*desktop.MouseEvent) {
-}
-
-func (b *tabCloseButton) MouseOut() {
-	b.hovered = false
-	b.parent.Refresh()
-}
-
-func (b *tabCloseButton) Tapped(*fyne.PointEvent) {
-	b.onTapped()
-}
-
-type tabCloseButtonRenderer struct {
-	button     *tabCloseButton
-	background *canvas.Rectangle
-	icon       *canvas.Image
-	objects    []fyne.CanvasObject
-}
-
-func (r *tabCloseButtonRenderer) Destroy() {
-}
-
-func (r *tabCloseButtonRenderer) Layout(size fyne.Size) {
-	r.background.Resize(size)
-	r.icon.Resize(size)
-}
-
-func (r *tabCloseButtonRenderer) MinSize() fyne.Size {
-	return fyne.NewSquareSize(theme.IconInlineSize())
-}
-
-func (r *tabCloseButtonRenderer) Objects() []fyne.CanvasObject {
-	return r.objects
-}
-
-func (r *tabCloseButtonRenderer) Refresh() {
-	if r.button.hovered {
-		r.background.FillColor = theme.HoverColor()
-		r.background.CornerRadius = theme.SelectionRadiusSize()
-		r.background.Show()
-	} else {
-		r.background.Hide()
-	}
-	r.background.Refresh()
-	switch res := r.icon.Resource.(type) {
-	case *theme.ThemedResource:
-		if r.button.parent.importance == widget.HighImportance {
-			r.icon.Resource = theme.NewPrimaryThemedResource(res)
-		}
-	case *theme.PrimaryThemedResource:
-		if r.button.parent.importance != widget.HighImportance {
-			r.icon.Resource = res.Original()
-		}
-	}
-	r.icon.Refresh()
-}
-
-func mismatchedTabItems(items []*TabItem) bool {
-	var hasText, hasIcon bool
-	for _, tab := range items {
-		hasText = hasText || tab.Text != ""
-		hasIcon = hasIcon || tab.Icon != nil
-	}
-
-	mismatch := false
-	for _, tab := range items {
-		if (hasText && tab.Text == "") || (hasIcon && tab.Icon == nil) {
-			mismatch = true
-			break
-		}
-	}
-
-	return mismatch
-}
-
-func moreIcon(t baseTabs) fyne.Resource {
-	if l := t.tabLocation(); l == TabLocationLeading || l == TabLocationTrailing {
-		return theme.MoreVerticalIcon()
-	}
-	return theme.MoreHorizontalIcon()
-}

+ 0 - 178
vendor/fyne.io/fyne/v2/data/binding/binding.go

@@ -1,178 +0,0 @@
-//go:generate go run gen.go
-
-// Package binding provides support for binding data to widgets.
-package binding
-
-import (
-	"errors"
-	"reflect"
-	"sync"
-
-	"fyne.io/fyne/v2"
-)
-
-var (
-	errKeyNotFound = errors.New("key not found")
-	errOutOfBounds = errors.New("index out of bounds")
-	errParseFailed = errors.New("format did not match 1 value")
-
-	// As an optimisation we connect any listeners asking for the same key, so that there is only 1 per preference item.
-	prefBinds = newPreferencesMap()
-)
-
-// DataItem is the base interface for all bindable data items.
-//
-// Since: 2.0
-type DataItem interface {
-	// AddListener attaches a new change listener to this DataItem.
-	// Listeners are called each time the data inside this DataItem changes.
-	// Additionally the listener will be triggered upon successful connection to get the current value.
-	AddListener(DataListener)
-	// RemoveListener will detach the specified change listener from the DataItem.
-	// Disconnected listener will no longer be triggered when changes occur.
-	RemoveListener(DataListener)
-}
-
-// DataListener is any object that can register for changes in a bindable DataItem.
-// See NewDataListener to define a new listener using just an inline function.
-//
-// Since: 2.0
-type DataListener interface {
-	DataChanged()
-}
-
-// NewDataListener is a helper function that creates a new listener type from a simple callback function.
-//
-// Since: 2.0
-func NewDataListener(fn func()) DataListener {
-	return &listener{fn}
-}
-
-type listener struct {
-	callback func()
-}
-
-func (l *listener) DataChanged() {
-	l.callback()
-}
-
-type base struct {
-	listeners sync.Map // map[DataListener]bool
-
-	lock sync.RWMutex
-}
-
-// AddListener allows a data listener to be informed of changes to this item.
-func (b *base) AddListener(l DataListener) {
-	b.listeners.Store(l, true)
-	queueItem(l.DataChanged)
-}
-
-// RemoveListener should be called if the listener is no longer interested in being informed of data change events.
-func (b *base) RemoveListener(l DataListener) {
-	b.listeners.Delete(l)
-}
-
-func (b *base) trigger() {
-	b.listeners.Range(func(key, _ interface{}) bool {
-		queueItem(key.(DataListener).DataChanged)
-		return true
-	})
-}
-
-// Untyped supports binding a interface{} value.
-//
-// Since: 2.1
-type Untyped interface {
-	DataItem
-	Get() (interface{}, error)
-	Set(interface{}) error
-}
-
-// NewUntyped returns a bindable interface{} value that is managed internally.
-//
-// Since: 2.1
-func NewUntyped() Untyped {
-	var blank interface{} = nil
-	v := &blank
-	return &boundUntyped{val: reflect.ValueOf(v).Elem()}
-}
-
-type boundUntyped struct {
-	base
-
-	val reflect.Value
-}
-
-func (b *boundUntyped) Get() (interface{}, error) {
-	b.lock.RLock()
-	defer b.lock.RUnlock()
-
-	return b.val.Interface(), nil
-}
-
-func (b *boundUntyped) Set(val interface{}) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if b.val.Interface() == val {
-		return nil
-	}
-
-	b.val.Set(reflect.ValueOf(val))
-
-	b.trigger()
-	return nil
-}
-
-// ExternalUntyped supports binding a interface{} value to an external value.
-//
-// Since: 2.1
-type ExternalUntyped interface {
-	Untyped
-	Reload() error
-}
-
-// BindUntyped returns a bindable interface{} value that is bound to an external type.
-// The parameter must be a pointer to the type you wish to bind.
-//
-// Since: 2.1
-func BindUntyped(v interface{}) ExternalUntyped {
-	t := reflect.TypeOf(v)
-	if t.Kind() != reflect.Ptr {
-		fyne.LogError("Invalid type passed to BindUntyped, must be a pointer", nil)
-		v = nil
-	}
-
-	if v == nil {
-		var blank interface{}
-		v = &blank // never allow a nil value pointer
-	}
-
-	b := &boundExternalUntyped{}
-	b.val = reflect.ValueOf(v).Elem()
-	b.old = b.val.Interface()
-	return b
-}
-
-type boundExternalUntyped struct {
-	boundUntyped
-
-	old interface{}
-}
-
-func (b *boundExternalUntyped) Set(val interface{}) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if b.old == val {
-		return nil
-	}
-	b.val.Set(reflect.ValueOf(val))
-	b.old = val
-
-	b.trigger()
-	return nil
-}
-
-func (b *boundExternalUntyped) Reload() error {
-	return b.Set(b.val.Interface())
-}

+ 0 - 647
vendor/fyne.io/fyne/v2/data/binding/binditems.go

@@ -1,647 +0,0 @@
-// auto-generated
-// **** THIS FILE IS AUTO-GENERATED, PLEASE DO NOT EDIT IT **** //
-
-package binding
-
-import (
-	"bytes"
-
-	"fyne.io/fyne/v2"
-)
-
-// Bool supports binding a bool value.
-//
-// Since: 2.0
-type Bool interface {
-	DataItem
-	Get() (bool, error)
-	Set(bool) error
-}
-
-// ExternalBool supports binding a bool value to an external value.
-//
-// Since: 2.0
-type ExternalBool interface {
-	Bool
-	Reload() error
-}
-
-// NewBool returns a bindable bool value that is managed internally.
-//
-// Since: 2.0
-func NewBool() Bool {
-	var blank bool = false
-	return &boundBool{val: &blank}
-}
-
-// BindBool returns a new bindable value that controls the contents of the provided bool variable.
-// If your code changes the content of the variable this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.0
-func BindBool(v *bool) ExternalBool {
-	if v == nil {
-		var blank bool = false
-		v = &blank // never allow a nil value pointer
-	}
-	b := &boundExternalBool{}
-	b.val = v
-	b.old = *v
-	return b
-}
-
-type boundBool struct {
-	base
-
-	val *bool
-}
-
-func (b *boundBool) Get() (bool, error) {
-	b.lock.RLock()
-	defer b.lock.RUnlock()
-
-	if b.val == nil {
-		return false, nil
-	}
-	return *b.val, nil
-}
-
-func (b *boundBool) Set(val bool) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if *b.val == val {
-		return nil
-	}
-	*b.val = val
-
-	b.trigger()
-	return nil
-}
-
-type boundExternalBool struct {
-	boundBool
-
-	old bool
-}
-
-func (b *boundExternalBool) Set(val bool) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if b.old == val {
-		return nil
-	}
-	*b.val = val
-	b.old = val
-
-	b.trigger()
-	return nil
-}
-
-func (b *boundExternalBool) Reload() error {
-	return b.Set(*b.val)
-}
-
-// Bytes supports binding a []byte value.
-//
-// Since: 2.2
-type Bytes interface {
-	DataItem
-	Get() ([]byte, error)
-	Set([]byte) error
-}
-
-// ExternalBytes supports binding a []byte value to an external value.
-//
-// Since: 2.2
-type ExternalBytes interface {
-	Bytes
-	Reload() error
-}
-
-// NewBytes returns a bindable []byte value that is managed internally.
-//
-// Since: 2.2
-func NewBytes() Bytes {
-	var blank []byte = nil
-	return &boundBytes{val: &blank}
-}
-
-// BindBytes returns a new bindable value that controls the contents of the provided []byte variable.
-// If your code changes the content of the variable this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.2
-func BindBytes(v *[]byte) ExternalBytes {
-	if v == nil {
-		var blank []byte = nil
-		v = &blank // never allow a nil value pointer
-	}
-	b := &boundExternalBytes{}
-	b.val = v
-	b.old = *v
-	return b
-}
-
-type boundBytes struct {
-	base
-
-	val *[]byte
-}
-
-func (b *boundBytes) Get() ([]byte, error) {
-	b.lock.RLock()
-	defer b.lock.RUnlock()
-
-	if b.val == nil {
-		return nil, nil
-	}
-	return *b.val, nil
-}
-
-func (b *boundBytes) Set(val []byte) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if bytes.Equal(*b.val, val) {
-		return nil
-	}
-	*b.val = val
-
-	b.trigger()
-	return nil
-}
-
-type boundExternalBytes struct {
-	boundBytes
-
-	old []byte
-}
-
-func (b *boundExternalBytes) Set(val []byte) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if bytes.Equal(b.old, val) {
-		return nil
-	}
-	*b.val = val
-	b.old = val
-
-	b.trigger()
-	return nil
-}
-
-func (b *boundExternalBytes) Reload() error {
-	return b.Set(*b.val)
-}
-
-// Float supports binding a float64 value.
-//
-// Since: 2.0
-type Float interface {
-	DataItem
-	Get() (float64, error)
-	Set(float64) error
-}
-
-// ExternalFloat supports binding a float64 value to an external value.
-//
-// Since: 2.0
-type ExternalFloat interface {
-	Float
-	Reload() error
-}
-
-// NewFloat returns a bindable float64 value that is managed internally.
-//
-// Since: 2.0
-func NewFloat() Float {
-	var blank float64 = 0.0
-	return &boundFloat{val: &blank}
-}
-
-// BindFloat returns a new bindable value that controls the contents of the provided float64 variable.
-// If your code changes the content of the variable this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.0
-func BindFloat(v *float64) ExternalFloat {
-	if v == nil {
-		var blank float64 = 0.0
-		v = &blank // never allow a nil value pointer
-	}
-	b := &boundExternalFloat{}
-	b.val = v
-	b.old = *v
-	return b
-}
-
-type boundFloat struct {
-	base
-
-	val *float64
-}
-
-func (b *boundFloat) Get() (float64, error) {
-	b.lock.RLock()
-	defer b.lock.RUnlock()
-
-	if b.val == nil {
-		return 0.0, nil
-	}
-	return *b.val, nil
-}
-
-func (b *boundFloat) Set(val float64) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if *b.val == val {
-		return nil
-	}
-	*b.val = val
-
-	b.trigger()
-	return nil
-}
-
-type boundExternalFloat struct {
-	boundFloat
-
-	old float64
-}
-
-func (b *boundExternalFloat) Set(val float64) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if b.old == val {
-		return nil
-	}
-	*b.val = val
-	b.old = val
-
-	b.trigger()
-	return nil
-}
-
-func (b *boundExternalFloat) Reload() error {
-	return b.Set(*b.val)
-}
-
-// Int supports binding a int value.
-//
-// Since: 2.0
-type Int interface {
-	DataItem
-	Get() (int, error)
-	Set(int) error
-}
-
-// ExternalInt supports binding a int value to an external value.
-//
-// Since: 2.0
-type ExternalInt interface {
-	Int
-	Reload() error
-}
-
-// NewInt returns a bindable int value that is managed internally.
-//
-// Since: 2.0
-func NewInt() Int {
-	var blank int = 0
-	return &boundInt{val: &blank}
-}
-
-// BindInt returns a new bindable value that controls the contents of the provided int variable.
-// If your code changes the content of the variable this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.0
-func BindInt(v *int) ExternalInt {
-	if v == nil {
-		var blank int = 0
-		v = &blank // never allow a nil value pointer
-	}
-	b := &boundExternalInt{}
-	b.val = v
-	b.old = *v
-	return b
-}
-
-type boundInt struct {
-	base
-
-	val *int
-}
-
-func (b *boundInt) Get() (int, error) {
-	b.lock.RLock()
-	defer b.lock.RUnlock()
-
-	if b.val == nil {
-		return 0, nil
-	}
-	return *b.val, nil
-}
-
-func (b *boundInt) Set(val int) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if *b.val == val {
-		return nil
-	}
-	*b.val = val
-
-	b.trigger()
-	return nil
-}
-
-type boundExternalInt struct {
-	boundInt
-
-	old int
-}
-
-func (b *boundExternalInt) Set(val int) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if b.old == val {
-		return nil
-	}
-	*b.val = val
-	b.old = val
-
-	b.trigger()
-	return nil
-}
-
-func (b *boundExternalInt) Reload() error {
-	return b.Set(*b.val)
-}
-
-// Rune supports binding a rune value.
-//
-// Since: 2.0
-type Rune interface {
-	DataItem
-	Get() (rune, error)
-	Set(rune) error
-}
-
-// ExternalRune supports binding a rune value to an external value.
-//
-// Since: 2.0
-type ExternalRune interface {
-	Rune
-	Reload() error
-}
-
-// NewRune returns a bindable rune value that is managed internally.
-//
-// Since: 2.0
-func NewRune() Rune {
-	var blank rune = rune(0)
-	return &boundRune{val: &blank}
-}
-
-// BindRune returns a new bindable value that controls the contents of the provided rune variable.
-// If your code changes the content of the variable this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.0
-func BindRune(v *rune) ExternalRune {
-	if v == nil {
-		var blank rune = rune(0)
-		v = &blank // never allow a nil value pointer
-	}
-	b := &boundExternalRune{}
-	b.val = v
-	b.old = *v
-	return b
-}
-
-type boundRune struct {
-	base
-
-	val *rune
-}
-
-func (b *boundRune) Get() (rune, error) {
-	b.lock.RLock()
-	defer b.lock.RUnlock()
-
-	if b.val == nil {
-		return rune(0), nil
-	}
-	return *b.val, nil
-}
-
-func (b *boundRune) Set(val rune) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if *b.val == val {
-		return nil
-	}
-	*b.val = val
-
-	b.trigger()
-	return nil
-}
-
-type boundExternalRune struct {
-	boundRune
-
-	old rune
-}
-
-func (b *boundExternalRune) Set(val rune) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if b.old == val {
-		return nil
-	}
-	*b.val = val
-	b.old = val
-
-	b.trigger()
-	return nil
-}
-
-func (b *boundExternalRune) Reload() error {
-	return b.Set(*b.val)
-}
-
-// String supports binding a string value.
-//
-// Since: 2.0
-type String interface {
-	DataItem
-	Get() (string, error)
-	Set(string) error
-}
-
-// ExternalString supports binding a string value to an external value.
-//
-// Since: 2.0
-type ExternalString interface {
-	String
-	Reload() error
-}
-
-// NewString returns a bindable string value that is managed internally.
-//
-// Since: 2.0
-func NewString() String {
-	var blank string = ""
-	return &boundString{val: &blank}
-}
-
-// BindString returns a new bindable value that controls the contents of the provided string variable.
-// If your code changes the content of the variable this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.0
-func BindString(v *string) ExternalString {
-	if v == nil {
-		var blank string = ""
-		v = &blank // never allow a nil value pointer
-	}
-	b := &boundExternalString{}
-	b.val = v
-	b.old = *v
-	return b
-}
-
-type boundString struct {
-	base
-
-	val *string
-}
-
-func (b *boundString) Get() (string, error) {
-	b.lock.RLock()
-	defer b.lock.RUnlock()
-
-	if b.val == nil {
-		return "", nil
-	}
-	return *b.val, nil
-}
-
-func (b *boundString) Set(val string) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if *b.val == val {
-		return nil
-	}
-	*b.val = val
-
-	b.trigger()
-	return nil
-}
-
-type boundExternalString struct {
-	boundString
-
-	old string
-}
-
-func (b *boundExternalString) Set(val string) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if b.old == val {
-		return nil
-	}
-	*b.val = val
-	b.old = val
-
-	b.trigger()
-	return nil
-}
-
-func (b *boundExternalString) Reload() error {
-	return b.Set(*b.val)
-}
-
-// URI supports binding a fyne.URI value.
-//
-// Since: 2.1
-type URI interface {
-	DataItem
-	Get() (fyne.URI, error)
-	Set(fyne.URI) error
-}
-
-// ExternalURI supports binding a fyne.URI value to an external value.
-//
-// Since: 2.1
-type ExternalURI interface {
-	URI
-	Reload() error
-}
-
-// NewURI returns a bindable fyne.URI value that is managed internally.
-//
-// Since: 2.1
-func NewURI() URI {
-	var blank fyne.URI = fyne.URI(nil)
-	return &boundURI{val: &blank}
-}
-
-// BindURI returns a new bindable value that controls the contents of the provided fyne.URI variable.
-// If your code changes the content of the variable this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.1
-func BindURI(v *fyne.URI) ExternalURI {
-	if v == nil {
-		var blank fyne.URI = fyne.URI(nil)
-		v = &blank // never allow a nil value pointer
-	}
-	b := &boundExternalURI{}
-	b.val = v
-	b.old = *v
-	return b
-}
-
-type boundURI struct {
-	base
-
-	val *fyne.URI
-}
-
-func (b *boundURI) Get() (fyne.URI, error) {
-	b.lock.RLock()
-	defer b.lock.RUnlock()
-
-	if b.val == nil {
-		return fyne.URI(nil), nil
-	}
-	return *b.val, nil
-}
-
-func (b *boundURI) Set(val fyne.URI) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if compareURI(*b.val, val) {
-		return nil
-	}
-	*b.val = val
-
-	b.trigger()
-	return nil
-}
-
-type boundExternalURI struct {
-	boundURI
-
-	old fyne.URI
-}
-
-func (b *boundExternalURI) Set(val fyne.URI) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-	if compareURI(b.old, val) {
-		return nil
-	}
-	*b.val = val
-	b.old = val
-
-	b.trigger()
-	return nil
-}
-
-func (b *boundExternalURI) Reload() error {
-	return b.Set(*b.val)
-}

+ 0 - 1786
vendor/fyne.io/fyne/v2/data/binding/bindlists.go

@@ -1,1786 +0,0 @@
-// auto-generated
-// **** THIS FILE IS AUTO-GENERATED, PLEASE DO NOT EDIT IT **** //
-
-package binding
-
-import (
-	"bytes"
-
-	"fyne.io/fyne/v2"
-)
-
-// BoolList supports binding a list of bool values.
-//
-// Since: 2.0
-type BoolList interface {
-	DataList
-
-	Append(value bool) error
-	Get() ([]bool, error)
-	GetValue(index int) (bool, error)
-	Prepend(value bool) error
-	Set(list []bool) error
-	SetValue(index int, value bool) error
-}
-
-// ExternalBoolList supports binding a list of bool values from an external variable.
-//
-// Since: 2.0
-type ExternalBoolList interface {
-	BoolList
-
-	Reload() error
-}
-
-// NewBoolList returns a bindable list of bool values.
-//
-// Since: 2.0
-func NewBoolList() BoolList {
-	return &boundBoolList{val: &[]bool{}}
-}
-
-// BindBoolList returns a bound list of bool values, based on the contents of the passed slice.
-// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.0
-func BindBoolList(v *[]bool) ExternalBoolList {
-	if v == nil {
-		return NewBoolList().(ExternalBoolList)
-	}
-
-	b := &boundBoolList{val: v, updateExternal: true}
-
-	for i := range *v {
-		b.appendItem(bindBoolListItem(v, i, b.updateExternal))
-	}
-
-	return b
-}
-
-type boundBoolList struct {
-	listBase
-
-	updateExternal bool
-	val            *[]bool
-}
-
-func (l *boundBoolList) Append(val bool) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	*l.val = append(*l.val, val)
-
-	return l.doReload()
-}
-
-func (l *boundBoolList) Get() ([]bool, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	return *l.val, nil
-}
-
-func (l *boundBoolList) GetValue(i int) (bool, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	if i < 0 || i >= l.Length() {
-		return false, errOutOfBounds
-	}
-
-	return (*l.val)[i], nil
-}
-
-func (l *boundBoolList) Prepend(val bool) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = append([]bool{val}, *l.val...)
-
-	return l.doReload()
-}
-
-func (l *boundBoolList) Reload() error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	return l.doReload()
-}
-
-func (l *boundBoolList) Set(v []bool) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = v
-
-	return l.doReload()
-}
-
-func (l *boundBoolList) doReload() (retErr error) {
-	oldLen := len(l.items)
-	newLen := len(*l.val)
-	if oldLen > newLen {
-		for i := oldLen - 1; i >= newLen; i-- {
-			l.deleteItem(i)
-		}
-		l.trigger()
-	} else if oldLen < newLen {
-		for i := oldLen; i < newLen; i++ {
-			l.appendItem(bindBoolListItem(l.val, i, l.updateExternal))
-		}
-		l.trigger()
-	}
-
-	for i, item := range l.items {
-		if i > oldLen || i > newLen {
-			break
-		}
-
-		var err error
-		if l.updateExternal {
-			item.(*boundExternalBoolListItem).lock.Lock()
-			err = item.(*boundExternalBoolListItem).setIfChanged((*l.val)[i])
-			item.(*boundExternalBoolListItem).lock.Unlock()
-		} else {
-			item.(*boundBoolListItem).lock.Lock()
-			err = item.(*boundBoolListItem).doSet((*l.val)[i])
-			item.(*boundBoolListItem).lock.Unlock()
-		}
-		if err != nil {
-			retErr = err
-		}
-	}
-	return
-}
-
-func (l *boundBoolList) SetValue(i int, v bool) error {
-	l.lock.RLock()
-	len := l.Length()
-	l.lock.RUnlock()
-
-	if i < 0 || i >= len {
-		return errOutOfBounds
-	}
-
-	l.lock.Lock()
-	(*l.val)[i] = v
-	l.lock.Unlock()
-
-	item, err := l.GetItem(i)
-	if err != nil {
-		return err
-	}
-	return item.(Bool).Set(v)
-}
-
-func bindBoolListItem(v *[]bool, i int, external bool) Bool {
-	if external {
-		ret := &boundExternalBoolListItem{old: (*v)[i]}
-		ret.val = v
-		ret.index = i
-		return ret
-	}
-
-	return &boundBoolListItem{val: v, index: i}
-}
-
-type boundBoolListItem struct {
-	base
-
-	val   *[]bool
-	index int
-}
-
-func (b *boundBoolListItem) Get() (bool, error) {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	if b.index < 0 || b.index >= len(*b.val) {
-		return false, errOutOfBounds
-	}
-
-	return (*b.val)[b.index], nil
-}
-
-func (b *boundBoolListItem) Set(val bool) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	return b.doSet(val)
-}
-
-func (b *boundBoolListItem) doSet(val bool) error {
-	(*b.val)[b.index] = val
-
-	b.trigger()
-	return nil
-}
-
-type boundExternalBoolListItem struct {
-	boundBoolListItem
-
-	old bool
-}
-
-func (b *boundExternalBoolListItem) setIfChanged(val bool) error {
-	if val == b.old {
-		return nil
-	}
-	(*b.val)[b.index] = val
-	b.old = val
-
-	b.trigger()
-	return nil
-}
-
-// BytesList supports binding a list of []byte values.
-//
-// Since: 2.2
-type BytesList interface {
-	DataList
-
-	Append(value []byte) error
-	Get() ([][]byte, error)
-	GetValue(index int) ([]byte, error)
-	Prepend(value []byte) error
-	Set(list [][]byte) error
-	SetValue(index int, value []byte) error
-}
-
-// ExternalBytesList supports binding a list of []byte values from an external variable.
-//
-// Since: 2.2
-type ExternalBytesList interface {
-	BytesList
-
-	Reload() error
-}
-
-// NewBytesList returns a bindable list of []byte values.
-//
-// Since: 2.2
-func NewBytesList() BytesList {
-	return &boundBytesList{val: &[][]byte{}}
-}
-
-// BindBytesList returns a bound list of []byte values, based on the contents of the passed slice.
-// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.2
-func BindBytesList(v *[][]byte) ExternalBytesList {
-	if v == nil {
-		return NewBytesList().(ExternalBytesList)
-	}
-
-	b := &boundBytesList{val: v, updateExternal: true}
-
-	for i := range *v {
-		b.appendItem(bindBytesListItem(v, i, b.updateExternal))
-	}
-
-	return b
-}
-
-type boundBytesList struct {
-	listBase
-
-	updateExternal bool
-	val            *[][]byte
-}
-
-func (l *boundBytesList) Append(val []byte) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	*l.val = append(*l.val, val)
-
-	return l.doReload()
-}
-
-func (l *boundBytesList) Get() ([][]byte, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	return *l.val, nil
-}
-
-func (l *boundBytesList) GetValue(i int) ([]byte, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	if i < 0 || i >= l.Length() {
-		return nil, errOutOfBounds
-	}
-
-	return (*l.val)[i], nil
-}
-
-func (l *boundBytesList) Prepend(val []byte) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = append([][]byte{val}, *l.val...)
-
-	return l.doReload()
-}
-
-func (l *boundBytesList) Reload() error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	return l.doReload()
-}
-
-func (l *boundBytesList) Set(v [][]byte) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = v
-
-	return l.doReload()
-}
-
-func (l *boundBytesList) doReload() (retErr error) {
-	oldLen := len(l.items)
-	newLen := len(*l.val)
-	if oldLen > newLen {
-		for i := oldLen - 1; i >= newLen; i-- {
-			l.deleteItem(i)
-		}
-		l.trigger()
-	} else if oldLen < newLen {
-		for i := oldLen; i < newLen; i++ {
-			l.appendItem(bindBytesListItem(l.val, i, l.updateExternal))
-		}
-		l.trigger()
-	}
-
-	for i, item := range l.items {
-		if i > oldLen || i > newLen {
-			break
-		}
-
-		var err error
-		if l.updateExternal {
-			item.(*boundExternalBytesListItem).lock.Lock()
-			err = item.(*boundExternalBytesListItem).setIfChanged((*l.val)[i])
-			item.(*boundExternalBytesListItem).lock.Unlock()
-		} else {
-			item.(*boundBytesListItem).lock.Lock()
-			err = item.(*boundBytesListItem).doSet((*l.val)[i])
-			item.(*boundBytesListItem).lock.Unlock()
-		}
-		if err != nil {
-			retErr = err
-		}
-	}
-	return
-}
-
-func (l *boundBytesList) SetValue(i int, v []byte) error {
-	l.lock.RLock()
-	len := l.Length()
-	l.lock.RUnlock()
-
-	if i < 0 || i >= len {
-		return errOutOfBounds
-	}
-
-	l.lock.Lock()
-	(*l.val)[i] = v
-	l.lock.Unlock()
-
-	item, err := l.GetItem(i)
-	if err != nil {
-		return err
-	}
-	return item.(Bytes).Set(v)
-}
-
-func bindBytesListItem(v *[][]byte, i int, external bool) Bytes {
-	if external {
-		ret := &boundExternalBytesListItem{old: (*v)[i]}
-		ret.val = v
-		ret.index = i
-		return ret
-	}
-
-	return &boundBytesListItem{val: v, index: i}
-}
-
-type boundBytesListItem struct {
-	base
-
-	val   *[][]byte
-	index int
-}
-
-func (b *boundBytesListItem) Get() ([]byte, error) {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	if b.index < 0 || b.index >= len(*b.val) {
-		return nil, errOutOfBounds
-	}
-
-	return (*b.val)[b.index], nil
-}
-
-func (b *boundBytesListItem) Set(val []byte) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	return b.doSet(val)
-}
-
-func (b *boundBytesListItem) doSet(val []byte) error {
-	(*b.val)[b.index] = val
-
-	b.trigger()
-	return nil
-}
-
-type boundExternalBytesListItem struct {
-	boundBytesListItem
-
-	old []byte
-}
-
-func (b *boundExternalBytesListItem) setIfChanged(val []byte) error {
-	if bytes.Equal(val, b.old) {
-		return nil
-	}
-	(*b.val)[b.index] = val
-	b.old = val
-
-	b.trigger()
-	return nil
-}
-
-// FloatList supports binding a list of float64 values.
-//
-// Since: 2.0
-type FloatList interface {
-	DataList
-
-	Append(value float64) error
-	Get() ([]float64, error)
-	GetValue(index int) (float64, error)
-	Prepend(value float64) error
-	Set(list []float64) error
-	SetValue(index int, value float64) error
-}
-
-// ExternalFloatList supports binding a list of float64 values from an external variable.
-//
-// Since: 2.0
-type ExternalFloatList interface {
-	FloatList
-
-	Reload() error
-}
-
-// NewFloatList returns a bindable list of float64 values.
-//
-// Since: 2.0
-func NewFloatList() FloatList {
-	return &boundFloatList{val: &[]float64{}}
-}
-
-// BindFloatList returns a bound list of float64 values, based on the contents of the passed slice.
-// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.0
-func BindFloatList(v *[]float64) ExternalFloatList {
-	if v == nil {
-		return NewFloatList().(ExternalFloatList)
-	}
-
-	b := &boundFloatList{val: v, updateExternal: true}
-
-	for i := range *v {
-		b.appendItem(bindFloatListItem(v, i, b.updateExternal))
-	}
-
-	return b
-}
-
-type boundFloatList struct {
-	listBase
-
-	updateExternal bool
-	val            *[]float64
-}
-
-func (l *boundFloatList) Append(val float64) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	*l.val = append(*l.val, val)
-
-	return l.doReload()
-}
-
-func (l *boundFloatList) Get() ([]float64, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	return *l.val, nil
-}
-
-func (l *boundFloatList) GetValue(i int) (float64, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	if i < 0 || i >= l.Length() {
-		return 0.0, errOutOfBounds
-	}
-
-	return (*l.val)[i], nil
-}
-
-func (l *boundFloatList) Prepend(val float64) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = append([]float64{val}, *l.val...)
-
-	return l.doReload()
-}
-
-func (l *boundFloatList) Reload() error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	return l.doReload()
-}
-
-func (l *boundFloatList) Set(v []float64) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = v
-
-	return l.doReload()
-}
-
-func (l *boundFloatList) doReload() (retErr error) {
-	oldLen := len(l.items)
-	newLen := len(*l.val)
-	if oldLen > newLen {
-		for i := oldLen - 1; i >= newLen; i-- {
-			l.deleteItem(i)
-		}
-		l.trigger()
-	} else if oldLen < newLen {
-		for i := oldLen; i < newLen; i++ {
-			l.appendItem(bindFloatListItem(l.val, i, l.updateExternal))
-		}
-		l.trigger()
-	}
-
-	for i, item := range l.items {
-		if i > oldLen || i > newLen {
-			break
-		}
-
-		var err error
-		if l.updateExternal {
-			item.(*boundExternalFloatListItem).lock.Lock()
-			err = item.(*boundExternalFloatListItem).setIfChanged((*l.val)[i])
-			item.(*boundExternalFloatListItem).lock.Unlock()
-		} else {
-			item.(*boundFloatListItem).lock.Lock()
-			err = item.(*boundFloatListItem).doSet((*l.val)[i])
-			item.(*boundFloatListItem).lock.Unlock()
-		}
-		if err != nil {
-			retErr = err
-		}
-	}
-	return
-}
-
-func (l *boundFloatList) SetValue(i int, v float64) error {
-	l.lock.RLock()
-	len := l.Length()
-	l.lock.RUnlock()
-
-	if i < 0 || i >= len {
-		return errOutOfBounds
-	}
-
-	l.lock.Lock()
-	(*l.val)[i] = v
-	l.lock.Unlock()
-
-	item, err := l.GetItem(i)
-	if err != nil {
-		return err
-	}
-	return item.(Float).Set(v)
-}
-
-func bindFloatListItem(v *[]float64, i int, external bool) Float {
-	if external {
-		ret := &boundExternalFloatListItem{old: (*v)[i]}
-		ret.val = v
-		ret.index = i
-		return ret
-	}
-
-	return &boundFloatListItem{val: v, index: i}
-}
-
-type boundFloatListItem struct {
-	base
-
-	val   *[]float64
-	index int
-}
-
-func (b *boundFloatListItem) Get() (float64, error) {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	if b.index < 0 || b.index >= len(*b.val) {
-		return 0.0, errOutOfBounds
-	}
-
-	return (*b.val)[b.index], nil
-}
-
-func (b *boundFloatListItem) Set(val float64) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	return b.doSet(val)
-}
-
-func (b *boundFloatListItem) doSet(val float64) error {
-	(*b.val)[b.index] = val
-
-	b.trigger()
-	return nil
-}
-
-type boundExternalFloatListItem struct {
-	boundFloatListItem
-
-	old float64
-}
-
-func (b *boundExternalFloatListItem) setIfChanged(val float64) error {
-	if val == b.old {
-		return nil
-	}
-	(*b.val)[b.index] = val
-	b.old = val
-
-	b.trigger()
-	return nil
-}
-
-// IntList supports binding a list of int values.
-//
-// Since: 2.0
-type IntList interface {
-	DataList
-
-	Append(value int) error
-	Get() ([]int, error)
-	GetValue(index int) (int, error)
-	Prepend(value int) error
-	Set(list []int) error
-	SetValue(index int, value int) error
-}
-
-// ExternalIntList supports binding a list of int values from an external variable.
-//
-// Since: 2.0
-type ExternalIntList interface {
-	IntList
-
-	Reload() error
-}
-
-// NewIntList returns a bindable list of int values.
-//
-// Since: 2.0
-func NewIntList() IntList {
-	return &boundIntList{val: &[]int{}}
-}
-
-// BindIntList returns a bound list of int values, based on the contents of the passed slice.
-// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.0
-func BindIntList(v *[]int) ExternalIntList {
-	if v == nil {
-		return NewIntList().(ExternalIntList)
-	}
-
-	b := &boundIntList{val: v, updateExternal: true}
-
-	for i := range *v {
-		b.appendItem(bindIntListItem(v, i, b.updateExternal))
-	}
-
-	return b
-}
-
-type boundIntList struct {
-	listBase
-
-	updateExternal bool
-	val            *[]int
-}
-
-func (l *boundIntList) Append(val int) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	*l.val = append(*l.val, val)
-
-	return l.doReload()
-}
-
-func (l *boundIntList) Get() ([]int, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	return *l.val, nil
-}
-
-func (l *boundIntList) GetValue(i int) (int, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	if i < 0 || i >= l.Length() {
-		return 0, errOutOfBounds
-	}
-
-	return (*l.val)[i], nil
-}
-
-func (l *boundIntList) Prepend(val int) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = append([]int{val}, *l.val...)
-
-	return l.doReload()
-}
-
-func (l *boundIntList) Reload() error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	return l.doReload()
-}
-
-func (l *boundIntList) Set(v []int) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = v
-
-	return l.doReload()
-}
-
-func (l *boundIntList) doReload() (retErr error) {
-	oldLen := len(l.items)
-	newLen := len(*l.val)
-	if oldLen > newLen {
-		for i := oldLen - 1; i >= newLen; i-- {
-			l.deleteItem(i)
-		}
-		l.trigger()
-	} else if oldLen < newLen {
-		for i := oldLen; i < newLen; i++ {
-			l.appendItem(bindIntListItem(l.val, i, l.updateExternal))
-		}
-		l.trigger()
-	}
-
-	for i, item := range l.items {
-		if i > oldLen || i > newLen {
-			break
-		}
-
-		var err error
-		if l.updateExternal {
-			item.(*boundExternalIntListItem).lock.Lock()
-			err = item.(*boundExternalIntListItem).setIfChanged((*l.val)[i])
-			item.(*boundExternalIntListItem).lock.Unlock()
-		} else {
-			item.(*boundIntListItem).lock.Lock()
-			err = item.(*boundIntListItem).doSet((*l.val)[i])
-			item.(*boundIntListItem).lock.Unlock()
-		}
-		if err != nil {
-			retErr = err
-		}
-	}
-	return
-}
-
-func (l *boundIntList) SetValue(i int, v int) error {
-	l.lock.RLock()
-	len := l.Length()
-	l.lock.RUnlock()
-
-	if i < 0 || i >= len {
-		return errOutOfBounds
-	}
-
-	l.lock.Lock()
-	(*l.val)[i] = v
-	l.lock.Unlock()
-
-	item, err := l.GetItem(i)
-	if err != nil {
-		return err
-	}
-	return item.(Int).Set(v)
-}
-
-func bindIntListItem(v *[]int, i int, external bool) Int {
-	if external {
-		ret := &boundExternalIntListItem{old: (*v)[i]}
-		ret.val = v
-		ret.index = i
-		return ret
-	}
-
-	return &boundIntListItem{val: v, index: i}
-}
-
-type boundIntListItem struct {
-	base
-
-	val   *[]int
-	index int
-}
-
-func (b *boundIntListItem) Get() (int, error) {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	if b.index < 0 || b.index >= len(*b.val) {
-		return 0, errOutOfBounds
-	}
-
-	return (*b.val)[b.index], nil
-}
-
-func (b *boundIntListItem) Set(val int) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	return b.doSet(val)
-}
-
-func (b *boundIntListItem) doSet(val int) error {
-	(*b.val)[b.index] = val
-
-	b.trigger()
-	return nil
-}
-
-type boundExternalIntListItem struct {
-	boundIntListItem
-
-	old int
-}
-
-func (b *boundExternalIntListItem) setIfChanged(val int) error {
-	if val == b.old {
-		return nil
-	}
-	(*b.val)[b.index] = val
-	b.old = val
-
-	b.trigger()
-	return nil
-}
-
-// RuneList supports binding a list of rune values.
-//
-// Since: 2.0
-type RuneList interface {
-	DataList
-
-	Append(value rune) error
-	Get() ([]rune, error)
-	GetValue(index int) (rune, error)
-	Prepend(value rune) error
-	Set(list []rune) error
-	SetValue(index int, value rune) error
-}
-
-// ExternalRuneList supports binding a list of rune values from an external variable.
-//
-// Since: 2.0
-type ExternalRuneList interface {
-	RuneList
-
-	Reload() error
-}
-
-// NewRuneList returns a bindable list of rune values.
-//
-// Since: 2.0
-func NewRuneList() RuneList {
-	return &boundRuneList{val: &[]rune{}}
-}
-
-// BindRuneList returns a bound list of rune values, based on the contents of the passed slice.
-// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.0
-func BindRuneList(v *[]rune) ExternalRuneList {
-	if v == nil {
-		return NewRuneList().(ExternalRuneList)
-	}
-
-	b := &boundRuneList{val: v, updateExternal: true}
-
-	for i := range *v {
-		b.appendItem(bindRuneListItem(v, i, b.updateExternal))
-	}
-
-	return b
-}
-
-type boundRuneList struct {
-	listBase
-
-	updateExternal bool
-	val            *[]rune
-}
-
-func (l *boundRuneList) Append(val rune) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	*l.val = append(*l.val, val)
-
-	return l.doReload()
-}
-
-func (l *boundRuneList) Get() ([]rune, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	return *l.val, nil
-}
-
-func (l *boundRuneList) GetValue(i int) (rune, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	if i < 0 || i >= l.Length() {
-		return rune(0), errOutOfBounds
-	}
-
-	return (*l.val)[i], nil
-}
-
-func (l *boundRuneList) Prepend(val rune) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = append([]rune{val}, *l.val...)
-
-	return l.doReload()
-}
-
-func (l *boundRuneList) Reload() error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	return l.doReload()
-}
-
-func (l *boundRuneList) Set(v []rune) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = v
-
-	return l.doReload()
-}
-
-func (l *boundRuneList) doReload() (retErr error) {
-	oldLen := len(l.items)
-	newLen := len(*l.val)
-	if oldLen > newLen {
-		for i := oldLen - 1; i >= newLen; i-- {
-			l.deleteItem(i)
-		}
-		l.trigger()
-	} else if oldLen < newLen {
-		for i := oldLen; i < newLen; i++ {
-			l.appendItem(bindRuneListItem(l.val, i, l.updateExternal))
-		}
-		l.trigger()
-	}
-
-	for i, item := range l.items {
-		if i > oldLen || i > newLen {
-			break
-		}
-
-		var err error
-		if l.updateExternal {
-			item.(*boundExternalRuneListItem).lock.Lock()
-			err = item.(*boundExternalRuneListItem).setIfChanged((*l.val)[i])
-			item.(*boundExternalRuneListItem).lock.Unlock()
-		} else {
-			item.(*boundRuneListItem).lock.Lock()
-			err = item.(*boundRuneListItem).doSet((*l.val)[i])
-			item.(*boundRuneListItem).lock.Unlock()
-		}
-		if err != nil {
-			retErr = err
-		}
-	}
-	return
-}
-
-func (l *boundRuneList) SetValue(i int, v rune) error {
-	l.lock.RLock()
-	len := l.Length()
-	l.lock.RUnlock()
-
-	if i < 0 || i >= len {
-		return errOutOfBounds
-	}
-
-	l.lock.Lock()
-	(*l.val)[i] = v
-	l.lock.Unlock()
-
-	item, err := l.GetItem(i)
-	if err != nil {
-		return err
-	}
-	return item.(Rune).Set(v)
-}
-
-func bindRuneListItem(v *[]rune, i int, external bool) Rune {
-	if external {
-		ret := &boundExternalRuneListItem{old: (*v)[i]}
-		ret.val = v
-		ret.index = i
-		return ret
-	}
-
-	return &boundRuneListItem{val: v, index: i}
-}
-
-type boundRuneListItem struct {
-	base
-
-	val   *[]rune
-	index int
-}
-
-func (b *boundRuneListItem) Get() (rune, error) {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	if b.index < 0 || b.index >= len(*b.val) {
-		return rune(0), errOutOfBounds
-	}
-
-	return (*b.val)[b.index], nil
-}
-
-func (b *boundRuneListItem) Set(val rune) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	return b.doSet(val)
-}
-
-func (b *boundRuneListItem) doSet(val rune) error {
-	(*b.val)[b.index] = val
-
-	b.trigger()
-	return nil
-}
-
-type boundExternalRuneListItem struct {
-	boundRuneListItem
-
-	old rune
-}
-
-func (b *boundExternalRuneListItem) setIfChanged(val rune) error {
-	if val == b.old {
-		return nil
-	}
-	(*b.val)[b.index] = val
-	b.old = val
-
-	b.trigger()
-	return nil
-}
-
-// StringList supports binding a list of string values.
-//
-// Since: 2.0
-type StringList interface {
-	DataList
-
-	Append(value string) error
-	Get() ([]string, error)
-	GetValue(index int) (string, error)
-	Prepend(value string) error
-	Set(list []string) error
-	SetValue(index int, value string) error
-}
-
-// ExternalStringList supports binding a list of string values from an external variable.
-//
-// Since: 2.0
-type ExternalStringList interface {
-	StringList
-
-	Reload() error
-}
-
-// NewStringList returns a bindable list of string values.
-//
-// Since: 2.0
-func NewStringList() StringList {
-	return &boundStringList{val: &[]string{}}
-}
-
-// BindStringList returns a bound list of string values, based on the contents of the passed slice.
-// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.0
-func BindStringList(v *[]string) ExternalStringList {
-	if v == nil {
-		return NewStringList().(ExternalStringList)
-	}
-
-	b := &boundStringList{val: v, updateExternal: true}
-
-	for i := range *v {
-		b.appendItem(bindStringListItem(v, i, b.updateExternal))
-	}
-
-	return b
-}
-
-type boundStringList struct {
-	listBase
-
-	updateExternal bool
-	val            *[]string
-}
-
-func (l *boundStringList) Append(val string) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	*l.val = append(*l.val, val)
-
-	return l.doReload()
-}
-
-func (l *boundStringList) Get() ([]string, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	return *l.val, nil
-}
-
-func (l *boundStringList) GetValue(i int) (string, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	if i < 0 || i >= l.Length() {
-		return "", errOutOfBounds
-	}
-
-	return (*l.val)[i], nil
-}
-
-func (l *boundStringList) Prepend(val string) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = append([]string{val}, *l.val...)
-
-	return l.doReload()
-}
-
-func (l *boundStringList) Reload() error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	return l.doReload()
-}
-
-func (l *boundStringList) Set(v []string) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = v
-
-	return l.doReload()
-}
-
-func (l *boundStringList) doReload() (retErr error) {
-	oldLen := len(l.items)
-	newLen := len(*l.val)
-	if oldLen > newLen {
-		for i := oldLen - 1; i >= newLen; i-- {
-			l.deleteItem(i)
-		}
-		l.trigger()
-	} else if oldLen < newLen {
-		for i := oldLen; i < newLen; i++ {
-			l.appendItem(bindStringListItem(l.val, i, l.updateExternal))
-		}
-		l.trigger()
-	}
-
-	for i, item := range l.items {
-		if i > oldLen || i > newLen {
-			break
-		}
-
-		var err error
-		if l.updateExternal {
-			item.(*boundExternalStringListItem).lock.Lock()
-			err = item.(*boundExternalStringListItem).setIfChanged((*l.val)[i])
-			item.(*boundExternalStringListItem).lock.Unlock()
-		} else {
-			item.(*boundStringListItem).lock.Lock()
-			err = item.(*boundStringListItem).doSet((*l.val)[i])
-			item.(*boundStringListItem).lock.Unlock()
-		}
-		if err != nil {
-			retErr = err
-		}
-	}
-	return
-}
-
-func (l *boundStringList) SetValue(i int, v string) error {
-	l.lock.RLock()
-	len := l.Length()
-	l.lock.RUnlock()
-
-	if i < 0 || i >= len {
-		return errOutOfBounds
-	}
-
-	l.lock.Lock()
-	(*l.val)[i] = v
-	l.lock.Unlock()
-
-	item, err := l.GetItem(i)
-	if err != nil {
-		return err
-	}
-	return item.(String).Set(v)
-}
-
-func bindStringListItem(v *[]string, i int, external bool) String {
-	if external {
-		ret := &boundExternalStringListItem{old: (*v)[i]}
-		ret.val = v
-		ret.index = i
-		return ret
-	}
-
-	return &boundStringListItem{val: v, index: i}
-}
-
-type boundStringListItem struct {
-	base
-
-	val   *[]string
-	index int
-}
-
-func (b *boundStringListItem) Get() (string, error) {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	if b.index < 0 || b.index >= len(*b.val) {
-		return "", errOutOfBounds
-	}
-
-	return (*b.val)[b.index], nil
-}
-
-func (b *boundStringListItem) Set(val string) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	return b.doSet(val)
-}
-
-func (b *boundStringListItem) doSet(val string) error {
-	(*b.val)[b.index] = val
-
-	b.trigger()
-	return nil
-}
-
-type boundExternalStringListItem struct {
-	boundStringListItem
-
-	old string
-}
-
-func (b *boundExternalStringListItem) setIfChanged(val string) error {
-	if val == b.old {
-		return nil
-	}
-	(*b.val)[b.index] = val
-	b.old = val
-
-	b.trigger()
-	return nil
-}
-
-// UntypedList supports binding a list of interface{} values.
-//
-// Since: 2.1
-type UntypedList interface {
-	DataList
-
-	Append(value interface{}) error
-	Get() ([]interface{}, error)
-	GetValue(index int) (interface{}, error)
-	Prepend(value interface{}) error
-	Set(list []interface{}) error
-	SetValue(index int, value interface{}) error
-}
-
-// ExternalUntypedList supports binding a list of interface{} values from an external variable.
-//
-// Since: 2.1
-type ExternalUntypedList interface {
-	UntypedList
-
-	Reload() error
-}
-
-// NewUntypedList returns a bindable list of interface{} values.
-//
-// Since: 2.1
-func NewUntypedList() UntypedList {
-	return &boundUntypedList{val: &[]interface{}{}}
-}
-
-// BindUntypedList returns a bound list of interface{} values, based on the contents of the passed slice.
-// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.1
-func BindUntypedList(v *[]interface{}) ExternalUntypedList {
-	if v == nil {
-		return NewUntypedList().(ExternalUntypedList)
-	}
-
-	b := &boundUntypedList{val: v, updateExternal: true}
-
-	for i := range *v {
-		b.appendItem(bindUntypedListItem(v, i, b.updateExternal))
-	}
-
-	return b
-}
-
-type boundUntypedList struct {
-	listBase
-
-	updateExternal bool
-	val            *[]interface{}
-}
-
-func (l *boundUntypedList) Append(val interface{}) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	*l.val = append(*l.val, val)
-
-	return l.doReload()
-}
-
-func (l *boundUntypedList) Get() ([]interface{}, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	return *l.val, nil
-}
-
-func (l *boundUntypedList) GetValue(i int) (interface{}, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	if i < 0 || i >= l.Length() {
-		return nil, errOutOfBounds
-	}
-
-	return (*l.val)[i], nil
-}
-
-func (l *boundUntypedList) Prepend(val interface{}) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = append([]interface{}{val}, *l.val...)
-
-	return l.doReload()
-}
-
-func (l *boundUntypedList) Reload() error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	return l.doReload()
-}
-
-func (l *boundUntypedList) Set(v []interface{}) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = v
-
-	return l.doReload()
-}
-
-func (l *boundUntypedList) doReload() (retErr error) {
-	oldLen := len(l.items)
-	newLen := len(*l.val)
-	if oldLen > newLen {
-		for i := oldLen - 1; i >= newLen; i-- {
-			l.deleteItem(i)
-		}
-		l.trigger()
-	} else if oldLen < newLen {
-		for i := oldLen; i < newLen; i++ {
-			l.appendItem(bindUntypedListItem(l.val, i, l.updateExternal))
-		}
-		l.trigger()
-	}
-
-	for i, item := range l.items {
-		if i > oldLen || i > newLen {
-			break
-		}
-
-		var err error
-		if l.updateExternal {
-			item.(*boundExternalUntypedListItem).lock.Lock()
-			err = item.(*boundExternalUntypedListItem).setIfChanged((*l.val)[i])
-			item.(*boundExternalUntypedListItem).lock.Unlock()
-		} else {
-			item.(*boundUntypedListItem).lock.Lock()
-			err = item.(*boundUntypedListItem).doSet((*l.val)[i])
-			item.(*boundUntypedListItem).lock.Unlock()
-		}
-		if err != nil {
-			retErr = err
-		}
-	}
-	return
-}
-
-func (l *boundUntypedList) SetValue(i int, v interface{}) error {
-	l.lock.RLock()
-	len := l.Length()
-	l.lock.RUnlock()
-
-	if i < 0 || i >= len {
-		return errOutOfBounds
-	}
-
-	l.lock.Lock()
-	(*l.val)[i] = v
-	l.lock.Unlock()
-
-	item, err := l.GetItem(i)
-	if err != nil {
-		return err
-	}
-	return item.(Untyped).Set(v)
-}
-
-func bindUntypedListItem(v *[]interface{}, i int, external bool) Untyped {
-	if external {
-		ret := &boundExternalUntypedListItem{old: (*v)[i]}
-		ret.val = v
-		ret.index = i
-		return ret
-	}
-
-	return &boundUntypedListItem{val: v, index: i}
-}
-
-type boundUntypedListItem struct {
-	base
-
-	val   *[]interface{}
-	index int
-}
-
-func (b *boundUntypedListItem) Get() (interface{}, error) {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	if b.index < 0 || b.index >= len(*b.val) {
-		return nil, errOutOfBounds
-	}
-
-	return (*b.val)[b.index], nil
-}
-
-func (b *boundUntypedListItem) Set(val interface{}) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	return b.doSet(val)
-}
-
-func (b *boundUntypedListItem) doSet(val interface{}) error {
-	(*b.val)[b.index] = val
-
-	b.trigger()
-	return nil
-}
-
-type boundExternalUntypedListItem struct {
-	boundUntypedListItem
-
-	old interface{}
-}
-
-func (b *boundExternalUntypedListItem) setIfChanged(val interface{}) error {
-	if val == b.old {
-		return nil
-	}
-	(*b.val)[b.index] = val
-	b.old = val
-
-	b.trigger()
-	return nil
-}
-
-// URIList supports binding a list of fyne.URI values.
-//
-// Since: 2.1
-type URIList interface {
-	DataList
-
-	Append(value fyne.URI) error
-	Get() ([]fyne.URI, error)
-	GetValue(index int) (fyne.URI, error)
-	Prepend(value fyne.URI) error
-	Set(list []fyne.URI) error
-	SetValue(index int, value fyne.URI) error
-}
-
-// ExternalURIList supports binding a list of fyne.URI values from an external variable.
-//
-// Since: 2.1
-type ExternalURIList interface {
-	URIList
-
-	Reload() error
-}
-
-// NewURIList returns a bindable list of fyne.URI values.
-//
-// Since: 2.1
-func NewURIList() URIList {
-	return &boundURIList{val: &[]fyne.URI{}}
-}
-
-// BindURIList returns a bound list of fyne.URI values, based on the contents of the passed slice.
-// If your code changes the content of the slice this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.1
-func BindURIList(v *[]fyne.URI) ExternalURIList {
-	if v == nil {
-		return NewURIList().(ExternalURIList)
-	}
-
-	b := &boundURIList{val: v, updateExternal: true}
-
-	for i := range *v {
-		b.appendItem(bindURIListItem(v, i, b.updateExternal))
-	}
-
-	return b
-}
-
-type boundURIList struct {
-	listBase
-
-	updateExternal bool
-	val            *[]fyne.URI
-}
-
-func (l *boundURIList) Append(val fyne.URI) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	*l.val = append(*l.val, val)
-
-	return l.doReload()
-}
-
-func (l *boundURIList) Get() ([]fyne.URI, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	return *l.val, nil
-}
-
-func (l *boundURIList) GetValue(i int) (fyne.URI, error) {
-	l.lock.RLock()
-	defer l.lock.RUnlock()
-
-	if i < 0 || i >= l.Length() {
-		return fyne.URI(nil), errOutOfBounds
-	}
-
-	return (*l.val)[i], nil
-}
-
-func (l *boundURIList) Prepend(val fyne.URI) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = append([]fyne.URI{val}, *l.val...)
-
-	return l.doReload()
-}
-
-func (l *boundURIList) Reload() error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-
-	return l.doReload()
-}
-
-func (l *boundURIList) Set(v []fyne.URI) error {
-	l.lock.Lock()
-	defer l.lock.Unlock()
-	*l.val = v
-
-	return l.doReload()
-}
-
-func (l *boundURIList) doReload() (retErr error) {
-	oldLen := len(l.items)
-	newLen := len(*l.val)
-	if oldLen > newLen {
-		for i := oldLen - 1; i >= newLen; i-- {
-			l.deleteItem(i)
-		}
-		l.trigger()
-	} else if oldLen < newLen {
-		for i := oldLen; i < newLen; i++ {
-			l.appendItem(bindURIListItem(l.val, i, l.updateExternal))
-		}
-		l.trigger()
-	}
-
-	for i, item := range l.items {
-		if i > oldLen || i > newLen {
-			break
-		}
-
-		var err error
-		if l.updateExternal {
-			item.(*boundExternalURIListItem).lock.Lock()
-			err = item.(*boundExternalURIListItem).setIfChanged((*l.val)[i])
-			item.(*boundExternalURIListItem).lock.Unlock()
-		} else {
-			item.(*boundURIListItem).lock.Lock()
-			err = item.(*boundURIListItem).doSet((*l.val)[i])
-			item.(*boundURIListItem).lock.Unlock()
-		}
-		if err != nil {
-			retErr = err
-		}
-	}
-	return
-}
-
-func (l *boundURIList) SetValue(i int, v fyne.URI) error {
-	l.lock.RLock()
-	len := l.Length()
-	l.lock.RUnlock()
-
-	if i < 0 || i >= len {
-		return errOutOfBounds
-	}
-
-	l.lock.Lock()
-	(*l.val)[i] = v
-	l.lock.Unlock()
-
-	item, err := l.GetItem(i)
-	if err != nil {
-		return err
-	}
-	return item.(URI).Set(v)
-}
-
-func bindURIListItem(v *[]fyne.URI, i int, external bool) URI {
-	if external {
-		ret := &boundExternalURIListItem{old: (*v)[i]}
-		ret.val = v
-		ret.index = i
-		return ret
-	}
-
-	return &boundURIListItem{val: v, index: i}
-}
-
-type boundURIListItem struct {
-	base
-
-	val   *[]fyne.URI
-	index int
-}
-
-func (b *boundURIListItem) Get() (fyne.URI, error) {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	if b.index < 0 || b.index >= len(*b.val) {
-		return fyne.URI(nil), errOutOfBounds
-	}
-
-	return (*b.val)[b.index], nil
-}
-
-func (b *boundURIListItem) Set(val fyne.URI) error {
-	b.lock.Lock()
-	defer b.lock.Unlock()
-
-	return b.doSet(val)
-}
-
-func (b *boundURIListItem) doSet(val fyne.URI) error {
-	(*b.val)[b.index] = val
-
-	b.trigger()
-	return nil
-}
-
-type boundExternalURIListItem struct {
-	boundURIListItem
-
-	old fyne.URI
-}
-
-func (b *boundExternalURIListItem) setIfChanged(val fyne.URI) error {
-	if compareURI(val, b.old) {
-		return nil
-	}
-	(*b.val)[b.index] = val
-	b.old = val
-
-	b.trigger()
-	return nil
-}

+ 0 - 1816
vendor/fyne.io/fyne/v2/data/binding/bindtrees.go

@@ -1,1816 +0,0 @@
-// auto-generated
-// **** THIS FILE IS AUTO-GENERATED, PLEASE DO NOT EDIT IT **** //
-
-package binding
-
-import (
-	"bytes"
-
-	"fyne.io/fyne/v2"
-)
-
-// BoolTree supports binding a tree of bool values.
-//
-// Since: 2.4
-type BoolTree interface {
-	DataTree
-
-	Append(parent, id string, value bool) error
-	Get() (map[string][]string, map[string]bool, error)
-	GetValue(id string) (bool, error)
-	Prepend(parent, id string, value bool) error
-	Set(ids map[string][]string, values map[string]bool) error
-	SetValue(id string, value bool) error
-}
-
-// ExternalBoolTree supports binding a tree of bool values from an external variable.
-//
-// Since: 2.4
-type ExternalBoolTree interface {
-	BoolTree
-
-	Reload() error
-}
-
-// NewBoolTree returns a bindable tree of bool values.
-//
-// Since: 2.4
-func NewBoolTree() BoolTree {
-	t := &boundBoolTree{val: &map[string]bool{}}
-	t.ids = make(map[string][]string)
-	t.items = make(map[string]DataItem)
-	return t
-}
-
-// BindBoolTree returns a bound tree of bool values, based on the contents of the passed values.
-// The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map.
-// If your code changes the content of the maps this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.4
-func BindBoolTree(ids *map[string][]string, v *map[string]bool) ExternalBoolTree {
-	if v == nil {
-		return NewBoolTree().(ExternalBoolTree)
-	}
-
-	t := &boundBoolTree{val: v, updateExternal: true}
-	t.ids = make(map[string][]string)
-	t.items = make(map[string]DataItem)
-
-	for parent, children := range *ids {
-		for _, leaf := range children {
-			t.appendItem(bindBoolTreeItem(v, leaf, t.updateExternal), leaf, parent)
-		}
-	}
-
-	return t
-}
-
-type boundBoolTree struct {
-	treeBase
-
-	updateExternal bool
-	val            *map[string]bool
-}
-
-func (t *boundBoolTree) Append(parent, id string, val bool) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	ids, ok := t.ids[parent]
-	if !ok {
-		ids = make([]string, 0)
-	}
-
-	t.ids[parent] = append(ids, id)
-	v := *t.val
-	v[id] = val
-
-	return t.doReload()
-}
-
-func (t *boundBoolTree) Get() (map[string][]string, map[string]bool, error) {
-	t.lock.RLock()
-	defer t.lock.RUnlock()
-
-	return t.ids, *t.val, nil
-}
-
-func (t *boundBoolTree) GetValue(id string) (bool, error) {
-	t.lock.RLock()
-	defer t.lock.RUnlock()
-
-	if item, ok := (*t.val)[id]; ok {
-		return item, nil
-	}
-
-	return false, errOutOfBounds
-}
-
-func (t *boundBoolTree) Prepend(parent, id string, val bool) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	ids, ok := t.ids[parent]
-	if !ok {
-		ids = make([]string, 0)
-	}
-
-	t.ids[parent] = append([]string{id}, ids...)
-	v := *t.val
-	v[id] = val
-
-	return t.doReload()
-}
-
-func (t *boundBoolTree) Reload() error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	return t.doReload()
-}
-
-func (t *boundBoolTree) Set(ids map[string][]string, v map[string]bool) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	t.ids = ids
-	*t.val = v
-
-	return t.doReload()
-}
-
-func (t *boundBoolTree) doReload() (retErr error) {
-	updated := []string{}
-	fire := false
-	for id := range *t.val {
-		found := false
-		for child := range t.items {
-			if child == id { // update existing
-				updated = append(updated, id)
-				found = true
-				break
-			}
-		}
-		if found {
-			continue
-		}
-
-		// append new
-		t.appendItem(bindBoolTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids))
-		updated = append(updated, id)
-		fire = true
-	}
-
-	for id := range t.items {
-		remove := true
-		for _, done := range updated {
-			if done == id {
-				remove = false
-				break
-			}
-		}
-
-		if remove { // remove item no longer present
-			fire = true
-			t.deleteItem(id, parentIDFor(id, t.ids))
-		}
-	}
-	if fire {
-		t.trigger()
-	}
-
-	for id, item := range t.items {
-		var err error
-		if t.updateExternal {
-			item.(*boundExternalBoolTreeItem).lock.Lock()
-			err = item.(*boundExternalBoolTreeItem).setIfChanged((*t.val)[id])
-			item.(*boundExternalBoolTreeItem).lock.Unlock()
-		} else {
-			item.(*boundBoolTreeItem).lock.Lock()
-			err = item.(*boundBoolTreeItem).doSet((*t.val)[id])
-			item.(*boundBoolTreeItem).lock.Unlock()
-		}
-		if err != nil {
-			retErr = err
-		}
-	}
-	return
-}
-
-func (t *boundBoolTree) SetValue(id string, v bool) error {
-	t.lock.Lock()
-	(*t.val)[id] = v
-	t.lock.Unlock()
-
-	item, err := t.GetItem(id)
-	if err != nil {
-		return err
-	}
-	return item.(Bool).Set(v)
-}
-
-func bindBoolTreeItem(v *map[string]bool, id string, external bool) Bool {
-	if external {
-		ret := &boundExternalBoolTreeItem{old: (*v)[id]}
-		ret.val = v
-		ret.id = id
-		return ret
-	}
-
-	return &boundBoolTreeItem{id: id, val: v}
-}
-
-type boundBoolTreeItem struct {
-	base
-
-	val *map[string]bool
-	id  string
-}
-
-func (t *boundBoolTreeItem) Get() (bool, error) {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	v := *t.val
-	if item, ok := v[t.id]; ok {
-		return item, nil
-	}
-
-	return false, errOutOfBounds
-}
-
-func (t *boundBoolTreeItem) Set(val bool) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	return t.doSet(val)
-}
-
-func (t *boundBoolTreeItem) doSet(val bool) error {
-	(*t.val)[t.id] = val
-
-	t.trigger()
-	return nil
-}
-
-type boundExternalBoolTreeItem struct {
-	boundBoolTreeItem
-
-	old bool
-}
-
-func (t *boundExternalBoolTreeItem) setIfChanged(val bool) error {
-	if val == t.old {
-		return nil
-	}
-	(*t.val)[t.id] = val
-	t.old = val
-
-	t.trigger()
-	return nil
-}
-
-// BytesTree supports binding a tree of []byte values.
-//
-// Since: 2.4
-type BytesTree interface {
-	DataTree
-
-	Append(parent, id string, value []byte) error
-	Get() (map[string][]string, map[string][]byte, error)
-	GetValue(id string) ([]byte, error)
-	Prepend(parent, id string, value []byte) error
-	Set(ids map[string][]string, values map[string][]byte) error
-	SetValue(id string, value []byte) error
-}
-
-// ExternalBytesTree supports binding a tree of []byte values from an external variable.
-//
-// Since: 2.4
-type ExternalBytesTree interface {
-	BytesTree
-
-	Reload() error
-}
-
-// NewBytesTree returns a bindable tree of []byte values.
-//
-// Since: 2.4
-func NewBytesTree() BytesTree {
-	t := &boundBytesTree{val: &map[string][]byte{}}
-	t.ids = make(map[string][]string)
-	t.items = make(map[string]DataItem)
-	return t
-}
-
-// BindBytesTree returns a bound tree of []byte values, based on the contents of the passed values.
-// The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map.
-// If your code changes the content of the maps this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.4
-func BindBytesTree(ids *map[string][]string, v *map[string][]byte) ExternalBytesTree {
-	if v == nil {
-		return NewBytesTree().(ExternalBytesTree)
-	}
-
-	t := &boundBytesTree{val: v, updateExternal: true}
-	t.ids = make(map[string][]string)
-	t.items = make(map[string]DataItem)
-
-	for parent, children := range *ids {
-		for _, leaf := range children {
-			t.appendItem(bindBytesTreeItem(v, leaf, t.updateExternal), leaf, parent)
-		}
-	}
-
-	return t
-}
-
-type boundBytesTree struct {
-	treeBase
-
-	updateExternal bool
-	val            *map[string][]byte
-}
-
-func (t *boundBytesTree) Append(parent, id string, val []byte) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	ids, ok := t.ids[parent]
-	if !ok {
-		ids = make([]string, 0)
-	}
-
-	t.ids[parent] = append(ids, id)
-	v := *t.val
-	v[id] = val
-
-	return t.doReload()
-}
-
-func (t *boundBytesTree) Get() (map[string][]string, map[string][]byte, error) {
-	t.lock.RLock()
-	defer t.lock.RUnlock()
-
-	return t.ids, *t.val, nil
-}
-
-func (t *boundBytesTree) GetValue(id string) ([]byte, error) {
-	t.lock.RLock()
-	defer t.lock.RUnlock()
-
-	if item, ok := (*t.val)[id]; ok {
-		return item, nil
-	}
-
-	return nil, errOutOfBounds
-}
-
-func (t *boundBytesTree) Prepend(parent, id string, val []byte) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	ids, ok := t.ids[parent]
-	if !ok {
-		ids = make([]string, 0)
-	}
-
-	t.ids[parent] = append([]string{id}, ids...)
-	v := *t.val
-	v[id] = val
-
-	return t.doReload()
-}
-
-func (t *boundBytesTree) Reload() error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	return t.doReload()
-}
-
-func (t *boundBytesTree) Set(ids map[string][]string, v map[string][]byte) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	t.ids = ids
-	*t.val = v
-
-	return t.doReload()
-}
-
-func (t *boundBytesTree) doReload() (retErr error) {
-	updated := []string{}
-	fire := false
-	for id := range *t.val {
-		found := false
-		for child := range t.items {
-			if child == id { // update existing
-				updated = append(updated, id)
-				found = true
-				break
-			}
-		}
-		if found {
-			continue
-		}
-
-		// append new
-		t.appendItem(bindBytesTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids))
-		updated = append(updated, id)
-		fire = true
-	}
-
-	for id := range t.items {
-		remove := true
-		for _, done := range updated {
-			if done == id {
-				remove = false
-				break
-			}
-		}
-
-		if remove { // remove item no longer present
-			fire = true
-			t.deleteItem(id, parentIDFor(id, t.ids))
-		}
-	}
-	if fire {
-		t.trigger()
-	}
-
-	for id, item := range t.items {
-		var err error
-		if t.updateExternal {
-			item.(*boundExternalBytesTreeItem).lock.Lock()
-			err = item.(*boundExternalBytesTreeItem).setIfChanged((*t.val)[id])
-			item.(*boundExternalBytesTreeItem).lock.Unlock()
-		} else {
-			item.(*boundBytesTreeItem).lock.Lock()
-			err = item.(*boundBytesTreeItem).doSet((*t.val)[id])
-			item.(*boundBytesTreeItem).lock.Unlock()
-		}
-		if err != nil {
-			retErr = err
-		}
-	}
-	return
-}
-
-func (t *boundBytesTree) SetValue(id string, v []byte) error {
-	t.lock.Lock()
-	(*t.val)[id] = v
-	t.lock.Unlock()
-
-	item, err := t.GetItem(id)
-	if err != nil {
-		return err
-	}
-	return item.(Bytes).Set(v)
-}
-
-func bindBytesTreeItem(v *map[string][]byte, id string, external bool) Bytes {
-	if external {
-		ret := &boundExternalBytesTreeItem{old: (*v)[id]}
-		ret.val = v
-		ret.id = id
-		return ret
-	}
-
-	return &boundBytesTreeItem{id: id, val: v}
-}
-
-type boundBytesTreeItem struct {
-	base
-
-	val *map[string][]byte
-	id  string
-}
-
-func (t *boundBytesTreeItem) Get() ([]byte, error) {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	v := *t.val
-	if item, ok := v[t.id]; ok {
-		return item, nil
-	}
-
-	return nil, errOutOfBounds
-}
-
-func (t *boundBytesTreeItem) Set(val []byte) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	return t.doSet(val)
-}
-
-func (t *boundBytesTreeItem) doSet(val []byte) error {
-	(*t.val)[t.id] = val
-
-	t.trigger()
-	return nil
-}
-
-type boundExternalBytesTreeItem struct {
-	boundBytesTreeItem
-
-	old []byte
-}
-
-func (t *boundExternalBytesTreeItem) setIfChanged(val []byte) error {
-	if bytes.Equal(val, t.old) {
-		return nil
-	}
-	(*t.val)[t.id] = val
-	t.old = val
-
-	t.trigger()
-	return nil
-}
-
-// FloatTree supports binding a tree of float64 values.
-//
-// Since: 2.4
-type FloatTree interface {
-	DataTree
-
-	Append(parent, id string, value float64) error
-	Get() (map[string][]string, map[string]float64, error)
-	GetValue(id string) (float64, error)
-	Prepend(parent, id string, value float64) error
-	Set(ids map[string][]string, values map[string]float64) error
-	SetValue(id string, value float64) error
-}
-
-// ExternalFloatTree supports binding a tree of float64 values from an external variable.
-//
-// Since: 2.4
-type ExternalFloatTree interface {
-	FloatTree
-
-	Reload() error
-}
-
-// NewFloatTree returns a bindable tree of float64 values.
-//
-// Since: 2.4
-func NewFloatTree() FloatTree {
-	t := &boundFloatTree{val: &map[string]float64{}}
-	t.ids = make(map[string][]string)
-	t.items = make(map[string]DataItem)
-	return t
-}
-
-// BindFloatTree returns a bound tree of float64 values, based on the contents of the passed values.
-// The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map.
-// If your code changes the content of the maps this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.4
-func BindFloatTree(ids *map[string][]string, v *map[string]float64) ExternalFloatTree {
-	if v == nil {
-		return NewFloatTree().(ExternalFloatTree)
-	}
-
-	t := &boundFloatTree{val: v, updateExternal: true}
-	t.ids = make(map[string][]string)
-	t.items = make(map[string]DataItem)
-
-	for parent, children := range *ids {
-		for _, leaf := range children {
-			t.appendItem(bindFloatTreeItem(v, leaf, t.updateExternal), leaf, parent)
-		}
-	}
-
-	return t
-}
-
-type boundFloatTree struct {
-	treeBase
-
-	updateExternal bool
-	val            *map[string]float64
-}
-
-func (t *boundFloatTree) Append(parent, id string, val float64) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	ids, ok := t.ids[parent]
-	if !ok {
-		ids = make([]string, 0)
-	}
-
-	t.ids[parent] = append(ids, id)
-	v := *t.val
-	v[id] = val
-
-	return t.doReload()
-}
-
-func (t *boundFloatTree) Get() (map[string][]string, map[string]float64, error) {
-	t.lock.RLock()
-	defer t.lock.RUnlock()
-
-	return t.ids, *t.val, nil
-}
-
-func (t *boundFloatTree) GetValue(id string) (float64, error) {
-	t.lock.RLock()
-	defer t.lock.RUnlock()
-
-	if item, ok := (*t.val)[id]; ok {
-		return item, nil
-	}
-
-	return 0.0, errOutOfBounds
-}
-
-func (t *boundFloatTree) Prepend(parent, id string, val float64) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	ids, ok := t.ids[parent]
-	if !ok {
-		ids = make([]string, 0)
-	}
-
-	t.ids[parent] = append([]string{id}, ids...)
-	v := *t.val
-	v[id] = val
-
-	return t.doReload()
-}
-
-func (t *boundFloatTree) Reload() error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	return t.doReload()
-}
-
-func (t *boundFloatTree) Set(ids map[string][]string, v map[string]float64) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	t.ids = ids
-	*t.val = v
-
-	return t.doReload()
-}
-
-func (t *boundFloatTree) doReload() (retErr error) {
-	updated := []string{}
-	fire := false
-	for id := range *t.val {
-		found := false
-		for child := range t.items {
-			if child == id { // update existing
-				updated = append(updated, id)
-				found = true
-				break
-			}
-		}
-		if found {
-			continue
-		}
-
-		// append new
-		t.appendItem(bindFloatTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids))
-		updated = append(updated, id)
-		fire = true
-	}
-
-	for id := range t.items {
-		remove := true
-		for _, done := range updated {
-			if done == id {
-				remove = false
-				break
-			}
-		}
-
-		if remove { // remove item no longer present
-			fire = true
-			t.deleteItem(id, parentIDFor(id, t.ids))
-		}
-	}
-	if fire {
-		t.trigger()
-	}
-
-	for id, item := range t.items {
-		var err error
-		if t.updateExternal {
-			item.(*boundExternalFloatTreeItem).lock.Lock()
-			err = item.(*boundExternalFloatTreeItem).setIfChanged((*t.val)[id])
-			item.(*boundExternalFloatTreeItem).lock.Unlock()
-		} else {
-			item.(*boundFloatTreeItem).lock.Lock()
-			err = item.(*boundFloatTreeItem).doSet((*t.val)[id])
-			item.(*boundFloatTreeItem).lock.Unlock()
-		}
-		if err != nil {
-			retErr = err
-		}
-	}
-	return
-}
-
-func (t *boundFloatTree) SetValue(id string, v float64) error {
-	t.lock.Lock()
-	(*t.val)[id] = v
-	t.lock.Unlock()
-
-	item, err := t.GetItem(id)
-	if err != nil {
-		return err
-	}
-	return item.(Float).Set(v)
-}
-
-func bindFloatTreeItem(v *map[string]float64, id string, external bool) Float {
-	if external {
-		ret := &boundExternalFloatTreeItem{old: (*v)[id]}
-		ret.val = v
-		ret.id = id
-		return ret
-	}
-
-	return &boundFloatTreeItem{id: id, val: v}
-}
-
-type boundFloatTreeItem struct {
-	base
-
-	val *map[string]float64
-	id  string
-}
-
-func (t *boundFloatTreeItem) Get() (float64, error) {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	v := *t.val
-	if item, ok := v[t.id]; ok {
-		return item, nil
-	}
-
-	return 0.0, errOutOfBounds
-}
-
-func (t *boundFloatTreeItem) Set(val float64) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	return t.doSet(val)
-}
-
-func (t *boundFloatTreeItem) doSet(val float64) error {
-	(*t.val)[t.id] = val
-
-	t.trigger()
-	return nil
-}
-
-type boundExternalFloatTreeItem struct {
-	boundFloatTreeItem
-
-	old float64
-}
-
-func (t *boundExternalFloatTreeItem) setIfChanged(val float64) error {
-	if val == t.old {
-		return nil
-	}
-	(*t.val)[t.id] = val
-	t.old = val
-
-	t.trigger()
-	return nil
-}
-
-// IntTree supports binding a tree of int values.
-//
-// Since: 2.4
-type IntTree interface {
-	DataTree
-
-	Append(parent, id string, value int) error
-	Get() (map[string][]string, map[string]int, error)
-	GetValue(id string) (int, error)
-	Prepend(parent, id string, value int) error
-	Set(ids map[string][]string, values map[string]int) error
-	SetValue(id string, value int) error
-}
-
-// ExternalIntTree supports binding a tree of int values from an external variable.
-//
-// Since: 2.4
-type ExternalIntTree interface {
-	IntTree
-
-	Reload() error
-}
-
-// NewIntTree returns a bindable tree of int values.
-//
-// Since: 2.4
-func NewIntTree() IntTree {
-	t := &boundIntTree{val: &map[string]int{}}
-	t.ids = make(map[string][]string)
-	t.items = make(map[string]DataItem)
-	return t
-}
-
-// BindIntTree returns a bound tree of int values, based on the contents of the passed values.
-// The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map.
-// If your code changes the content of the maps this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.4
-func BindIntTree(ids *map[string][]string, v *map[string]int) ExternalIntTree {
-	if v == nil {
-		return NewIntTree().(ExternalIntTree)
-	}
-
-	t := &boundIntTree{val: v, updateExternal: true}
-	t.ids = make(map[string][]string)
-	t.items = make(map[string]DataItem)
-
-	for parent, children := range *ids {
-		for _, leaf := range children {
-			t.appendItem(bindIntTreeItem(v, leaf, t.updateExternal), leaf, parent)
-		}
-	}
-
-	return t
-}
-
-type boundIntTree struct {
-	treeBase
-
-	updateExternal bool
-	val            *map[string]int
-}
-
-func (t *boundIntTree) Append(parent, id string, val int) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	ids, ok := t.ids[parent]
-	if !ok {
-		ids = make([]string, 0)
-	}
-
-	t.ids[parent] = append(ids, id)
-	v := *t.val
-	v[id] = val
-
-	return t.doReload()
-}
-
-func (t *boundIntTree) Get() (map[string][]string, map[string]int, error) {
-	t.lock.RLock()
-	defer t.lock.RUnlock()
-
-	return t.ids, *t.val, nil
-}
-
-func (t *boundIntTree) GetValue(id string) (int, error) {
-	t.lock.RLock()
-	defer t.lock.RUnlock()
-
-	if item, ok := (*t.val)[id]; ok {
-		return item, nil
-	}
-
-	return 0, errOutOfBounds
-}
-
-func (t *boundIntTree) Prepend(parent, id string, val int) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	ids, ok := t.ids[parent]
-	if !ok {
-		ids = make([]string, 0)
-	}
-
-	t.ids[parent] = append([]string{id}, ids...)
-	v := *t.val
-	v[id] = val
-
-	return t.doReload()
-}
-
-func (t *boundIntTree) Reload() error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	return t.doReload()
-}
-
-func (t *boundIntTree) Set(ids map[string][]string, v map[string]int) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	t.ids = ids
-	*t.val = v
-
-	return t.doReload()
-}
-
-func (t *boundIntTree) doReload() (retErr error) {
-	updated := []string{}
-	fire := false
-	for id := range *t.val {
-		found := false
-		for child := range t.items {
-			if child == id { // update existing
-				updated = append(updated, id)
-				found = true
-				break
-			}
-		}
-		if found {
-			continue
-		}
-
-		// append new
-		t.appendItem(bindIntTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids))
-		updated = append(updated, id)
-		fire = true
-	}
-
-	for id := range t.items {
-		remove := true
-		for _, done := range updated {
-			if done == id {
-				remove = false
-				break
-			}
-		}
-
-		if remove { // remove item no longer present
-			fire = true
-			t.deleteItem(id, parentIDFor(id, t.ids))
-		}
-	}
-	if fire {
-		t.trigger()
-	}
-
-	for id, item := range t.items {
-		var err error
-		if t.updateExternal {
-			item.(*boundExternalIntTreeItem).lock.Lock()
-			err = item.(*boundExternalIntTreeItem).setIfChanged((*t.val)[id])
-			item.(*boundExternalIntTreeItem).lock.Unlock()
-		} else {
-			item.(*boundIntTreeItem).lock.Lock()
-			err = item.(*boundIntTreeItem).doSet((*t.val)[id])
-			item.(*boundIntTreeItem).lock.Unlock()
-		}
-		if err != nil {
-			retErr = err
-		}
-	}
-	return
-}
-
-func (t *boundIntTree) SetValue(id string, v int) error {
-	t.lock.Lock()
-	(*t.val)[id] = v
-	t.lock.Unlock()
-
-	item, err := t.GetItem(id)
-	if err != nil {
-		return err
-	}
-	return item.(Int).Set(v)
-}
-
-func bindIntTreeItem(v *map[string]int, id string, external bool) Int {
-	if external {
-		ret := &boundExternalIntTreeItem{old: (*v)[id]}
-		ret.val = v
-		ret.id = id
-		return ret
-	}
-
-	return &boundIntTreeItem{id: id, val: v}
-}
-
-type boundIntTreeItem struct {
-	base
-
-	val *map[string]int
-	id  string
-}
-
-func (t *boundIntTreeItem) Get() (int, error) {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	v := *t.val
-	if item, ok := v[t.id]; ok {
-		return item, nil
-	}
-
-	return 0, errOutOfBounds
-}
-
-func (t *boundIntTreeItem) Set(val int) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	return t.doSet(val)
-}
-
-func (t *boundIntTreeItem) doSet(val int) error {
-	(*t.val)[t.id] = val
-
-	t.trigger()
-	return nil
-}
-
-type boundExternalIntTreeItem struct {
-	boundIntTreeItem
-
-	old int
-}
-
-func (t *boundExternalIntTreeItem) setIfChanged(val int) error {
-	if val == t.old {
-		return nil
-	}
-	(*t.val)[t.id] = val
-	t.old = val
-
-	t.trigger()
-	return nil
-}
-
-// RuneTree supports binding a tree of rune values.
-//
-// Since: 2.4
-type RuneTree interface {
-	DataTree
-
-	Append(parent, id string, value rune) error
-	Get() (map[string][]string, map[string]rune, error)
-	GetValue(id string) (rune, error)
-	Prepend(parent, id string, value rune) error
-	Set(ids map[string][]string, values map[string]rune) error
-	SetValue(id string, value rune) error
-}
-
-// ExternalRuneTree supports binding a tree of rune values from an external variable.
-//
-// Since: 2.4
-type ExternalRuneTree interface {
-	RuneTree
-
-	Reload() error
-}
-
-// NewRuneTree returns a bindable tree of rune values.
-//
-// Since: 2.4
-func NewRuneTree() RuneTree {
-	t := &boundRuneTree{val: &map[string]rune{}}
-	t.ids = make(map[string][]string)
-	t.items = make(map[string]DataItem)
-	return t
-}
-
-// BindRuneTree returns a bound tree of rune values, based on the contents of the passed values.
-// The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map.
-// If your code changes the content of the maps this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.4
-func BindRuneTree(ids *map[string][]string, v *map[string]rune) ExternalRuneTree {
-	if v == nil {
-		return NewRuneTree().(ExternalRuneTree)
-	}
-
-	t := &boundRuneTree{val: v, updateExternal: true}
-	t.ids = make(map[string][]string)
-	t.items = make(map[string]DataItem)
-
-	for parent, children := range *ids {
-		for _, leaf := range children {
-			t.appendItem(bindRuneTreeItem(v, leaf, t.updateExternal), leaf, parent)
-		}
-	}
-
-	return t
-}
-
-type boundRuneTree struct {
-	treeBase
-
-	updateExternal bool
-	val            *map[string]rune
-}
-
-func (t *boundRuneTree) Append(parent, id string, val rune) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	ids, ok := t.ids[parent]
-	if !ok {
-		ids = make([]string, 0)
-	}
-
-	t.ids[parent] = append(ids, id)
-	v := *t.val
-	v[id] = val
-
-	return t.doReload()
-}
-
-func (t *boundRuneTree) Get() (map[string][]string, map[string]rune, error) {
-	t.lock.RLock()
-	defer t.lock.RUnlock()
-
-	return t.ids, *t.val, nil
-}
-
-func (t *boundRuneTree) GetValue(id string) (rune, error) {
-	t.lock.RLock()
-	defer t.lock.RUnlock()
-
-	if item, ok := (*t.val)[id]; ok {
-		return item, nil
-	}
-
-	return rune(0), errOutOfBounds
-}
-
-func (t *boundRuneTree) Prepend(parent, id string, val rune) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	ids, ok := t.ids[parent]
-	if !ok {
-		ids = make([]string, 0)
-	}
-
-	t.ids[parent] = append([]string{id}, ids...)
-	v := *t.val
-	v[id] = val
-
-	return t.doReload()
-}
-
-func (t *boundRuneTree) Reload() error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	return t.doReload()
-}
-
-func (t *boundRuneTree) Set(ids map[string][]string, v map[string]rune) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	t.ids = ids
-	*t.val = v
-
-	return t.doReload()
-}
-
-func (t *boundRuneTree) doReload() (retErr error) {
-	updated := []string{}
-	fire := false
-	for id := range *t.val {
-		found := false
-		for child := range t.items {
-			if child == id { // update existing
-				updated = append(updated, id)
-				found = true
-				break
-			}
-		}
-		if found {
-			continue
-		}
-
-		// append new
-		t.appendItem(bindRuneTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids))
-		updated = append(updated, id)
-		fire = true
-	}
-
-	for id := range t.items {
-		remove := true
-		for _, done := range updated {
-			if done == id {
-				remove = false
-				break
-			}
-		}
-
-		if remove { // remove item no longer present
-			fire = true
-			t.deleteItem(id, parentIDFor(id, t.ids))
-		}
-	}
-	if fire {
-		t.trigger()
-	}
-
-	for id, item := range t.items {
-		var err error
-		if t.updateExternal {
-			item.(*boundExternalRuneTreeItem).lock.Lock()
-			err = item.(*boundExternalRuneTreeItem).setIfChanged((*t.val)[id])
-			item.(*boundExternalRuneTreeItem).lock.Unlock()
-		} else {
-			item.(*boundRuneTreeItem).lock.Lock()
-			err = item.(*boundRuneTreeItem).doSet((*t.val)[id])
-			item.(*boundRuneTreeItem).lock.Unlock()
-		}
-		if err != nil {
-			retErr = err
-		}
-	}
-	return
-}
-
-func (t *boundRuneTree) SetValue(id string, v rune) error {
-	t.lock.Lock()
-	(*t.val)[id] = v
-	t.lock.Unlock()
-
-	item, err := t.GetItem(id)
-	if err != nil {
-		return err
-	}
-	return item.(Rune).Set(v)
-}
-
-func bindRuneTreeItem(v *map[string]rune, id string, external bool) Rune {
-	if external {
-		ret := &boundExternalRuneTreeItem{old: (*v)[id]}
-		ret.val = v
-		ret.id = id
-		return ret
-	}
-
-	return &boundRuneTreeItem{id: id, val: v}
-}
-
-type boundRuneTreeItem struct {
-	base
-
-	val *map[string]rune
-	id  string
-}
-
-func (t *boundRuneTreeItem) Get() (rune, error) {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	v := *t.val
-	if item, ok := v[t.id]; ok {
-		return item, nil
-	}
-
-	return rune(0), errOutOfBounds
-}
-
-func (t *boundRuneTreeItem) Set(val rune) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	return t.doSet(val)
-}
-
-func (t *boundRuneTreeItem) doSet(val rune) error {
-	(*t.val)[t.id] = val
-
-	t.trigger()
-	return nil
-}
-
-type boundExternalRuneTreeItem struct {
-	boundRuneTreeItem
-
-	old rune
-}
-
-func (t *boundExternalRuneTreeItem) setIfChanged(val rune) error {
-	if val == t.old {
-		return nil
-	}
-	(*t.val)[t.id] = val
-	t.old = val
-
-	t.trigger()
-	return nil
-}
-
-// StringTree supports binding a tree of string values.
-//
-// Since: 2.4
-type StringTree interface {
-	DataTree
-
-	Append(parent, id string, value string) error
-	Get() (map[string][]string, map[string]string, error)
-	GetValue(id string) (string, error)
-	Prepend(parent, id string, value string) error
-	Set(ids map[string][]string, values map[string]string) error
-	SetValue(id string, value string) error
-}
-
-// ExternalStringTree supports binding a tree of string values from an external variable.
-//
-// Since: 2.4
-type ExternalStringTree interface {
-	StringTree
-
-	Reload() error
-}
-
-// NewStringTree returns a bindable tree of string values.
-//
-// Since: 2.4
-func NewStringTree() StringTree {
-	t := &boundStringTree{val: &map[string]string{}}
-	t.ids = make(map[string][]string)
-	t.items = make(map[string]DataItem)
-	return t
-}
-
-// BindStringTree returns a bound tree of string values, based on the contents of the passed values.
-// The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map.
-// If your code changes the content of the maps this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.4
-func BindStringTree(ids *map[string][]string, v *map[string]string) ExternalStringTree {
-	if v == nil {
-		return NewStringTree().(ExternalStringTree)
-	}
-
-	t := &boundStringTree{val: v, updateExternal: true}
-	t.ids = make(map[string][]string)
-	t.items = make(map[string]DataItem)
-
-	for parent, children := range *ids {
-		for _, leaf := range children {
-			t.appendItem(bindStringTreeItem(v, leaf, t.updateExternal), leaf, parent)
-		}
-	}
-
-	return t
-}
-
-type boundStringTree struct {
-	treeBase
-
-	updateExternal bool
-	val            *map[string]string
-}
-
-func (t *boundStringTree) Append(parent, id string, val string) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	ids, ok := t.ids[parent]
-	if !ok {
-		ids = make([]string, 0)
-	}
-
-	t.ids[parent] = append(ids, id)
-	v := *t.val
-	v[id] = val
-
-	return t.doReload()
-}
-
-func (t *boundStringTree) Get() (map[string][]string, map[string]string, error) {
-	t.lock.RLock()
-	defer t.lock.RUnlock()
-
-	return t.ids, *t.val, nil
-}
-
-func (t *boundStringTree) GetValue(id string) (string, error) {
-	t.lock.RLock()
-	defer t.lock.RUnlock()
-
-	if item, ok := (*t.val)[id]; ok {
-		return item, nil
-	}
-
-	return "", errOutOfBounds
-}
-
-func (t *boundStringTree) Prepend(parent, id string, val string) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	ids, ok := t.ids[parent]
-	if !ok {
-		ids = make([]string, 0)
-	}
-
-	t.ids[parent] = append([]string{id}, ids...)
-	v := *t.val
-	v[id] = val
-
-	return t.doReload()
-}
-
-func (t *boundStringTree) Reload() error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	return t.doReload()
-}
-
-func (t *boundStringTree) Set(ids map[string][]string, v map[string]string) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	t.ids = ids
-	*t.val = v
-
-	return t.doReload()
-}
-
-func (t *boundStringTree) doReload() (retErr error) {
-	updated := []string{}
-	fire := false
-	for id := range *t.val {
-		found := false
-		for child := range t.items {
-			if child == id { // update existing
-				updated = append(updated, id)
-				found = true
-				break
-			}
-		}
-		if found {
-			continue
-		}
-
-		// append new
-		t.appendItem(bindStringTreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids))
-		updated = append(updated, id)
-		fire = true
-	}
-
-	for id := range t.items {
-		remove := true
-		for _, done := range updated {
-			if done == id {
-				remove = false
-				break
-			}
-		}
-
-		if remove { // remove item no longer present
-			fire = true
-			t.deleteItem(id, parentIDFor(id, t.ids))
-		}
-	}
-	if fire {
-		t.trigger()
-	}
-
-	for id, item := range t.items {
-		var err error
-		if t.updateExternal {
-			item.(*boundExternalStringTreeItem).lock.Lock()
-			err = item.(*boundExternalStringTreeItem).setIfChanged((*t.val)[id])
-			item.(*boundExternalStringTreeItem).lock.Unlock()
-		} else {
-			item.(*boundStringTreeItem).lock.Lock()
-			err = item.(*boundStringTreeItem).doSet((*t.val)[id])
-			item.(*boundStringTreeItem).lock.Unlock()
-		}
-		if err != nil {
-			retErr = err
-		}
-	}
-	return
-}
-
-func (t *boundStringTree) SetValue(id string, v string) error {
-	t.lock.Lock()
-	(*t.val)[id] = v
-	t.lock.Unlock()
-
-	item, err := t.GetItem(id)
-	if err != nil {
-		return err
-	}
-	return item.(String).Set(v)
-}
-
-func bindStringTreeItem(v *map[string]string, id string, external bool) String {
-	if external {
-		ret := &boundExternalStringTreeItem{old: (*v)[id]}
-		ret.val = v
-		ret.id = id
-		return ret
-	}
-
-	return &boundStringTreeItem{id: id, val: v}
-}
-
-type boundStringTreeItem struct {
-	base
-
-	val *map[string]string
-	id  string
-}
-
-func (t *boundStringTreeItem) Get() (string, error) {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	v := *t.val
-	if item, ok := v[t.id]; ok {
-		return item, nil
-	}
-
-	return "", errOutOfBounds
-}
-
-func (t *boundStringTreeItem) Set(val string) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	return t.doSet(val)
-}
-
-func (t *boundStringTreeItem) doSet(val string) error {
-	(*t.val)[t.id] = val
-
-	t.trigger()
-	return nil
-}
-
-type boundExternalStringTreeItem struct {
-	boundStringTreeItem
-
-	old string
-}
-
-func (t *boundExternalStringTreeItem) setIfChanged(val string) error {
-	if val == t.old {
-		return nil
-	}
-	(*t.val)[t.id] = val
-	t.old = val
-
-	t.trigger()
-	return nil
-}
-
-// URITree supports binding a tree of fyne.URI values.
-//
-// Since: 2.4
-type URITree interface {
-	DataTree
-
-	Append(parent, id string, value fyne.URI) error
-	Get() (map[string][]string, map[string]fyne.URI, error)
-	GetValue(id string) (fyne.URI, error)
-	Prepend(parent, id string, value fyne.URI) error
-	Set(ids map[string][]string, values map[string]fyne.URI) error
-	SetValue(id string, value fyne.URI) error
-}
-
-// ExternalURITree supports binding a tree of fyne.URI values from an external variable.
-//
-// Since: 2.4
-type ExternalURITree interface {
-	URITree
-
-	Reload() error
-}
-
-// NewURITree returns a bindable tree of fyne.URI values.
-//
-// Since: 2.4
-func NewURITree() URITree {
-	t := &boundURITree{val: &map[string]fyne.URI{}}
-	t.ids = make(map[string][]string)
-	t.items = make(map[string]DataItem)
-	return t
-}
-
-// BindURITree returns a bound tree of fyne.URI values, based on the contents of the passed values.
-// The ids map specifies how each item relates to its parent (with id ""), with the values being in the v map.
-// If your code changes the content of the maps this refers to you should call Reload() to inform the bindings.
-//
-// Since: 2.4
-func BindURITree(ids *map[string][]string, v *map[string]fyne.URI) ExternalURITree {
-	if v == nil {
-		return NewURITree().(ExternalURITree)
-	}
-
-	t := &boundURITree{val: v, updateExternal: true}
-	t.ids = make(map[string][]string)
-	t.items = make(map[string]DataItem)
-
-	for parent, children := range *ids {
-		for _, leaf := range children {
-			t.appendItem(bindURITreeItem(v, leaf, t.updateExternal), leaf, parent)
-		}
-	}
-
-	return t
-}
-
-type boundURITree struct {
-	treeBase
-
-	updateExternal bool
-	val            *map[string]fyne.URI
-}
-
-func (t *boundURITree) Append(parent, id string, val fyne.URI) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	ids, ok := t.ids[parent]
-	if !ok {
-		ids = make([]string, 0)
-	}
-
-	t.ids[parent] = append(ids, id)
-	v := *t.val
-	v[id] = val
-
-	return t.doReload()
-}
-
-func (t *boundURITree) Get() (map[string][]string, map[string]fyne.URI, error) {
-	t.lock.RLock()
-	defer t.lock.RUnlock()
-
-	return t.ids, *t.val, nil
-}
-
-func (t *boundURITree) GetValue(id string) (fyne.URI, error) {
-	t.lock.RLock()
-	defer t.lock.RUnlock()
-
-	if item, ok := (*t.val)[id]; ok {
-		return item, nil
-	}
-
-	return fyne.URI(nil), errOutOfBounds
-}
-
-func (t *boundURITree) Prepend(parent, id string, val fyne.URI) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	ids, ok := t.ids[parent]
-	if !ok {
-		ids = make([]string, 0)
-	}
-
-	t.ids[parent] = append([]string{id}, ids...)
-	v := *t.val
-	v[id] = val
-
-	return t.doReload()
-}
-
-func (t *boundURITree) Reload() error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	return t.doReload()
-}
-
-func (t *boundURITree) Set(ids map[string][]string, v map[string]fyne.URI) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-	t.ids = ids
-	*t.val = v
-
-	return t.doReload()
-}
-
-func (t *boundURITree) doReload() (retErr error) {
-	updated := []string{}
-	fire := false
-	for id := range *t.val {
-		found := false
-		for child := range t.items {
-			if child == id { // update existing
-				updated = append(updated, id)
-				found = true
-				break
-			}
-		}
-		if found {
-			continue
-		}
-
-		// append new
-		t.appendItem(bindURITreeItem(t.val, id, t.updateExternal), id, parentIDFor(id, t.ids))
-		updated = append(updated, id)
-		fire = true
-	}
-
-	for id := range t.items {
-		remove := true
-		for _, done := range updated {
-			if done == id {
-				remove = false
-				break
-			}
-		}
-
-		if remove { // remove item no longer present
-			fire = true
-			t.deleteItem(id, parentIDFor(id, t.ids))
-		}
-	}
-	if fire {
-		t.trigger()
-	}
-
-	for id, item := range t.items {
-		var err error
-		if t.updateExternal {
-			item.(*boundExternalURITreeItem).lock.Lock()
-			err = item.(*boundExternalURITreeItem).setIfChanged((*t.val)[id])
-			item.(*boundExternalURITreeItem).lock.Unlock()
-		} else {
-			item.(*boundURITreeItem).lock.Lock()
-			err = item.(*boundURITreeItem).doSet((*t.val)[id])
-			item.(*boundURITreeItem).lock.Unlock()
-		}
-		if err != nil {
-			retErr = err
-		}
-	}
-	return
-}
-
-func (t *boundURITree) SetValue(id string, v fyne.URI) error {
-	t.lock.Lock()
-	(*t.val)[id] = v
-	t.lock.Unlock()
-
-	item, err := t.GetItem(id)
-	if err != nil {
-		return err
-	}
-	return item.(URI).Set(v)
-}
-
-func bindURITreeItem(v *map[string]fyne.URI, id string, external bool) URI {
-	if external {
-		ret := &boundExternalURITreeItem{old: (*v)[id]}
-		ret.val = v
-		ret.id = id
-		return ret
-	}
-
-	return &boundURITreeItem{id: id, val: v}
-}
-
-type boundURITreeItem struct {
-	base
-
-	val *map[string]fyne.URI
-	id  string
-}
-
-func (t *boundURITreeItem) Get() (fyne.URI, error) {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	v := *t.val
-	if item, ok := v[t.id]; ok {
-		return item, nil
-	}
-
-	return fyne.URI(nil), errOutOfBounds
-}
-
-func (t *boundURITreeItem) Set(val fyne.URI) error {
-	t.lock.Lock()
-	defer t.lock.Unlock()
-
-	return t.doSet(val)
-}
-
-func (t *boundURITreeItem) doSet(val fyne.URI) error {
-	(*t.val)[t.id] = val
-
-	t.trigger()
-	return nil
-}
-
-type boundExternalURITreeItem struct {
-	boundURITreeItem
-
-	old fyne.URI
-}
-
-func (t *boundExternalURITreeItem) setIfChanged(val fyne.URI) error {
-	if compareURI(val, t.old) {
-		return nil
-	}
-	(*t.val)[t.id] = val
-	t.old = val
-
-	t.trigger()
-	return nil
-}

+ 0 - 118
vendor/fyne.io/fyne/v2/data/binding/bool.go

@@ -1,118 +0,0 @@
-package binding
-
-type not struct {
-	Bool
-}
-
-var _ Bool = (*not)(nil)
-
-// Not returns a Bool binding that invert the value of the given data binding.
-// This is providing the logical Not boolean operation as a data binding.
-//
-// Since 2.4
-func Not(data Bool) Bool {
-	return &not{Bool: data}
-}
-
-func (n *not) Get() (bool, error) {
-	v, err := n.Bool.Get()
-	return !v, err
-}
-
-func (n *not) Set(value bool) error {
-	return n.Bool.Set(!value)
-}
-
-type and struct {
-	booleans
-}
-
-var _ Bool = (*and)(nil)
-
-// And returns a Bool binding that return true when all the passed Bool binding are
-// true and false otherwise. It does apply a logical and boolean operation on all passed
-// Bool bindings. This binding is two way. In case of a Set, it will propagate the value
-// identically to all the Bool bindings used for its construction.
-//
-// Since 2.4
-func And(data ...Bool) Bool {
-	return &and{booleans: booleans{data: data}}
-}
-
-func (a *and) Get() (bool, error) {
-	for _, d := range a.data {
-		v, err := d.Get()
-		if err != nil {
-			return false, err
-		}
-		if !v {
-			return false, nil
-		}
-	}
-	return true, nil
-}
-
-func (a *and) Set(value bool) error {
-	for _, d := range a.data {
-		err := d.Set(value)
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-type or struct {
-	booleans
-}
-
-var _ Bool = (*or)(nil)
-
-// Or returns a Bool binding that return true when at least one of the passed Bool binding
-// is true and false otherwise. It does apply a logical or boolean operation on all passed
-// Bool bindings. This binding is two way. In case of a Set, it will propagate the value
-// identically to all the Bool bindings used for its construction.
-//
-// Since 2.4
-func Or(data ...Bool) Bool {
-	return &or{booleans: booleans{data: data}}
-}
-
-func (o *or) Get() (bool, error) {
-	for _, d := range o.data {
-		v, err := d.Get()
-		if err != nil {
-			return false, err
-		}
-		if v {
-			return true, nil
-		}
-	}
-	return false, nil
-}
-
-func (o *or) Set(value bool) error {
-	for _, d := range o.data {
-		err := d.Set(value)
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-type booleans struct {
-	data []Bool
-}
-
-func (g *booleans) AddListener(listener DataListener) {
-	for _, d := range g.data {
-		d.AddListener(listener)
-	}
-}
-
-func (g *booleans) RemoveListener(listener DataListener) {
-	for _, d := range g.data {
-		d.RemoveListener(listener)
-	}
-}

+ 0 - 13
vendor/fyne.io/fyne/v2/data/binding/comparator_helper.go

@@ -1,13 +0,0 @@
-package binding
-
-import "fyne.io/fyne/v2"
-
-func compareURI(v1, v2 fyne.URI) bool {
-	if v1 == nil && v1 == v2 {
-		return true
-	}
-	if v1 == nil || v2 == nil {
-		return false
-	}
-	return v1.String() == v2.String()
-}

Vissa filer visades inte eftersom för många filer har ändrats