This commit is contained in:
josc146 2023-05-17 23:27:52 +08:00
parent df8eef5f64
commit 00257f2e68
15 changed files with 160 additions and 35 deletions

View File

@ -2,6 +2,9 @@ package backend_golang
import ( import (
"context" "context"
"net/http"
"github.com/minio/selfupdate"
) )
// App struct // App struct
@ -19,3 +22,19 @@ func NewApp() *App {
func (a *App) OnStartup(ctx context.Context) { func (a *App) OnStartup(ctx context.Context) {
a.ctx = ctx a.ctx = ctx
} }
func (a *App) UpdateApp(url string) (broken bool, err error) {
resp, err := http.Get(url)
if err != nil {
return false, err
}
defer resp.Body.Close()
err = selfupdate.Apply(resp.Body, selfupdate.Options{})
if err != nil {
if rerr := selfupdate.RollbackError(err); rerr != nil {
return true, rerr
}
return false, err
}
return false, nil
}

View File

@ -6,12 +6,12 @@ import (
"strconv" "strconv"
) )
func (a *App) StartServer(port int) (string, error) { func cmd(args ...string) (string, error) {
cmdHelper, err := filepath.Abs("./cmd-helper") cmdHelper, err := filepath.Abs("./cmd-helper")
if err != nil { if err != nil {
return "", err return "", err
} }
cmd := exec.Command(cmdHelper, "python", "./backend-python/main.py", strconv.Itoa(port)) cmd := exec.Command(cmdHelper, args...)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return "", err return "", err
@ -19,15 +19,10 @@ func (a *App) StartServer(port int) (string, error) {
return string(out), nil return string(out), nil
} }
func (a *App) ConvertModel(modelPath string, strategy string, outPath string) (string, error) { func (a *App) StartServer(port int) (string, error) {
cmdHelper, err := filepath.Abs("./cmd-helper") return cmd("python", "./backend-python/main.py", strconv.Itoa(port))
if err != nil { }
return "", err
} func (a *App) ConvertModel(modelPath string, strategy string, outPath string) (string, error) {
cmd := exec.Command(cmdHelper, "python", "./backend-python/convert_model.py", "--in", modelPath, "--out", outPath, "--strategy", strategy) return cmd("python", "./backend-python/convert_model.py", "--in", modelPath, "--out", outPath, "--strategy", strategy)
out, err := cmd.CombinedOutput()
if err != nil {
return "", err
}
return string(out), nil
} }

View File

@ -23,14 +23,16 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE. // SOFTWARE.
import {FluentProvider, Tab, TabList, webDarkTheme} from '@fluentui/react-components'; import {FluentProvider, Tab, TabList, webDarkTheme, webLightTheme} from '@fluentui/react-components';
import {FC, useEffect, useState} from 'react'; import {FC, useEffect, useState} from 'react';
import {Route, Routes, useLocation, useNavigate} from 'react-router'; import {Route, Routes, useLocation, useNavigate} from 'react-router';
import {pages} from './pages'; import {pages} from './pages';
import {useMediaQuery} from 'usehooks-ts'; import {useMediaQuery} from 'usehooks-ts';
import {ToastContainer} from 'react-toastify'; import {ToastContainer} from 'react-toastify';
import commonStore from './stores/commonStore';
import {observer} from 'mobx-react-lite';
const App: FC = () => { const App: FC = observer(() => {
const navigate = useNavigate(); const navigate = useNavigate();
const location = useLocation(); const location = useLocation();
const mq = useMediaQuery('(min-width: 640px)'); const mq = useMediaQuery('(min-width: 640px)');
@ -43,7 +45,7 @@ const App: FC = () => {
useEffect(() => setPath(location.pathname), [location]); useEffect(() => setPath(location.pathname), [location]);
return ( return (
<FluentProvider theme={webDarkTheme} className="h-screen"> <FluentProvider theme={commonStore.settings.darkMode ? webDarkTheme : webLightTheme} className="h-screen">
<div className="flex h-full"> <div className="flex h-full">
<div className="flex flex-col w-16 sm:w-48 p-2 justify-between"> <div className="flex flex-col w-16 sm:w-48 p-2 justify-between">
<TabList <TabList
@ -93,10 +95,10 @@ const App: FC = () => {
rtl={false} rtl={false}
pauseOnFocusLoss={false} pauseOnFocusLoss={false}
draggable={false} draggable={false}
theme={'dark'} theme={commonStore.settings.darkMode ? 'dark' : 'light'}
/> />
</FluentProvider> </FluentProvider>
); );
}; });
export default App; export default App;

View File

@ -1,9 +1,21 @@
import {FC, ReactElement} from 'react'; import {FC, ReactElement} from 'react';
import {Label, Tooltip} from '@fluentui/react-components'; import {Label, Tooltip} from '@fluentui/react-components';
export const Labeled: FC<{ label: string; desc?: string, content: ReactElement }> = ({label, desc, content}) => { export const Labeled: FC<{
label: string; desc?: string, content: ReactElement, flex?: boolean, spaceBetween?: boolean
}> = ({
label,
desc,
content,
flex,
spaceBetween
}) => {
return ( return (
<div className="grid grid-cols-2 items-center"> <div className={
(flex ? 'flex' : 'grid grid-cols-2') + ' ' +
(spaceBetween ? 'justify-between' : '') + ' ' +
'items-center'
}>
{desc ? {desc ?
<Tooltip content={desc} showDelay={0} hideDelay={0} relationship="description"> <Tooltip content={desc} showDelay={0} hideDelay={0} relationship="description">
<Label>{label}</Label> <Label>{label}</Label>

View File

@ -1,7 +1,7 @@
import React, {FC, ReactElement} from 'react'; import React, {FC, ReactElement} from 'react';
import {Divider, Text} from '@fluentui/react-components'; import {Divider, Text} from '@fluentui/react-components';
export const Page: FC<{ title: string; content: ReactElement }> = ({title, content = true}) => { export const Page: FC<{ title: string; content: ReactElement }> = ({title, content}) => {
return ( return (
<div className="flex flex-col gap-2 p-2 h-full"> <div className="flex flex-col gap-2 p-2 h-full">
<Text size={600}>{title}</Text> <Text size={600}>{title}</Text>

View File

@ -1,10 +1,13 @@
import React, {FC} from 'react'; import React, {FC} from 'react';
import {Text} from '@fluentui/react-components'; import {Page} from '../components/Page';
import {PresenceBadge} from '@fluentui/react-components';
export const Chat: FC = () => { export const Chat: FC = () => {
return ( return (
<div className="flex flex-col box-border gap-5 p-2"> <Page title="Chat" content={
<Text size={600}>In Development</Text> <div className="flex flex-col gap-2 overflow-hidden">
</div> <PresenceBadge/>
</div>
}/>
); );
}; };

View File

@ -21,7 +21,7 @@ import {DownloadFile, OpenFileFolder} from '../../wailsjs/go/backend_golang/App'
import manifest from '../../../manifest.json'; import manifest from '../../../manifest.json';
import {toast} from 'react-toastify'; import {toast} from 'react-toastify';
import {Page} from '../components/Page'; import {Page} from '../components/Page';
import {refreshModels} from '../utils'; import {refreshModels, saveConfigs} from '../utils';
const columns: TableColumnDefinition<ModelSourceItem>[] = [ const columns: TableColumnDefinition<ModelSourceItem>[] = [
createTableColumn<ModelSourceItem>({ createTableColumn<ModelSourceItem>({
@ -134,6 +134,7 @@ export const Models: FC = observer(() => {
<Text weight="medium">Model Source Manifest List</Text> <Text weight="medium">Model Source Manifest List</Text>
<ToolTipButton desc="Refresh" icon={<ArrowClockwise20Regular/>} onClick={() => { <ToolTipButton desc="Refresh" icon={<ArrowClockwise20Regular/>} onClick={() => {
refreshModels(false); refreshModels(false);
saveConfigs();
}}/> }}/>
</div> </div>
<Text size={100}> <Text size={100}>

View File

@ -1,10 +1,40 @@
import React, {FC} from 'react'; import React, {FC} from 'react';
import {Text} from '@fluentui/react-components'; import {Page} from '../components/Page';
import {Dropdown, Option, Switch} from '@fluentui/react-components';
import {Labeled} from '../components/Labeled';
import commonStore from '../stores/commonStore';
import {observer} from 'mobx-react-lite';
export const Settings: FC = () => { export const Settings: FC = observer(() => {
return ( return (
<div className="flex flex-col box-border gap-5 p-2"> <Page title="Settings" content={
<Text size={600}>In Development</Text> <div className="flex flex-col gap-2 overflow-hidden">
</div> <Labeled label="Language" flex spaceBetween content={
<Dropdown style={{minWidth: 0}} listbox={{style: {minWidth: 0}}}
value="English"
selectedOptions={['English']}
onOptionSelect={(_, data) => {
if (data.optionText) {
}
}}>
<Option>English</Option>
<Option></Option>
</Dropdown>
}/>
<Labeled label="Dark Mode" flex spaceBetween content={
<Switch checked={commonStore.settings.darkMode}
onChange={(e, data) => {
commonStore.setSettings({
darkMode: data.checked
});
}}/>
}/>
<Labeled label="Automatic Updates Check" flex spaceBetween content={
<Switch checked={commonStore.settings.autoUpdatesCheck}
onChange={(e, data) => {
}}/>
}/>
</div>
}/>
); );
}; });

View File

@ -11,6 +11,10 @@ async function initConfig() {
await ReadJson('config.json').then((configData: LocalConfig) => { await ReadJson('config.json').then((configData: LocalConfig) => {
if (configData.modelSourceManifestList) if (configData.modelSourceManifestList)
commonStore.setModelSourceManifestList(configData.modelSourceManifestList); commonStore.setModelSourceManifestList(configData.modelSourceManifestList);
if (configData.settings)
commonStore.setSettings(configData.settings, false);
if (configData.modelConfigs && Array.isArray(configData.modelConfigs)) if (configData.modelConfigs && Array.isArray(configData.modelConfigs))
commonStore.setModelConfigs(configData.modelConfigs, false); commonStore.setModelConfigs(configData.modelConfigs, false);
else throw new Error('Invalid config.json'); else throw new Error('Invalid config.json');

View File

@ -1,5 +1,6 @@
import {makeAutoObservable} from 'mobx'; import {makeAutoObservable} from 'mobx';
import {saveConfigs} from '../utils'; import {getNavigatorLanguage, isSystemLightMode, saveConfigs, Settings} from '../utils';
import {WindowSetDarkTheme, WindowSetLightTheme} from '../../wailsjs/runtime';
export enum ModelStatus { export enum ModelStatus {
Offline, Offline,
@ -82,6 +83,11 @@ class CommonStore {
modelConfigs: ModelConfig[] = []; modelConfigs: ModelConfig[] = [];
modelSourceManifestList: string = 'https://cdn.jsdelivr.net/gh/josstorer/RWKV-Runner/manifest.json;'; modelSourceManifestList: string = 'https://cdn.jsdelivr.net/gh/josstorer/RWKV-Runner/manifest.json;';
modelSourceList: ModelSourceItem[] = []; modelSourceList: ModelSourceItem[] = [];
settings: Settings = {
language: getNavigatorLanguage(),
darkMode: !isSystemLightMode(),
autoUpdatesCheck: true
};
getCurrentModelConfig = () => { getCurrentModelConfig = () => {
return this.modelConfigs[this.currentModelConfigIndex]; return this.modelConfigs[this.currentModelConfigIndex];
@ -139,6 +145,18 @@ class CommonStore {
setModelSourceList = (value: ModelSourceItem[]) => { setModelSourceList = (value: ModelSourceItem[]) => {
this.modelSourceList = value; this.modelSourceList = value;
}; };
setSettings = (value: Partial<Settings>, saveConfig: boolean = true) => {
this.settings = {...this.settings, ...value};
if (this.settings.darkMode)
WindowSetDarkTheme();
else
WindowSetLightTheme();
if (saveConfig)
saveConfigs();
};
} }
export default new CommonStore(); export default new CommonStore();

View File

@ -6,10 +6,17 @@ export type Cache = {
models: ModelSourceItem[] models: ModelSourceItem[]
} }
export type Settings = {
language: string,
darkMode: boolean
autoUpdatesCheck: boolean
}
export type LocalConfig = { export type LocalConfig = {
modelSourceManifestList: string modelSourceManifestList: string
currentModelConfigIndex: number currentModelConfigIndex: number
modelConfigs: ModelConfig[] modelConfigs: ModelConfig[]
settings: Settings
} }
export async function refreshBuiltInModels(readCache: boolean = false) { export async function refreshBuiltInModels(readCache: boolean = false) {
@ -122,7 +129,8 @@ export const saveConfigs = async () => {
const data: LocalConfig = { const data: LocalConfig = {
modelSourceManifestList: commonStore.modelSourceManifestList, modelSourceManifestList: commonStore.modelSourceManifestList,
currentModelConfigIndex: commonStore.currentModelConfigIndex, currentModelConfigIndex: commonStore.currentModelConfigIndex,
modelConfigs: commonStore.modelConfigs modelConfigs: commonStore.modelConfigs,
settings: commonStore.settings
}; };
return SaveJson('config.json', data); return SaveJson('config.json', data);
}; };
@ -133,3 +141,13 @@ export const saveCache = async () => {
}; };
return SaveJson('cache.json', data); return SaveJson('cache.json', data);
}; };
export function getNavigatorLanguage() {
// const l = navigator.language.toLowerCase();
// if (['zh-hk', 'zh-mo', 'zh-tw', 'zh-cht', 'zh-hant'].includes(l)) return 'zhHant'
return navigator.language.substring(0, 2);
}
export function isSystemLightMode() {
return window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches;
}

View File

@ -19,3 +19,5 @@ export function ReadJson(arg1:string):Promise<any>;
export function SaveJson(arg1:string,arg2:any):Promise<void>; export function SaveJson(arg1:string,arg2:any):Promise<void>;
export function StartServer(arg1:number):Promise<string>; export function StartServer(arg1:number):Promise<string>;
export function UpdateApp(arg1:string):Promise<boolean>;

View File

@ -37,3 +37,7 @@ export function SaveJson(arg1, arg2) {
export function StartServer(arg1) { export function StartServer(arg1) {
return window['go']['backend_golang']['App']['StartServer'](arg1); return window['go']['backend_golang']['App']['StartServer'](arg1);
} }
export function UpdateApp(arg1) {
return window['go']['backend_golang']['App']['UpdateApp'](arg1);
}

2
go.mod
View File

@ -4,10 +4,12 @@ go 1.20
require ( require (
github.com/cavaliergopher/grab/v3 v3.0.1 github.com/cavaliergopher/grab/v3 v3.0.1
github.com/minio/selfupdate v0.6.0
github.com/wailsapp/wails/v2 v2.5.1 github.com/wailsapp/wails/v2 v2.5.1
) )
require ( require (
aead.dev/minisign v0.2.0 // indirect
github.com/bep/debounce v1.2.1 // indirect github.com/bep/debounce v1.2.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
github.com/google/uuid v1.3.0 // indirect github.com/google/uuid v1.3.0 // indirect

15
go.sum
View File

@ -1,3 +1,5 @@
aead.dev/minisign v0.2.0 h1:kAWrq/hBRu4AARY6AlciO83xhNnW9UaC8YipS2uhLPk=
aead.dev/minisign v0.2.0/go.mod h1:zdq6LdSd9TbuSxchxwhpA9zEb9YXcVGoE8JakuiGaIQ=
github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY=
github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0=
github.com/cavaliergopher/grab/v3 v3.0.1 h1:4z7TkBfmPjmLAAmkkAZNX/6QJ1nNFdv3SdIHXju0Fr4= github.com/cavaliergopher/grab/v3 v3.0.1 h1:4z7TkBfmPjmLAAmkkAZNX/6QJ1nNFdv3SdIHXju0Fr4=
@ -33,6 +35,8 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
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.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/minio/selfupdate v0.6.0 h1:i76PgT0K5xO9+hjzKcacQtO7+MjJ4JKA8Ak8XQ9DDwU=
github.com/minio/selfupdate v0.6.0/go.mod h1:bO02GTIPCMQFTEvE5h4DjYB58bCoZ35XLeBf0buTDdM=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -58,17 +62,26 @@ github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhw
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o= github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
github.com/wailsapp/wails/v2 v2.5.1 h1:mfG+2kWqQXYOwdgI43HEILjOZDXbk5woPYI3jP2b+js= github.com/wailsapp/wails/v2 v2.5.1 h1:mfG+2kWqQXYOwdgI43HEILjOZDXbk5woPYI3jP2b+js=
github.com/wailsapp/wails/v2 v2.5.1/go.mod h1:jbOZbcr/zm79PxXxAjP8UoVlDd9wLW3uDs+isIthDfs= github.com/wailsapp/wails/v2 v2.5.1/go.mod h1:jbOZbcr/zm79PxXxAjP8UoVlDd9wLW3uDs+isIthDfs=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU=
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -77,7 +90,9 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
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.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=