diff --git a/cspell.json b/cspell.json index 82370b1..f3da924 100644 --- a/cspell.json +++ b/cspell.json @@ -33,6 +33,7 @@ "KOBOLDAI", "koboldcpp", "KoboldCpp", + "lora", "lowvram", "Lowvram", "maximizable", @@ -50,6 +51,7 @@ "nvidia", "oldpc", "OLDPC", + "opencl", "Papi", "Philippov", "pkexec", diff --git a/package.json b/package.json index 181aaea..e2223bc 100644 --- a/package.json +++ b/package.json @@ -82,9 +82,11 @@ "@mantine/core": "^8.2.5", "@mantine/hooks": "^8.2.5", "lucide-react": "^0.540.0", + "opencl-info": "^0.3.0", "react": "^19.1.1", "react-dom": "^19.1.1", - "systeminformation": "^5.27.7" + "systeminformation": "^5.27.7", + "zustand": "^5.0.8" }, "build": { "appId": "com.friendly-kobold.app", diff --git a/src/components/ConfigFileManager.tsx b/src/components/ConfigFileManager.tsx index e39b965..320bd8e 100644 --- a/src/components/ConfigFileManager.tsx +++ b/src/components/ConfigFileManager.tsx @@ -21,7 +21,6 @@ import styles from '@/styles/layout.module.css'; interface ConfigFileManagerProps { configFiles: ConfigFile[]; selectedFile: string | null; - hasUnsavedChanges: boolean; onFileSelection: (fileName: string) => Promise; onCreateNewConfig: (configName: string) => Promise; onSaveConfig: () => void; @@ -64,7 +63,6 @@ SelectItem.displayName = 'SelectItem'; export const ConfigFileManager = ({ configFiles, selectedFile, - hasUnsavedChanges, onFileSelection, onCreateNewConfig, onSaveConfig, @@ -108,15 +106,6 @@ export const ConfigFileManager = ({ }; }); - if (selectedFile === null && hasUnsavedChanges) { - const displayName = 'New Configuration (unsaved)'; - selectData.unshift({ - value: '__new__', - label: displayName, - extension: '.kcpps', - }); - } - return ( <> @@ -127,11 +116,7 @@ export const ConfigFileManager = ({
- value && onGpuDeviceChange(parseInt(value, 10)) + value && handleGpuDeviceChange(parseInt(value, 10)) } data={selectedBackend.devices!.map((device, index) => ({ value: index.toString(), @@ -233,42 +205,40 @@ export const BackendSelector = ({ })()}
- {onGpuLayersChange && onAutoGpuLayersChange && ( -
- - - GPU Layers - - - - - + + + GPU Layers + + + + + + handleGpuLayersChange(Number(event.target.value) || 0) + } + type="number" + min={0} + max={100} + step={1} + size="sm" + w={80} + disabled={autoGpuLayers} + /> + + - onGpuLayersChange(Number(event.target.value) || 0) + handleAutoGpuLayersChange(event.currentTarget.checked) } - type="number" - min={0} - max={100} - step={1} size="sm" - w={80} - disabled={autoGpuLayers} /> - - - onAutoGpuLayersChange(event.currentTarget.checked) - } - size="sm" - /> - - + -
- )} + + ); diff --git a/src/components/screens/Launch/GeneralTab/index.tsx b/src/components/screens/Launch/GeneralTab/index.tsx index 6ee20a1..f9afeca 100644 --- a/src/components/screens/Launch/GeneralTab/index.tsx +++ b/src/components/screens/Launch/GeneralTab/index.tsx @@ -3,24 +3,10 @@ import { File, Search } from 'lucide-react'; import { InfoTooltip } from '@/components/InfoTooltip'; import { BackendSelector } from '@/components/screens/Launch/GeneralTab/BackendSelector'; import { getInputValidationState } from '@/utils'; +import { useLaunchConfig } from '@/hooks/useLaunchConfig'; import styles from '@/styles/layout.module.css'; interface GeneralTabProps { - modelPath: string; - gpuLayers: number; - autoGpuLayers: boolean; - contextSize: number; - backend: string; - gpuDevice?: number; - noavx2: boolean; - failsafe: boolean; - onModelPathChange: (path: string) => void; - onSelectModelFile: () => void; - onGpuLayersChange: (layers: number) => void; - onAutoGpuLayersChange: (auto: boolean) => void; - onContextSizeChange: (size: number) => void; - onBackendChange: (backend: string) => void; - onGpuDeviceChange?: (device: number) => void; onWarningsChange?: ( warnings: Array<{ type: 'warning' | 'info'; message: string }> ) => void; @@ -28,24 +14,17 @@ interface GeneralTabProps { } export const GeneralTab = ({ - modelPath, - gpuLayers, - autoGpuLayers, - contextSize, - backend, - gpuDevice, - noavx2, - failsafe, - onModelPathChange, - onSelectModelFile, - onGpuLayersChange, - onAutoGpuLayersChange, - onContextSizeChange, - onBackendChange, - onGpuDeviceChange, onWarningsChange, onBackendsReady, }: GeneralTabProps) => { + const { + modelPath, + contextSize, + handleModelPathChange, + handleSelectModelFile, + handleContextSizeChangeWithStep, + } = useLaunchConfig(); + const validationState = getInputValidationState(modelPath); const getInputColor = () => { @@ -72,18 +51,8 @@ export const GeneralTab = ({ return (
@@ -95,7 +64,7 @@ export const GeneralTab = ({ onModelPathChange(event.currentTarget.value)} + onChange={(e) => handleModelPathChange(e.target.value)} color={getInputColor()} error={ validationState === 'invalid' ? getHelperText() : undefined @@ -103,7 +72,7 @@ export const GeneralTab = ({ />
- {showSearchHF && ( - - )} - - - ); -}; - -export const ImageGenerationTab = ({ - sdmodel, - sdt5xxl, - sdclipl, - sdclipg, - sdphotomaker, - sdvae, - sdlora, - onSdmodelChange, - onSelectSdmodelFile, - onSdt5xxlChange, - onSelectSdt5xxlFile, - onSdcliplChange, - onSelectSdcliplFile, - onSdclipgChange, - onSelectSdclipgFile, - onSdphotomakerChange, - onSelectSdphotomakerFile, - onSdvaeChange, - onSelectSdvaeFile, - onSdloraChange, - onSelectSdloraFile, - onApplyPreset, -}: ImageGenerationTabProps) => { const [selectedPreset, setSelectedPreset] = useState(null); + const ModelField = ({ + label, + value, + placeholder, + tooltip, + onChange, + onSelectFile, + showSearchHF = false, + }: { + label: string; + value: string; + placeholder: string; + tooltip?: string; + onChange: (value: string) => void; + onSelectFile: () => void; + showSearchHF?: boolean; + }) => { + const validationState = getInputValidationState(value); + + const getInputColor = () => { + switch (validationState) { + case 'valid': + return 'green'; + case 'invalid': + return 'red'; + default: + return undefined; + } + }; + + const getHelperText = () => { + if (!value.trim()) return undefined; + + if (validationState === 'invalid') { + return 'Enter a valid URL or file path'; + } + + return undefined; + }; + + return ( +
+ + + {label} + + {tooltip && } + + +
+ onChange(event.currentTarget.value)} + color={getInputColor()} + error={ + validationState === 'invalid' ? getHelperText() : undefined + } + /> +
+ + {showSearchHF && ( + + )} +
+
+ ); + }; + return (
@@ -158,7 +138,7 @@ export const ImageGenerationTab = ({ onChange={(value) => { setSelectedPreset(value); if (value) { - onApplyPreset(value); + handleApplyPreset(value); } }} clearable @@ -169,8 +149,8 @@ export const ImageGenerationTab = ({ label="Image Gen. Model File" value={sdmodel} placeholder="Select a model file or enter a direct URL" - onChange={onSdmodelChange} - onSelectFile={onSelectSdmodelFile} + onChange={handleSdmodelChange} + onSelectFile={handleSelectSdmodelFile} showSearchHF /> @@ -178,24 +158,24 @@ export const ImageGenerationTab = ({ label="T5-XXL File" value={sdt5xxl} placeholder="Select a T5-XXL file or enter a direct URL" - onChange={onSdt5xxlChange} - onSelectFile={onSelectSdt5xxlFile} + onChange={handleSdt5xxlChange} + onSelectFile={handleSelectSdt5xxlFile} /> ); diff --git a/src/components/screens/Launch/NetworkTab.tsx b/src/components/screens/Launch/NetworkTab.tsx index caf0094..00e681c 100644 --- a/src/components/screens/Launch/NetworkTab.tsx +++ b/src/components/screens/Launch/NetworkTab.tsx @@ -1,41 +1,26 @@ import { Stack, Text, TextInput, Group, Checkbox } from '@mantine/core'; import { useState, useEffect } from 'react'; import { InfoTooltip } from '@/components/InfoTooltip'; +import { useLaunchConfig } from '@/hooks/useLaunchConfig'; import styles from '@/styles/layout.module.css'; -interface NetworkTabProps { - port: number | undefined; - host: string; - multiuser: boolean; - multiplayer: boolean; - remotetunnel: boolean; - nocertify: boolean; - websearch: boolean; - onPortChange: (port: number | undefined) => void; - onHostChange: (host: string) => void; - onMultiuserChange: (multiuser: boolean) => void; - onMultiplayerChange: (multiplayer: boolean) => void; - onRemotetunnelChange: (remotetunnel: boolean) => void; - onNocertifyChange: (nocertify: boolean) => void; - onWebsearchChange: (websearch: boolean) => void; -} - -export const NetworkTab = ({ - port, - host, - multiuser, - multiplayer, - remotetunnel, - nocertify, - websearch, - onPortChange, - onHostChange, - onMultiuserChange, - onMultiplayerChange, - onRemotetunnelChange, - onNocertifyChange, - onWebsearchChange, -}: NetworkTabProps) => { +export const NetworkTab = () => { + const { + port, + host, + multiuser, + multiplayer, + remotetunnel, + nocertify, + websearch, + handlePortChange, + handleHostChange, + handleMultiuserChange, + handleMultiplayerChange, + handleRemotetunnelChange, + handleNocertifyChange, + handleWebsearchChange, + } = useLaunchConfig(); const [portInput, setPortInput] = useState(port?.toString() ?? ''); useEffect(() => { @@ -53,10 +38,10 @@ export const NetworkTab = ({ onHostChange(event.currentTarget.value)} - style={{ maxWidth: 200 }} + onChange={(event) => handleHostChange(event.currentTarget.value)} />
@@ -80,13 +65,13 @@ export const NetworkTab = ({ const numValue = Number(value); if (!isNaN(numValue) && numValue >= 1 && numValue <= 65535) { - onPortChange(numValue); + handlePortChange(numValue); } }} onBlur={(event) => { const value = event.currentTarget.value; if (value === '') { - onPortChange(undefined); + handlePortChange(undefined); setPortInput(''); } }} @@ -106,7 +91,7 @@ export const NetworkTab = ({ - onMultiuserChange(event.currentTarget.checked) + handleMultiuserChange(event.currentTarget.checked) } label="Multiuser Mode" /> @@ -119,7 +104,7 @@ export const NetworkTab = ({ - onMultiplayerChange(event.currentTarget.checked) + handleMultiplayerChange(event.currentTarget.checked) } label="Shared Multiplayer" /> @@ -134,7 +119,7 @@ export const NetworkTab = ({ - onRemotetunnelChange(event.currentTarget.checked) + handleRemotetunnelChange(event.currentTarget.checked) } label="Remote Tunnel" /> @@ -147,7 +132,7 @@ export const NetworkTab = ({ - onNocertifyChange(event.currentTarget.checked) + handleNocertifyChange(event.currentTarget.checked) } label="No Certify Mode (Insecure)" /> @@ -160,7 +145,7 @@ export const NetworkTab = ({ - onWebsearchChange(event.currentTarget.checked) + handleWebsearchChange(event.currentTarget.checked) } label="Enable WebSearch" /> diff --git a/src/components/screens/Launch/index.tsx b/src/components/screens/Launch/index.tsx index f7f2be6..def0c92 100644 --- a/src/components/screens/Launch/index.tsx +++ b/src/components/screens/Launch/index.tsx @@ -1,10 +1,9 @@ import { Card, Container, Stack, Tabs, Group, Button } from '@mantine/core'; import { useState, useEffect, useCallback } from 'react'; import { useLaunchConfig } from '@/hooks/useLaunchConfig'; -import { useTrackedConfigHandlers } from '@/hooks/useTrackedConfigHandlers'; import { useLaunchLogic } from '@/hooks/useLaunchLogic'; import { useWarnings } from '@/hooks/useWarnings'; -import { GeneralTab } from '@/components/screens/Launch/GeneralTab'; +import { GeneralTab } from '@/components/screens/Launch/GeneralTab/index'; import { AdvancedTab } from '@/components/screens/Launch/AdvancedTab'; import { NetworkTab } from '@/components/screens/Launch/NetworkTab'; import { ImageGenerationTab } from '@/components/screens/Launch/ImageGenerationTab'; @@ -25,7 +24,6 @@ export const LaunchScreen = ({ const [selectedFile, setSelectedFile] = useState(null); const [, setInstallDir] = useState(''); const [activeTab, setActiveTab] = useState('general'); - const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false); const [warnings, setWarnings] = useState< Array<{ type: 'warning' | 'info'; message: string }> >([]); @@ -51,6 +49,7 @@ export const LaunchScreen = ({ quantmatmul, backend, gpuDevice, + gpuPlatform, sdmodel, sdt5xxl, sdclipl, @@ -59,78 +58,9 @@ export const LaunchScreen = ({ sdvae, sdlora, parseAndApplyConfigFile, - loadSavedSettings, loadConfigFromFile, - handleSelectModelFile, - handleGpuDeviceChange, - handleSelectSdmodelFile, - handleSelectSdt5xxlFile, - handleSelectSdcliplFile, - handleSelectSdclipgFile, - handleSelectSdphotomakerFile, - handleSelectSdvaeFile, - handleSelectSdloraFile, - handleApplyPreset, - handleModelPathChange, - handleGpuLayersChange, - handleAutoGpuLayersChange, - handleContextSizeChangeWithStep, - handleAdditionalArgumentsChange, - handlePortChange, - handleHostChange, - handleMultiuserChange, - handleMultiplayerChange, - handleRemotetunnelChange, - handleNocertifyChange, - handleWebsearchChange, - handleNoshiftChange, - handleFlashattentionChange, - handleNoavx2Change, - handleFailsafeChange, - handleLowvramChange, - handleQuantmatmulChange, - handleBackendChange, - handleSdmodelChange, - handleSdt5xxlChange, - handleSdcliplChange, - handleSdclipgChange, - handleSdphotomakerChange, - handleSdvaeChange, - handleSdloraChange, } = useLaunchConfig(); - const trackedHandlers = useTrackedConfigHandlers({ - setHasUnsavedChanges, - handlers: { - handleModelPathChange, - handleGpuLayersChange, - handleAutoGpuLayersChange, - handleContextSizeChangeWithStep, - handleAdditionalArgumentsChange, - handlePortChange, - handleHostChange, - handleMultiuserChange, - handleMultiplayerChange, - handleRemotetunnelChange, - handleNocertifyChange, - handleWebsearchChange, - handleNoshiftChange, - handleFlashattentionChange, - handleNoavx2Change, - handleFailsafeChange, - handleLowvramChange, - handleQuantmatmulChange, - handleBackendChange, - handleSdmodelChange, - handleSdt5xxlChange, - handleSdcliplChange, - handleSdclipgChange, - handleSdphotomakerChange, - handleSdvaeChange, - handleSdloraChange, - }, - }); - const { isLaunching, handleLaunch } = useLaunchLogic({ modelPath, sdmodel, @@ -156,13 +86,11 @@ export const LaunchScreen = ({ setSelectedFile(files[0].name); } - await loadSavedSettings(); - - const currentSelectedFile = await loadConfigFromFile(files, savedConfig); - if (currentSelectedFile && !selectedFile) { - setSelectedFile(currentSelectedFile); + const loadedConfigFileName = await loadConfigFromFile(files, savedConfig); + if (loadedConfigFileName && !selectedFile) { + setSelectedFile(loadedConfigFileName); } - }, [selectedFile, loadSavedSettings, loadConfigFromFile]); + }, [selectedFile, loadConfigFromFile]); const handleFileSelection = async (fileName: string) => { setSelectedFile(fileName); @@ -172,35 +100,41 @@ export const LaunchScreen = ({ if (selectedConfig) { await parseAndApplyConfigFile(selectedConfig.path); } - - setHasUnsavedChanges(false); }; - const buildConfigData = () => ({ - gpulayers: gpuLayers, - contextsize: contextSize, - model_param: modelPath, - port, - host, - multiuser: multiuser ? 1 : 0, - multiplayer, - remotetunnel, - nocertify, - websearch, - noshift, - flashattention, - noavx2, - failsafe, - usecuda: backend === 'cuda' || backend === 'rocm', - usevulkan: backend === 'vulkan', - useclblast: backend === 'clblast', - sdmodel, - sdt5xxl, - sdclipl, - sdclipg, - sdphotomaker, - sdvae, - }); + const buildConfigData = () => { + let useclblastValue: [number, number] | false = false; + + if (backend === 'clblast') { + useclblastValue = [gpuDevice, gpuPlatform]; + } + + return { + gpulayers: gpuLayers, + contextsize: contextSize, + model: modelPath, + port, + host, + multiuser: multiuser ? 1 : 0, + multiplayer, + remotetunnel, + nocertify, + websearch, + noshift, + flashattention, + noavx2, + failsafe, + usecuda: backend === 'cuda' || backend === 'rocm', + usevulkan: backend === 'vulkan', + useclblast: useclblastValue, + sdmodel, + sdt5xxl, + sdclipl, + sdclipg, + sdphotomaker, + sdvae, + }; + }; const handleCreateNewConfig = async (configName: string) => { try { @@ -214,7 +148,6 @@ export const LaunchScreen = ({ const newFileName = `${configName}.kcpps`; setSelectedFile(newFileName); await window.electronAPI.kobold.setSelectedConfig(newFileName); - setHasUnsavedChanges(false); } else { window.electronAPI.logs.logError( 'Failed to create new configuration', @@ -246,9 +179,7 @@ export const LaunchScreen = ({ buildConfigData() ); - if (success) { - setHasUnsavedChanges(false); - } else { + if (!success) { window.electronAPI.logs.logError( 'Failed to save configuration', new Error('Save operation failed') @@ -318,7 +249,6 @@ export const LaunchScreen = ({ - + - + - + - + diff --git a/src/hooks/useChangeTracking.ts b/src/hooks/useChangeTracking.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/hooks/useLaunchConfig.ts b/src/hooks/useLaunchConfig.ts index 2260402..cb3c438 100644 --- a/src/hooks/useLaunchConfig.ts +++ b/src/hooks/useLaunchConfig.ts @@ -1,534 +1,90 @@ -import { useState, useCallback } from 'react'; -import type { ConfigFile } from '@/types'; +import { useLaunchConfigStore } from '@/stores/launchConfigStore'; import { - getPresetByName, + IMAGE_MODEL_PRESETS, type ImageModelPreset, } from '@/utils/imageModelPresets'; -import { - DEFAULT_CONTEXT_SIZE, - DEFAULT_MODEL_URL, - DEFAULT_HOST, -} from '@/constants'; export const useLaunchConfig = () => { - const [gpuLayers, setGpuLayers] = useState(0); - const [autoGpuLayers, setAutoGpuLayers] = useState(false); - const [contextSize, setContextSize] = useState(DEFAULT_CONTEXT_SIZE); - const [modelPath, setModelPath] = useState(DEFAULT_MODEL_URL); - const [additionalArguments, setAdditionalArguments] = useState(''); - const [port, setPort] = useState(undefined); - const [host, setHost] = useState(DEFAULT_HOST); - const [multiuser, setMultiuser] = useState(false); - const [multiplayer, setMultiplayer] = useState(false); - const [remotetunnel, setRemotetunnel] = useState(false); - const [nocertify, setNocertify] = useState(false); - const [websearch, setWebsearch] = useState(false); - const [noshift, setNoshift] = useState(false); - const [flashattention, setFlashattention] = useState(true); - const [noavx2, setNoavx2] = useState(false); - const [failsafe, setFailsafe] = useState(false); - const [lowvram, setLowvram] = useState(false); - const [quantmatmul, setQuantmatmul] = useState(true); - const [backend, setBackend] = useState(''); - const [gpuDevice, setGpuDevice] = useState(0); - - const [sdmodel, setSdmodel] = useState(''); - const [sdt5xxl, setSdt5xxl] = useState(''); - const [sdclipl, setSdclipl] = useState(''); - const [sdclipg, setSdclipg] = useState(''); - const [sdphotomaker, setSdphotomaker] = useState(''); - const [sdvae, setSdvae] = useState(''); - const [sdlora, setSdlora] = useState(''); - - // eslint-disable-next-line sonarjs/cognitive-complexity - const parseAndApplyConfigFile = useCallback(async (configPath: string) => { - const configData = - await window.electronAPI.kobold.parseConfigFile(configPath); - - if (configData) { - if (typeof configData.gpulayers === 'number') { - setGpuLayers(configData.gpulayers); - } else { - setGpuLayers(0); - } - - if (typeof configData.contextsize === 'number') { - setContextSize(configData.contextsize); - } else { - setContextSize(DEFAULT_CONTEXT_SIZE); - } - - if (typeof configData.model_param === 'string') { - setModelPath(configData.model_param); - } - - if (typeof configData.port === 'number') { - setPort(configData.port); - } else { - setPort(undefined); - } - - if (typeof configData.host === 'string') { - setHost(configData.host); - } else { - setHost(DEFAULT_HOST); - } - - if (typeof configData.multiuser === 'number') { - setMultiuser(configData.multiuser === 1); - } else { - setMultiuser(false); - } - - if (typeof configData.multiplayer === 'boolean') { - setMultiplayer(configData.multiplayer); - } else { - setMultiplayer(false); - } - - if (typeof configData.remotetunnel === 'boolean') { - setRemotetunnel(configData.remotetunnel); - } else { - setRemotetunnel(false); - } - - if (typeof configData.nocertify === 'boolean') { - setNocertify(configData.nocertify); - } else { - setNocertify(false); - } - - if (typeof configData.websearch === 'boolean') { - setWebsearch(configData.websearch); - } else { - setWebsearch(false); - } - - if (typeof configData.noshift === 'boolean') { - setNoshift(configData.noshift); - } else { - setNoshift(false); - } - - if (typeof configData.flashattention === 'boolean') { - setFlashattention(configData.flashattention); - } else { - setFlashattention(true); - } - - if (typeof configData.noavx2 === 'boolean') { - setNoavx2(configData.noavx2); - } else { - setNoavx2(false); - } - - if (typeof configData.failsafe === 'boolean') { - setFailsafe(configData.failsafe); - } else { - setFailsafe(false); - } - - if (typeof configData.lowvram === 'boolean') { - setLowvram(configData.lowvram); - } - - if (typeof configData.quantmatmul === 'boolean') { - setQuantmatmul(configData.quantmatmul); - } - - if (configData.usecuda === true) { - const gpuInfo = await window.electronAPI.kobold.detectGPU(); - setBackend(gpuInfo.hasNVIDIA ? 'cuda' : 'rocm'); - - if ( - Array.isArray(configData.usecuda) && - configData.usecuda.length >= 3 - ) { - const [vramMode, deviceId, mmqMode] = configData.usecuda; - setLowvram(vramMode === 'lowvram'); - setGpuDevice(parseInt(deviceId, 10) || 0); - setQuantmatmul(mmqMode === 'mmq'); - } - } else if (configData.usevulkan === true) { - setBackend('vulkan'); - } else if (configData.useclblast === true) { - setBackend('clblast'); - } else { - setBackend('cpu'); - } - - if (typeof configData.sdmodel === 'string') { - setSdmodel(configData.sdmodel); - } - - if (typeof configData.sdt5xxl === 'string') { - setSdt5xxl(configData.sdt5xxl); - } - - if (typeof configData.sdclipl === 'string') { - setSdclipl(configData.sdclipl); - } - - if (typeof configData.sdclipg === 'string') { - setSdclipg(configData.sdclipg); - } - - if (typeof configData.sdphotomaker === 'string') { - setSdphotomaker(configData.sdphotomaker); - } - - if (typeof configData.sdvae === 'string') { - setSdvae(configData.sdvae); - } - - if (typeof configData.sdlora === 'string') { - setSdlora(configData.sdlora); - } - } else { - const cpuCapabilities = await window.electronAPI.kobold.detectCPU(); - setGpuLayers(0); - setContextSize(DEFAULT_CONTEXT_SIZE); - setPort(undefined); - setHost(DEFAULT_HOST); - setMultiuser(false); - setMultiplayer(false); - setRemotetunnel(false); - setNocertify(false); - setWebsearch(false); - setNoshift(false); - setFlashattention(true); - setNoavx2(!cpuCapabilities.avx2); - setFailsafe(!cpuCapabilities.avx && !cpuCapabilities.avx2); - setBackend(''); - - setSdmodel(''); - setSdt5xxl( - 'https://huggingface.co/camenduru/FLUX.1-dev/resolve/main/t5xxl_fp8_e4m3fn.safetensors?download=true' - ); - setSdclipl( - 'https://huggingface.co/camenduru/FLUX.1-dev/resolve/main/clip_l.safetensors?download=true' - ); - setSdclipg(''); - setSdphotomaker(''); - setSdvae( - 'https://huggingface.co/camenduru/FLUX.1-dev/resolve/main/ae.safetensors?download=true' - ); - } - }, []); - - const loadSavedSettings = useCallback(async () => { - const cpuCapabilities = await window.electronAPI.kobold.detectCPU(); - - setModelPath(DEFAULT_MODEL_URL); - setGpuLayers(0); - setContextSize(DEFAULT_CONTEXT_SIZE); - setPort(undefined); - setHost(DEFAULT_HOST); - setMultiuser(false); - setMultiplayer(false); - setRemotetunnel(false); - setNocertify(false); - setWebsearch(false); - setNoshift(false); - setFlashattention(true); - setNoavx2(!cpuCapabilities.avx2); - setFailsafe(!cpuCapabilities.avx && !cpuCapabilities.avx2); - setBackend(''); - - setSdmodel(''); - setSdt5xxl(''); - setSdclipl(''); - setSdclipg(''); - setSdphotomaker(''); - setSdvae(''); - }, []); - - const loadConfigFromFile = useCallback( - async (configFiles: ConfigFile[], savedConfig: string | null) => { - let currentSelectedFile = null; - - if (savedConfig && configFiles.some((f) => f.name === savedConfig)) { - currentSelectedFile = savedConfig; - } else if (configFiles.length > 0) { - currentSelectedFile = configFiles[0].name; - } - - if (currentSelectedFile) { - const selectedConfig = configFiles.find( - (f) => f.name === currentSelectedFile - ); - if (selectedConfig) { - await parseAndApplyConfigFile(selectedConfig.path); - } - } - - return currentSelectedFile; - }, - [parseAndApplyConfigFile] - ); - - const handleGpuLayersChange = useCallback(async (value: number) => { - setGpuLayers(value); - }, []); - - const roundToValidContextSize = useCallback((value: number): number => { - if (value < 1024) { - return Math.round(value / 256) * 256; - } - return Math.round(value / 1024) * 1024; - }, []); - - const handleContextSizeChangeWithStep = useCallback( - async (value: number) => { - const roundedValue = roundToValidContextSize(value); - setContextSize(roundedValue); - }, - [roundToValidContextSize] - ); - - const handleModelPathChange = useCallback((value: string) => { - setModelPath(value); - }, []); - - const handleSelectModelFile = useCallback(async () => { - const filePath = await window.electronAPI.kobold.selectModelFile(); - if (filePath) { - handleModelPathChange(filePath); - } - }, [handleModelPathChange]); - - const handleAdditionalArgumentsChange = useCallback((value: string) => { - setAdditionalArguments(value); - }, []); - - const handleAutoGpuLayersChange = useCallback((checked: boolean) => { - setAutoGpuLayers(checked); - }, []); - - const handlePortChange = useCallback((value: number | undefined) => { - setPort(value); - }, []); - - const handleHostChange = useCallback((value: string) => { - setHost(value); - }, []); - - const handleMultiuserChange = useCallback((checked: boolean) => { - setMultiuser(checked); - }, []); - - const handleMultiplayerChange = useCallback((checked: boolean) => { - setMultiplayer(checked); - }, []); - - const handleRemotetunnelChange = useCallback((checked: boolean) => { - setRemotetunnel(checked); - }, []); - - const handleNocertifyChange = useCallback((checked: boolean) => { - setNocertify(checked); - }, []); - - const handleWebsearchChange = useCallback((checked: boolean) => { - setWebsearch(checked); - }, []); - - const handleNoshiftChange = useCallback((checked: boolean) => { - setNoshift(checked); - }, []); - - const handleFlashattentionChange = useCallback((checked: boolean) => { - setFlashattention(checked); - }, []); - - const handleNoavx2Change = useCallback((checked: boolean) => { - setNoavx2(checked); - }, []); - - const handleFailsafeChange = useCallback((checked: boolean) => { - setFailsafe(checked); - }, []); - - const handleLowvramChange = useCallback((checked: boolean) => { - setLowvram(checked); - }, []); - - const handleQuantmatmulChange = useCallback((checked: boolean) => { - setQuantmatmul(checked); - }, []); - - const handleBackendChange = useCallback((backend: string) => { - setBackend(backend); - }, []); - - const handleGpuDeviceChange = useCallback((device: number) => { - setGpuDevice(device); - }, []); - - const handleSdmodelChange = useCallback((path: string) => { - setSdmodel(path); - }, []); - - const handleSelectSdmodelFile = useCallback(async () => { - const filePath = await window.electronAPI.kobold.selectModelFile(); - if (filePath) { - setSdmodel(filePath); - } - }, []); - - const handleSdt5xxlChange = useCallback((path: string) => { - setSdt5xxl(path); - }, []); - - const handleSelectSdt5xxlFile = useCallback(async () => { - const filePath = await window.electronAPI.kobold.selectModelFile(); - if (filePath) { - setSdt5xxl(filePath); - } - }, []); - - const handleSdcliplChange = useCallback((path: string) => { - setSdclipl(path); - }, []); - - const handleSelectSdcliplFile = useCallback(async () => { - const filePath = await window.electronAPI.kobold.selectModelFile(); - if (filePath) { - setSdclipl(filePath); - } - }, []); - - const handleSdclipgChange = useCallback((path: string) => { - setSdclipg(path); - }, []); - - const handleSelectSdclipgFile = useCallback(async () => { - const filePath = await window.electronAPI.kobold.selectModelFile(); - if (filePath) { - setSdclipg(filePath); - } - }, []); - - const handleSdphotomakerChange = useCallback((path: string) => { - setSdphotomaker(path); - }, []); - - const handleSelectSdphotomakerFile = useCallback(async () => { - const filePath = await window.electronAPI.kobold.selectModelFile(); - if (filePath) { - setSdphotomaker(filePath); - } - }, []); - - const handleSdvaeChange = useCallback((path: string) => { - setSdvae(path); - }, []); - - const handleSelectSdvaeFile = useCallback(async () => { - const filePath = await window.electronAPI.kobold.selectModelFile(); - if (filePath) { - setSdvae(filePath); - } - }, []); - - const handleSdloraChange = useCallback((path: string) => { - setSdlora(path); - }, []); - - const handleSelectSdloraFile = useCallback(async () => { - const filePath = await window.electronAPI.kobold.selectModelFile(); - if (filePath) { - setSdlora(filePath); - } - }, []); - - const applyImageModelPreset = useCallback((preset: ImageModelPreset) => { - setSdmodel(preset.sdmodel); - setSdt5xxl(preset.sdt5xxl); - setSdclipl(preset.sdclipl); - setSdclipg(preset.sdclipg); - setSdphotomaker(preset.sdphotomaker); - setSdvae(preset.sdvae); - }, []); - - const handleApplyPreset = useCallback( - (presetName: string) => { - const preset = getPresetByName(presetName); - if (preset) { - applyImageModelPreset(preset); - } - }, - [applyImageModelPreset] - ); + const state = useLaunchConfigStore(); return { - gpuLayers, - autoGpuLayers, - contextSize, - modelPath, - additionalArguments, - port, - host, - multiuser, - multiplayer, - remotetunnel, - nocertify, - websearch, - noshift, - flashattention, - noavx2, - failsafe, - lowvram, - quantmatmul, - backend, - gpuDevice, - sdmodel, - sdt5xxl, - sdclipl, - sdclipg, - sdphotomaker, - sdvae, - sdlora, + gpuLayers: state.gpuLayers, + autoGpuLayers: state.autoGpuLayers, + contextSize: state.contextSize, + modelPath: state.modelPath, + additionalArguments: state.additionalArguments, + port: state.port, + host: state.host, + multiuser: state.multiuser, + multiplayer: state.multiplayer, + remotetunnel: state.remotetunnel, + nocertify: state.nocertify, + websearch: state.websearch, + noshift: state.noshift, + flashattention: state.flashattention, + noavx2: state.noavx2, + failsafe: state.failsafe, + lowvram: state.lowvram, + quantmatmul: state.quantmatmul, + backend: state.backend, + gpuDevice: state.gpuDevice, + gpuPlatform: state.gpuPlatform, + sdmodel: state.sdmodel, + sdt5xxl: state.sdt5xxl, + sdclipl: state.sdclipl, + sdclipg: state.sdclipg, + sdphotomaker: state.sdphotomaker, + sdvae: state.sdvae, + sdlora: state.sdlora, - parseAndApplyConfigFile, - loadSavedSettings, - loadConfigFromFile, - handleGpuLayersChange, - handleAutoGpuLayersChange, - handleContextSizeChangeWithStep, - handleModelPathChange, - handleSelectModelFile, - handleAdditionalArgumentsChange, - handlePortChange, - handleHostChange, - handleMultiuserChange, - handleMultiplayerChange, - handleRemotetunnelChange, - handleNocertifyChange, - handleWebsearchChange, - handleNoshiftChange, - handleFlashattentionChange, - handleNoavx2Change, - handleFailsafeChange, - handleLowvramChange, - handleQuantmatmulChange, - handleBackendChange, - handleGpuDeviceChange, - handleSdmodelChange, - handleSelectSdmodelFile, - handleSdt5xxlChange, - handleSelectSdt5xxlFile, - handleSdcliplChange, - handleSelectSdcliplFile, - handleSdclipgChange, - handleSelectSdclipgFile, - handleSdphotomakerChange, - handleSelectSdphotomakerFile, - handleSdvaeChange, - handleSelectSdvaeFile, - handleSdloraChange, - handleSelectSdloraFile, - applyImageModelPreset, - handleApplyPreset, + handleGpuLayersChange: state.setGpuLayers, + handleAutoGpuLayersChange: state.setAutoGpuLayers, + handleContextSizeChangeWithStep: state.contextSizeChangeWithStep, + handleModelPathChange: state.setModelPath, + handleAdditionalArgumentsChange: state.setAdditionalArguments, + handlePortChange: state.setPort, + handleHostChange: state.setHost, + handleMultiuserChange: state.setMultiuser, + handleMultiplayerChange: state.setMultiplayer, + handleRemotetunnelChange: state.setRemotetunnel, + handleNocertifyChange: state.setNocertify, + handleWebsearchChange: state.setWebsearch, + handleNoshiftChange: state.setNoshift, + handleFlashattentionChange: state.setFlashattention, + handleNoavx2Change: state.setNoavx2, + handleFailsafeChange: state.setFailsafe, + handleLowvramChange: state.setLowvram, + handleQuantmatmulChange: state.setQuantmatmul, + handleBackendChange: state.setBackend, + handleGpuDeviceChange: state.setGpuDevice, + handleGpuPlatformChange: state.setGpuPlatform, + handleSdmodelChange: state.setSdmodel, + handleSdt5xxlChange: state.setSdt5xxl, + handleSdcliplChange: state.setSdclipl, + handleSdclipgChange: state.setSdclipg, + handleSdphotomakerChange: state.setSdphotomaker, + handleSdvaeChange: state.setSdvae, + handleSdloraChange: state.setSdlora, + + parseAndApplyConfigFile: state.parseAndApplyConfigFile, + loadConfigFromFile: state.loadConfigFromFile, + handleSelectModelFile: state.selectModelFile, + handleImageModelPresetChange: state.applyImageModelPreset, + handleApplyPreset: (presetName: string) => { + const preset = IMAGE_MODEL_PRESETS.find( + (p: ImageModelPreset) => p.name === presetName + ); + if (preset) { + state.applyImageModelPreset(preset); + } + }, + + handleSelectSdmodelFile: state.selectSdmodelFile, + handleSelectSdt5xxlFile: state.selectSdt5xxlFile, + handleSelectSdcliplFile: state.selectSdcliplFile, + handleSelectSdclipgFile: state.selectSdclipgFile, + handleSelectSdphotomakerFile: state.selectSdphotomakerFile, + handleSelectSdvaeFile: state.selectSdvaeFile, + handleSelectSdloraFile: state.selectSdloraFile, }; }; diff --git a/src/hooks/useLaunchLogic.ts b/src/hooks/useLaunchLogic.ts index b8bfd99..5b54e84 100644 --- a/src/hooks/useLaunchLogic.ts +++ b/src/hooks/useLaunchLogic.ts @@ -1,4 +1,5 @@ import { useState, useCallback } from 'react'; +import { parseCLBlastDevice } from '@/utils'; interface UseLaunchLogicProps { modelPath: string; @@ -22,7 +23,7 @@ interface LaunchArgs { flashattention: boolean; backend: string; lowvram: boolean; - gpuDevice: number; + gpuDevice: number | string; quantmatmul: boolean; additionalArguments: string; sdt5xxl: string; @@ -116,13 +117,33 @@ const buildBackendArgs = (launchArgs: LaunchArgs): string[] => { if (launchArgs.backend === 'cuda' || launchArgs.backend === 'rocm') { const cudaArgs = ['--usecuda']; cudaArgs.push(launchArgs.lowvram ? 'lowvram' : 'normal'); - cudaArgs.push(launchArgs.gpuDevice.toString()); + cudaArgs.push( + typeof launchArgs.gpuDevice === 'string' + ? '0' + : launchArgs.gpuDevice.toString() + ); cudaArgs.push(launchArgs.quantmatmul ? 'mmq' : 'nommq'); args.push(...cudaArgs); } else if (launchArgs.backend === 'vulkan') { args.push('--usevulkan'); } else if (launchArgs.backend === 'clblast') { - args.push('--useclblast'); + const clblastArgs = ['--useclblast']; + + if (typeof launchArgs.gpuDevice === 'string') { + const parsed = parseCLBlastDevice(launchArgs.gpuDevice); + if (parsed) { + clblastArgs.push( + parsed.deviceIndex.toString(), + parsed.platformIndex.toString() + ); + } else { + clblastArgs.push('0', '0'); + } + } else { + clblastArgs.push(launchArgs.gpuDevice.toString(), '0'); + } + + args.push(...clblastArgs); } } diff --git a/src/hooks/useTrackedConfigHandlers.ts b/src/hooks/useTrackedConfigHandlers.ts index 47ca31f..10c00ab 100644 --- a/src/hooks/useTrackedConfigHandlers.ts +++ b/src/hooks/useTrackedConfigHandlers.ts @@ -22,6 +22,8 @@ interface TrackedConfigHandlersProps { handleLowvramChange: (enabled: boolean) => void; handleQuantmatmulChange: (enabled: boolean) => void; handleBackendChange: (backend: string) => void; + handleGpuDeviceChange: (device: number) => void; + handleGpuPlatformChange: (platform: number) => void; handleSdmodelChange: (path: string) => void; handleSdt5xxlChange: (path: string) => void; handleSdcliplChange: (path: string) => void; @@ -58,6 +60,8 @@ export const useTrackedConfigHandlers = ({ handleLowvramChange, handleQuantmatmulChange, handleBackendChange, + handleGpuDeviceChange, + handleGpuPlatformChange, handleSdmodelChange, handleSdt5xxlChange, handleSdcliplChange, @@ -144,6 +148,14 @@ export const useTrackedConfigHandlers = ({ handleBackendChange, setHasUnsavedChanges ), + handleGpuDeviceChangeWithTracking: createChangeTracker( + handleGpuDeviceChange, + setHasUnsavedChanges + ), + handleGpuPlatformChangeWithTracking: createChangeTracker( + handleGpuPlatformChange, + setHasUnsavedChanges + ), handleSdmodelChangeWithTracking: createChangeTracker( handleSdmodelChange, setHasUnsavedChanges diff --git a/src/main/managers/KoboldCppManager.ts b/src/main/managers/KoboldCppManager.ts index b75f96d..c78e7aa 100644 --- a/src/main/managers/KoboldCppManager.ts +++ b/src/main/managers/KoboldCppManager.ts @@ -348,7 +348,7 @@ export class KoboldCppManager { async parseConfigFile(filePath: string): Promise<{ gpulayers?: number; contextsize?: number; - model_param?: string; + model?: string; [key: string]: unknown; } | null> { try { @@ -371,7 +371,7 @@ export class KoboldCppManager { configData: { gpulayers?: number; contextsize?: number; - model_param?: string; + model?: string; port?: number; host?: string; multiuser?: number; @@ -385,7 +385,7 @@ export class KoboldCppManager { failsafe?: boolean; usecuda?: boolean; usevulkan?: boolean; - useclblast?: boolean; + useclblast?: [number, number] | boolean; sdmodel?: string; sdt5xxl?: string; sdclipl?: string; @@ -615,6 +615,7 @@ export class KoboldCppManager { this.koboldProcess = spawn(versionPath, args, { stdio: ['ignore', 'pipe', 'pipe'], + shell: process.platform === 'win32', }); if (onOutput) { @@ -938,6 +939,7 @@ export class KoboldCppManager { const child = spawn(currentVersion.path, finalArgs, { stdio: ['pipe', 'pipe', 'pipe'], detached: false, + shell: process.platform === 'win32', }); this.koboldProcess = child; diff --git a/src/main/services/BinaryService.ts b/src/main/services/BinaryService.ts index f473f6e..8fafeee 100644 --- a/src/main/services/BinaryService.ts +++ b/src/main/services/BinaryService.ts @@ -13,6 +13,10 @@ export interface BackendSupport { export class BinaryService { private backendSupportCache = new Map(); + private availableBackendsCache = new Map< + string, + Array<{ value: string; label: string; devices?: string[] }> + >(); private logManager: LogManager; constructor(logManager: LogManager) { @@ -78,6 +82,12 @@ export class BinaryService { clblast: { supported: boolean; devices: string[] }; } ): Array<{ value: string; label: string; devices?: string[] }> { + const cacheKey = `${koboldBinaryPath}:${JSON.stringify(hardwareCapabilities)}`; + + if (this.availableBackendsCache.has(cacheKey)) { + return this.availableBackendsCache.get(cacheKey)!; + } + const backendSupport = this.detectBackendSupport(koboldBinaryPath); const backends: Array<{ value: string; @@ -122,10 +132,12 @@ export class BinaryService { label: 'CPU', }); + this.availableBackendsCache.set(cacheKey, backends); return backends; } clearCache(): void { this.backendSupportCache.clear(); + this.availableBackendsCache.clear(); } } diff --git a/src/main/services/HardwareService.ts b/src/main/services/HardwareService.ts index e97b836..2590e14 100644 --- a/src/main/services/HardwareService.ts +++ b/src/main/services/HardwareService.ts @@ -1,5 +1,6 @@ /* eslint-disable no-comments/disallowComments */ import si from 'systeminformation'; +import * as openclInfo from 'opencl-info'; import { shortenDeviceName } from '@/utils'; import type { CPUCapabilities, @@ -343,74 +344,35 @@ export class HardwareService { devices: string[]; }> { try { - const { spawn } = await import('child_process'); - const clinfo = spawn('clinfo', ['--json'], { timeout: 5000 }); + const platforms = openclInfo.getPlatformInfo(); - let output = ''; - clinfo.stdout.on('data', (data) => { - output += data.toString(); - }); + const devices: string[] = []; - return new Promise((resolve) => { - // eslint-disable-next-line sonarjs/cognitive-complexity - clinfo.on('close', (code) => { - if (code === 0 && output.trim()) { - try { - const data = JSON.parse(output); - const devices: string[] = []; - - if (data.platforms) { - for (const platform of data.platforms) { - if (platform.devices) { - for (const device of platform.devices) { - if (device.name && device.type !== 'CPU') { - devices.push(shortenDeviceName(device.name)); - } - } - } - } - } - - resolve({ - supported: devices.length > 0, - devices, - }); - } catch { - const lines = output.split('\n'); - const devices: string[] = []; - - for (const line of lines) { - if (line.includes('Device Name') && !line.includes('CPU')) { - const name = line.split(':')[1]?.trim(); - if (name) { - devices.push(shortenDeviceName(name)); - } - } - } - - resolve({ - supported: devices.length > 0, - devices, - }); + for ( + let platformIndex = 0; + platformIndex < platforms.length; + platformIndex++ + ) { + const platform = platforms[platformIndex]; + if (platform.devices) { + for ( + let deviceIndex = 0; + deviceIndex < platform.devices.length; + deviceIndex++ + ) { + const device = platform.devices[deviceIndex]; + if (device.name && device.type === 'GPU') { + const deviceLabel = `${shortenDeviceName(device.name)} (${platform.name})`; + devices.push(deviceLabel); } - } else { - resolve({ supported: false, devices: [] }); } - }); + } + } - clinfo.on('error', () => { - resolve({ supported: false, devices: [] }); - }); - - setTimeout(() => { - try { - clinfo.kill('SIGTERM'); - } catch { - void 0; - } - resolve({ supported: false, devices: [] }); - }, 5000); - }); + return { + supported: devices.length > 0, + devices, + }; } catch { return { supported: false, devices: [] }; } diff --git a/src/preload/index.ts b/src/preload/index.ts index 16ea03e..2226dff 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -55,7 +55,7 @@ const koboldAPI: KoboldAPI = { configData: { gpulayers?: number; contextsize?: number; - model_param?: string; + model?: string; port?: number; host?: string; multiuser?: number; @@ -69,7 +69,7 @@ const koboldAPI: KoboldAPI = { failsafe?: boolean; usecuda?: boolean; usevulkan?: boolean; - useclblast?: boolean; + useclblast?: [number, number] | boolean; sdmodel?: string; sdt5xxl?: string; sdclipl?: string; diff --git a/src/stores/launchConfigStore.ts b/src/stores/launchConfigStore.ts new file mode 100644 index 0000000..5829644 --- /dev/null +++ b/src/stores/launchConfigStore.ts @@ -0,0 +1,393 @@ +import { create } from 'zustand'; +import type { ConfigFile } from '@/types'; +import type { ImageModelPreset } from '@/utils/imageModelPresets'; +import { + DEFAULT_CONTEXT_SIZE, + DEFAULT_MODEL_URL, + DEFAULT_HOST, +} from '@/constants'; + +interface LaunchConfigState { + gpuLayers: number; + autoGpuLayers: boolean; + contextSize: number; + modelPath: string; + additionalArguments: string; + port?: number; + host: string; + multiuser: boolean; + multiplayer: boolean; + remotetunnel: boolean; + nocertify: boolean; + websearch: boolean; + noshift: boolean; + flashattention: boolean; + noavx2: boolean; + failsafe: boolean; + lowvram: boolean; + quantmatmul: boolean; + backend: string; + gpuDevice: number; + gpuPlatform: number; + sdmodel: string; + sdt5xxl: string; + sdclipl: string; + sdclipg: string; + sdphotomaker: string; + sdvae: string; + sdlora: string; + + setGpuLayers: (layers: number) => void; + setAutoGpuLayers: (auto: boolean) => void; + setContextSize: (size: number) => void; + setModelPath: (path: string) => void; + setAdditionalArguments: (args: string) => void; + setPort: (port?: number) => void; + setHost: (host: string) => void; + setMultiuser: (multiuser: boolean) => void; + setMultiplayer: (multiplayer: boolean) => void; + setRemotetunnel: (remotetunnel: boolean) => void; + setNocertify: (nocertify: boolean) => void; + setWebsearch: (websearch: boolean) => void; + setNoshift: (noshift: boolean) => void; + setFlashattention: (flashattention: boolean) => void; + setNoavx2: (noavx2: boolean) => void; + setFailsafe: (failsafe: boolean) => void; + setLowvram: (lowvram: boolean) => void; + setQuantmatmul: (quantmatmul: boolean) => void; + setBackend: (backend: string) => void; + setGpuDevice: (device: number) => void; + setGpuPlatform: (platform: number) => void; + setSdmodel: (model: string) => void; + setSdt5xxl: (model: string) => void; + setSdclipl: (model: string) => void; + setSdclipg: (model: string) => void; + setSdphotomaker: (model: string) => void; + setSdvae: (vae: string) => void; + setSdlora: (loraModel: string) => void; + + parseAndApplyConfigFile: (configPath: string) => Promise; + loadConfigFromFile: ( + configFiles: ConfigFile[], + savedConfig: string | null + ) => Promise; + selectModelFile: () => Promise; + selectSdmodelFile: () => Promise; + selectSdt5xxlFile: () => Promise; + selectSdcliplFile: () => Promise; + selectSdclipgFile: () => Promise; + selectSdphotomakerFile: () => Promise; + selectSdvaeFile: () => Promise; + selectSdloraFile: () => Promise; + contextSizeChangeWithStep: (size: number) => void; + applyImageModelPreset: (preset: ImageModelPreset) => void; +} + +export const useLaunchConfigStore = create((set, get) => ({ + gpuLayers: 0, + autoGpuLayers: false, + contextSize: DEFAULT_CONTEXT_SIZE, + modelPath: DEFAULT_MODEL_URL, + additionalArguments: '', + port: undefined, + host: DEFAULT_HOST, + multiuser: false, + multiplayer: false, + remotetunnel: false, + nocertify: false, + websearch: false, + noshift: false, + flashattention: true, + noavx2: false, + failsafe: false, + lowvram: false, + quantmatmul: true, + backend: '', + gpuDevice: 0, + gpuPlatform: 0, + sdmodel: '', + sdt5xxl: '', + sdclipl: '', + sdclipg: '', + sdphotomaker: '', + sdvae: '', + sdlora: '', + + setGpuLayers: (layers) => set({ gpuLayers: layers }), + setAutoGpuLayers: (auto) => set({ autoGpuLayers: auto }), + setContextSize: (size) => set({ contextSize: size }), + setModelPath: (path) => set({ modelPath: path }), + setAdditionalArguments: (args) => set({ additionalArguments: args }), + setPort: (port) => set({ port }), + setHost: (host) => set({ host }), + setMultiuser: (multiuser) => set({ multiuser }), + setMultiplayer: (multiplayer) => set({ multiplayer }), + setRemotetunnel: (remotetunnel) => set({ remotetunnel }), + setNocertify: (nocertify) => set({ nocertify }), + setWebsearch: (websearch) => set({ websearch }), + setNoshift: (noshift) => set({ noshift }), + setFlashattention: (flashattention) => set({ flashattention }), + setNoavx2: (noavx2) => set({ noavx2 }), + setFailsafe: (failsafe) => set({ failsafe }), + setLowvram: (lowvram) => set({ lowvram }), + setQuantmatmul: (quantmatmul) => set({ quantmatmul }), + setBackend: (backend) => set({ backend }), + setGpuDevice: (device) => set({ gpuDevice: device }), + setGpuPlatform: (platform) => set({ gpuPlatform: platform }), + setSdmodel: (model) => set({ sdmodel: model }), + setSdt5xxl: (model) => set({ sdt5xxl: model }), + setSdclipl: (model) => set({ sdclipl: model }), + setSdclipg: (model) => set({ sdclipg: model }), + setSdphotomaker: (model) => set({ sdphotomaker: model }), + setSdvae: (vae) => set({ sdvae: vae }), + setSdlora: (loraModel) => set({ sdlora: loraModel }), + + // eslint-disable-next-line sonarjs/cognitive-complexity + parseAndApplyConfigFile: async (configPath: string) => { + const configData = + await window.electronAPI.kobold.parseConfigFile(configPath); + + if (configData) { + const updates: Partial = {}; + + if (typeof configData.gpulayers === 'number') { + updates.gpuLayers = configData.gpulayers; + } else { + updates.gpuLayers = 0; + } + + if (typeof configData.contextsize === 'number') { + updates.contextSize = configData.contextsize; + } else { + updates.contextSize = DEFAULT_CONTEXT_SIZE; + } + + if (typeof configData.model === 'string') { + updates.modelPath = configData.model; + } + + if (typeof configData.port === 'number') { + updates.port = configData.port; + } else { + updates.port = undefined; + } + + if (typeof configData.host === 'string') { + updates.host = configData.host; + } else { + updates.host = DEFAULT_HOST; + } + + if (typeof configData.multiuser === 'number') { + updates.multiuser = configData.multiuser === 1; + } else { + updates.multiuser = false; + } + + if (typeof configData.multiplayer === 'boolean') { + updates.multiplayer = configData.multiplayer; + } else { + updates.multiplayer = false; + } + + if (typeof configData.remotetunnel === 'boolean') { + updates.remotetunnel = configData.remotetunnel; + } else { + updates.remotetunnel = false; + } + + if (typeof configData.nocertify === 'boolean') { + updates.nocertify = configData.nocertify; + } else { + updates.nocertify = false; + } + + if (typeof configData.websearch === 'boolean') { + updates.websearch = configData.websearch; + } else { + updates.websearch = false; + } + + if (typeof configData.noshift === 'boolean') { + updates.noshift = configData.noshift; + } else { + updates.noshift = false; + } + + if (typeof configData.flashattention === 'boolean') { + updates.flashattention = configData.flashattention; + } else { + updates.flashattention = true; + } + + if (typeof configData.noavx2 === 'boolean') { + updates.noavx2 = configData.noavx2; + } else { + updates.noavx2 = false; + } + + if (typeof configData.failsafe === 'boolean') { + updates.failsafe = configData.failsafe; + } else { + updates.failsafe = false; + } + + if (typeof configData.lowvram === 'boolean') { + updates.lowvram = configData.lowvram; + } + + if (typeof configData.quantmatmul === 'boolean') { + updates.quantmatmul = configData.quantmatmul; + } + + if (configData.usecuda === true) { + const gpuInfo = await window.electronAPI.kobold.detectGPU(); + updates.backend = gpuInfo.hasNVIDIA ? 'cuda' : 'rocm'; + + if ( + Array.isArray(configData.usecuda) && + configData.usecuda.length >= 3 + ) { + const [vramMode, deviceId, mmqMode] = configData.usecuda; + updates.lowvram = vramMode === 'lowvram'; + updates.gpuDevice = parseInt(deviceId, 10) || 0; + updates.quantmatmul = mmqMode === 'mmq'; + } + } else if (configData.usevulkan === true) { + updates.backend = 'vulkan'; + } else if ( + Array.isArray(configData.useclblast) && + configData.useclblast.length === 2 + ) { + updates.backend = 'clblast'; + const [deviceIndex, platformIndex] = configData.useclblast; + updates.gpuDevice = deviceIndex; + updates.gpuPlatform = platformIndex; + } else { + updates.backend = 'cpu'; + } + + if (typeof configData.sdmodel === 'string') { + updates.sdmodel = configData.sdmodel; + } + + if (typeof configData.sdt5xxl === 'string') { + updates.sdt5xxl = configData.sdt5xxl; + } + + if (typeof configData.sdclipl === 'string') { + updates.sdclipl = configData.sdclipl; + } + + if (typeof configData.sdclipg === 'string') { + updates.sdclipg = configData.sdclipg; + } + + if (typeof configData.sdphotomaker === 'string') { + updates.sdphotomaker = configData.sdphotomaker; + } + + if (typeof configData.sdvae === 'string') { + updates.sdvae = configData.sdvae; + } + + if (typeof configData.sdlora === 'string') { + updates.sdlora = configData.sdlora; + } + + set(updates); + } + }, + + loadConfigFromFile: async ( + configFiles: ConfigFile[], + savedConfig: string | null + ): Promise => { + let currentSelectedFile = null; + + if (savedConfig) { + currentSelectedFile = configFiles.find((f) => f.name === savedConfig); + } + + if (!currentSelectedFile && configFiles.length > 0) { + currentSelectedFile = configFiles[0]; + } + + if (currentSelectedFile) { + await get().parseAndApplyConfigFile(currentSelectedFile.path); + return currentSelectedFile.name; + } + + return null; + }, + + selectModelFile: async () => { + const result = await window.electronAPI.kobold.selectModelFile(); + if (result) { + set({ modelPath: result }); + } + }, + + selectSdmodelFile: async () => { + const result = await window.electronAPI.kobold.selectModelFile(); + if (result) { + set({ sdmodel: result }); + } + }, + + selectSdt5xxlFile: async () => { + const result = await window.electronAPI.kobold.selectModelFile(); + if (result) { + set({ sdt5xxl: result }); + } + }, + + selectSdcliplFile: async () => { + const result = await window.electronAPI.kobold.selectModelFile(); + if (result) { + set({ sdclipl: result }); + } + }, + + selectSdclipgFile: async () => { + const result = await window.electronAPI.kobold.selectModelFile(); + if (result) { + set({ sdclipg: result }); + } + }, + + selectSdphotomakerFile: async () => { + const result = await window.electronAPI.kobold.selectModelFile(); + if (result) { + set({ sdphotomaker: result }); + } + }, + + selectSdvaeFile: async () => { + const result = await window.electronAPI.kobold.selectModelFile(); + if (result) { + set({ sdvae: result }); + } + }, + + selectSdloraFile: async () => { + const result = await window.electronAPI.kobold.selectModelFile(); + if (result) { + set({ sdlora: result }); + } + }, + + contextSizeChangeWithStep: (size: number) => { + const roundedSize = Math.round(size / 256) * 256; + set({ contextSize: Math.max(256, Math.min(131072, roundedSize)) }); + }, + + applyImageModelPreset: (preset: ImageModelPreset) => { + set({ + sdt5xxl: preset.sdt5xxl, + sdclipl: preset.sdclipl, + sdclipg: preset.sdclipg || '', + sdvae: preset.sdvae, + }); + }, +})); diff --git a/src/types/electron.d.ts b/src/types/electron.d.ts index c14e88a..3774b86 100644 --- a/src/types/electron.d.ts +++ b/src/types/electron.d.ts @@ -110,7 +110,7 @@ export interface KoboldAPI { configData: { gpulayers?: number; contextsize?: number; - model_param?: string; + model?: string; port?: number; host?: string; multiuser?: number; @@ -124,7 +124,7 @@ export interface KoboldAPI { failsafe?: boolean; usecuda?: boolean; usevulkan?: boolean; - useclblast?: boolean; + useclblast?: [number, number] | boolean; sdmodel?: string; sdt5xxl?: string; sdclipl?: string; @@ -139,7 +139,7 @@ export interface KoboldAPI { parseConfigFile: (filePath: string) => Promise<{ gpulayers?: number; contextsize?: number; - model_param?: string; + model?: string; [key: string]: unknown; } | null>; selectModelFile: () => Promise; diff --git a/src/utils/clblast.ts b/src/utils/clblast.ts new file mode 100644 index 0000000..a9fd5e3 --- /dev/null +++ b/src/utils/clblast.ts @@ -0,0 +1,25 @@ +export function parseCLBlastDevice(deviceString: string): { + deviceIndex: number; + platformIndex: number; +} | null { + const match = deviceString.match(/\[(\d+),(\d+)\]$/); + if (match) { + return { + deviceIndex: parseInt(match[1], 10), + platformIndex: parseInt(match[2], 10), + }; + } + return null; +} + +export function formatCLBlastArgs( + deviceIndex: number, + platformIndex: number +): [string, string] { + return [deviceIndex.toString(), platformIndex.toString()]; +} + +export function getCLBlastDeviceName(deviceString: string): string { + const match = deviceString.match(/^(.+?)\s+\(Platform:/); + return match ? match[1].trim() : deviceString; +} diff --git a/src/utils/index.ts b/src/utils/index.ts index ad98b3a..44ee491 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,4 +1,5 @@ export * from './assets'; +export * from './clblast'; export * from './downloadUtils'; export * from './fileSize'; export * from './hardware'; diff --git a/yarn.lock b/yarn.lock index 2d29742..8731e65 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2051,7 +2051,7 @@ __metadata: languageName: node linkType: hard -"abbrev@npm:^1.0.0": +"abbrev@npm:1, abbrev@npm:^1.0.0": version: 1.1.1 resolution: "abbrev@npm:1.1.1" checksum: 10c0/3f762677702acb24f65e813070e306c61fafe25d4b2583f9dfc935131f774863f3addd5741572ed576bd69cabe473c5af18e1e108b829cb7b6b4747884f726e6 @@ -2139,6 +2139,15 @@ __metadata: languageName: node linkType: hard +"ansi-escapes@npm:^4.2.1": + version: 4.3.2 + resolution: "ansi-escapes@npm:4.3.2" + dependencies: + type-fest: "npm:^0.21.3" + checksum: 10c0/da917be01871525a3dfcf925ae2977bc59e8c513d4423368645634bf5d4ceba5401574eb705c1e92b79f7292af5a656f78c5725a4b0e1cec97c4b413705c1d50 + languageName: node + linkType: hard + "ansi-escapes@npm:^7.0.0": version: 7.0.0 resolution: "ansi-escapes@npm:7.0.0" @@ -2148,6 +2157,13 @@ __metadata: languageName: node linkType: hard +"ansi-regex@npm:^2.0.0": + version: 2.1.1 + resolution: "ansi-regex@npm:2.1.1" + checksum: 10c0/78cebaf50bce2cb96341a7230adf28d804611da3ce6bf338efa7b72f06cc6ff648e29f80cd95e582617ba58d5fdbec38abfeed3500a98bce8381a9daec7c548b + languageName: node + linkType: hard + "ansi-regex@npm:^5.0.1": version: 5.0.1 resolution: "ansi-regex@npm:5.0.1" @@ -2162,6 +2178,15 @@ __metadata: languageName: node linkType: hard +"ansi-styles@npm:^3.2.1": + version: 3.2.1 + resolution: "ansi-styles@npm:3.2.1" + dependencies: + color-convert: "npm:^1.9.0" + checksum: 10c0/ece5a8ef069fcc5298f67e3f4771a663129abd174ea2dfa87923a2be2abf6cd367ef72ac87942da00ce85bd1d651d4cd8595aebdb1b385889b89b205860e977b + languageName: node + linkType: hard + "ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": version: 4.3.0 resolution: "ansi-styles@npm:4.3.0" @@ -2230,6 +2255,23 @@ __metadata: languageName: node linkType: hard +"aproba@npm:^1.0.3": + version: 1.2.0 + resolution: "aproba@npm:1.2.0" + checksum: 10c0/2d34f008c9edfa991f42fe4b667d541d38a474a39ae0e24805350486d76744cd91ee45313283c1d39a055b14026dd0fc4d0cbfc13f210855d59d7e8b5a61dc51 + languageName: node + linkType: hard + +"are-we-there-yet@npm:~1.1.2": + version: 1.1.7 + resolution: "are-we-there-yet@npm:1.1.7" + dependencies: + delegates: "npm:^1.0.0" + readable-stream: "npm:^2.0.6" + checksum: 10c0/03cb45f2892767773c86a616205fc67feb8dfdd56685d1b34999cfa6c0d2aebe73ec0e6ba88a406422b998dea24138337fdb9a3f9b172d7c2a7f75d02f3df088 + languageName: node + linkType: hard + "argparse@npm:^2.0.1": version: 2.0.1 resolution: "argparse@npm:2.0.1" @@ -2237,6 +2279,20 @@ __metadata: languageName: node linkType: hard +"array-back@npm:^3.0.1, array-back@npm:^3.1.0": + version: 3.1.0 + resolution: "array-back@npm:3.1.0" + checksum: 10c0/bb1fe86aa8b39c21e73c68c7abf8b05ed939b8951a3b17527217f6a2a84e00e4cfa4fdec823081689c5e216709bf1f214a4f5feeee6726eaff83897fa1a7b8ee + languageName: node + linkType: hard + +"array-back@npm:^4.0.1, array-back@npm:^4.0.2": + version: 4.0.2 + resolution: "array-back@npm:4.0.2" + checksum: 10c0/8beb5b4c9535eab2905d4ff7d16c4d90ee5ca080d2b26b1e637434c0fcfadb3585283524aada753bd5d06bb88a5dac9e175c3a236183741d3d795a69b6678c96 + languageName: node + linkType: hard + "array-buffer-byte-length@npm:^1.0.1, array-buffer-byte-length@npm:^1.0.2": version: 1.0.2 resolution: "array-buffer-byte-length@npm:1.0.2" @@ -2549,6 +2605,13 @@ __metadata: languageName: node linkType: hard +"builtins@npm:^1.0.3": + version: 1.0.3 + resolution: "builtins@npm:1.0.3" + checksum: 10c0/493afcc1db0a56d174cc85bebe5ca69144f6fdd0007d6cbe6b2434185314c79d83cb867e492b56aa5cf421b4b8a8135bf96ba4c3ce71994cf3da154d1ea59747 + languageName: node + linkType: hard + "bytes@npm:3.1.2": version: 3.1.2 resolution: "bytes@npm:3.1.2" @@ -2686,6 +2749,17 @@ __metadata: languageName: node linkType: hard +"chalk@npm:^2.4.2": + version: 2.4.2 + resolution: "chalk@npm:2.4.2" + dependencies: + ansi-styles: "npm:^3.2.1" + escape-string-regexp: "npm:^1.0.5" + supports-color: "npm:^5.3.0" + checksum: 10c0/e6543f02ec877732e3a2d1c3c3323ddb4d39fbab687c23f526e25bd4c6a9bf3b83a696e8c769d078e04e5754921648f7821b2a2acfd16c550435fd630026e073 + languageName: node + linkType: hard + "chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.1, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" @@ -2703,6 +2777,20 @@ __metadata: languageName: node linkType: hard +"chardet@npm:^0.7.0": + version: 0.7.0 + resolution: "chardet@npm:0.7.0" + checksum: 10c0/96e4731b9ec8050cbb56ab684e8c48d6c33f7826b755802d14e3ebfdc51c57afeece3ea39bc6b09acc359e4363525388b915e16640c1378053820f5e70d0f27d + languageName: node + linkType: hard + +"chownr@npm:^1.1.4": + version: 1.1.4 + resolution: "chownr@npm:1.1.4" + checksum: 10c0/ed57952a84cc0c802af900cf7136de643d3aba2eecb59d29344bc2f3f9bf703a301b9d84cdc71f82c3ffc9ccde831b0d92f5b45f91727d6c9da62f23aef9d9db + languageName: node + linkType: hard + "chownr@npm:^2.0.0": version: 2.0.0 resolution: "chownr@npm:2.0.0" @@ -2793,6 +2881,13 @@ __metadata: languageName: node linkType: hard +"cli-width@npm:^3.0.0": + version: 3.0.0 + resolution: "cli-width@npm:3.0.0" + checksum: 10c0/125a62810e59a2564268c80fdff56c23159a7690c003e34aeb2e68497dccff26911998ff49c33916fcfdf71e824322cc3953e3f7b48b27267c7a062c81348a9a + languageName: node + linkType: hard + "cliui@npm:^8.0.1": version: 8.0.1 resolution: "cliui@npm:8.0.1" @@ -2827,6 +2922,22 @@ __metadata: languageName: node linkType: hard +"code-point-at@npm:^1.0.0": + version: 1.1.0 + resolution: "code-point-at@npm:1.1.0" + checksum: 10c0/33f6b234084e46e6e369b6f0b07949392651b4dde70fc6a592a8d3dafa08d5bb32e3981a02f31f6fc323a26bc03a4c063a9d56834848695bda7611c2417ea2e6 + languageName: node + linkType: hard + +"color-convert@npm:^1.9.0": + version: 1.9.3 + resolution: "color-convert@npm:1.9.3" + dependencies: + color-name: "npm:1.1.3" + checksum: 10c0/5ad3c534949a8c68fca8fbc6f09068f435f0ad290ab8b2f76841b9e6af7e0bb57b98cb05b0e19fe33f5d91e5a8611ad457e5f69e0a484caad1f7487fd0e8253c + languageName: node + linkType: hard + "color-convert@npm:^2.0.1": version: 2.0.1 resolution: "color-convert@npm:2.0.1" @@ -2836,6 +2947,13 @@ __metadata: languageName: node linkType: hard +"color-name@npm:1.1.3": + version: 1.1.3 + resolution: "color-name@npm:1.1.3" + checksum: 10c0/566a3d42cca25b9b3cd5528cd7754b8e89c0eb646b7f214e8e2eaddb69994ac5f0557d9c175eb5d8f0ad73531140d9c47525085ee752a91a2ab15ab459caf6d6 + languageName: node + linkType: hard + "color-name@npm:~1.1.4": version: 1.1.4 resolution: "color-name@npm:1.1.4" @@ -2859,6 +2977,39 @@ __metadata: languageName: node linkType: hard +"command-line-args@npm:^5.1.1": + version: 5.2.1 + resolution: "command-line-args@npm:5.2.1" + dependencies: + array-back: "npm:^3.1.0" + find-replace: "npm:^3.0.0" + lodash.camelcase: "npm:^4.3.0" + typical: "npm:^4.0.0" + checksum: 10c0/a4f6a23a1e420441bd1e44dee24efd12d2e49af7efe6e21eb32fca4e843ca3d5501ddebad86a4e9d99aa626dd6dcb64c04a43695388be54e3a803dbc326cc89f + languageName: node + linkType: hard + +"command-line-commands@npm:^3.0.1": + version: 3.0.2 + resolution: "command-line-commands@npm:3.0.2" + dependencies: + array-back: "npm:^4.0.1" + checksum: 10c0/ba04828c831dcd2cecb569f9bef42c3feabe0435ab14259562266f1146ecc1eb3d5d4b91331266c23dbcfe03c9c977b4e144b8bd92fa4633426bbf4119918a27 + languageName: node + linkType: hard + +"command-line-usage@npm:^6.1.0": + version: 6.1.3 + resolution: "command-line-usage@npm:6.1.3" + dependencies: + array-back: "npm:^4.0.2" + chalk: "npm:^2.4.2" + table-layout: "npm:^1.0.2" + typical: "npm:^5.2.0" + checksum: 10c0/23d7577ccb6b6c004e67bb6a9a8cb77282ae7b7507ae92249a9548a39050b7602fef70f124c765000ab23b8f7e0fb7a3352419ab73ea42a2d9ea32f520cdfe9e + languageName: node + linkType: hard + "commander@npm:^14.0.0": version: 14.0.0 resolution: "commander@npm:14.0.0" @@ -2900,6 +3051,13 @@ __metadata: languageName: node linkType: hard +"console-control-strings@npm:^1.0.0, console-control-strings@npm:~1.1.0": + version: 1.1.0 + resolution: "console-control-strings@npm:1.1.0" + checksum: 10c0/7ab51d30b52d461412cd467721bb82afe695da78fff8f29fe6f6b9cbaac9a2328e27a22a966014df9532100f6dd85370460be8130b9c677891ba36d96a343f50 + languageName: node + linkType: hard + "convert-source-map@npm:^2.0.0": version: 2.0.0 resolution: "convert-source-map@npm:2.0.0" @@ -2914,7 +3072,7 @@ __metadata: languageName: node linkType: hard -"core-util-is@npm:^1.0.3": +"core-util-is@npm:^1.0.3, core-util-is@npm:~1.0.0": version: 1.0.3 resolution: "core-util-is@npm:1.0.3" checksum: 10c0/90a0e40abbddfd7618f8ccd63a74d88deea94e77d0e8dbbea059fa7ebebb8fbb4e2909667fe26f3a467073de1a542ebe6ae4c73a73745ac5833786759cd906c9 @@ -3147,7 +3305,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:^3.2.7": +"debug@npm:^3.2.6, debug@npm:^3.2.7": version: 3.2.7 resolution: "debug@npm:3.2.7" dependencies: @@ -3165,6 +3323,13 @@ __metadata: languageName: node linkType: hard +"deep-extend@npm:^0.6.0, deep-extend@npm:~0.6.0": + version: 0.6.0 + resolution: "deep-extend@npm:0.6.0" + checksum: 10c0/1c6b0abcdb901e13a44c7d699116d3d4279fdb261983122a3783e7273844d5f2537dc2e1c454a23fcf645917f93fbf8d07101c1d03c015a87faa662755212566 + languageName: node + linkType: hard + "deep-is@npm:^0.1.3": version: 0.1.4 resolution: "deep-is@npm:0.1.4" @@ -3224,6 +3389,22 @@ __metadata: languageName: node linkType: hard +"delegates@npm:^1.0.0": + version: 1.0.0 + resolution: "delegates@npm:1.0.0" + checksum: 10c0/ba05874b91148e1db4bf254750c042bf2215febd23a6d3cda2e64896aef79745fbd4b9996488bd3cafb39ce19dbce0fd6e3b6665275638befffe1c9b312b91b5 + languageName: node + linkType: hard + +"detect-libc@npm:^1.0.3": + version: 1.0.3 + resolution: "detect-libc@npm:1.0.3" + bin: + detect-libc: ./bin/detect-libc.js + checksum: 10c0/4da0deae9f69e13bc37a0902d78bf7169480004b1fed3c19722d56cff578d16f0e11633b7fbf5fb6249181236c72e90024cbd68f0b9558ae06e281f47326d50d + languageName: node + linkType: hard + "detect-libc@npm:^2.0.1": version: 2.0.4 resolution: "detect-libc@npm:2.0.4" @@ -3734,6 +3915,13 @@ __metadata: languageName: node linkType: hard +"escape-string-regexp@npm:^1.0.5": + version: 1.0.5 + resolution: "escape-string-regexp@npm:1.0.5" + checksum: 10c0/a968ad453dd0c2724e14a4f20e177aaf32bb384ab41b674a8454afe9a41c5e6fe8903323e0a1052f56289d04bd600f81278edf140b0fcc02f5cac98d0f5b5371 + languageName: node + linkType: hard + "escape-string-regexp@npm:^4.0.0": version: 4.0.0 resolution: "escape-string-regexp@npm:4.0.0" @@ -4007,6 +4195,17 @@ __metadata: languageName: node linkType: hard +"external-editor@npm:^3.0.3": + version: 3.1.0 + resolution: "external-editor@npm:3.1.0" + dependencies: + chardet: "npm:^0.7.0" + iconv-lite: "npm:^0.4.24" + tmp: "npm:^0.0.33" + checksum: 10c0/c98f1ba3efdfa3c561db4447ff366a6adb5c1e2581462522c56a18bf90dfe4da382f9cd1feee3e330108c3595a854b218272539f311ba1b3298f841eb0fbf339 + languageName: node + linkType: hard + "extract-zip@npm:^2.0.1": version: 2.0.1 resolution: "extract-zip@npm:2.0.1" @@ -4102,6 +4301,15 @@ __metadata: languageName: node linkType: hard +"figures@npm:^3.0.0": + version: 3.2.0 + resolution: "figures@npm:3.2.0" + dependencies: + escape-string-regexp: "npm:^1.0.5" + checksum: 10c0/9c421646ede432829a50bc4e55c7a4eb4bcb7cc07b5bab2f471ef1ab9a344595bbebb6c5c21470093fbb730cd81bbca119624c40473a125293f656f49cb47629 + languageName: node + linkType: hard + "file-entry-cache@npm:^8.0.0": version: 8.0.0 resolution: "file-entry-cache@npm:8.0.0" @@ -4129,6 +4337,15 @@ __metadata: languageName: node linkType: hard +"find-replace@npm:^3.0.0": + version: 3.0.0 + resolution: "find-replace@npm:3.0.0" + dependencies: + array-back: "npm:^3.0.1" + checksum: 10c0/fcd1bf7960388c8193c2861bcdc760c18ac14edb4bde062a961915d9a25727b2e8aabf0229e90cc09c753fd557e5a3e5ae61e49cadbe727be89a9e8e49ce7668 + languageName: node + linkType: hard + "find-up@npm:^5.0.0": version: 5.0.0 resolution: "find-up@npm:5.0.0" @@ -4219,6 +4436,7 @@ __metadata: jiti: "npm:^2.5.1" lint-staged: "npm:^16.1.5" lucide-react: "npm:^0.540.0" + opencl-info: "npm:^0.3.0" prettier: "npm:^3.6.2" react: "npm:^19.1.1" react-dom: "npm:^19.1.1" @@ -4226,6 +4444,7 @@ __metadata: systeminformation: "npm:^5.27.7" typescript: "npm:^5.9.2" vite: "npm:^7.1.3" + zustand: "npm:^5.0.8" languageName: unknown linkType: soft @@ -4274,6 +4493,15 @@ __metadata: languageName: node linkType: hard +"fs-minipass@npm:^1.2.7": + version: 1.2.7 + resolution: "fs-minipass@npm:1.2.7" + dependencies: + minipass: "npm:^2.6.0" + checksum: 10c0/c8259ce8caab360f16b8c3774fd09dd1d5240d6f3f78fd8efa0a215b5f40edfa90e7b5b5ddc2335a4c50885e29d5983f9fe6ac3ac19320e6917a21dbb9f05c64 + languageName: node + linkType: hard + "fs-minipass@npm:^2.0.0, fs-minipass@npm:^2.1.0": version: 2.1.0 resolution: "fs-minipass@npm:2.1.0" @@ -4353,6 +4581,22 @@ __metadata: languageName: node linkType: hard +"gauge@npm:~2.7.3": + version: 2.7.4 + resolution: "gauge@npm:2.7.4" + dependencies: + aproba: "npm:^1.0.3" + console-control-strings: "npm:^1.0.0" + has-unicode: "npm:^2.0.0" + object-assign: "npm:^4.1.0" + signal-exit: "npm:^3.0.0" + string-width: "npm:^1.0.1" + strip-ansi: "npm:^3.0.1" + wide-align: "npm:^1.1.0" + checksum: 10c0/d606346e2e47829e0bc855d0becb36c4ce492feabd61ae92884b89e07812dd8a67a860ca30ece3a4c2e9f2c73bd68ba2b8e558ed362432ffd86de83c08847f84 + languageName: node + linkType: hard + "gensequence@npm:^7.0.0": version: 7.0.0 resolution: "gensequence@npm:7.0.0" @@ -4436,6 +4680,15 @@ __metadata: languageName: node linkType: hard +"git-config@npm:0.0.7": + version: 0.0.7 + resolution: "git-config@npm:0.0.7" + dependencies: + iniparser: "npm:~1.0.5" + checksum: 10c0/b90310802585de6fb8d61f0eb090d42b5d710c56a8109f7f1720a25c03eb2d9f089a4082fde460eebf06cf3f61248565a351eb8634b60dcc495639388b7f015c + languageName: node + linkType: hard + "glob-parent@npm:^5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" @@ -4584,6 +4837,24 @@ __metadata: languageName: node linkType: hard +"handlebars@npm:^4.7.6": + version: 4.7.8 + resolution: "handlebars@npm:4.7.8" + dependencies: + minimist: "npm:^1.2.5" + neo-async: "npm:^2.6.2" + source-map: "npm:^0.6.1" + uglify-js: "npm:^3.1.4" + wordwrap: "npm:^1.0.0" + dependenciesMeta: + uglify-js: + optional: true + bin: + handlebars: bin/handlebars + checksum: 10c0/7aff423ea38a14bb379316f3857fe0df3c5d66119270944247f155ba1f08e07a92b340c58edaa00cfe985c21508870ee5183e0634dcb53dd405f35c93ef7f10d + languageName: node + linkType: hard + "has-bigints@npm:^1.0.2": version: 1.1.0 resolution: "has-bigints@npm:1.1.0" @@ -4591,6 +4862,13 @@ __metadata: languageName: node linkType: hard +"has-flag@npm:^3.0.0": + version: 3.0.0 + resolution: "has-flag@npm:3.0.0" + checksum: 10c0/1c6c83b14b8b1b3c25b0727b8ba3e3b647f99e9e6e13eb7322107261de07a4c1be56fc0d45678fc376e09772a3a1642ccdaf8fc69bdf123b6c086598397ce473 + languageName: node + linkType: hard + "has-flag@npm:^4.0.0": version: 4.0.0 resolution: "has-flag@npm:4.0.0" @@ -4639,6 +4917,13 @@ __metadata: languageName: node linkType: hard +"has-unicode@npm:^2.0.0": + version: 2.0.1 + resolution: "has-unicode@npm:2.0.1" + checksum: 10c0/ebdb2f4895c26bb08a8a100b62d362e49b2190bcfd84b76bc4be1a3bd4d254ec52d0dd9f2fbcc093fc5eb878b20c52146f9dfd33e2686ed28982187be593b47c + languageName: node + linkType: hard + "hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" @@ -4743,6 +5028,15 @@ __metadata: languageName: node linkType: hard +"iconv-lite@npm:^0.4.24, iconv-lite@npm:^0.4.4": + version: 0.4.24 + resolution: "iconv-lite@npm:0.4.24" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3" + checksum: 10c0/c6886a24cc00f2a059767440ec1bc00d334a89f250db8e0f7feb4961c8727118457e27c495ba94d082e51d3baca378726cd110aaf7ded8b9bbfd6a44760cf1d4 + languageName: node + linkType: hard + "iconv-lite@npm:^0.6.2": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" @@ -4759,6 +5053,15 @@ __metadata: languageName: node linkType: hard +"ignore-walk@npm:^3.0.1": + version: 3.0.4 + resolution: "ignore-walk@npm:3.0.4" + dependencies: + minimatch: "npm:^3.0.4" + checksum: 10c0/690372b433887796fa3badd25babab7daf60a1882259dcc130ec78eea79745c2416322e10d1a96b367071204471c532647d20b11cd7ab70bd9b49879e461f956 + languageName: node + linkType: hard + "ignore@npm:^5.2.0": version: 5.3.2 resolution: "ignore@npm:5.3.2" @@ -4821,7 +5124,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4": +"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 @@ -4835,6 +5138,41 @@ __metadata: languageName: node linkType: hard +"ini@npm:~1.3.0": + version: 1.3.8 + resolution: "ini@npm:1.3.8" + checksum: 10c0/ec93838d2328b619532e4f1ff05df7909760b6f66d9c9e2ded11e5c1897d6f2f9980c54dd638f88654b00919ce31e827040631eab0a3969e4d1abefa0719516a + languageName: node + linkType: hard + +"iniparser@npm:~1.0.5": + version: 1.0.5 + resolution: "iniparser@npm:1.0.5" + checksum: 10c0/196460705d9cfd17c4633a52e47c4b8cc27fd6e5890dbfd941742d003d18a7cb72ae3ac8f7e9272fcd9989ed597b8137105ddb90476d044b2101495ff39e4575 + languageName: node + linkType: hard + +"inquirer@npm:^7.3.3": + version: 7.3.3 + resolution: "inquirer@npm:7.3.3" + dependencies: + ansi-escapes: "npm:^4.2.1" + chalk: "npm:^4.1.0" + cli-cursor: "npm:^3.1.0" + cli-width: "npm:^3.0.0" + external-editor: "npm:^3.0.3" + figures: "npm:^3.0.0" + lodash: "npm:^4.17.19" + mute-stream: "npm:0.0.8" + run-async: "npm:^2.4.0" + rxjs: "npm:^6.6.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + through: "npm:^2.3.6" + checksum: 10c0/96e75974cfd863fe6653c075e41fa5f1a290896df141189816db945debabcd92d3277145f11aef8d2cfca5409ab003ccdd18a099744814057b52a2f27aeb8c94 + languageName: node + linkType: hard + "internal-slot@npm:^1.1.0": version: 1.1.0 resolution: "internal-slot@npm:1.1.0" @@ -4958,6 +5296,15 @@ __metadata: languageName: node linkType: hard +"is-fullwidth-code-point@npm:^1.0.0": + version: 1.0.0 + resolution: "is-fullwidth-code-point@npm:1.0.0" + dependencies: + number-is-nan: "npm:^1.0.0" + checksum: 10c0/12acfcf16142f2d431bf6af25d68569d3198e81b9799b4ae41058247aafcc666b0127d64384ea28e67a746372611fcbe9b802f69175287aba466da3eddd5ba0f + languageName: node + linkType: hard + "is-fullwidth-code-point@npm:^3.0.0": version: 3.0.0 resolution: "is-fullwidth-code-point@npm:3.0.0" @@ -5154,6 +5501,13 @@ __metadata: languageName: node linkType: hard +"isarray@npm:~1.0.0": + version: 1.0.0 + resolution: "isarray@npm:1.0.0" + checksum: 10c0/18b5be6669be53425f0b84098732670ed4e727e3af33bc7f948aac01782110eb9a18b3b329c5323bcdd3acdaae547ee077d3951317e7f133bff7105264b3003d + languageName: node + linkType: hard + "isbinaryfile@npm:^4.0.8": version: 4.0.10 resolution: "isbinaryfile@npm:4.0.10" @@ -5419,6 +5773,13 @@ __metadata: languageName: node linkType: hard +"lodash.camelcase@npm:^4.3.0": + version: 4.3.0 + resolution: "lodash.camelcase@npm:4.3.0" + checksum: 10c0/fcba15d21a458076dd309fce6b1b4bf611d84a0ec252cb92447c948c533ac250b95d2e00955801ebc367e5af5ed288b996d75d37d2035260a937008e14eaf432 + languageName: node + linkType: hard + "lodash.merge@npm:4.6.2, lodash.merge@npm:^4.6.2": version: 4.6.2 resolution: "lodash.merge@npm:4.6.2" @@ -5426,7 +5787,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.15": +"lodash@npm:^4.17.15, lodash@npm:^4.17.19": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c @@ -5567,6 +5928,13 @@ __metadata: languageName: node linkType: hard +"make-promises-safe@npm:^5.1.0": + version: 5.1.0 + resolution: "make-promises-safe@npm:5.1.0" + checksum: 10c0/e7344a7588c9f541011973a754d47345279af41e9068d43b3a8bd9eecba507e9cfe26b420361b6eb1dc14c636fdbb1855fe5af8c7b7dc8a8b054efb182cee084 + languageName: node + linkType: hard + "matcher@npm:^3.0.0": version: 3.0.0 resolution: "matcher@npm:3.0.0" @@ -5771,6 +6139,16 @@ __metadata: languageName: node linkType: hard +"minipass@npm:^2.6.0, minipass@npm:^2.9.0": + version: 2.9.0 + resolution: "minipass@npm:2.9.0" + dependencies: + safe-buffer: "npm:^5.1.2" + yallist: "npm:^3.0.0" + checksum: 10c0/307d8765ac3db9fcd6b486367e6f6c3e460f3a3e198d95d6c0005a2d95804c40c72959261cdebde3c8237cda0b03d4c01975e4581fe11abcf201f5005caafd2a + languageName: node + linkType: hard + "minipass@npm:^3.0.0, minipass@npm:^3.1.1, minipass@npm:^3.1.6": version: 3.3.6 resolution: "minipass@npm:3.3.6" @@ -5794,6 +6172,15 @@ __metadata: languageName: node linkType: hard +"minizlib@npm:^1.3.3": + version: 1.3.3 + resolution: "minizlib@npm:1.3.3" + dependencies: + minipass: "npm:^2.9.0" + checksum: 10c0/79798032bbaa6594fa517e5b7ff9977951984fc9548a421b28d3fb0add8ed7e98a33e41e262af53b944f9d860c1e00fc778b477ef692e7b38b1ba12b390ffb17 + languageName: node + linkType: hard + "minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": version: 2.1.2 resolution: "minizlib@npm:2.1.2" @@ -5813,6 +6200,17 @@ __metadata: languageName: node linkType: hard +"mkdirp@npm:^0.5.5": + version: 0.5.6 + resolution: "mkdirp@npm:0.5.6" + dependencies: + minimist: "npm:^1.2.6" + bin: + mkdirp: bin/cmd.js + checksum: 10c0/e2e2be789218807b58abced04e7b49851d9e46e88a2f9539242cc8a92c9b5c3a0b9bab360bd3014e02a140fc4fbc58e31176c408b493f8a2a6f4986bd7527b01 + languageName: node + linkType: hard + "mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4": version: 1.0.4 resolution: "mkdirp@npm:1.0.4" @@ -5838,6 +6236,13 @@ __metadata: languageName: node linkType: hard +"mute-stream@npm:0.0.8": + version: 0.0.8 + resolution: "mute-stream@npm:0.0.8" + checksum: 10c0/18d06d92e5d6d45e2b63c0e1b8f25376af71748ac36f53c059baa8b76ffac31c5ab225480494e7d35d30215ecdb18fed26ec23cafcd2f7733f2f14406bcd19e2 + languageName: node + linkType: hard + "nano-spawn@npm:^1.0.2": version: 1.0.2 resolution: "nano-spawn@npm:1.0.2" @@ -5861,6 +6266,19 @@ __metadata: languageName: node linkType: hard +"needle@npm:^2.5.2": + version: 2.9.1 + resolution: "needle@npm:2.9.1" + dependencies: + debug: "npm:^3.2.6" + iconv-lite: "npm:^0.4.4" + sax: "npm:^1.2.4" + bin: + needle: ./bin/needle + checksum: 10c0/65a7eaeaf4ca3410de492957474592af9838e02875273d9232ff6cff331393c58a95e48c592bd9a05f575e5bb9b08543d6cfd19eb96595dbd3d7da2c5fe1accb + languageName: node + linkType: hard + "negotiator@npm:^0.6.3": version: 0.6.4 resolution: "negotiator@npm:0.6.4" @@ -5875,6 +6293,37 @@ __metadata: languageName: node linkType: hard +"neo-async@npm:^2.6.2": + version: 2.6.2 + resolution: "neo-async@npm:2.6.2" + checksum: 10c0/c2f5a604a54a8ec5438a342e1f356dff4bc33ccccdb6dc668d94fe8e5eccfc9d2c2eea6064b0967a767ba63b33763f51ccf2cd2441b461a7322656c1f06b3f5d + languageName: node + linkType: hard + +"neon-cli@npm:^0.7.1": + version: 0.7.1 + resolution: "neon-cli@npm:0.7.1" + dependencies: + chalk: "npm:^4.1.0" + command-line-args: "npm:^5.1.1" + command-line-commands: "npm:^3.0.1" + command-line-usage: "npm:^6.1.0" + git-config: "npm:0.0.7" + handlebars: "npm:^4.7.6" + inquirer: "npm:^7.3.3" + make-promises-safe: "npm:^5.1.0" + rimraf: "npm:^3.0.2" + semver: "npm:^7.3.2" + toml: "npm:^3.0.0" + ts-typed-json: "npm:^0.3.2" + validate-npm-package-license: "npm:^3.0.4" + validate-npm-package-name: "npm:^3.0.0" + bin: + neon: bin/cli.js + checksum: 10c0/eaaf4b6978d90728e064e9e2ca4466c65d09b2bdc25d9f7a10c6bac1e158cb11bbb786c855a0a9f483acaf8049c8ba80f659b90d2f4f10d6108e4c02f02e1a28 + languageName: node + linkType: hard + "node-abi@npm:^3.45.0": version: 3.75.0 resolution: "node-abi@npm:3.75.0" @@ -5922,6 +6371,26 @@ __metadata: languageName: node linkType: hard +"node-pre-gyp@npm:^0.17.0": + version: 0.17.0 + resolution: "node-pre-gyp@npm:0.17.0" + dependencies: + detect-libc: "npm:^1.0.3" + mkdirp: "npm:^0.5.5" + needle: "npm:^2.5.2" + nopt: "npm:^4.0.3" + npm-packlist: "npm:^1.4.8" + npmlog: "npm:^4.1.2" + rc: "npm:^1.2.8" + rimraf: "npm:^2.7.1" + semver: "npm:^5.7.1" + tar: "npm:^4.4.13" + bin: + node-pre-gyp: bin/node-pre-gyp + checksum: 10c0/ed02b350dbe9f06a6d9b19703839a239fdb841869f89edd129462b0d9c51e021464abd415198e3c19744797f04647b0b173b1446bce4b1772e4821290b9595ec + languageName: node + linkType: hard + "node-releases@npm:^2.0.19": version: 2.0.19 resolution: "node-releases@npm:2.0.19" @@ -5929,6 +6398,18 @@ __metadata: languageName: node linkType: hard +"nopt@npm:^4.0.3": + version: 4.0.3 + resolution: "nopt@npm:4.0.3" + dependencies: + abbrev: "npm:1" + osenv: "npm:^0.1.4" + bin: + nopt: bin/nopt.js + checksum: 10c0/03e54cdf8c9b46924cfadf333b2b86fc180410d74d51f9c72fec5ef9c6f1a19ec533f647c05e40d49ef7491af59664c5d0baace808d6ccfe3ff064ae630a61b4 + languageName: node + linkType: hard + "nopt@npm:^6.0.0": version: 6.0.0 resolution: "nopt@npm:6.0.0" @@ -5958,7 +6439,53 @@ __metadata: languageName: node linkType: hard -"object-assign@npm:^4.1.1": +"npm-bundled@npm:^1.0.1": + version: 1.1.2 + resolution: "npm-bundled@npm:1.1.2" + dependencies: + npm-normalize-package-bin: "npm:^1.0.1" + checksum: 10c0/3f2337789afc8cb608a0dd71cefe459531053d48a5497db14b07b985c4cab15afcae88600db9f92eae072c89b982eeeec8e4463e1d77bc03a7e90f5dacf29769 + languageName: node + linkType: hard + +"npm-normalize-package-bin@npm:^1.0.1": + version: 1.0.1 + resolution: "npm-normalize-package-bin@npm:1.0.1" + checksum: 10c0/b0c8c05fe419a122e0ff970ccbe7874ae24b4b4b08941a24d18097fe6e1f4b93e3f6abfb5512f9c5488827a5592f2fb3ce2431c41d338802aed24b9a0c160551 + languageName: node + linkType: hard + +"npm-packlist@npm:^1.4.8": + version: 1.4.8 + resolution: "npm-packlist@npm:1.4.8" + dependencies: + ignore-walk: "npm:^3.0.1" + npm-bundled: "npm:^1.0.1" + npm-normalize-package-bin: "npm:^1.0.1" + checksum: 10c0/3b6dd1d0f677a3c1ad8e5f59362f4249459ad9fbb31c8a9306c0cf2af74016078d17a37fffee66b5437e76aba33c7ceb008905bccbadb23ea4776171d4b22b92 + languageName: node + linkType: hard + +"npmlog@npm:^4.1.2": + version: 4.1.2 + resolution: "npmlog@npm:4.1.2" + dependencies: + are-we-there-yet: "npm:~1.1.2" + console-control-strings: "npm:~1.1.0" + gauge: "npm:~2.7.3" + set-blocking: "npm:~2.0.0" + checksum: 10c0/d6a26cb362277c65e24a70ebdaff31f81184ceb5415fd748abaaf26417bf0794a17ba849116e4f454a0370b9067ae320834cc78d74527dbeadf6e9d19a959046 + languageName: node + linkType: hard + +"number-is-nan@npm:^1.0.0": + version: 1.0.1 + resolution: "number-is-nan@npm:1.0.1" + checksum: 10c0/cb97149006acc5cd512c13c1838223abdf202e76ddfa059c5e8e7507aff2c3a78cd19057516885a2f6f5b576543dc4f7b6f3c997cc7df53ae26c260855466df5 + languageName: node + linkType: hard + +"object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414 @@ -6078,6 +6605,16 @@ __metadata: languageName: node linkType: hard +"opencl-info@npm:^0.3.0": + version: 0.3.0 + resolution: "opencl-info@npm:0.3.0" + dependencies: + neon-cli: "npm:^0.7.1" + node-pre-gyp: "npm:^0.17.0" + checksum: 10c0/9721f6e4c6048200210a3475334e1c7ad76ff8d74c4b5ee680f49a86db0498b5894cd2f64894e6f4f447b916f48584e232ed624365fc3751bdeeafe5c9686f54 + languageName: node + linkType: hard + "optionator@npm:^0.9.3": version: 0.9.4 resolution: "optionator@npm:0.9.4" @@ -6109,6 +6646,30 @@ __metadata: languageName: node linkType: hard +"os-homedir@npm:^1.0.0": + version: 1.0.2 + resolution: "os-homedir@npm:1.0.2" + checksum: 10c0/6be4aa67317ee247b8d46142e243fb4ef1d2d65d3067f54bfc5079257a2f4d4d76b2da78cba7af3cb3f56dbb2e4202e0c47f26171d11ca1ed4008d842c90363f + languageName: node + linkType: hard + +"os-tmpdir@npm:^1.0.0, os-tmpdir@npm:~1.0.2": + version: 1.0.2 + resolution: "os-tmpdir@npm:1.0.2" + checksum: 10c0/f438450224f8e2687605a8dd318f0db694b6293c5d835ae509a69e97c8de38b6994645337e5577f5001115470414638978cc49da1cdcc25106dad8738dc69990 + languageName: node + linkType: hard + +"osenv@npm:^0.1.4": + version: 0.1.5 + resolution: "osenv@npm:0.1.5" + dependencies: + os-homedir: "npm:^1.0.0" + os-tmpdir: "npm:^1.0.0" + checksum: 10c0/b33ed4b77e662f3ee2a04bf4b56cad2107ab069dee982feb9e39ad44feb9aa0cf1016b9ac6e05d0d84c91fa496798fe48dd05a33175d624e51668068b9805302 + languageName: node + linkType: hard + "own-keys@npm:^1.0.1": version: 1.0.1 resolution: "own-keys@npm:1.0.1" @@ -6327,6 +6888,13 @@ __metadata: languageName: node linkType: hard +"process-nextick-args@npm:~2.0.0": + version: 2.0.1 + resolution: "process-nextick-args@npm:2.0.1" + checksum: 10c0/bec089239487833d46b59d80327a1605e1c5287eaad770a291add7f45fda1bb5e28b38e0e061add0a1d0ee0984788ce74fa394d345eed1c420cacf392c554367 + languageName: node + linkType: hard + "progress@npm:^2.0.3": version: 2.0.3 resolution: "progress@npm:2.0.3" @@ -6393,6 +6961,20 @@ __metadata: languageName: node linkType: hard +"rc@npm:^1.2.8": + version: 1.2.8 + resolution: "rc@npm:1.2.8" + dependencies: + deep-extend: "npm:^0.6.0" + ini: "npm:~1.3.0" + minimist: "npm:^1.2.0" + strip-json-comments: "npm:~2.0.1" + bin: + rc: ./cli.js + checksum: 10c0/24a07653150f0d9ac7168e52943cc3cb4b7a22c0e43c7dff3219977c2fdca5a2760a304a029c20811a0e79d351f57d46c9bde216193a0f73978496afc2b85b15 + languageName: node + linkType: hard + "react-dom@npm:^19.1.1": version: 19.1.1 resolution: "react-dom@npm:19.1.1" @@ -6510,6 +7092,21 @@ __metadata: languageName: node linkType: hard +"readable-stream@npm:^2.0.6": + version: 2.3.8 + resolution: "readable-stream@npm:2.3.8" + dependencies: + core-util-is: "npm:~1.0.0" + inherits: "npm:~2.0.3" + isarray: "npm:~1.0.0" + process-nextick-args: "npm:~2.0.0" + safe-buffer: "npm:~5.1.1" + string_decoder: "npm:~1.1.1" + util-deprecate: "npm:~1.0.1" + checksum: 10c0/7efdb01f3853bc35ac62ea25493567bf588773213f5f4a79f9c365e1ad13bab845ac0dae7bc946270dc40c3929483228415e92a3fc600cc7e4548992f41ee3fa + languageName: node + linkType: hard + "readable-stream@npm:^3.4.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" @@ -6521,6 +7118,13 @@ __metadata: languageName: node linkType: hard +"reduce-flatten@npm:^2.0.0": + version: 2.0.0 + resolution: "reduce-flatten@npm:2.0.0" + checksum: 10c0/9275064535bc070a787824c835a4f18394942f8a78f08e69fb500920124ce1c46a287c8d9e565a7ffad8104875a6feda14efa8e951e8e4585370b8ff007b0abd + languageName: node + linkType: hard + "refa@npm:^0.12.0, refa@npm:^0.12.1": version: 0.12.1 resolution: "refa@npm:0.12.1" @@ -6716,6 +7320,17 @@ __metadata: languageName: node linkType: hard +"rimraf@npm:^2.7.1": + version: 2.7.1 + resolution: "rimraf@npm:2.7.1" + dependencies: + glob: "npm:^7.1.3" + bin: + rimraf: ./bin.js + checksum: 10c0/4eef73d406c6940927479a3a9dee551e14a54faf54b31ef861250ac815172bade86cc6f7d64a4dc5e98b65e4b18a2e1c9ff3b68d296be0c748413f092bb0dd40 + languageName: node + linkType: hard + "rimraf@npm:^3.0.2": version: 3.0.2 resolution: "rimraf@npm:3.0.2" @@ -6838,6 +7453,13 @@ __metadata: languageName: node linkType: hard +"run-async@npm:^2.4.0": + version: 2.4.1 + resolution: "run-async@npm:2.4.1" + checksum: 10c0/35a68c8f1d9664f6c7c2e153877ca1d6e4f886e5ca067c25cdd895a6891ff3a1466ee07c63d6a9be306e9619ff7d509494e6d9c129516a36b9fd82263d579ee1 + languageName: node + linkType: hard + "run-parallel@npm:^1.1.9": version: 1.2.0 resolution: "run-parallel@npm:1.2.0" @@ -6847,6 +7469,15 @@ __metadata: languageName: node linkType: hard +"rxjs@npm:^6.6.0": + version: 6.6.7 + resolution: "rxjs@npm:6.6.7" + dependencies: + tslib: "npm:^1.9.0" + checksum: 10c0/e556a13a9aa89395e5c9d825eabcfa325568d9c9990af720f3f29f04a888a3b854f25845c2b55875d875381abcae2d8100af9cacdc57576e7ed6be030a01d2fe + languageName: node + linkType: hard + "safe-array-concat@npm:^1.1.3": version: 1.1.3 resolution: "safe-array-concat@npm:1.1.3" @@ -6860,13 +7491,20 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:~5.2.0": +"safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 languageName: node linkType: hard +"safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": + version: 5.1.2 + resolution: "safe-buffer@npm:5.1.2" + checksum: 10c0/780ba6b5d99cc9a40f7b951d47152297d0e260f0df01472a1b99d4889679a4b94a13d644f7dbc4f022572f09ae9005fa2fbb93bbbd83643316f365a3e9a45b21 + languageName: node + linkType: hard + "safe-push-apply@npm:^1.0.0": version: 1.0.0 resolution: "safe-push-apply@npm:1.0.0" @@ -6888,7 +7526,7 @@ __metadata: languageName: node linkType: hard -"safer-buffer@npm:>= 2.1.2 < 3.0.0": +"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4 @@ -6945,7 +7583,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^5.5.0": +"semver@npm:^5.5.0, semver@npm:^5.7.1": version: 5.7.2 resolution: "semver@npm:5.7.2" bin: @@ -6972,6 +7610,13 @@ __metadata: languageName: node linkType: hard +"set-blocking@npm:~2.0.0": + version: 2.0.0 + resolution: "set-blocking@npm:2.0.0" + checksum: 10c0/9f8c1b2d800800d0b589de1477c753492de5c1548d4ade52f57f1d1f5e04af5481554d75ce5e5c43d4004b80a3eb714398d6907027dc0534177b7539119f4454 + languageName: node + linkType: hard + "set-function-length@npm:^1.2.2": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" @@ -7073,7 +7718,7 @@ __metadata: languageName: node linkType: hard -"signal-exit@npm:^3.0.2": +"signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912 @@ -7190,7 +7835,7 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.6.0": +"source-map@npm:^0.6.0, source-map@npm:^0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 @@ -7204,6 +7849,40 @@ __metadata: languageName: node linkType: hard +"spdx-correct@npm:^3.0.0": + version: 3.2.0 + resolution: "spdx-correct@npm:3.2.0" + dependencies: + spdx-expression-parse: "npm:^3.0.0" + spdx-license-ids: "npm:^3.0.0" + checksum: 10c0/49208f008618b9119208b0dadc9208a3a55053f4fd6a0ae8116861bd22696fc50f4142a35ebfdb389e05ccf2de8ad142573fefc9e26f670522d899f7b2fe7386 + languageName: node + linkType: hard + +"spdx-exceptions@npm:^2.1.0": + version: 2.5.0 + resolution: "spdx-exceptions@npm:2.5.0" + checksum: 10c0/37217b7762ee0ea0d8b7d0c29fd48b7e4dfb94096b109d6255b589c561f57da93bf4e328c0290046115961b9209a8051ad9f525e48d433082fc79f496a4ea940 + languageName: node + linkType: hard + +"spdx-expression-parse@npm:^3.0.0": + version: 3.0.1 + resolution: "spdx-expression-parse@npm:3.0.1" + dependencies: + spdx-exceptions: "npm:^2.1.0" + spdx-license-ids: "npm:^3.0.0" + checksum: 10c0/6f8a41c87759fa184a58713b86c6a8b028250f158159f1d03ed9d1b6ee4d9eefdc74181c8ddc581a341aa971c3e7b79e30b59c23b05d2436d5de1c30bdef7171 + languageName: node + linkType: hard + +"spdx-license-ids@npm:^3.0.0": + version: 3.0.22 + resolution: "spdx-license-ids@npm:3.0.22" + checksum: 10c0/4a85e44c2ccfc06eebe63239193f526508ebec1abc7cf7bca8ee43923755636234395447c2c87f40fb672cf580a9c8e684513a676bfb2da3d38a4983684bbb38 + languageName: node + linkType: hard + "sprintf-js@npm:^1.1.2": version: 1.1.3 resolution: "sprintf-js@npm:1.1.3" @@ -7253,7 +7932,7 @@ __metadata: languageName: node linkType: hard -"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" dependencies: @@ -7264,6 +7943,17 @@ __metadata: languageName: node linkType: hard +"string-width@npm:^1.0.1": + version: 1.0.2 + resolution: "string-width@npm:1.0.2" + dependencies: + code-point-at: "npm:^1.0.0" + is-fullwidth-code-point: "npm:^1.0.0" + strip-ansi: "npm:^3.0.0" + checksum: 10c0/c558438baed23a9ab9370bb6a939acbdb2b2ffc517838d651aad0f5b2b674fb85d460d9b1d0b6a4c210dffd09e3235222d89a5bd4c0c1587f78b2bb7bc00c65e + languageName: node + linkType: hard + "string-width@npm:^5.0.1, string-width@npm:^5.1.2": version: 5.1.2 resolution: "string-width@npm:5.1.2" @@ -7364,6 +8054,15 @@ __metadata: languageName: node linkType: hard +"string_decoder@npm:~1.1.1": + version: 1.1.1 + resolution: "string_decoder@npm:1.1.1" + dependencies: + safe-buffer: "npm:~5.1.0" + checksum: 10c0/b4f89f3a92fd101b5653ca3c99550e07bdf9e13b35037e9e2a1c7b47cec4e55e06ff3fc468e314a0b5e80bfbaf65c1ca5a84978764884ae9413bec1fc6ca924e + languageName: node + linkType: hard + "strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": version: 6.0.1 resolution: "strip-ansi@npm:6.0.1" @@ -7373,6 +8072,15 @@ __metadata: languageName: node linkType: hard +"strip-ansi@npm:^3.0.0, strip-ansi@npm:^3.0.1": + version: 3.0.1 + resolution: "strip-ansi@npm:3.0.1" + dependencies: + ansi-regex: "npm:^2.0.0" + checksum: 10c0/f6e7fbe8e700105dccf7102eae20e4f03477537c74b286fd22cfc970f139002ed6f0d9c10d0e21aa9ed9245e0fa3c9275930e8795c5b947da136e4ecb644a70f + languageName: node + linkType: hard + "strip-ansi@npm:^7.0.1, strip-ansi@npm:^7.1.0": version: 7.1.0 resolution: "strip-ansi@npm:7.1.0" @@ -7396,6 +8104,13 @@ __metadata: languageName: node linkType: hard +"strip-json-comments@npm:~2.0.1": + version: 2.0.1 + resolution: "strip-json-comments@npm:2.0.1" + checksum: 10c0/b509231cbdee45064ff4f9fd73609e2bcc4e84a4d508e9dd0f31f70356473fde18abfb5838c17d56fb236f5a06b102ef115438de0600b749e818a35fbbc48c43 + languageName: node + linkType: hard + "sumchecker@npm:^3.0.1": version: 3.0.1 resolution: "sumchecker@npm:3.0.1" @@ -7405,6 +8120,15 @@ __metadata: languageName: node linkType: hard +"supports-color@npm:^5.3.0": + version: 5.5.0 + resolution: "supports-color@npm:5.5.0" + dependencies: + has-flag: "npm:^3.0.0" + checksum: 10c0/6ae5ff319bfbb021f8a86da8ea1f8db52fac8bd4d499492e30ec17095b58af11f0c55f8577390a749b1c4dde691b6a0315dab78f5f54c9b3d83f8fb5905c1c05 + languageName: node + linkType: hard + "supports-color@npm:^7.1.0": version: 7.2.0 resolution: "supports-color@npm:7.2.0" @@ -7447,6 +8171,33 @@ __metadata: languageName: node linkType: hard +"table-layout@npm:^1.0.2": + version: 1.0.2 + resolution: "table-layout@npm:1.0.2" + dependencies: + array-back: "npm:^4.0.1" + deep-extend: "npm:~0.6.0" + typical: "npm:^5.2.0" + wordwrapjs: "npm:^4.0.0" + checksum: 10c0/c1d16d5ba2199571606ff574a5c91cff77f14e8477746e191e7dfd294da03e61af4e8004f1f6f783da9582e1365f38d3c469980428998750d558bf29462cc6c3 + languageName: node + linkType: hard + +"tar@npm:^4.4.13": + version: 4.4.19 + resolution: "tar@npm:4.4.19" + dependencies: + chownr: "npm:^1.1.4" + fs-minipass: "npm:^1.2.7" + minipass: "npm:^2.9.0" + minizlib: "npm:^1.3.3" + mkdirp: "npm:^0.5.5" + safe-buffer: "npm:^5.2.1" + yallist: "npm:^3.1.1" + checksum: 10c0/1a32a68feabd55e040f399f75fed37c35fd76202bb60e393986312cdee0175ff0dfd1aec9cc04ad2ade8a252d2a08c7d191fda877ce23f14a3da954d91d301d7 + languageName: node + linkType: hard + "tar@npm:^6.0.5, tar@npm:^6.1.11, tar@npm:^6.1.12, tar@npm:^6.2.1": version: 6.2.1 resolution: "tar@npm:6.2.1" @@ -7485,6 +8236,13 @@ __metadata: languageName: node linkType: hard +"through@npm:^2.3.6": + version: 2.3.8 + resolution: "through@npm:2.3.8" + checksum: 10c0/4b09f3774099de0d4df26d95c5821a62faee32c7e96fb1f4ebd54a2d7c11c57fe88b0a0d49cf375de5fee5ae6bf4eb56dbbf29d07366864e2ee805349970d3cc + languageName: node + linkType: hard + "tiny-async-pool@npm:1.3.0": version: 1.3.0 resolution: "tiny-async-pool@npm:1.3.0" @@ -7513,6 +8271,15 @@ __metadata: languageName: node linkType: hard +"tmp@npm:^0.0.33": + version: 0.0.33 + resolution: "tmp@npm:0.0.33" + dependencies: + os-tmpdir: "npm:~1.0.2" + checksum: 10c0/69863947b8c29cabad43fe0ce65cec5bb4b481d15d4b4b21e036b060b3edbf3bc7a5541de1bacb437bb3f7c4538f669752627fdf9b4aaf034cebd172ba373408 + languageName: node + linkType: hard + "tmp@npm:^0.2.0": version: 0.2.5 resolution: "tmp@npm:0.2.5" @@ -7529,6 +8296,13 @@ __metadata: languageName: node linkType: hard +"toml@npm:^3.0.0": + version: 3.0.0 + resolution: "toml@npm:3.0.0" + checksum: 10c0/8d7ed3e700ca602e5419fca343e1c595eb7aa177745141f0761a5b20874b58ee5c878cd045c408da9d130cb2b611c639912210ba96ce2f78e443569aa8060c18 + languageName: node + linkType: hard + "truncate-utf8-bytes@npm:^1.0.0": version: 1.0.2 resolution: "truncate-utf8-bytes@npm:1.0.2" @@ -7547,6 +8321,13 @@ __metadata: languageName: node linkType: hard +"ts-typed-json@npm:^0.3.2": + version: 0.3.2 + resolution: "ts-typed-json@npm:0.3.2" + checksum: 10c0/6c47e9f45b0a9e20fced5e4c8ad1548b9727b8114f5dfbaadc25822a1f96dd219a4e58ca8270a6f20abb519d9b1b9ea344601a4c5fe9459650b96d0201ddabe7 + languageName: node + linkType: hard + "tsconfig-paths@npm:^3.15.0": version: 3.15.0 resolution: "tsconfig-paths@npm:3.15.0" @@ -7559,6 +8340,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:^1.9.0": + version: 1.14.1 + resolution: "tslib@npm:1.14.1" + checksum: 10c0/69ae09c49eea644bc5ebe1bca4fa4cc2c82b7b3e02f43b84bd891504edf66dbc6b2ec0eef31a957042de2269139e4acff911e6d186a258fb14069cd7f6febce2 + languageName: node + linkType: hard + "tslib@npm:^2.0.0, tslib@npm:^2.1.0": version: 2.8.1 resolution: "tslib@npm:2.8.1" @@ -7582,6 +8370,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^0.21.3": + version: 0.21.3 + resolution: "type-fest@npm:0.21.3" + checksum: 10c0/902bd57bfa30d51d4779b641c2bc403cdf1371fb9c91d3c058b0133694fcfdb817aef07a47f40faf79039eecbaa39ee9d3c532deff244f3a19ce68cea71a61e8 + languageName: node + linkType: hard + "type-fest@npm:^4.27.0": version: 4.41.0 resolution: "type-fest@npm:4.41.0" @@ -7662,6 +8457,29 @@ __metadata: languageName: node linkType: hard +"typical@npm:^4.0.0": + version: 4.0.0 + resolution: "typical@npm:4.0.0" + checksum: 10c0/f300b198fb9fe743859b75ec761d53c382723dc178bbce4957d9cb754f2878a44ce17dc0b6a5156c52be1065449271f63754ba594dac225b80ce3aa39f9241ed + languageName: node + linkType: hard + +"typical@npm:^5.2.0": + version: 5.2.0 + resolution: "typical@npm:5.2.0" + checksum: 10c0/1cceaa20d4b77a02ab8eccfe4a20500729431aecc1e1b7dc70c0e726e7966efdca3bf0b4bee285555b751647e37818fd99154ea73f74b5c29adc95d3c13f5973 + languageName: node + linkType: hard + +"uglify-js@npm:^3.1.4": + version: 3.19.3 + resolution: "uglify-js@npm:3.19.3" + bin: + uglifyjs: bin/uglifyjs + checksum: 10c0/83b0a90eca35f778e07cad9622b80c448b6aad457c9ff8e568afed978212b42930a95f9e1be943a1ffa4258a3340fbb899f41461131c05bb1d0a9c303aed8479 + languageName: node + linkType: hard + "unbox-primitive@npm:^1.1.0": version: 1.1.0 resolution: "unbox-primitive@npm:1.1.0" @@ -7837,13 +8655,32 @@ __metadata: languageName: node linkType: hard -"util-deprecate@npm:^1.0.1": +"util-deprecate@npm:^1.0.1, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" checksum: 10c0/41a5bdd214df2f6c3ecf8622745e4a366c4adced864bc3c833739791aeeeb1838119af7daed4ba36428114b5c67dcda034a79c882e97e43c03e66a4dd7389942 languageName: node linkType: hard +"validate-npm-package-license@npm:^3.0.4": + version: 3.0.4 + resolution: "validate-npm-package-license@npm:3.0.4" + dependencies: + spdx-correct: "npm:^3.0.0" + spdx-expression-parse: "npm:^3.0.0" + checksum: 10c0/7b91e455a8de9a0beaa9fe961e536b677da7f48c9a493edf4d4d4a87fd80a7a10267d438723364e432c2fcd00b5650b5378275cded362383ef570276e6312f4f + languageName: node + linkType: hard + +"validate-npm-package-name@npm:^3.0.0": + version: 3.0.0 + resolution: "validate-npm-package-name@npm:3.0.0" + dependencies: + builtins: "npm:^1.0.3" + checksum: 10c0/064f21f59aefae6cc286dd4a50b15d14adb0227e0facab4316197dfb8d06801669e997af5081966c15f7828a5e6ff1957bd20886aeb6b9d0fa430e4cb5db9c4a + languageName: node + linkType: hard + "verror@npm:^1.10.0": version: 1.10.1 resolution: "verror@npm:1.10.1" @@ -8016,6 +8853,15 @@ __metadata: languageName: node linkType: hard +"wide-align@npm:^1.1.0": + version: 1.1.5 + resolution: "wide-align@npm:1.1.5" + dependencies: + string-width: "npm:^1.0.2 || 2 || 3 || 4" + checksum: 10c0/1d9c2a3e36dfb09832f38e2e699c367ef190f96b82c71f809bc0822c306f5379df87bab47bed27ea99106d86447e50eb972d3c516c2f95782807a9d082fbea95 + languageName: node + linkType: hard + "word-wrap@npm:^1.2.5": version: 1.2.5 resolution: "word-wrap@npm:1.2.5" @@ -8023,6 +8869,23 @@ __metadata: languageName: node linkType: hard +"wordwrap@npm:^1.0.0": + version: 1.0.0 + resolution: "wordwrap@npm:1.0.0" + checksum: 10c0/7ed2e44f3c33c5c3e3771134d2b0aee4314c9e49c749e37f464bf69f2bcdf0cbf9419ca638098e2717cff4875c47f56a007532f6111c3319f557a2ca91278e92 + languageName: node + linkType: hard + +"wordwrapjs@npm:^4.0.0": + version: 4.0.1 + resolution: "wordwrapjs@npm:4.0.1" + dependencies: + reduce-flatten: "npm:^2.0.0" + typical: "npm:^5.2.0" + checksum: 10c0/4cc43eb0f6adb7214d427e68918357a9df483815efbb4c59beb30972714b1804ede2a551b1dfd2234c0bd413c6f07d6daa6522d1c53f43f89a376d815fbf3c43 + languageName: node + linkType: hard + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": version: 7.0.0 resolution: "wrap-ansi@npm:7.0.0" @@ -8084,7 +8947,7 @@ __metadata: languageName: node linkType: hard -"yallist@npm:^3.0.2": +"yallist@npm:^3.0.0, yallist@npm:^3.0.2, yallist@npm:^3.1.1": version: 3.1.1 resolution: "yallist@npm:3.1.1" checksum: 10c0/c66a5c46bc89af1625476f7f0f2ec3653c1a1791d2f9407cfb4c2ba812a1e1c9941416d71ba9719876530e3340a99925f697142989371b72d93b9ee628afd8c1 @@ -8152,3 +9015,24 @@ __metadata: checksum: 10c0/dceb44c28578b31641e13695d200d34ec4ab3966a5729814d5445b194933c096b7ced71494ce53a0e8820685d1d010df8b2422e5bf2cdea7e469d97ffbea306f languageName: node linkType: hard + +"zustand@npm:^5.0.8": + version: 5.0.8 + resolution: "zustand@npm:5.0.8" + peerDependencies: + "@types/react": ">=18.0.0" + immer: ">=9.0.6" + react: ">=18.0.0" + use-sync-external-store: ">=1.2.0" + peerDependenciesMeta: + "@types/react": + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + checksum: 10c0/e865a6f7f1c0e03571701db5904151aaa7acefd6f85541a117085e129bf16e8f60b11f8cc82f277472de5c7ad5dcb201e1b0a89035ea0b40c9d9aab3cd24c8ad + languageName: node + linkType: hard