diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..36a3128
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,34 @@
+BasedOnStyle: WebKit
+
+AlignAfterOpenBracket: Align
+AlignEscapedNewlines: DontAlign
+AllowAllParametersOfDeclarationOnNextLine: "false"
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortIfStatementsOnASingleLine: "false"
+AllowShortLambdasOnASingleLine: All
+AllowShortLoopsOnASingleLine: "false"
+AlwaysBreakAfterReturnType: TopLevelDefinitions
+AlwaysBreakTemplateDeclarations: Yes
+BinPackArguments: "false"
+BinPackParameters: "false"
+BreakBeforeBraces: Allman
+BreakBeforeTernaryOperators: "true"
+BreakConstructorInitializers: BeforeComma
+ColumnLimit: 120
+Cpp11BracedListStyle: "false"
+FixNamespaceComments: "true"
+IncludeBlocks: Preserve
+IndentWidth: "4"
+InsertBraces: "true"
+MaxEmptyLinesToKeep: "2"
+NamespaceIndentation: None
+PointerAlignment: Left
+ReflowComments: "false"
+SortIncludes: "true"
+SpaceAfterCStyleCast: "false"
+SpaceInEmptyBlock: "false"
+SpacesBeforeTrailingComments: "2"
+SpacesInAngles: "true"
+SpacesInParentheses: "true"
+SpacesInSquareBrackets: "true"
+Standard: c++17
\ No newline at end of file
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..9ccbd91
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,152 @@
+name: Build and Release ALG App Store
+
+on:
+ push:
+ branches: [ "main", "devel", "qt6" ]
+ paths:
+ - '**.cpp'
+ - '**.h'
+ - 'CMakeLists.txt'
+ - '.github/workflows/**'
+ pull_request:
+ branches: [ "main", "devel", "qt6" ]
+ workflow_dispatch:
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ container:
+ image: archlinux:latest
+ outputs:
+ version: ${{ steps.get_version.outputs.version }}
+ should_release: ${{ steps.check_release.outputs.should_release }}
+ artifact_name: ${{ steps.artifact.outputs.name }}
+
+ steps:
+ - name: Install base dependencies
+ run: |
+ pacman -Syu --noconfirm
+ pacman -S --noconfirm --needed \
+ base-devel \
+ git \
+ cmake \
+ qt6-base \
+ qt6-tools \
+ pacman \
+ libarchive \
+ curl \
+ pkgconf
+
+ - name: Checkout code
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 2 # Need history to check changed files
+
+ - name: Mark git directory as safe
+ run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
+
+ - name: Extract version from CMakeLists.txt
+ id: get_version
+ run: |
+ VERSION=$(grep -oP 'project\(alg-app-store VERSION \K[0-9]+\.[0-9]+\.[0-9]+' CMakeLists.txt)
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
+ echo "Detected version: $VERSION"
+
+ - name: Check if this should trigger a release
+ id: check_release
+ run: |
+ # Only release on main branch when CMakeLists.txt was modified
+ if [[ "${{ github.ref }}" == "refs/heads/main" && "${{ github.event_name }}" == "push" ]]; then
+ # Check if CMakeLists.txt was changed in this push
+ if git diff --name-only HEAD~1 HEAD | grep -q "CMakeLists.txt"; then
+ echo "should_release=true" >> $GITHUB_OUTPUT
+ echo "Release triggered: CMakeLists.txt changed on main branch"
+ else
+ echo "should_release=false" >> $GITHUB_OUTPUT
+ echo "No release: CMakeLists.txt not changed"
+ fi
+ else
+ echo "should_release=false" >> $GITHUB_OUTPUT
+ echo "No release: not on main branch or not a push event"
+ fi
+
+ - name: Configure CMake
+ run: |
+ mkdir -p build
+ cd build
+ cmake ..
+
+ - name: Build
+ run: |
+ cd build
+ make -j$(nproc)
+
+ - name: Check build artifacts
+ run: |
+ ls -lh build/alg-app-store
+ file build/alg-app-store
+
+ - name: Set artifact name
+ id: artifact
+ run: |
+ # Replace forward slashes with dashes to handle PR refs like "12/merge"
+ ARTIFACT_NAME="alg-app-store-${{ github.ref_name }}-${{ steps.get_version.outputs.version }}"
+ ARTIFACT_NAME="${ARTIFACT_NAME//\//-}"
+ echo "name=$ARTIFACT_NAME" >> $GITHUB_OUTPUT
+ echo "Artifact name: $ARTIFACT_NAME"
+
+ - name: Upload build artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ steps.artifact.outputs.name }}
+ path: build/alg-app-store
+ retention-days: 30
+
+ release:
+ needs: build
+ runs-on: ubuntu-latest
+ if: needs.build.outputs.should_release == 'true'
+ permissions:
+ contents: write
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Download build artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: ${{ needs.build.outputs.artifact_name }}
+ path: ./release
+
+ - name: Prepare release assets
+ run: |
+ chmod +x ./release/alg-app-store
+ tar -czvf alg-app-store-${{ needs.build.outputs.version }}-linux-x86_64.tar.gz -C ./release alg-app-store
+
+ - name: Create GitHub Release
+ uses: softprops/action-gh-release@v1
+ with:
+ tag_name: v${{ needs.build.outputs.version }}
+ name: ALG App Store v${{ needs.build.outputs.version }}
+ body: |
+ ## ALG App Store v${{ needs.build.outputs.version }}
+
+ A modern package manager GUI for Arch Linux.
+
+ ### Installation
+ ```bash
+ tar -xzvf alg-app-store-${{ needs.build.outputs.version }}-linux-x86_64.tar.gz
+ sudo mv alg-app-store /usr/local/bin/
+ ```
+
+ ### Requirements
+ - Qt6 (Core, Gui, Widgets, Network, Concurrent)
+ - libalpm (pacman library)
+ - yay or paru (for AUR support)
+ files: |
+ alg-app-store-${{ needs.build.outputs.version }}-linux-x86_64.tar.gz
+ draft: false
+ prerelease: false
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b202a2f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,52 @@
+# Qt/C++ Build artifacts
+build/
+*.o
+*.so
+*.a
+*.user
+*.autosave
+moc_*.cpp
+qrc_*.cpp
+ui_*.h
+
+# CMake
+CMakeCache.txt
+CMakeFiles/
+cmake_install.cmake
+Makefile
+
+# Qt Creator
+*.pro.user
+*.pro.user.*
+
+# Executable
+alg-app-store
+
+# IDE
+.vscode/
+.idea/
+*.swp
+*.swo
+*~
+
+# Compiled Object files
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Debug files
+*.dSYM/
+*.su
+*.idb
+*.pdb
+
+# OS specific
+.DS_Store
+Thumbs.db
+
+# Backup files
+*~
+*.bak
+*.backup
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..e990cd5
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,117 @@
+cmake_minimum_required(VERSION 3.16)
+
+project(alg-app-store VERSION 0.2.28 LANGUAGES CXX)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTORCC ON)
+set(CMAKE_AUTOUIC ON)
+
+# Find Qt6 packages
+find_package(Qt6 REQUIRED COMPONENTS
+ Core
+ Gui
+ Widgets
+ Network
+ Concurrent
+)
+
+# Find libalpm
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(ALPM REQUIRED libalpm)
+
+# Include directories
+include_directories(
+ ${CMAKE_SOURCE_DIR}/src
+ ${ALPM_INCLUDE_DIRS}
+)
+
+# Source files
+set(SOURCES
+ src/main.cpp
+
+ # Core
+ src/core/alpm_wrapper.cpp
+ src/core/aur_helper.cpp
+ src/core/package_manager.cpp
+
+ # GUI
+ src/gui/mainwindow.cpp
+ src/gui/home_widget.cpp
+ src/gui/search_widget.cpp
+ src/gui/installed_widget.cpp
+ src/gui/updates_widget.cpp
+ src/gui/settings_widget.cpp
+ src/gui/package_card.cpp
+ src/gui/package_details_dialog.cpp
+)
+
+# Header files
+set(HEADERS
+ src/utils/logger.h
+ src/utils/types.h
+
+ # Core
+ src/core/alpm_wrapper.h
+ src/core/aur_helper.h
+ src/core/package_manager.h
+
+ # GUI
+ src/gui/mainwindow.h
+ src/gui/home_widget.h
+ src/gui/search_widget.h
+ src/gui/installed_widget.h
+ src/gui/updates_widget.h
+ src/gui/settings_widget.h
+ src/gui/package_card.h
+ src/gui/package_details_dialog.h
+)
+
+# Create executable
+add_executable(${PROJECT_NAME}
+ ${SOURCES}
+ ${HEADERS}
+)
+
+# Link libraries
+target_link_libraries(${PROJECT_NAME} PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
+ Qt6::Network
+ Qt6::Concurrent
+ ${ALPM_LIBRARIES}
+)
+
+# Link directories
+link_directories(${ALPM_LIBRARY_DIRS})
+
+# Compiler flags
+target_compile_options(${PROJECT_NAME} PRIVATE
+ -Wall
+ -Wextra
+ -Wpedantic
+)
+
+# Install target
+install(TARGETS ${PROJECT_NAME}
+ RUNTIME DESTINATION bin
+)
+
+# Install desktop file
+install(FILES assets/alg-app-store.desktop
+ DESTINATION share/applications
+)
+
+# Copy stylesheet to build directory
+configure_file(
+ ${CMAKE_SOURCE_DIR}/stylesheet.qss
+ ${CMAKE_BINARY_DIR}/stylesheet.qss
+ COPYONLY
+)
+
+# Install stylesheet
+install(FILES stylesheet.qss
+ DESTINATION share/alg-app-store
+)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..48ad1ab
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,155 @@
+# Contributing to ALG Welcome
+
+Contributions are welcome and appreciated! To contribute:
+
+- Code follows C++17 standards
+- Proper error handling and logging
+- Thread safety for concurrent operations
+- Qt best practices for GUI code
+- Comments for complex logic
+
+### How to contribute
+1. **Fork the Repository.**
+2. **Create a New Branch** for your feature or bug fix:
+ ```bash
+ git checkout -b feature/your-feature-name
+ ```
+3. **Make Your Changes:**
+ - Follow modern C++17 best practices
+ - Use Qt6 APIs and conventions
+ - Ensure code compiles without warnings
+ - Test on your desktop environment (KDE, GNOME, or Xfce)
+4. **Commit Your Changes** and push your branch:
+ ```bash
+ git commit -m "Add new feature or fix bug"
+ git push -u origin feature/your-feature-name
+ ```
+5. **Open a Pull Request** describing your changes.
+
+
+## Project Structure
+
+```
+├── assets
+│ ├── alg-app-store.desktop
+│ └── alg-app-store.png
+├── build.sh
+├── CMakeLists.txt
+├── CONTRIBUTING.md
+├── DEVELOPER_GUIDE.md
+├── LICENSE
+├── QT_REWRITE_SUMMARY.md
+├── README.md
+├── src
+│ ├── core
+│ │ ├── alpm_wrapper.cpp
+│ │ ├── alpm_wrapper.h
+│ │ ├── aur_helper.cpp
+│ │ ├── aur_helper.h
+│ │ ├── package_manager.cpp
+│ │ └── package_manager.h
+│ ├── gui
+│ │ ├── home_widget.cpp
+│ │ ├── home_widget.h
+│ │ ├── installed_widget.cpp
+│ │ ├── installed_widget.h
+│ │ ├── mainwindow.cpp
+│ │ ├── mainwindow.h
+│ │ ├── package_card.cpp
+│ │ ├── package_card.h
+│ │ ├── package_details_dialog.cpp
+│ │ ├── package_details_dialog.h
+│ │ ├── search_widget.cpp
+│ │ ├── search_widget.h
+│ │ ├── settings_widget.cpp
+│ │ ├── settings_widget.h
+│ │ ├── updates_widget.cpp
+│ │ └── updates_widget.h
+│ ├── main.cpp
+│ └── utils
+│ ├── logger.h
+│ └── types.h
+├── stylesheet.qss
+└── TODO.md
+
+6 directories, 36 files
+```
+
+## Understanding the code
+### Core
+#### AlpmWrapper (Singleton)
+Wraps libalpm functionality with thread-safe operations:
+- Package searching
+- Installed package enumeration
+- Update detection
+- Package information retrieval
+
+#### AurHelper
+Handles AUR integration:
+- Package search via AUR RPC API
+- Package information retrieval
+- Update checking for AUR packages
+
+#### PackageManager (Singleton)
+Manages package operations with proper privilege escalation:
+- Install/uninstall packages
+- Update operations
+- Automatic helper detection (yay/paru/pacman)
+- Process management with signals
+
+### GUI Components
+- **MainWindow**: Tabbed interface container
+- **HomeWidget**: Featured packages display
+- **SearchWidget**: Package search with filtering
+- **InstalledWidget**: Installed package browser
+- **UpdatesWidget**: Update management
+- **PackageCard**: Reusable package display widget
+- **PackageDetailsDialog**: Detailed package information
+
+## Design Decisions
+
+### Modern C++ Features
+
+- **Smart Pointers**: `std::unique_ptr` and `std::shared_ptr` for automatic memory management
+- **Move Semantics**: `std::move()` for efficient resource transfer
+- **Auto Type Deduction**: Cleaner, more maintainable code
+- **Range-based Loops**: Cleaner iteration
+- **Lambda Functions**: Inline callbacks and signal connections
+
+### Thread Safety
+
+- **Mutexes**: `std::mutex` and `std::lock_guard` for critical sections
+- **Qt Concurrent**: `QtConcurrent::run()` for background operations
+- **Signal/Slot**: Qt's thread-safe communication mechanism
+
+### Singleton Pattern
+
+Used for `AlpmWrapper` and `PackageManager` to ensure:
+- Single libalpm handle instance
+- Centralized package operation management
+- Thread-safe access
+
+## Logging
+
+The application includes a comprehensive logging system:
+
+```cpp
+Logger::info("Information message");
+Logger::warning("Warning message");
+Logger::error("Error message");
+Logger::debug("Debug message");
+```
+
+Logs are output to standard output and can be redirected for persistent logging.
+
+## Package Helper Detection
+
+The application automatically detects available package helpers in this order:
+
+1. **yay** - Preferred for AUR support
+2. **paru** - Alternative AUR helper
+3. **pacman** - Fallback (official repos only)
+
+## Privilege Escalation
+
+Package operations require root privileges. The application uses `pkexec` (PolicyKit) for secure privilege escalation. Ensure PolicyKit is properly configured on your system.
\ No newline at end of file
diff --git a/GetPackage/get.go b/GetPackage/get.go
deleted file mode 100644
index 96ba5f5..0000000
--- a/GetPackage/get.go
+++ /dev/null
@@ -1,184 +0,0 @@
-package getpackage
-
-import (
- "encoding/json"
- "fmt"
- "os"
- "os/exec"
- "strings"
- "sync"
- "time"
-
- "github.com/Jguer/go-alpm/v2"
-)
-
-type PackageInfo struct {
- Name string `json:"name"`
- Version string `json:"version"`
- Description string `json:"description"`
- Repository string `json:"repository"`
- Maintainer string `json:"maintainer"`
- UpstreamURL string `json:"upstreamurl"`
- DependList []string `json:"dependlist"`
- LastUpdated string `json:"lastupdated"`
-}
-
-func SavePackageInfoToFile(pkgName, fileName string) error {
- pkgs := SearchPackage(pkgName)
- if len(pkgs) == 0 {
- return fmt.Errorf("package %s not found", pkgName)
- }
-
- // Assume the first result is the most relevant one
- pkgInfo := pkgs
-
- file, err := os.Create(fileName)
- if err != nil {
- return fmt.Errorf("failed to create file: %w", err)
- }
- defer file.Close()
-
- encoder := json.NewEncoder(file)
- encoder.SetIndent("", " ")
- err = encoder.Encode(pkgInfo)
- if err != nil {
- return fmt.Errorf("failed to encode package info to JSON: %w", err)
- }
-
- fmt.Printf("Package information for %s saved to %s\n", pkgName, fileName)
- return nil
-}
-
-func SearchPackage(query string) []PackageInfo {
- var h *alpm.Handle
-
- // var dbs []alpm.IDB
- var dbs []alpm.IDB
- var err error
- h, err = alpm.Initialize("/", "/var/lib/pacman")
- if err != nil {
- fmt.Fprintf(os.Stderr, "failed to initialize alpm: %v\n", err)
- os.Exit(1)
- }
-
- // Register and sync repositories
- repos := []string{"core", "extra"}
- for _, repo := range repos {
- db, err := h.RegisterSyncDB(repo, 0)
- if err != nil {
- fmt.Printf("Error getting sync db for %s: %v\n", repo, err)
- }
- dbs = append(dbs, db)
- }
- var results []PackageInfo
- var wg sync.WaitGroup
- resultChan := make(chan PackageInfo, 100)
- doneChan := make(chan bool)
-
- // Start a goroutine to collect results
- go func() {
- for pkg := range resultChan {
- results = append(results, pkg)
- }
- doneChan <- true
- }()
-
- // Search official repositories concurrently
- for _, db := range dbs {
- wg.Add(1)
- go func(db alpm.IDB) {
- defer wg.Done()
- searchDB(db, query, resultChan)
- }(db)
- }
-
- // Search AUR concurrently
- wg.Add(1)
- go func() {
- defer wg.Done()
- searchAUR(query, resultChan)
- }()
-
- // Wait for all searches to complete
- wg.Wait()
- close(resultChan)
-
- // Wait for result collection to finish
- <-doneChan
-
- return results
-}
-
-func searchDB(db alpm.IDB, query string, resultChan chan<- PackageInfo) {
- db.PkgCache().ForEach(func(pkg alpm.IPackage) error {
- if strings.Contains(strings.ToLower(pkg.Name()), strings.ToLower(query)) {
- lastUpdated := pkg.BuildDate().UTC().Format("Jan. 2, 2006, 3 p.m. MST")
- resultChan <- PackageInfo{
- Name: pkg.Name(),
- Version: pkg.Version(),
- Description: pkg.Description(),
- Repository: db.Name(),
- Maintainer: pkg.Packager(),
- UpstreamURL: pkg.URL(),
- DependList: convertDependList(pkg.Depends()),
- LastUpdated: lastUpdated,
- }
- }
- return nil
- })
-}
-
-func searchAUR(query string, resultChan chan<- PackageInfo) {
- cmd := exec.Command("curl", "-s", fmt.Sprintf("https://aur.archlinux.org/rpc/?v=5&type=search&arg=%s", query))
- output, err := cmd.Output()
- if err != nil {
- fmt.Printf("Error searching AUR: %v\n", err)
- return
- }
-
- var aurResponse struct {
- Results []struct {
- Name string `json:"Name"`
- Version string `json:"Version"`
- Description string `json:"Description"`
- Maintainer string `json:"Maintainer"`
- URL string `json:"URL"`
- LastModified int64 `json:"LastModified"`
- } `json:"results"`
- }
- err = json.Unmarshal(output, &aurResponse)
- if err != nil {
- fmt.Printf("Error parsing AUR response: %v\n", err)
- return
- }
-
- for _, aurPkg := range aurResponse.Results {
- lastUpdated := time.Unix(aurPkg.LastModified, 0).UTC().Format("02-01-2006")
- resultChan <- PackageInfo{
- Name: aurPkg.Name,
- Version: aurPkg.Version,
- Description: aurPkg.Description,
- Repository: "AUR",
- Maintainer: aurPkg.Maintainer,
- UpstreamURL: aurPkg.URL,
- DependList: nil,
- LastUpdated: lastUpdated,
- }
- }
-}
-
-func convertDependList(depList alpm.IDependList) []string {
- var deps []string
- depList.ForEach(func(dep *alpm.Depend) error {
- deps = append(deps, dep.Name)
- return nil
- })
- return deps
-}
-
-func main() {
- err := SavePackageInfoToFile("google-chrome", "package-info.json")
- if err != nil {
- fmt.Println("Error:", err)
- }
-}
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..33100ba
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 ALG Team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
index ed259fc..3fe1751 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,83 @@
-# README
+# ALG App Store - Qt6/C++ Version
-## About
+A modern, native package manager for Arch Linux built with Qt6 and C++17. This is a complete rewrite of the original Wails-based application.
-About your template
+## Features
-## Live Development
+- **Search Packages**: Search through official Arch repositories (core, extra) and AUR
+- **View Installed Packages**: Browse and manage installed packages
+- **Check for Updates**: View available updates for both official and AUR packages
+- **Package Management**: Install, uninstall, and update packages
+- **Modern UI**: Clean, dark-themed interface with responsive design
+- **Smart Helper Detection**: Automatically detects and uses yay, paru, or falls back to pacman
+- **Thread-Safe**: Uses modern C++ threading features for safe concurrent operations
+- **Comprehensive Logging**: Built-in logger for debugging and monitoring
-To run in live development mode, run `wails dev` in the project directory. In another terminal, go into the `frontend`
-directory and run `npm run dev`. The frontend dev server will run on http://localhost:34115. Connect to this in your
-browser and connect to your application.
+## Technology Stack
+
+- **Language**: C++17
+- **GUI Framework**: Qt6 (Widgets)
+- **Package Management**: libalpm (Arch Linux Package Manager library)
+- **AUR Integration**: AUR RPC API via Qt Network + Chaotic AUR Support
+- **Build System**: CMake
+- **Threading**: Qt Concurrent & STL threading
+
+## Prerequisites
+
+### Build Dependencies
+
+```bash
+sudo pacman -S base-devel cmake qt6-base qt6-svg alpm pkgconf
+```
+
+You can optionally also have either either yay or paru if you would like to work with packages from the AUR.
## Building
-To build a redistributable, production mode package, use `wails build`.
+1. Clone the repository:
+```bash
+git clone https://github.com/arch-linux-gui/alg-app-store.git
+cd alg-app-store
+```
+
+2. Run Build Script
+```bash
+# This will create a build directory.
+./build.sh
+```
+
+Binary will be in the build directory.
+
+## Running
+
+### From Build Directory
+
+```bash
+./build/alg-app-store
+```
+
+### From System Installation (if installed)
+
+```bash
+alg-app-store
+```
+
+
+## License
+
+This project is part of the Arch Linux GUI project.
+It is distributed under the MIT License. Check LICENSE.
+
+## Credits
+
+- **Author**: DemonKiller
+- **Original Project**: Wails-based ALG App Store
+- **Rewrite**: Qt6/C++ implementation
+- **Community**: Arch Linux and Qt communities
+
+## Contact
+
+For issues, questions, or contributions, please visit:
+- GitHub: https://github.com/arch-linux-gui/alg-app-store
+- Website: https://arkalinuxgui.org
+- Discord: https://discord.com/invite/NgAFEw9Tkf
\ No newline at end of file
diff --git a/TODO.md b/TODO.md
index 2555835..6998488 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,7 +1,25 @@
-- [x] Search packages from all DB: Core, Extra & AUR
-- [x] Search Local DB and display packages in Install screen
-- [x] Add Install Func
-- [x] Add Uninstall Func
-- [x] Do State Management while installing with loader
-- [x] Do State Managerment while uninstalling with loader
-- [ ] Add Update All for updation of all packages
+- [x] Add chaotic aur to search tab if enabled
+- [x] Add launch button on package card if package is installed and remove when uninstalled
+- [] Add detailed mirrorlist tab to set mirrorlist
+- [x] Add version information
+- [] Implement an AUR helper in core to remove dependence on paru and yay
+- [] Ask password only once on startup - startup_auth
+- [] Improve settings page - settings_tab
+- [] Move all styles to single stylesheet - style_and_theme
+- [] Clean up UI; make UI look more modern (check gnome's styling options) - style_and_theme
+- [] Set a light/dark theme toggle, or follow system's theme - style_and_theme
+- [] Look into spdlog for logging
+- [] Look into CppUTest or Google Test (gtest) for test
+
+## Future Enhancements
+
+- Package categories/tags
+- Package ratings and reviews
+- Automated testing suite
+- Flatpak integration
+- AppImage support
+- Configuration file support
+- Multi-language support
+- Package download progress
+- Transaction history
+- Dependency visualization
\ No newline at end of file
diff --git a/app.go b/app.go
deleted file mode 100644
index 64edd00..0000000
--- a/app.go
+++ /dev/null
@@ -1,647 +0,0 @@
-package main
-
-import (
- "bytes"
- "context"
- "encoding/json"
- "fmt"
- "log"
- "os"
- "sort"
- "strings"
- "sync"
- "time"
-
- "os/exec"
-
- "github.com/Jguer/go-alpm/v2"
- paconf "github.com/Morganamilo/go-pacmanconf"
-)
-
-var h *alpm.Handle
-
-// var dbs []alpm.IDB
-var dbs []alpm.IDB
-
-var DesktopEnv string
-
-// App struct
-type App struct {
- ctx context.Context
-}
-
-// NewApp creates a new App application struct
-func NewApp() *App {
- return &App{}
-}
-
-// startup is called at application startup
-func (a *App) startup(ctx context.Context) {
- // Perform your setup here
- a.ctx = ctx
-
- DesktopEnv = getDesktopEnvironment()
-
- var err error
- h, err = alpm.Initialize("/", "/var/lib/pacman")
- if err != nil {
- fmt.Fprintf(os.Stderr, "failed to initialize alpm: %v\n", err)
- os.Exit(1)
- }
-
- // Register and sync repositories
- repos := []string{"core", "extra"}
- for _, repo := range repos {
- db, err := h.RegisterSyncDB(repo, 0)
- if err != nil {
- fmt.Printf("Error getting sync db for %s: %v\n", repo, err)
- return
- }
- dbs = append(dbs, db)
- }
-}
-
-// domReady is called after front-end resources have been loaded
-func (a App) domReady(ctx context.Context) {
- // Add your action here
-}
-
-// beforeClose is called when the application is about to quit,
-// either by clicking the window close button or calling runtime.Quit.
-// Returning true will cause the application to continue, false will continue shutdown as normal.
-func (a *App) beforeClose(ctx context.Context) (prevent bool) {
- return false
-}
-
-// shutdown is called at application termination
-func (a *App) shutdown(ctx context.Context) {
- // Perform your teardown here
- if h != nil {
- h.Release()
- }
-}
-
-type PackageInfo struct {
- Name string `json:"name"`
- Version string `json:"version"`
- Description string `json:"description"`
- Repository string `json:"repository"`
- Maintainer string `json:"maintainer"`
- UpstreamURL string `json:"upstreamurl"`
- DependList []string `json:"dependlist"`
- LastUpdated string `json:"lastupdated"`
-}
-
-func (a *App) SearchPackage(query string) []PackageInfo {
- var results []PackageInfo
- var wg sync.WaitGroup
- resultChan := make(chan PackageInfo, 100)
- doneChan := make(chan bool)
-
- // Start a goroutine to collect results
- go func() {
- for pkg := range resultChan {
- results = append(results, pkg)
- }
- doneChan <- true
- }()
-
- // Search official repositories concurrently
- for _, db := range dbs {
- wg.Add(1)
- go func(db alpm.IDB) {
- defer wg.Done()
- searchDB(db, query, resultChan)
- }(db)
- }
-
- // Search AUR concurrently
- wg.Add(1)
- go func() {
- defer wg.Done()
- searchAUR(query, resultChan)
- }()
-
- // Wait for all searches to complete
- wg.Wait()
- close(resultChan)
-
- // Wait for result collection to finish
- <-doneChan
-
- return results
-}
-
-func searchDB(db alpm.IDB, query string, resultChan chan<- PackageInfo) {
- db.PkgCache().ForEach(func(pkg alpm.IPackage) error {
- if strings.Contains(strings.ToLower(pkg.Name()), strings.ToLower(query)) {
- lastUpdated := pkg.BuildDate().UTC().Format("Jan. 2, 2006, 3 p.m. MST")
- resultChan <- PackageInfo{
- Name: pkg.Name(),
- Version: pkg.Version(),
- Description: pkg.Description(),
- Repository: db.Name(),
- Maintainer: pkg.Packager(),
- UpstreamURL: pkg.URL(),
- DependList: convertDependList(pkg.Depends()),
- LastUpdated: lastUpdated,
- }
- }
- return nil
- })
-}
-
-func searchAUR(query string, resultChan chan<- PackageInfo) {
- cmd := exec.Command("curl", "-s", fmt.Sprintf("https://aur.archlinux.org/rpc/?v=5&type=search&arg=%s", query))
- output, err := cmd.Output()
- if err != nil {
- fmt.Printf("Error searching AUR: %v\n", err)
- return
- }
-
- var aurResponse struct {
- Results []struct {
- Name string `json:"Name"`
- Version string `json:"Version"`
- Description string `json:"Description"`
- Maintainer string `json:"Maintainer"`
- URL string `json:"URL"`
- LastModified int64 `json:"LastModified"`
- } `json:"results"`
- }
- err = json.Unmarshal(output, &aurResponse)
- if err != nil {
- fmt.Printf("Error parsing AUR response: %v\n", err)
- return
- }
-
- for _, aurPkg := range aurResponse.Results {
- lastUpdated := time.Unix(aurPkg.LastModified, 0).UTC().Format("02-01-2006")
- resultChan <- PackageInfo{
- Name: aurPkg.Name,
- Version: aurPkg.Version,
- Description: aurPkg.Description,
- Repository: "AUR",
- Maintainer: aurPkg.Maintainer,
- UpstreamURL: aurPkg.URL,
- DependList: nil,
- LastUpdated: lastUpdated,
- }
- }
-}
-
-func convertDependList(depList alpm.IDependList) []string {
- var deps []string
- depList.ForEach(func(dep *alpm.Depend) error {
- deps = append(deps, dep.Name)
- return nil
- })
- return deps
-}
-
-func (a *App) GetInstalledPackages() ([]PackageInfo, error) {
- h, err := alpm.Initialize("/", "/var/lib/pacman")
- if err != nil {
- fmt.Fprintf(os.Stderr, "failed to initialize alpm: %v\n", err)
- os.Exit(1)
- }
-
- if h == nil {
- return nil, fmt.Errorf("ALPM handle is not initialized")
- }
-
- db, err := h.LocalDB()
- if err != nil {
- return nil, fmt.Errorf("failed to get local DB: %v", err)
- }
-
- var packages []PackageInfo
- var mutex sync.Mutex
-
- err = db.PkgCache().ForEach(func(pkg alpm.IPackage) error {
- mutex.Lock()
- lastUpdated := pkg.BuildDate().UTC().Format("Jan. 2, 2006, 3 p.m. MST")
- packages = append(packages, PackageInfo{
- Name: pkg.Name(),
- Version: pkg.Version(),
- Description: pkg.Description(),
- Repository: pkg.DB().Name(),
- Maintainer: pkg.Packager(),
- UpstreamURL: pkg.URL(),
- DependList: convertDependList(pkg.Depends()),
- LastUpdated: lastUpdated,
- })
- mutex.Unlock()
- return nil
- })
-
- if err != nil {
- return nil, fmt.Errorf("error iterating over packages: %v", err)
- }
-
- if len(packages) == 0 {
- return nil, fmt.Errorf("no installed packages found")
- }
-
- return packages, nil
-}
-
-func (a *App) SearchLocalPackage(pkg string) (bool, error) {
- if pkg == "" {
- return false, fmt.Errorf("empty package name provided")
- }
-
- local, err := searchLocalDB(pkg)
- if err != nil {
- return false, fmt.Errorf("error searching local DB: %w", err)
- }
-
- if local == nil {
- return false, nil
- }
-
- fmt.Println(strings.Contains(strings.ToLower(local.Name()), strings.ToLower(pkg)))
-
- return strings.Contains(strings.ToLower(local.Name()), strings.ToLower(pkg)), nil
-}
-
-func searchLocalDB(pkg string) (alpm.IPackage, error) {
- h, err := alpm.Initialize("/", "/var/lib/pacman")
- if err != nil {
- fmt.Fprintf(os.Stderr, "failed to initialize alpm: %v\n", err)
- os.Exit(1)
- }
- if h == nil {
- return nil, fmt.Errorf("ALPM handle is not initialized")
- }
-
- db, err := h.LocalDB()
- if err != nil {
- return nil, fmt.Errorf("failed to get local DB: %w", err)
- }
-
- res := db.Pkg(pkg)
- return res, nil
-}
-
-func (a *App) CheckPackageInstalled(packageName string) bool {
- h, err := alpm.Initialize("/", "/var/lib/pacman")
- if err != nil {
- fmt.Fprintf(os.Stderr, "failed to initialize alpm: %v\n", err)
- os.Exit(1)
- }
- if h == nil {
- log.Fatal("ALPM handle is not initialized")
- }
- localDB, err := h.LocalDB()
- if err != nil {
- log.Fatal(err)
- }
- packageHandle := localDB.Pkg(packageName)
- return packageHandle != nil
-}
-
-func (a *App) Install(pkg string) {
- cmdStr := fmt.Sprintf("pkexec yay -S %s --noconfirm", pkg)
- cmd := exec.Command("sh", "-c", cmdStr)
- fmt.Println("Executing command:", cmdStr)
-
- var outBuffer, errBuffer bytes.Buffer
- cmd.Stdout = &outBuffer
- cmd.Stderr = &errBuffer
-
- err := cmd.Run()
- if err != nil {
- fmt.Println("Error executing command:", err)
- fmt.Println("stderr:", errBuffer.String())
- return
- }
-
- fmt.Println("stdout:", outBuffer.String())
- fmt.Println("stderr:", errBuffer.String())
-}
-
-func (a *App) Uninstall(pkg string) {
- cmdStr := fmt.Sprintf("pkexec yay -Rdd %s --noconfirm", pkg)
- cmd := exec.Command("sh", "-c", cmdStr)
- fmt.Println("Executing command:", cmdStr)
-
- var outBuffer, errBuffer bytes.Buffer
- cmd.Stdout = &outBuffer
- cmd.Stderr = &errBuffer
-
- err := cmd.Run()
- if err != nil {
- fmt.Println("Error executing command:", err)
- fmt.Println("stderr:", errBuffer.String())
- return
- }
-
- fmt.Println("stdout:", outBuffer.String())
- fmt.Println("stderr:", errBuffer.String())
-}
-
-// func openTerminal(cmd string) {
-// var pkexecCmd *exec.Cmd
-
-// switch DesktopEnv {
-// case "xfce":
-// pkexecCmd = exec.Command("xfce4-terminal", "-e", cmd)
-// case "gnome":
-// pkexecCmd = exec.Command("gnome-terminal", "--", "bash", "-c", cmd)
-// case "kde":
-// pkexecCmd = exec.Command("konsole", "-e", cmd)
-// case "mate":
-// pkexecCmd = exec.Command("mate-terminal", "-e", cmd)
-// case "lxde":
-// pkexecCmd = exec.Command("lxterminal", "-e", cmd)
-// case "lxqt":
-// pkexecCmd = exec.Command("qterminal", "-e", cmd)
-// default:
-// fmt.Printf("Unsupported desktop environment: %s\n", DesktopEnv)
-// return
-// }
-
-// if err := pkexecCmd.Run(); err != nil {
-// fmt.Printf("Error executing command: %v\n", err)
-// }
-// }
-
-func getDesktopEnvironment() string {
- return strings.ToLower(os.Getenv("XDG_CURRENT_DESKTOP"))
-}
-
-func (a *App) GetMultiplePackageInfo(packageNames []string) ([]PackageInfo, error) {
- var results []PackageInfo
- var wg sync.WaitGroup
- resultChan := make(chan PackageInfo, len(packageNames))
- errorChan := make(chan error, len(packageNames))
-
- for _, pkgName := range packageNames {
- wg.Add(1)
- go func(name string) {
- defer wg.Done()
-
- // Search for package info
- searchResults := a.SearchPackage(name)
-
- var pkg PackageInfo
- for _, result := range searchResults {
- if result.Repository == "core" || result.Repository == "extra" || result.Repository == "AUR" {
- pkg = result
- pkg.Name = name // Ensure the name matches the search query
- resultChan <- pkg
- return
- }
- }
-
- // If no package was found in core, extra, or AUR, add a placeholder
- if pkg.Name == "" {
- resultChan <- PackageInfo{
- Name: name,
- Description: "Package not found in core, extra, or AUR",
- Repository: "unknown",
- }
- }
- }(pkgName)
- }
-
- // Close channels when all goroutines are done
- go func() {
- wg.Wait()
- close(resultChan)
- close(errorChan)
- }()
-
- // Collect results and errors
- for i := 0; i < len(packageNames); i++ {
- select {
- case result := <-resultChan:
- results = append(results, result)
- case err := <-errorChan:
- return nil, fmt.Errorf("error processing packages: %w", err)
- case <-a.ctx.Done():
- return nil, a.ctx.Err()
- }
- }
-
- // Sort results to maintain order of input packageNames
- sort.Slice(results, func(i, j int) bool {
- iIndex := indexOf(packageNames, results[i].Name)
- jIndex := indexOf(packageNames, results[j].Name)
- return iIndex < jIndex
- })
-
- return results, nil
-}
-
-func indexOf(slice []string, item string) int {
- for i, s := range slice {
- if s == item {
- return i
- }
- }
- return -1
-}
-
-type UpdateInfo struct {
- Name string `json:"name"`
- OldVersion string `json:"oldVersion"`
- NewVersion string `json:"newVersion"`
- Repository string `json:"repository"`
- DownloadSize int64 `json:"downloadSize"`
-}
-
-// GetAvailableUpdates returns a list of available updates for packages
-func (a *App) GetAvailableUpdates() ([]UpdateInfo, error) {
- // Initialize ALPM
- h, err := alpm.Initialize("/", "/var/lib/pacman")
- if err != nil {
- return nil, fmt.Errorf("failed to initialize alpm: %v", err)
- }
- defer h.Release()
-
- // Parse pacman configuration
- pacmanConfig, _, err := paconf.ParseFile("/etc/pacman.conf")
- if err != nil {
- return nil, fmt.Errorf("failed to parse pacman config: %v", err)
- }
-
- // Register sync databases
- for _, repo := range pacmanConfig.Repos {
- db, err := h.RegisterSyncDB(repo.Name, 0)
- if err != nil {
- return nil, fmt.Errorf("failed to register sync db %s: %v", repo.Name, err)
- }
- db.SetServers(repo.Servers)
- }
-
- // Get local database
- localDB, err := h.LocalDB()
- if err != nil {
- return nil, fmt.Errorf("failed to get local DB: %v", err)
- }
-
- // Get sync databases
- syncDBs, err := h.SyncDBs()
- if err != nil {
- return nil, fmt.Errorf("failed to get sync DBs: %v", err)
- }
-
- var updates []UpdateInfo
- var mutex sync.Mutex
- var wg sync.WaitGroup
-
- // Check for updates in official repositories
- wg.Add(1)
- go func() {
- defer wg.Done()
- for _, pkg := range localDB.PkgCache().Slice() {
- select {
- case <-a.ctx.Done():
- return
- default:
- newPkg := pkg.SyncNewVersion(syncDBs)
- if newPkg != nil {
- mutex.Lock()
- updates = append(updates, UpdateInfo{
- Name: pkg.Name(),
- OldVersion: pkg.Version(),
- NewVersion: newPkg.Version(),
- Repository: newPkg.DB().Name(),
- DownloadSize: newPkg.Size(),
- })
- mutex.Unlock()
- }
- }
- }
- }()
-
- // Check for AUR updates
- wg.Add(1)
- go func() {
- defer wg.Done()
- aurUpdates, err := a.checkAURUpdates()
- if err != nil {
- log.Printf("Error checking AUR updates: %v", err)
- return
- }
- mutex.Lock()
- updates = append(updates, aurUpdates...)
- mutex.Unlock()
- }()
-
- wg.Wait()
-
- return updates, nil
-}
-
-func (a *App) checkAURUpdates() ([]UpdateInfo, error) {
- var aurUpdates []UpdateInfo
-
- // Get list of AUR packages
- cmd := exec.CommandContext(a.ctx, "yay", "-Qm")
- output, err := cmd.Output()
- if err != nil {
- return nil, fmt.Errorf("failed to get AUR package list: %v", err)
- }
-
- aurPackages := strings.Split(strings.TrimSpace(string(output)), "\n")
-
- for _, pkg := range aurPackages {
- select {
- case <-a.ctx.Done():
- return aurUpdates, a.ctx.Err()
- default:
- parts := strings.Fields(pkg)
- if len(parts) != 2 {
- continue
- }
- name, version := parts[0], parts[1]
-
- // Check for updates using AUR RPC
- cmd := exec.CommandContext(a.ctx, "curl", "-s", fmt.Sprintf("https://aur.archlinux.org/rpc/v5/info/%s", name))
- output, err := cmd.Output()
- if err != nil {
- log.Printf("Error checking AUR for package %s: %v", name, err)
- continue
- }
-
- var aurResponse struct {
- Results []struct {
- Version string `json:"Version"`
- } `json:"results"`
- }
- err = json.Unmarshal(output, &aurResponse)
- if err != nil {
- log.Printf("Error parsing AUR response for package %s: %v", name, err)
- continue
- }
-
- if len(aurResponse.Results) > 0 && aurResponse.Results[0].Version != version {
- aurUpdates = append(aurUpdates, UpdateInfo{
- Name: name,
- OldVersion: version,
- NewVersion: aurResponse.Results[0].Version,
- Repository: "AUR",
- DownloadSize: 0,
- })
- }
- }
- }
-
- return aurUpdates, nil
-}
-
-// HumanReadableSize converts bytes to a human-readable string
-func (a *App) HumanReadableSize(size int64) string {
- floatsize := float32(size)
- units := [...]string{"", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi"}
- for _, unit := range units {
- if floatsize < 1024 {
- return fmt.Sprintf("%.1f %sB", floatsize, unit)
- }
- floatsize /= 1024
- }
- return fmt.Sprintf("%d%s", size, "B")
-}
-
-func (a *App) UpdateSinglePkg(pkg string) {
- cmdStr := fmt.Sprintf("pkexec yay -S %s --noconfirm", pkg)
- cmd := exec.Command("sh", "-c", cmdStr)
- fmt.Println("Executing command:", cmdStr)
-
- var outBuffer, errBuffer bytes.Buffer
- cmd.Stdout = &outBuffer
- cmd.Stderr = &errBuffer
-
- err := cmd.Run()
- if err != nil {
- fmt.Println("Error executing command:", err)
- fmt.Println("stderr:", errBuffer.String())
- return
- }
-
- fmt.Println("stdout:", outBuffer.String())
- fmt.Println("stderr:", errBuffer.String())
-}
-
-func (a *App) UpdateAllPkg() {
- cmdStr := "pkexec yay -Syu --noconfirm"
- cmd := exec.Command("sh", "-c", cmdStr)
- fmt.Println("Executing command:", cmdStr)
-
- var outBuffer, errBuffer bytes.Buffer
- cmd.Stdout = &outBuffer
- cmd.Stderr = &errBuffer
-
- err := cmd.Run()
- if err != nil {
- fmt.Println("Error executing command:", err)
- fmt.Println("stderr:", errBuffer.String())
- return
- }
-
- fmt.Println("stdout:", outBuffer.String())
- fmt.Println("stderr:", errBuffer.String())
-}
diff --git a/assets/alg-app-store.desktop b/assets/alg-app-store.desktop
index c7449b1..9844259 100644
--- a/assets/alg-app-store.desktop
+++ b/assets/alg-app-store.desktop
@@ -2,12 +2,12 @@
Type=Application
Version=1.0
Name=App Store
-GenericName=ALG - App Store
-Keywords=utility;system;welcome;
+GenericName=ALG App Store
+Keywords=app;store;software;install;system;
Encoding=UTF-8
Terminal=false
Exec=alg-app-store
-Icon=/usr/share/pixmaps/alg-app-store.png
-Comment=ALG - App Store
-Categories=System;Go;
+Icon=alg-app-store
+Comment=Install all your favourite apps
+Categories=System;Apps;
StartupNotify=true
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..34e8e84
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+
+# Build script for ALG App Store Qt6 version
+
+set -e
+
+echo "==================================="
+echo "ALG App Store - Qt6 Build Script"
+echo "==================================="
+echo ""
+
+# Check for required dependencies
+echo "Checking dependencies..."
+
+command -v cmake >/dev/null 2>&1 || {
+ echo "Error: cmake is not installed. Install with: sudo pacman -S cmake"
+ exit 1
+}
+
+command -v qmake6 >/dev/null 2>&1 || command -v qmake >/dev/null 2>&1 || {
+ echo "Error: Qt6 is not installed. Install with: sudo pacman -S qt6-base"
+ exit 1
+}
+
+pkg-config --exists libalpm || {
+ echo "Error: libalpm is not installed. Install with: sudo pacman -S pacman"
+ exit 1
+}
+
+echo "All dependencies found!"
+echo ""
+
+# Clean previous build
+if [ -d "build" ]; then
+ echo "Cleaning previous build..."
+ rm -rf build
+fi
+
+# Create build directory
+echo "Creating build directory..."
+mkdir -p build
+cd build
+
+# Configure with CMake
+echo ""
+echo "Configuring with CMake..."
+cmake .. -DCMAKE_BUILD_TYPE=Release
+
+# Build
+echo ""
+echo "Building..."
+make -j$(nproc)
+
+echo ""
+echo "==================================="
+echo "Build completed successfully!"
+echo "==================================="
+echo ""
+echo "To run the application:"
+echo " ./build/alg-app-store"
+echo ""
+echo "To install system-wide:"
+echo " sudo make install (from build directory)"
+echo ""
diff --git a/build/README.md b/build/README.md
deleted file mode 100644
index 1ae2f67..0000000
--- a/build/README.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# Build Directory
-
-The build directory is used to house all the build files and assets for your application.
-
-The structure is:
-
-* bin - Output directory
-* darwin - macOS specific files
-* windows - Windows specific files
-
-## Mac
-
-The `darwin` directory holds files specific to Mac builds.
-These may be customised and used as part of the build. To return these files to the default state, simply delete them
-and
-build with `wails build`.
-
-The directory contains the following files:
-
-- `Info.plist` - the main plist file used for Mac builds. It is used when building using `wails build`.
-- `Info.dev.plist` - same as the main plist file but used when building using `wails dev`.
-
-## Windows
-
-The `windows` directory contains the manifest and rc files used when building with `wails build`.
-These may be customised for your application. To return these files to the default state, simply delete them and
-build with `wails build`.
-
-- `icon.ico` - The icon used for the application. This is used when building using `wails build`. If you wish to
- use a different icon, simply replace this file with your own. If it is missing, a new `icon.ico` file
- will be created using the `appicon.png` file in the build directory.
-- `installer/*` - The files used to create the Windows installer. These are used when building using `wails build`.
-- `info.json` - Application details used for Windows builds. The data here will be used by the Windows installer,
- as well as the application itself (right click the exe -> properties -> details)
-- `wails.exe.manifest` - The main application manifest file.
\ No newline at end of file
diff --git a/build/appicon.png b/build/appicon.png
deleted file mode 100644
index 63617fe..0000000
Binary files a/build/appicon.png and /dev/null differ
diff --git a/build/darwin/Info.dev.plist b/build/darwin/Info.dev.plist
deleted file mode 100644
index 04727c2..0000000
--- a/build/darwin/Info.dev.plist
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
- CFBundlePackageType
- APPL
- CFBundleName
- {{.Info.ProductName}}
- CFBundleExecutable
- {{.Name}}
- CFBundleIdentifier
- com.wails.{{.Name}}
- CFBundleVersion
- {{.Info.ProductVersion}}
- CFBundleGetInfoString
- {{.Info.Comments}}
- CFBundleShortVersionString
- {{.Info.ProductVersion}}
- CFBundleIconFile
- iconfile
- LSMinimumSystemVersion
- 10.13.0
- NSHighResolutionCapable
- true
- NSHumanReadableCopyright
- {{.Info.Copyright}}
- {{if .Info.FileAssociations}}
- CFBundleDocumentTypes
-
- {{range .Info.FileAssociations}}
-
- CFBundleTypeExtensions
-
- {{.Ext}}
-
- CFBundleTypeName
- {{.Name}}
- CFBundleTypeRole
- {{.Role}}
- CFBundleTypeIconFile
- {{.IconName}}
-
- {{end}}
-
- {{end}}
- {{if .Info.Protocols}}
- CFBundleURLTypes
-
- {{range .Info.Protocols}}
-
- CFBundleURLName
- com.wails.{{.Scheme}}
- CFBundleURLSchemes
-
- {{.Scheme}}
-
- CFBundleTypeRole
- {{.Role}}
-
- {{end}}
-
- {{end}}
- NSAppTransportSecurity
-
- NSAllowsLocalNetworking
-
-
-
-
diff --git a/build/darwin/Info.plist b/build/darwin/Info.plist
deleted file mode 100644
index 19cc937..0000000
--- a/build/darwin/Info.plist
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
- CFBundlePackageType
- APPL
- CFBundleName
- {{.Info.ProductName}}
- CFBundleExecutable
- {{.Name}}
- CFBundleIdentifier
- com.wails.{{.Name}}
- CFBundleVersion
- {{.Info.ProductVersion}}
- CFBundleGetInfoString
- {{.Info.Comments}}
- CFBundleShortVersionString
- {{.Info.ProductVersion}}
- CFBundleIconFile
- iconfile
- LSMinimumSystemVersion
- 10.13.0
- NSHighResolutionCapable
- true
- NSHumanReadableCopyright
- {{.Info.Copyright}}
- {{if .Info.FileAssociations}}
- CFBundleDocumentTypes
-
- {{range .Info.FileAssociations}}
-
- CFBundleTypeExtensions
-
- {{.Ext}}
-
- CFBundleTypeName
- {{.Name}}
- CFBundleTypeRole
- {{.Role}}
- CFBundleTypeIconFile
- {{.IconName}}
-
- {{end}}
-
- {{end}}
- {{if .Info.Protocols}}
- CFBundleURLTypes
-
- {{range .Info.Protocols}}
-
- CFBundleURLName
- com.wails.{{.Scheme}}
- CFBundleURLSchemes
-
- {{.Scheme}}
-
- CFBundleTypeRole
- {{.Role}}
-
- {{end}}
-
- {{end}}
-
-
diff --git a/build/windows/icon.ico b/build/windows/icon.ico
deleted file mode 100644
index f334798..0000000
Binary files a/build/windows/icon.ico and /dev/null differ
diff --git a/build/windows/info.json b/build/windows/info.json
deleted file mode 100644
index 9727946..0000000
--- a/build/windows/info.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "fixed": {
- "file_version": "{{.Info.ProductVersion}}"
- },
- "info": {
- "0000": {
- "ProductVersion": "{{.Info.ProductVersion}}",
- "CompanyName": "{{.Info.CompanyName}}",
- "FileDescription": "{{.Info.ProductName}}",
- "LegalCopyright": "{{.Info.Copyright}}",
- "ProductName": "{{.Info.ProductName}}",
- "Comments": "{{.Info.Comments}}"
- }
- }
-}
\ No newline at end of file
diff --git a/build/windows/installer/project.nsi b/build/windows/installer/project.nsi
deleted file mode 100644
index 654ae2e..0000000
--- a/build/windows/installer/project.nsi
+++ /dev/null
@@ -1,114 +0,0 @@
-Unicode true
-
-####
-## Please note: Template replacements don't work in this file. They are provided with default defines like
-## mentioned underneath.
-## If the keyword is not defined, "wails_tools.nsh" will populate them with the values from ProjectInfo.
-## If they are defined here, "wails_tools.nsh" will not touch them. This allows to use this project.nsi manually
-## from outside of Wails for debugging and development of the installer.
-##
-## For development first make a wails nsis build to populate the "wails_tools.nsh":
-## > wails build --target windows/amd64 --nsis
-## Then you can call makensis on this file with specifying the path to your binary:
-## For a AMD64 only installer:
-## > makensis -DARG_WAILS_AMD64_BINARY=..\..\bin\app.exe
-## For a ARM64 only installer:
-## > makensis -DARG_WAILS_ARM64_BINARY=..\..\bin\app.exe
-## For a installer with both architectures:
-## > makensis -DARG_WAILS_AMD64_BINARY=..\..\bin\app-amd64.exe -DARG_WAILS_ARM64_BINARY=..\..\bin\app-arm64.exe
-####
-## The following information is taken from the ProjectInfo file, but they can be overwritten here.
-####
-## !define INFO_PROJECTNAME "MyProject" # Default "{{.Name}}"
-## !define INFO_COMPANYNAME "MyCompany" # Default "{{.Info.CompanyName}}"
-## !define INFO_PRODUCTNAME "MyProduct" # Default "{{.Info.ProductName}}"
-## !define INFO_PRODUCTVERSION "1.0.0" # Default "{{.Info.ProductVersion}}"
-## !define INFO_COPYRIGHT "Copyright" # Default "{{.Info.Copyright}}"
-###
-## !define PRODUCT_EXECUTABLE "Application.exe" # Default "${INFO_PROJECTNAME}.exe"
-## !define UNINST_KEY_NAME "UninstKeyInRegistry" # Default "${INFO_COMPANYNAME}${INFO_PRODUCTNAME}"
-####
-## !define REQUEST_EXECUTION_LEVEL "admin" # Default "admin" see also https://nsis.sourceforge.io/Docs/Chapter4.html
-####
-## Include the wails tools
-####
-!include "wails_tools.nsh"
-
-# The version information for this two must consist of 4 parts
-VIProductVersion "${INFO_PRODUCTVERSION}.0"
-VIFileVersion "${INFO_PRODUCTVERSION}.0"
-
-VIAddVersionKey "CompanyName" "${INFO_COMPANYNAME}"
-VIAddVersionKey "FileDescription" "${INFO_PRODUCTNAME} Installer"
-VIAddVersionKey "ProductVersion" "${INFO_PRODUCTVERSION}"
-VIAddVersionKey "FileVersion" "${INFO_PRODUCTVERSION}"
-VIAddVersionKey "LegalCopyright" "${INFO_COPYRIGHT}"
-VIAddVersionKey "ProductName" "${INFO_PRODUCTNAME}"
-
-# Enable HiDPI support. https://nsis.sourceforge.io/Reference/ManifestDPIAware
-ManifestDPIAware true
-
-!include "MUI.nsh"
-
-!define MUI_ICON "..\icon.ico"
-!define MUI_UNICON "..\icon.ico"
-# !define MUI_WELCOMEFINISHPAGE_BITMAP "resources\leftimage.bmp" #Include this to add a bitmap on the left side of the Welcome Page. Must be a size of 164x314
-!define MUI_FINISHPAGE_NOAUTOCLOSE # Wait on the INSTFILES page so the user can take a look into the details of the installation steps
-!define MUI_ABORTWARNING # This will warn the user if they exit from the installer.
-
-!insertmacro MUI_PAGE_WELCOME # Welcome to the installer page.
-# !insertmacro MUI_PAGE_LICENSE "resources\eula.txt" # Adds a EULA page to the installer
-!insertmacro MUI_PAGE_DIRECTORY # In which folder install page.
-!insertmacro MUI_PAGE_INSTFILES # Installing page.
-!insertmacro MUI_PAGE_FINISH # Finished installation page.
-
-!insertmacro MUI_UNPAGE_INSTFILES # Uinstalling page
-
-!insertmacro MUI_LANGUAGE "English" # Set the Language of the installer
-
-## The following two statements can be used to sign the installer and the uninstaller. The path to the binaries are provided in %1
-#!uninstfinalize 'signtool --file "%1"'
-#!finalize 'signtool --file "%1"'
-
-Name "${INFO_PRODUCTNAME}"
-OutFile "..\..\bin\${INFO_PROJECTNAME}-${ARCH}-installer.exe" # Name of the installer's file.
-InstallDir "$PROGRAMFILES64\${INFO_COMPANYNAME}\${INFO_PRODUCTNAME}" # Default installing folder ($PROGRAMFILES is Program Files folder).
-ShowInstDetails show # This will always show the installation details.
-
-Function .onInit
- !insertmacro wails.checkArchitecture
-FunctionEnd
-
-Section
- !insertmacro wails.setShellContext
-
- !insertmacro wails.webview2runtime
-
- SetOutPath $INSTDIR
-
- !insertmacro wails.files
-
- CreateShortcut "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}"
- CreateShortCut "$DESKTOP\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}"
-
- !insertmacro wails.associateFiles
- !insertmacro wails.associateCustomProtocols
-
- !insertmacro wails.writeUninstaller
-SectionEnd
-
-Section "uninstall"
- !insertmacro wails.setShellContext
-
- RMDir /r "$AppData\${PRODUCT_EXECUTABLE}" # Remove the WebView2 DataPath
-
- RMDir /r $INSTDIR
-
- Delete "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk"
- Delete "$DESKTOP\${INFO_PRODUCTNAME}.lnk"
-
- !insertmacro wails.unassociateFiles
- !insertmacro wails.unassociateCustomProtocols
-
- !insertmacro wails.deleteUninstaller
-SectionEnd
diff --git a/build/windows/installer/wails_tools.nsh b/build/windows/installer/wails_tools.nsh
deleted file mode 100644
index f9c0f88..0000000
--- a/build/windows/installer/wails_tools.nsh
+++ /dev/null
@@ -1,249 +0,0 @@
-# DO NOT EDIT - Generated automatically by `wails build`
-
-!include "x64.nsh"
-!include "WinVer.nsh"
-!include "FileFunc.nsh"
-
-!ifndef INFO_PROJECTNAME
- !define INFO_PROJECTNAME "{{.Name}}"
-!endif
-!ifndef INFO_COMPANYNAME
- !define INFO_COMPANYNAME "{{.Info.CompanyName}}"
-!endif
-!ifndef INFO_PRODUCTNAME
- !define INFO_PRODUCTNAME "{{.Info.ProductName}}"
-!endif
-!ifndef INFO_PRODUCTVERSION
- !define INFO_PRODUCTVERSION "{{.Info.ProductVersion}}"
-!endif
-!ifndef INFO_COPYRIGHT
- !define INFO_COPYRIGHT "{{.Info.Copyright}}"
-!endif
-!ifndef PRODUCT_EXECUTABLE
- !define PRODUCT_EXECUTABLE "${INFO_PROJECTNAME}.exe"
-!endif
-!ifndef UNINST_KEY_NAME
- !define UNINST_KEY_NAME "${INFO_COMPANYNAME}${INFO_PRODUCTNAME}"
-!endif
-!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINST_KEY_NAME}"
-
-!ifndef REQUEST_EXECUTION_LEVEL
- !define REQUEST_EXECUTION_LEVEL "admin"
-!endif
-
-RequestExecutionLevel "${REQUEST_EXECUTION_LEVEL}"
-
-!ifdef ARG_WAILS_AMD64_BINARY
- !define SUPPORTS_AMD64
-!endif
-
-!ifdef ARG_WAILS_ARM64_BINARY
- !define SUPPORTS_ARM64
-!endif
-
-!ifdef SUPPORTS_AMD64
- !ifdef SUPPORTS_ARM64
- !define ARCH "amd64_arm64"
- !else
- !define ARCH "amd64"
- !endif
-!else
- !ifdef SUPPORTS_ARM64
- !define ARCH "arm64"
- !else
- !error "Wails: Undefined ARCH, please provide at least one of ARG_WAILS_AMD64_BINARY or ARG_WAILS_ARM64_BINARY"
- !endif
-!endif
-
-!macro wails.checkArchitecture
- !ifndef WAILS_WIN10_REQUIRED
- !define WAILS_WIN10_REQUIRED "This product is only supported on Windows 10 (Server 2016) and later."
- !endif
-
- !ifndef WAILS_ARCHITECTURE_NOT_SUPPORTED
- !define WAILS_ARCHITECTURE_NOT_SUPPORTED "This product can't be installed on the current Windows architecture. Supports: ${ARCH}"
- !endif
-
- ${If} ${AtLeastWin10}
- !ifdef SUPPORTS_AMD64
- ${if} ${IsNativeAMD64}
- Goto ok
- ${EndIf}
- !endif
-
- !ifdef SUPPORTS_ARM64
- ${if} ${IsNativeARM64}
- Goto ok
- ${EndIf}
- !endif
-
- IfSilent silentArch notSilentArch
- silentArch:
- SetErrorLevel 65
- Abort
- notSilentArch:
- MessageBox MB_OK "${WAILS_ARCHITECTURE_NOT_SUPPORTED}"
- Quit
- ${else}
- IfSilent silentWin notSilentWin
- silentWin:
- SetErrorLevel 64
- Abort
- notSilentWin:
- MessageBox MB_OK "${WAILS_WIN10_REQUIRED}"
- Quit
- ${EndIf}
-
- ok:
-!macroend
-
-!macro wails.files
- !ifdef SUPPORTS_AMD64
- ${if} ${IsNativeAMD64}
- File "/oname=${PRODUCT_EXECUTABLE}" "${ARG_WAILS_AMD64_BINARY}"
- ${EndIf}
- !endif
-
- !ifdef SUPPORTS_ARM64
- ${if} ${IsNativeARM64}
- File "/oname=${PRODUCT_EXECUTABLE}" "${ARG_WAILS_ARM64_BINARY}"
- ${EndIf}
- !endif
-!macroend
-
-!macro wails.writeUninstaller
- WriteUninstaller "$INSTDIR\uninstall.exe"
-
- SetRegView 64
- WriteRegStr HKLM "${UNINST_KEY}" "Publisher" "${INFO_COMPANYNAME}"
- WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "${INFO_PRODUCTNAME}"
- WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${INFO_PRODUCTVERSION}"
- WriteRegStr HKLM "${UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PRODUCT_EXECUTABLE}"
- WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
- WriteRegStr HKLM "${UNINST_KEY}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S"
-
- ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
- IntFmt $0 "0x%08X" $0
- WriteRegDWORD HKLM "${UNINST_KEY}" "EstimatedSize" "$0"
-!macroend
-
-!macro wails.deleteUninstaller
- Delete "$INSTDIR\uninstall.exe"
-
- SetRegView 64
- DeleteRegKey HKLM "${UNINST_KEY}"
-!macroend
-
-!macro wails.setShellContext
- ${If} ${REQUEST_EXECUTION_LEVEL} == "admin"
- SetShellVarContext all
- ${else}
- SetShellVarContext current
- ${EndIf}
-!macroend
-
-# Install webview2 by launching the bootstrapper
-# See https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#online-only-deployment
-!macro wails.webview2runtime
- !ifndef WAILS_INSTALL_WEBVIEW_DETAILPRINT
- !define WAILS_INSTALL_WEBVIEW_DETAILPRINT "Installing: WebView2 Runtime"
- !endif
-
- SetRegView 64
- # If the admin key exists and is not empty then webview2 is already installed
- ReadRegStr $0 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"
- ${If} $0 != ""
- Goto ok
- ${EndIf}
-
- ${If} ${REQUEST_EXECUTION_LEVEL} == "user"
- # If the installer is run in user level, check the user specific key exists and is not empty then webview2 is already installed
- ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"
- ${If} $0 != ""
- Goto ok
- ${EndIf}
- ${EndIf}
-
- SetDetailsPrint both
- DetailPrint "${WAILS_INSTALL_WEBVIEW_DETAILPRINT}"
- SetDetailsPrint listonly
-
- InitPluginsDir
- CreateDirectory "$pluginsdir\webview2bootstrapper"
- SetOutPath "$pluginsdir\webview2bootstrapper"
- File "tmp\MicrosoftEdgeWebview2Setup.exe"
- ExecWait '"$pluginsdir\webview2bootstrapper\MicrosoftEdgeWebview2Setup.exe" /silent /install'
-
- SetDetailsPrint both
- ok:
-!macroend
-
-# Copy of APP_ASSOCIATE and APP_UNASSOCIATE macros from here https://gist.github.com/nikku/281d0ef126dbc215dd58bfd5b3a5cd5b
-!macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND
- ; Backup the previously associated file class
- ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" ""
- WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "${FILECLASS}_backup" "$R0"
-
- WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "${FILECLASS}"
-
- WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}" "" `${DESCRIPTION}`
- WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\DefaultIcon" "" `${ICON}`
- WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell" "" "open"
- WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open" "" `${COMMANDTEXT}`
- WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open\command" "" `${COMMAND}`
-!macroend
-
-!macro APP_UNASSOCIATE EXT FILECLASS
- ; Backup the previously associated file class
- ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" `${FILECLASS}_backup`
- WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "$R0"
-
- DeleteRegKey SHELL_CONTEXT `Software\Classes\${FILECLASS}`
-!macroend
-
-!macro wails.associateFiles
- ; Create file associations
- {{range .Info.FileAssociations}}
- !insertmacro APP_ASSOCIATE "{{.Ext}}" "{{.Name}}" "{{.Description}}" "$INSTDIR\{{.IconName}}.ico" "Open with ${INFO_PRODUCTNAME}" "$INSTDIR\${PRODUCT_EXECUTABLE} $\"%1$\""
-
- File "..\{{.IconName}}.ico"
- {{end}}
-!macroend
-
-!macro wails.unassociateFiles
- ; Delete app associations
- {{range .Info.FileAssociations}}
- !insertmacro APP_UNASSOCIATE "{{.Ext}}" "{{.Name}}"
-
- Delete "$INSTDIR\{{.IconName}}.ico"
- {{end}}
-!macroend
-
-!macro CUSTOM_PROTOCOL_ASSOCIATE PROTOCOL DESCRIPTION ICON COMMAND
- DeleteRegKey SHELL_CONTEXT "Software\Classes\${PROTOCOL}"
- WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}" "" "${DESCRIPTION}"
- WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}" "URL Protocol" ""
- WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}\DefaultIcon" "" "${ICON}"
- WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}\shell" "" ""
- WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}\shell\open" "" ""
- WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}\shell\open\command" "" "${COMMAND}"
-!macroend
-
-!macro CUSTOM_PROTOCOL_UNASSOCIATE PROTOCOL
- DeleteRegKey SHELL_CONTEXT "Software\Classes\${PROTOCOL}"
-!macroend
-
-!macro wails.associateCustomProtocols
- ; Create custom protocols associations
- {{range .Info.Protocols}}
- !insertmacro CUSTOM_PROTOCOL_ASSOCIATE "{{.Scheme}}" "{{.Description}}" "$INSTDIR\${PRODUCT_EXECUTABLE},0" "$INSTDIR\${PRODUCT_EXECUTABLE} $\"%1$\""
-
- {{end}}
-!macroend
-
-!macro wails.unassociateCustomProtocols
- ; Delete app custom protocol associations
- {{range .Info.Protocols}}
- !insertmacro CUSTOM_PROTOCOL_UNASSOCIATE "{{.Scheme}}"
- {{end}}
-!macroend
diff --git a/build/windows/wails.exe.manifest b/build/windows/wails.exe.manifest
deleted file mode 100644
index 17e1a23..0000000
--- a/build/windows/wails.exe.manifest
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- true/pm
- permonitorv2,permonitor
-
-
-
\ No newline at end of file
diff --git a/frontend/.gitignore b/frontend/.gitignore
deleted file mode 100644
index ae34bd3..0000000
--- a/frontend/.gitignore
+++ /dev/null
@@ -1,36 +0,0 @@
-# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
-
-# dependencies
-/node_modules
-/.pnp
-.pnp.js
-
-# testing
-/coverage
-
-# next.js
-/.next/
-
-
-# production
-/build
-/dist
-
-# misc
-.DS_Store
-*.pem
-
-# debug
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-.pnpm-debug.log*
-
-# local env files
-.env*.local
-
-# vercel
-.vercel
-
-# typescript
-*.tsbuildinfo
\ No newline at end of file
diff --git a/frontend/components.json b/frontend/components.json
deleted file mode 100644
index 7c79d38..0000000
--- a/frontend/components.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "$schema": "https://ui.shadcn.com/schema.json",
- "style": "new-york",
- "rsc": false,
- "tsx": true,
- "tailwind": {
- "config": "tailwind.config.js",
- "css": "src/globals.css",
- "baseColor": "slate",
- "cssVariables": true
- },
- "aliases": {
- "components": "@/components",
- "utils": "@/lib/utils"
- }
-}
diff --git a/frontend/index.html b/frontend/index.html
deleted file mode 100644
index edbc62d..0000000
--- a/frontend/index.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
- myproject
-
-
-
-
-
-
-
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
deleted file mode 100644
index 2293397..0000000
--- a/frontend/package-lock.json
+++ /dev/null
@@ -1,4574 +0,0 @@
-{
- "name": "frontend",
- "version": "0.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "frontend",
- "version": "0.0.0",
- "dependencies": {
- "@radix-ui/react-checkbox": "^1.1.4",
- "@radix-ui/react-dropdown-menu": "^2.1.6",
- "@radix-ui/react-icons": "^1.3.2",
- "@radix-ui/react-label": "^2.1.0",
- "@radix-ui/react-progress": "^1.1.0",
- "@radix-ui/react-scroll-area": "^1.1.0",
- "@radix-ui/react-separator": "^1.1.0",
- "@radix-ui/react-slot": "^1.0.2",
- "@radix-ui/react-tabs": "^1.1.0",
- "@radix-ui/react-toast": "^1.2.1",
- "@radix-ui/react-tooltip": "^1.1.2",
- "@types/react-window": "^1.8.8",
- "class-variance-authority": "^0.7.0",
- "clsx": "^2.0.0",
- "lucide-react": "^0.290.0",
- "react": "^18.2.0",
- "react-dom": "^18.2.0",
- "react-virtualized-auto-sizer": "^1.0.24",
- "react-window": "^1.8.10",
- "tailwind-merge": "^1.14.0",
- "tailwindcss-animate": "^1.0.7"
- },
- "devDependencies": {
- "@types/node": "^20.8.9",
- "@types/react": "^18.0.17",
- "@types/react-dom": "^18.0.6",
- "@vitejs/plugin-react": "^2.0.1",
- "autoprefixer": "^10.4.16",
- "postcss": "^8.4.31",
- "tailwindcss": "^3.3.5",
- "typescript": "^4.6.4",
- "vite": "^3.0.7"
- }
- },
- "node_modules/@alloc/quick-lru": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
- "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@ampproject/remapping": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
- "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/code-frame": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
- "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/highlight": "^7.24.7",
- "picocolors": "^1.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/compat-data": {
- "version": "7.24.9",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz",
- "integrity": "sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/core": {
- "version": "7.24.9",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz",
- "integrity": "sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.24.7",
- "@babel/generator": "^7.24.9",
- "@babel/helper-compilation-targets": "^7.24.8",
- "@babel/helper-module-transforms": "^7.24.9",
- "@babel/helpers": "^7.24.8",
- "@babel/parser": "^7.24.8",
- "@babel/template": "^7.24.7",
- "@babel/traverse": "^7.24.8",
- "@babel/types": "^7.24.9",
- "convert-source-map": "^2.0.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.3",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/babel"
- }
- },
- "node_modules/@babel/generator": {
- "version": "7.24.10",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz",
- "integrity": "sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.24.9",
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.25",
- "jsesc": "^2.5.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-annotate-as-pure": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz",
- "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz",
- "integrity": "sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/compat-data": "^7.24.8",
- "@babel/helper-validator-option": "^7.24.8",
- "browserslist": "^4.23.1",
- "lru-cache": "^5.1.1",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-environment-visitor": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz",
- "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-function-name": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz",
- "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/template": "^7.24.7",
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-hoist-variables": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz",
- "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-imports": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
- "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-transforms": {
- "version": "7.24.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz",
- "integrity": "sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-environment-visitor": "^7.24.7",
- "@babel/helper-module-imports": "^7.24.7",
- "@babel/helper-simple-access": "^7.24.7",
- "@babel/helper-split-export-declaration": "^7.24.7",
- "@babel/helper-validator-identifier": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-plugin-utils": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz",
- "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-simple-access": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
- "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-split-export-declaration": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz",
- "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
- "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
- "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-option": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz",
- "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helpers": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz",
- "integrity": "sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/template": "^7.24.7",
- "@babel/types": "^7.24.8"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/highlight": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
- "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.24.7",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz",
- "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/plugin-syntax-jsx": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz",
- "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.24.7.tgz",
- "integrity": "sha512-+Dj06GDZEFRYvclU6k4bme55GKBEWUmByM/eoKuqg4zTNQHiApWRhQph5fxQB2wAEFvRzL1tOEj1RJ19wJrhoA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.24.7",
- "@babel/helper-module-imports": "^7.24.7",
- "@babel/helper-plugin-utils": "^7.24.7",
- "@babel/plugin-syntax-jsx": "^7.24.7",
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-development": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz",
- "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/plugin-transform-react-jsx": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-self": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz",
- "integrity": "sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-source": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz",
- "integrity": "sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/runtime": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz",
- "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==",
- "license": "MIT",
- "dependencies": {
- "regenerator-runtime": "^0.14.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/template": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz",
- "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.24.7",
- "@babel/parser": "^7.24.7",
- "@babel/types": "^7.24.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz",
- "integrity": "sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.24.7",
- "@babel/generator": "^7.24.8",
- "@babel/helper-environment-visitor": "^7.24.7",
- "@babel/helper-function-name": "^7.24.7",
- "@babel/helper-hoist-variables": "^7.24.7",
- "@babel/helper-split-export-declaration": "^7.24.7",
- "@babel/parser": "^7.24.8",
- "@babel/types": "^7.24.8",
- "debug": "^4.3.1",
- "globals": "^11.1.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.24.9",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz",
- "integrity": "sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/helper-string-parser": "^7.24.8",
- "@babel/helper-validator-identifier": "^7.24.7",
- "to-fast-properties": "^2.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@esbuild/android-arm": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.18.tgz",
- "integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz",
- "integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@floating-ui/core": {
- "version": "1.6.5",
- "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz",
- "integrity": "sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/utils": "^0.2.5"
- }
- },
- "node_modules/@floating-ui/dom": {
- "version": "1.6.8",
- "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz",
- "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/core": "^1.6.0",
- "@floating-ui/utils": "^0.2.5"
- }
- },
- "node_modules/@floating-ui/react-dom": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz",
- "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/dom": "^1.0.0"
- },
- "peerDependencies": {
- "react": ">=16.8.0",
- "react-dom": ">=16.8.0"
- }
- },
- "node_modules/@floating-ui/utils": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz",
- "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==",
- "license": "MIT"
- },
- "node_modules/@isaacs/cliui": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
- "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "string-width": "^5.1.2",
- "string-width-cjs": "npm:string-width@^4.2.0",
- "strip-ansi": "^7.0.1",
- "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
- "wrap-ansi": "^8.1.0",
- "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
- "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/set-array": "^1.2.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.24"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/set-array": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
- "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
- "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.25",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
- "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@pkgjs/parseargs": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
- "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/@radix-ui/number": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.0.tgz",
- "integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==",
- "license": "MIT"
- },
- "node_modules/@radix-ui/primitive": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
- "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==",
- "license": "MIT"
- },
- "node_modules/@radix-ui/react-arrow": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz",
- "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-primitive": "2.0.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-checkbox": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.4.tgz",
- "integrity": "sha512-wP0CPAHq+P5I4INKe3hJrIa1WoNqqrejzW+zoU0rOvo1b9gDEJJFl2rYfO1PYJUQCc2H1WZxIJmyv9BS8i5fLw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.1",
- "@radix-ui/react-compose-refs": "1.1.1",
- "@radix-ui/react-context": "1.1.1",
- "@radix-ui/react-presence": "1.1.2",
- "@radix-ui/react-primitive": "2.0.2",
- "@radix-ui/react-use-controllable-state": "1.1.0",
- "@radix-ui/react-use-previous": "1.1.0",
- "@radix-ui/react-use-size": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/primitive": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
- "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==",
- "license": "MIT"
- },
- "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-compose-refs": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz",
- "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-context": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
- "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-presence": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz",
- "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.1",
- "@radix-ui/react-use-layout-effect": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-primitive": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.2.tgz",
- "integrity": "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-slot": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-slot": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.2.tgz",
- "integrity": "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-collection": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz",
- "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.0",
- "@radix-ui/react-context": "1.1.0",
- "@radix-ui/react-primitive": "2.0.0",
- "@radix-ui/react-slot": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-compose-refs": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
- "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-context": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
- "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-direction": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz",
- "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-dismissable-layer": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz",
- "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.0",
- "@radix-ui/react-compose-refs": "1.1.0",
- "@radix-ui/react-primitive": "2.0.0",
- "@radix-ui/react-use-callback-ref": "1.1.0",
- "@radix-ui/react-use-escape-keydown": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-dropdown-menu": {
- "version": "2.1.6",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.6.tgz",
- "integrity": "sha512-no3X7V5fD487wab/ZYSHXq3H37u4NVeLDKI/Ks724X/eEFSSEFYZxWgsIlr1UBeEyDaM29HM5x9p1Nv8DuTYPA==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.1",
- "@radix-ui/react-compose-refs": "1.1.1",
- "@radix-ui/react-context": "1.1.1",
- "@radix-ui/react-id": "1.1.0",
- "@radix-ui/react-menu": "2.1.6",
- "@radix-ui/react-primitive": "2.0.2",
- "@radix-ui/react-use-controllable-state": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/primitive": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
- "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==",
- "license": "MIT"
- },
- "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-compose-refs": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz",
- "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-context": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
- "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-primitive": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.2.tgz",
- "integrity": "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-slot": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-slot": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.2.tgz",
- "integrity": "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-focus-guards": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz",
- "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-focus-scope": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.2.tgz",
- "integrity": "sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.1",
- "@radix-ui/react-primitive": "2.0.2",
- "@radix-ui/react-use-callback-ref": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-focus-scope/node_modules/@radix-ui/react-compose-refs": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz",
- "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-focus-scope/node_modules/@radix-ui/react-primitive": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.2.tgz",
- "integrity": "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-slot": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-focus-scope/node_modules/@radix-ui/react-slot": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.2.tgz",
- "integrity": "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-icons": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.2.tgz",
- "integrity": "sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==",
- "license": "MIT",
- "peerDependencies": {
- "react": "^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc"
- }
- },
- "node_modules/@radix-ui/react-id": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
- "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-use-layout-effect": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-label": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.0.tgz",
- "integrity": "sha512-peLblDlFw/ngk3UWq0VnYaOLy6agTZZ+MUO/WhVfm14vJGML+xH4FAl2XQGLqdefjNb7ApRg6Yn7U42ZhmYXdw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-primitive": "2.0.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-menu": {
- "version": "2.1.6",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.6.tgz",
- "integrity": "sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.1",
- "@radix-ui/react-collection": "1.1.2",
- "@radix-ui/react-compose-refs": "1.1.1",
- "@radix-ui/react-context": "1.1.1",
- "@radix-ui/react-direction": "1.1.0",
- "@radix-ui/react-dismissable-layer": "1.1.5",
- "@radix-ui/react-focus-guards": "1.1.1",
- "@radix-ui/react-focus-scope": "1.1.2",
- "@radix-ui/react-id": "1.1.0",
- "@radix-ui/react-popper": "1.2.2",
- "@radix-ui/react-portal": "1.1.4",
- "@radix-ui/react-presence": "1.1.2",
- "@radix-ui/react-primitive": "2.0.2",
- "@radix-ui/react-roving-focus": "1.1.2",
- "@radix-ui/react-slot": "1.1.2",
- "@radix-ui/react-use-callback-ref": "1.1.0",
- "aria-hidden": "^1.2.4",
- "react-remove-scroll": "^2.6.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/primitive": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
- "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==",
- "license": "MIT"
- },
- "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-arrow": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.2.tgz",
- "integrity": "sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-primitive": "2.0.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-collection": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.2.tgz",
- "integrity": "sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.1",
- "@radix-ui/react-context": "1.1.1",
- "@radix-ui/react-primitive": "2.0.2",
- "@radix-ui/react-slot": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-compose-refs": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz",
- "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-context": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
- "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-dismissable-layer": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.5.tgz",
- "integrity": "sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.1",
- "@radix-ui/react-compose-refs": "1.1.1",
- "@radix-ui/react-primitive": "2.0.2",
- "@radix-ui/react-use-callback-ref": "1.1.0",
- "@radix-ui/react-use-escape-keydown": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-popper": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.2.tgz",
- "integrity": "sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/react-dom": "^2.0.0",
- "@radix-ui/react-arrow": "1.1.2",
- "@radix-ui/react-compose-refs": "1.1.1",
- "@radix-ui/react-context": "1.1.1",
- "@radix-ui/react-primitive": "2.0.2",
- "@radix-ui/react-use-callback-ref": "1.1.0",
- "@radix-ui/react-use-layout-effect": "1.1.0",
- "@radix-ui/react-use-rect": "1.1.0",
- "@radix-ui/react-use-size": "1.1.0",
- "@radix-ui/rect": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-portal": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.4.tgz",
- "integrity": "sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-primitive": "2.0.2",
- "@radix-ui/react-use-layout-effect": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-presence": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz",
- "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.1",
- "@radix-ui/react-use-layout-effect": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-primitive": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.2.tgz",
- "integrity": "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-slot": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-roving-focus": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.2.tgz",
- "integrity": "sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.1",
- "@radix-ui/react-collection": "1.1.2",
- "@radix-ui/react-compose-refs": "1.1.1",
- "@radix-ui/react-context": "1.1.1",
- "@radix-ui/react-direction": "1.1.0",
- "@radix-ui/react-id": "1.1.0",
- "@radix-ui/react-primitive": "2.0.2",
- "@radix-ui/react-use-callback-ref": "1.1.0",
- "@radix-ui/react-use-controllable-state": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-slot": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.2.tgz",
- "integrity": "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.1"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-popper": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
- "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/react-dom": "^2.0.0",
- "@radix-ui/react-arrow": "1.1.0",
- "@radix-ui/react-compose-refs": "1.1.0",
- "@radix-ui/react-context": "1.1.0",
- "@radix-ui/react-primitive": "2.0.0",
- "@radix-ui/react-use-callback-ref": "1.1.0",
- "@radix-ui/react-use-layout-effect": "1.1.0",
- "@radix-ui/react-use-rect": "1.1.0",
- "@radix-ui/react-use-size": "1.1.0",
- "@radix-ui/rect": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-portal": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz",
- "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-primitive": "2.0.0",
- "@radix-ui/react-use-layout-effect": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-presence": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz",
- "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.0",
- "@radix-ui/react-use-layout-effect": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-primitive": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
- "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-slot": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-progress": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.0.tgz",
- "integrity": "sha512-aSzvnYpP725CROcxAOEBVZZSIQVQdHgBr2QQFKySsaD14u8dNT0batuXI+AAGDdAHfXH8rbnHmjYFqVJ21KkRg==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-context": "1.1.0",
- "@radix-ui/react-primitive": "2.0.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-roving-focus": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz",
- "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.0",
- "@radix-ui/react-collection": "1.1.0",
- "@radix-ui/react-compose-refs": "1.1.0",
- "@radix-ui/react-context": "1.1.0",
- "@radix-ui/react-direction": "1.1.0",
- "@radix-ui/react-id": "1.1.0",
- "@radix-ui/react-primitive": "2.0.0",
- "@radix-ui/react-use-callback-ref": "1.1.0",
- "@radix-ui/react-use-controllable-state": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-scroll-area": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.1.0.tgz",
- "integrity": "sha512-9ArIZ9HWhsrfqS765h+GZuLoxaRHD/j0ZWOWilsCvYTpYJp8XwCqNG7Dt9Nu/TItKOdgLGkOPCodQvDc+UMwYg==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/number": "1.1.0",
- "@radix-ui/primitive": "1.1.0",
- "@radix-ui/react-compose-refs": "1.1.0",
- "@radix-ui/react-context": "1.1.0",
- "@radix-ui/react-direction": "1.1.0",
- "@radix-ui/react-presence": "1.1.0",
- "@radix-ui/react-primitive": "2.0.0",
- "@radix-ui/react-use-callback-ref": "1.1.0",
- "@radix-ui/react-use-layout-effect": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-separator": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.0.tgz",
- "integrity": "sha512-3uBAs+egzvJBDZAzvb/n4NxxOYpnspmWxO2u5NbZ8Y6FM/NdrGSF9bop3Cf6F6C71z1rTSn8KV0Fo2ZVd79lGA==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-primitive": "2.0.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-slot": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
- "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-tabs": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.0.tgz",
- "integrity": "sha512-bZgOKB/LtZIij75FSuPzyEti/XBhJH52ExgtdVqjCIh+Nx/FW+LhnbXtbCzIi34ccyMsyOja8T0thCzoHFXNKA==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.0",
- "@radix-ui/react-context": "1.1.0",
- "@radix-ui/react-direction": "1.1.0",
- "@radix-ui/react-id": "1.1.0",
- "@radix-ui/react-presence": "1.1.0",
- "@radix-ui/react-primitive": "2.0.0",
- "@radix-ui/react-roving-focus": "1.1.0",
- "@radix-ui/react-use-controllable-state": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-toast": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.1.tgz",
- "integrity": "sha512-5trl7piMXcZiCq7MW6r8YYmu0bK5qDpTWz+FdEPdKyft2UixkspheYbjbrLXVN5NGKHFbOP7lm8eD0biiSqZqg==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.0",
- "@radix-ui/react-collection": "1.1.0",
- "@radix-ui/react-compose-refs": "1.1.0",
- "@radix-ui/react-context": "1.1.0",
- "@radix-ui/react-dismissable-layer": "1.1.0",
- "@radix-ui/react-portal": "1.1.1",
- "@radix-ui/react-presence": "1.1.0",
- "@radix-ui/react-primitive": "2.0.0",
- "@radix-ui/react-use-callback-ref": "1.1.0",
- "@radix-ui/react-use-controllable-state": "1.1.0",
- "@radix-ui/react-use-layout-effect": "1.1.0",
- "@radix-ui/react-visually-hidden": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-tooltip": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.2.tgz",
- "integrity": "sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.0",
- "@radix-ui/react-compose-refs": "1.1.0",
- "@radix-ui/react-context": "1.1.0",
- "@radix-ui/react-dismissable-layer": "1.1.0",
- "@radix-ui/react-id": "1.1.0",
- "@radix-ui/react-popper": "1.2.0",
- "@radix-ui/react-portal": "1.1.1",
- "@radix-ui/react-presence": "1.1.0",
- "@radix-ui/react-primitive": "2.0.0",
- "@radix-ui/react-slot": "1.1.0",
- "@radix-ui/react-use-controllable-state": "1.1.0",
- "@radix-ui/react-visually-hidden": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-use-callback-ref": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
- "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-use-controllable-state": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
- "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-use-callback-ref": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-use-escape-keydown": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz",
- "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-use-callback-ref": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-use-layout-effect": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
- "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-use-previous": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz",
- "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-use-rect": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz",
- "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/rect": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-use-size": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz",
- "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-use-layout-effect": "1.1.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-visually-hidden": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz",
- "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-primitive": "2.0.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/rect": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz",
- "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==",
- "license": "MIT"
- },
- "node_modules/@types/node": {
- "version": "20.14.12",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.12.tgz",
- "integrity": "sha512-r7wNXakLeSsGT0H1AU863vS2wa5wBOK4bWMjZz2wj+8nBx+m5PeIn0k8AloSLpRuiwdRQZwarZqHE4FNArPuJQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "undici-types": "~5.26.4"
- }
- },
- "node_modules/@types/prop-types": {
- "version": "15.7.12",
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
- "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==",
- "license": "MIT"
- },
- "node_modules/@types/react": {
- "version": "18.3.3",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz",
- "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==",
- "license": "MIT",
- "dependencies": {
- "@types/prop-types": "*",
- "csstype": "^3.0.2"
- }
- },
- "node_modules/@types/react-dom": {
- "version": "18.3.0",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz",
- "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/react": "*"
- }
- },
- "node_modules/@types/react-window": {
- "version": "1.8.8",
- "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz",
- "integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==",
- "license": "MIT",
- "dependencies": {
- "@types/react": "*"
- }
- },
- "node_modules/@vitejs/plugin-react": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-2.2.0.tgz",
- "integrity": "sha512-FFpefhvExd1toVRlokZgxgy2JtnBOdp4ZDsq7ldCWaqGSGn9UhWMAVm/1lxPL14JfNS5yGz+s9yFrQY6shoStA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.19.6",
- "@babel/plugin-transform-react-jsx": "^7.19.0",
- "@babel/plugin-transform-react-jsx-development": "^7.18.6",
- "@babel/plugin-transform-react-jsx-self": "^7.18.6",
- "@babel/plugin-transform-react-jsx-source": "^7.19.6",
- "magic-string": "^0.26.7",
- "react-refresh": "^0.14.0"
- },
- "engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "peerDependencies": {
- "vite": "^3.0.0"
- }
- },
- "node_modules/ansi-regex": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
- "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
- }
- },
- "node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/any-promise": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
- "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/arg": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
- "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/aria-hidden": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz",
- "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==",
- "license": "MIT",
- "dependencies": {
- "tslib": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/autoprefixer": {
- "version": "10.4.19",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz",
- "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/autoprefixer"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "browserslist": "^4.23.0",
- "caniuse-lite": "^1.0.30001599",
- "fraction.js": "^4.3.7",
- "normalize-range": "^0.1.2",
- "picocolors": "^1.0.0",
- "postcss-value-parser": "^4.2.0"
- },
- "bin": {
- "autoprefixer": "bin/autoprefixer"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- },
- "peerDependencies": {
- "postcss": "^8.1.0"
- }
- },
- "node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/binary-extensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/browserslist": {
- "version": "4.23.2",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz",
- "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "caniuse-lite": "^1.0.30001640",
- "electron-to-chromium": "^1.4.820",
- "node-releases": "^2.0.14",
- "update-browserslist-db": "^1.1.0"
- },
- "bin": {
- "browserslist": "cli.js"
- },
- "engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
- }
- },
- "node_modules/camelcase-css": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
- "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/caniuse-lite": {
- "version": "1.0.30001700",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz",
- "integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "CC-BY-4.0"
- },
- "node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/chokidar/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/class-variance-authority": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz",
- "integrity": "sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==",
- "license": "Apache-2.0",
- "dependencies": {
- "clsx": "2.0.0"
- },
- "funding": {
- "url": "https://joebell.co.uk"
- }
- },
- "node_modules/class-variance-authority/node_modules/clsx": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz",
- "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/clsx": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
- "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/commander": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
- "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/cssesc": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
- "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "cssesc": "bin/cssesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/csstype": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
- "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
- "license": "MIT"
- },
- "node_modules/debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/detect-node-es": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
- "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",
- "license": "MIT"
- },
- "node_modules/didyoumean": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
- "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
- "dev": true,
- "license": "Apache-2.0"
- },
- "node_modules/dlv": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
- "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/eastasianwidth": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
- "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/electron-to-chromium": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.0.tgz",
- "integrity": "sha512-Vb3xHHYnLseK8vlMJQKJYXJ++t4u1/qJ3vykuVrVjvdiOEhYyT1AuP4x03G8EnPmYvYOhe9T+dADTmthjRQMkA==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/emoji-regex": {
- "version": "9.2.2",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
- "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/esbuild": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.18.tgz",
- "integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=12"
- },
- "optionalDependencies": {
- "@esbuild/android-arm": "0.15.18",
- "@esbuild/linux-loong64": "0.15.18",
- "esbuild-android-64": "0.15.18",
- "esbuild-android-arm64": "0.15.18",
- "esbuild-darwin-64": "0.15.18",
- "esbuild-darwin-arm64": "0.15.18",
- "esbuild-freebsd-64": "0.15.18",
- "esbuild-freebsd-arm64": "0.15.18",
- "esbuild-linux-32": "0.15.18",
- "esbuild-linux-64": "0.15.18",
- "esbuild-linux-arm": "0.15.18",
- "esbuild-linux-arm64": "0.15.18",
- "esbuild-linux-mips64le": "0.15.18",
- "esbuild-linux-ppc64le": "0.15.18",
- "esbuild-linux-riscv64": "0.15.18",
- "esbuild-linux-s390x": "0.15.18",
- "esbuild-netbsd-64": "0.15.18",
- "esbuild-openbsd-64": "0.15.18",
- "esbuild-sunos-64": "0.15.18",
- "esbuild-windows-32": "0.15.18",
- "esbuild-windows-64": "0.15.18",
- "esbuild-windows-arm64": "0.15.18"
- }
- },
- "node_modules/esbuild-android-64": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz",
- "integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-android-arm64": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz",
- "integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-darwin-64": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz",
- "integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-darwin-arm64": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz",
- "integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-freebsd-64": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz",
- "integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-freebsd-arm64": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz",
- "integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-32": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz",
- "integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-64": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz",
- "integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-arm": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz",
- "integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-arm64": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz",
- "integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-mips64le": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz",
- "integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-ppc64le": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz",
- "integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-riscv64": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz",
- "integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-linux-s390x": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz",
- "integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-netbsd-64": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz",
- "integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-openbsd-64": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz",
- "integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-sunos-64": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz",
- "integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-windows-32": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz",
- "integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-windows-64": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz",
- "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild-windows-arm64": {
- "version": "0.15.18",
- "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz",
- "integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/escalade": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
- "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/fast-glob": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
- "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.4"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/fast-glob/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/fastq": {
- "version": "1.17.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
- "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/foreground-child": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz",
- "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "cross-spawn": "^7.0.0",
- "signal-exit": "^4.0.1"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/fraction.js": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
- "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "*"
- },
- "funding": {
- "type": "patreon",
- "url": "https://github.com/sponsors/rawify"
- }
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/gensync": {
- "version": "1.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/get-nonce": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
- "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/glob": {
- "version": "10.4.5",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
- "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "foreground-child": "^3.1.0",
- "jackspeak": "^3.1.2",
- "minimatch": "^9.0.4",
- "minipass": "^7.1.2",
- "package-json-from-dist": "^1.0.0",
- "path-scurry": "^1.11.1"
- },
- "bin": {
- "glob": "dist/esm/bin.mjs"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/globals": {
- "version": "11.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
- "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-core-module": {
- "version": "2.15.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz",
- "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/jackspeak": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
- "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
- "dev": true,
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "@isaacs/cliui": "^8.0.2"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- },
- "optionalDependencies": {
- "@pkgjs/parseargs": "^0.11.0"
- }
- },
- "node_modules/jiti": {
- "version": "1.21.6",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
- "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "jiti": "bin/jiti.js"
- }
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "license": "MIT"
- },
- "node_modules/jsesc": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
- "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/lilconfig": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
- "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/lines-and-columns": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/loose-envify": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
- "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "license": "MIT",
- "dependencies": {
- "js-tokens": "^3.0.0 || ^4.0.0"
- },
- "bin": {
- "loose-envify": "cli.js"
- }
- },
- "node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "yallist": "^3.0.2"
- }
- },
- "node_modules/lucide-react": {
- "version": "0.290.0",
- "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.290.0.tgz",
- "integrity": "sha512-CBDPRLOPjdo+bVlxhaa7FVWaB8OrZZQ34mwm0Fsz9ut6JltN/Td55640ur8bRWSJuz6+nX2klKrpBpV7ktwD3Q==",
- "license": "ISC",
- "peerDependencies": {
- "react": "^16.5.1 || ^17.0.0 || ^18.0.0"
- }
- },
- "node_modules/magic-string": {
- "version": "0.26.7",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.7.tgz",
- "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "sourcemap-codec": "^1.4.8"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/memoize-one": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
- "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==",
- "license": "MIT"
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.7",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
- "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/minipass": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
- "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/mz": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
- "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "any-promise": "^1.0.0",
- "object-assign": "^4.0.1",
- "thenify-all": "^1.0.0"
- }
- },
- "node_modules/nanoid": {
- "version": "3.3.7",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
- "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/node-releases": {
- "version": "2.0.18",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
- "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/normalize-range": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
- "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-hash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
- "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/package-json-from-dist": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
- "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==",
- "dev": true,
- "license": "BlueOak-1.0.0"
- },
- "node_modules/path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/path-scurry": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
- "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
- "dev": true,
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "lru-cache": "^10.2.0",
- "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
- },
- "engines": {
- "node": ">=16 || 14 >=14.18"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/path-scurry/node_modules/lru-cache": {
- "version": "10.4.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
- "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/picocolors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
- "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/pirates": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
- "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/postcss": {
- "version": "8.4.39",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz",
- "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "nanoid": "^3.3.7",
- "picocolors": "^1.0.1",
- "source-map-js": "^1.2.0"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/postcss-import": {
- "version": "15.1.0",
- "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
- "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "postcss-value-parser": "^4.0.0",
- "read-cache": "^1.0.0",
- "resolve": "^1.1.7"
- },
- "engines": {
- "node": ">=14.0.0"
- },
- "peerDependencies": {
- "postcss": "^8.0.0"
- }
- },
- "node_modules/postcss-js": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
- "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "camelcase-css": "^2.0.1"
- },
- "engines": {
- "node": "^12 || ^14 || >= 16"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- "peerDependencies": {
- "postcss": "^8.4.21"
- }
- },
- "node_modules/postcss-load-config": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
- "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "lilconfig": "^3.0.0",
- "yaml": "^2.3.4"
- },
- "engines": {
- "node": ">= 14"
- },
- "peerDependencies": {
- "postcss": ">=8.0.9",
- "ts-node": ">=9.0.0"
- },
- "peerDependenciesMeta": {
- "postcss": {
- "optional": true
- },
- "ts-node": {
- "optional": true
- }
- }
- },
- "node_modules/postcss-load-config/node_modules/lilconfig": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz",
- "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/antonk52"
- }
- },
- "node_modules/postcss-nested": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
- "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "postcss-selector-parser": "^6.1.1"
- },
- "engines": {
- "node": ">=12.0"
- },
- "peerDependencies": {
- "postcss": "^8.2.14"
- }
- },
- "node_modules/postcss-selector-parser": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz",
- "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/postcss-value-parser": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/react": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
- "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
- "license": "MIT",
- "dependencies": {
- "loose-envify": "^1.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-dom": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
- "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
- "license": "MIT",
- "dependencies": {
- "loose-envify": "^1.1.0",
- "scheduler": "^0.23.2"
- },
- "peerDependencies": {
- "react": "^18.3.1"
- }
- },
- "node_modules/react-refresh": {
- "version": "0.14.2",
- "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
- "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-remove-scroll": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.3.tgz",
- "integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==",
- "license": "MIT",
- "dependencies": {
- "react-remove-scroll-bar": "^2.3.7",
- "react-style-singleton": "^2.2.3",
- "tslib": "^2.1.0",
- "use-callback-ref": "^1.3.3",
- "use-sidecar": "^1.1.3"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/react-remove-scroll-bar": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",
- "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",
- "license": "MIT",
- "dependencies": {
- "react-style-singleton": "^2.2.2",
- "tslib": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/react-style-singleton": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
- "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",
- "license": "MIT",
- "dependencies": {
- "get-nonce": "^1.0.0",
- "tslib": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/react-virtualized-auto-sizer": {
- "version": "1.0.24",
- "resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.24.tgz",
- "integrity": "sha512-3kCn7N9NEb3FlvJrSHWGQ4iVl+ydQObq2fHMn12i5wbtm74zHOPhz/i64OL3c1S1vi9i2GXtZqNqUJTQ+BnNfg==",
- "license": "MIT",
- "peerDependencies": {
- "react": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0",
- "react-dom": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0"
- }
- },
- "node_modules/react-window": {
- "version": "1.8.10",
- "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.10.tgz",
- "integrity": "sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.0.0",
- "memoize-one": ">=3.1.1 <6"
- },
- "engines": {
- "node": ">8.0.0"
- },
- "peerDependencies": {
- "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
- "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
- }
- },
- "node_modules/read-cache": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
- "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "pify": "^2.3.0"
- }
- },
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/regenerator-runtime": {
- "version": "0.14.1",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
- "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
- "license": "MIT"
- },
- "node_modules/resolve": {
- "version": "1.22.8",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
- "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-core-module": "^2.13.0",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/reusify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/rollup": {
- "version": "2.79.1",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
- "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=10.0.0"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "queue-microtask": "^1.2.2"
- }
- },
- "node_modules/scheduler": {
- "version": "0.23.2",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
- "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
- "license": "MIT",
- "dependencies": {
- "loose-envify": "^1.1.0"
- }
- },
- "node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "shebang-regex": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/signal-exit": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
- "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
- "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/sourcemap-codec": {
- "version": "1.4.8",
- "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
- "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
- "deprecated": "Please use @jridgewell/sourcemap-codec instead",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/string-width": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
- "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "eastasianwidth": "^0.2.0",
- "emoji-regex": "^9.2.2",
- "strip-ansi": "^7.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/string-width-cjs": {
- "name": "string-width",
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/string-width-cjs/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/string-width-cjs/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/string-width-cjs/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-ansi": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
- "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^6.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/strip-ansi?sponsor=1"
- }
- },
- "node_modules/strip-ansi-cjs": {
- "name": "strip-ansi",
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/sucrase": {
- "version": "3.35.0",
- "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
- "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.2",
- "commander": "^4.0.0",
- "glob": "^10.3.10",
- "lines-and-columns": "^1.1.6",
- "mz": "^2.7.0",
- "pirates": "^4.0.1",
- "ts-interface-checker": "^0.1.9"
- },
- "bin": {
- "sucrase": "bin/sucrase",
- "sucrase-node": "bin/sucrase-node"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/tailwind-merge": {
- "version": "1.14.0",
- "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-1.14.0.tgz",
- "integrity": "sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ==",
- "license": "MIT",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/dcastil"
- }
- },
- "node_modules/tailwindcss": {
- "version": "3.4.6",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.6.tgz",
- "integrity": "sha512-1uRHzPB+Vzu57ocybfZ4jh5Q3SdlH7XW23J5sQoM9LhE9eIOlzxer/3XPSsycvih3rboRsvt0QCmzSrqyOYUIA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@alloc/quick-lru": "^5.2.0",
- "arg": "^5.0.2",
- "chokidar": "^3.5.3",
- "didyoumean": "^1.2.2",
- "dlv": "^1.1.3",
- "fast-glob": "^3.3.0",
- "glob-parent": "^6.0.2",
- "is-glob": "^4.0.3",
- "jiti": "^1.21.0",
- "lilconfig": "^2.1.0",
- "micromatch": "^4.0.5",
- "normalize-path": "^3.0.0",
- "object-hash": "^3.0.0",
- "picocolors": "^1.0.0",
- "postcss": "^8.4.23",
- "postcss-import": "^15.1.0",
- "postcss-js": "^4.0.1",
- "postcss-load-config": "^4.0.1",
- "postcss-nested": "^6.0.1",
- "postcss-selector-parser": "^6.0.11",
- "resolve": "^1.22.2",
- "sucrase": "^3.32.0"
- },
- "bin": {
- "tailwind": "lib/cli.js",
- "tailwindcss": "lib/cli.js"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/tailwindcss-animate": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz",
- "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==",
- "license": "MIT",
- "peerDependencies": {
- "tailwindcss": ">=3.0.0 || insiders"
- }
- },
- "node_modules/thenify": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
- "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "any-promise": "^1.0.0"
- }
- },
- "node_modules/thenify-all": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
- "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "thenify": ">= 3.1.0 < 4"
- },
- "engines": {
- "node": ">=0.8"
- }
- },
- "node_modules/to-fast-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/ts-interface-checker": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
- "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
- "dev": true,
- "license": "Apache-2.0"
- },
- "node_modules/tslib": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
- "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
- "license": "0BSD"
- },
- "node_modules/typescript": {
- "version": "4.9.5",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
- "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=4.2.0"
- }
- },
- "node_modules/undici-types": {
- "version": "5.26.5",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
- "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/update-browserslist-db": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz",
- "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "escalade": "^3.1.2",
- "picocolors": "^1.0.1"
- },
- "bin": {
- "update-browserslist-db": "cli.js"
- },
- "peerDependencies": {
- "browserslist": ">= 4.21.0"
- }
- },
- "node_modules/use-callback-ref": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz",
- "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==",
- "license": "MIT",
- "dependencies": {
- "tslib": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/use-sidecar": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
- "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",
- "license": "MIT",
- "dependencies": {
- "detect-node-es": "^1.1.0",
- "tslib": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/vite": {
- "version": "3.2.10",
- "resolved": "https://registry.npmjs.org/vite/-/vite-3.2.10.tgz",
- "integrity": "sha512-Dx3olBo/ODNiMVk/cA5Yft9Ws+snLOXrhLtrI3F4XLt4syz2Yg8fayZMWScPKoz12v5BUv7VEmQHnsfpY80fYw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "esbuild": "^0.15.9",
- "postcss": "^8.4.18",
- "resolve": "^1.22.1",
- "rollup": "^2.79.1"
- },
- "bin": {
- "vite": "bin/vite.js"
- },
- "engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- },
- "peerDependencies": {
- "@types/node": ">= 14",
- "less": "*",
- "sass": "*",
- "stylus": "*",
- "sugarss": "*",
- "terser": "^5.4.0"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "less": {
- "optional": true
- },
- "sass": {
- "optional": true
- },
- "stylus": {
- "optional": true
- },
- "sugarss": {
- "optional": true
- },
- "terser": {
- "optional": true
- }
- }
- },
- "node_modules/which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/wrap-ansi": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
- "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^6.1.0",
- "string-width": "^5.0.1",
- "strip-ansi": "^7.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/wrap-ansi-cjs": {
- "name": "wrap-ansi",
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/wrap-ansi-cjs/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/wrap-ansi/node_modules/ansi-styles": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
- "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/yaml": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz",
- "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "yaml": "bin.mjs"
- },
- "engines": {
- "node": ">= 14"
- }
- }
- }
-}
diff --git a/frontend/package.json b/frontend/package.json
deleted file mode 100644
index 10affba..0000000
--- a/frontend/package.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
- "name": "frontend",
- "private": true,
- "version": "0.0.0",
- "type": "module",
- "scripts": {
- "dev": "vite",
- "build": "tsc && vite build",
- "preview": "vite preview"
- },
- "dependencies": {
- "@radix-ui/react-checkbox": "^1.1.4",
- "@radix-ui/react-dropdown-menu": "^2.1.6",
- "@radix-ui/react-icons": "^1.3.2",
- "@radix-ui/react-label": "^2.1.0",
- "@radix-ui/react-progress": "^1.1.0",
- "@radix-ui/react-scroll-area": "^1.1.0",
- "@radix-ui/react-separator": "^1.1.0",
- "@radix-ui/react-slot": "^1.0.2",
- "@radix-ui/react-tabs": "^1.1.0",
- "@radix-ui/react-toast": "^1.2.1",
- "@radix-ui/react-tooltip": "^1.1.2",
- "@types/react-window": "^1.8.8",
- "class-variance-authority": "^0.7.0",
- "clsx": "^2.0.0",
- "lucide-react": "^0.290.0",
- "react": "^18.2.0",
- "react-dom": "^18.2.0",
- "react-virtualized-auto-sizer": "^1.0.24",
- "react-window": "^1.8.10",
- "tailwind-merge": "^1.14.0",
- "tailwindcss-animate": "^1.0.7"
- },
- "devDependencies": {
- "@types/node": "^20.8.9",
- "@types/react": "^18.0.17",
- "@types/react-dom": "^18.0.6",
- "@vitejs/plugin-react": "^2.0.1",
- "autoprefixer": "^10.4.16",
- "postcss": "^8.4.31",
- "tailwindcss": "^3.3.5",
- "typescript": "^4.6.4",
- "vite": "^3.0.7"
- }
-}
diff --git a/frontend/package.json.md5 b/frontend/package.json.md5
deleted file mode 100755
index 44dddfb..0000000
--- a/frontend/package.json.md5
+++ /dev/null
@@ -1 +0,0 @@
-dba055dd0a545865cffe1a57e682c54b
\ No newline at end of file
diff --git a/frontend/postcss.config.js b/frontend/postcss.config.js
deleted file mode 100644
index 2e7af2b..0000000
--- a/frontend/postcss.config.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export default {
- plugins: {
- tailwindcss: {},
- autoprefixer: {},
- },
-}
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
deleted file mode 100644
index 6ebebc9..0000000
--- a/frontend/src/App.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import React, { useState } from "react";
-import { ThemeProvider } from "./components/ui/theme-provider";
-import Navbar from "./components/Navbar";
-import Home from "./components/Home";
-import Search from "./components/Search";
-import Install from "./components/Installed";
-import { Toaster } from "./components/ui/toaster";
-import Updates from "./components/Updates";
-
-type PageType = "home" | "search" | "install" | "updates";
-
-const App: React.FC = () => {
- const [currentPage, setCurrentPage] = useState("home");
- const renderPage = () => {
- switch (currentPage) {
- case "home":
- return ;
- case "search":
- return ;
- case "install":
- return ;
- case "updates":
- return ;
- default:
- return ;
- }
- };
-
- return (
-
-
-
- {renderPage()}
-
-
-
- );
-};
-
-export default App;
diff --git a/frontend/src/assets/fonts/OFL.txt b/frontend/src/assets/fonts/OFL.txt
deleted file mode 100644
index 9cac04c..0000000
--- a/frontend/src/assets/fonts/OFL.txt
+++ /dev/null
@@ -1,93 +0,0 @@
-Copyright 2016 The Nunito Project Authors (contact@sansoxygen.com),
-
-This Font Software is licensed under the SIL Open Font License, Version 1.1.
-This license is copied below, and is also available with a FAQ at:
-http://scripts.sil.org/OFL
-
-
------------------------------------------------------------
-SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
------------------------------------------------------------
-
-PREAMBLE
-The goals of the Open Font License (OFL) are to stimulate worldwide
-development of collaborative font projects, to support the font creation
-efforts of academic and linguistic communities, and to provide a free and
-open framework in which fonts may be shared and improved in partnership
-with others.
-
-The OFL allows the licensed fonts to be used, studied, modified and
-redistributed freely as long as they are not sold by themselves. The
-fonts, including any derivative works, can be bundled, embedded,
-redistributed and/or sold with any software provided that any reserved
-names are not used by derivative works. The fonts and derivatives,
-however, cannot be released under any other type of license. The
-requirement for fonts to remain under this license does not apply
-to any document created using the fonts or their derivatives.
-
-DEFINITIONS
-"Font Software" refers to the set of files released by the Copyright
-Holder(s) under this license and clearly marked as such. This may
-include source files, build scripts and documentation.
-
-"Reserved Font Name" refers to any names specified as such after the
-copyright statement(s).
-
-"Original Version" refers to the collection of Font Software components as
-distributed by the Copyright Holder(s).
-
-"Modified Version" refers to any derivative made by adding to, deleting,
-or substituting -- in part or in whole -- any of the components of the
-Original Version, by changing formats or by porting the Font Software to a
-new environment.
-
-"Author" refers to any designer, engineer, programmer, technical
-writer or other person who contributed to the Font Software.
-
-PERMISSION & CONDITIONS
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of the Font Software, to use, study, copy, merge, embed, modify,
-redistribute, and sell modified and unmodified copies of the Font
-Software, subject to the following conditions:
-
-1) Neither the Font Software nor any of its individual components,
-in Original or Modified Versions, may be sold by itself.
-
-2) Original or Modified Versions of the Font Software may be bundled,
-redistributed and/or sold with any software, provided that each copy
-contains the above copyright notice and this license. These can be
-included either as stand-alone text files, human-readable headers or
-in the appropriate machine-readable metadata fields within text or
-binary files as long as those fields can be easily viewed by the user.
-
-3) No Modified Version of the Font Software may use the Reserved Font
-Name(s) unless explicit written permission is granted by the corresponding
-Copyright Holder. This restriction only applies to the primary font name as
-presented to the users.
-
-4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
-Software shall not be used to promote, endorse or advertise any
-Modified Version, except to acknowledge the contribution(s) of the
-Copyright Holder(s) and the Author(s) or with their explicit written
-permission.
-
-5) The Font Software, modified or unmodified, in part or in whole,
-must be distributed entirely under this license, and must not be
-distributed under any other license. The requirement for fonts to
-remain under this license does not apply to any document created
-using the Font Software.
-
-TERMINATION
-This license becomes null and void if any of the above conditions are
-not met.
-
-DISCLAIMER
-THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
-COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
-DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
-OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/frontend/src/assets/fonts/nunito-v16-latin-regular.woff2 b/frontend/src/assets/fonts/nunito-v16-latin-regular.woff2
deleted file mode 100644
index 2f9cc59..0000000
Binary files a/frontend/src/assets/fonts/nunito-v16-latin-regular.woff2 and /dev/null differ
diff --git a/frontend/src/assets/icon/appicon.png b/frontend/src/assets/icon/appicon.png
deleted file mode 100644
index a456330..0000000
Binary files a/frontend/src/assets/icon/appicon.png and /dev/null differ
diff --git a/frontend/src/assets/images/logo-universal.png b/frontend/src/assets/images/logo-universal.png
deleted file mode 100644
index 99ac71f..0000000
Binary files a/frontend/src/assets/images/logo-universal.png and /dev/null differ
diff --git a/frontend/src/components/ErrorBoundary.tsx b/frontend/src/components/ErrorBoundary.tsx
deleted file mode 100644
index 542f34c..0000000
--- a/frontend/src/components/ErrorBoundary.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import React, { Component, ErrorInfo, ReactNode } from "react";
-
-interface Props {
- children: ReactNode;
-}
-
-interface State {
- hasError: boolean;
-}
-
-class ErrorBoundary extends Component {
- public state: State = {
- hasError: false,
- };
-
- public static getDerivedStateFromError(_: Error): State {
- return { hasError: true };
- }
-
- public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
- console.error("Uncaught error:", error, errorInfo);
- }
-
- public render() {
- if (this.state.hasError) {
- return Sorry, there was an error ;
- }
-
- return this.props.children;
- }
-}
-
-export default ErrorBoundary;
diff --git a/frontend/src/components/Home.tsx b/frontend/src/components/Home.tsx
deleted file mode 100644
index 621de13..0000000
--- a/frontend/src/components/Home.tsx
+++ /dev/null
@@ -1,536 +0,0 @@
-import { useCallback, useEffect, useState } from "react";
-import {
- Card,
- CardContent,
- CardDescription,
- CardFooter,
- CardHeader,
- CardTitle,
-} from "../components/ui/card";
-import { Badge } from "../components/ui/badge";
-import { ScrollArea } from "../components/ui/scroll-area";
-import PackageDetails from "./PackageDetails";
-import ErrorBoundary from "./ErrorBoundary";
-import { CheckPackageInstalled } from "../../wailsjs/go/main/App";
-
-interface AppInfo {
- name: string;
- version: string;
- description: string;
- repository: string;
- maintainer: string;
- upstreamurl: string;
- dependlist: string[];
- lastupdated: string;
-}
-
-const featuredApps: AppInfo[] = [
- {
- name: "firefox",
- version: "128.0.2-1",
- description: "Fast, Private \u0026 Safe Web Browser",
- repository: "extra",
- maintainer:
- "Jan Alexander Steffens (heftig) \u003cheftig@archlinux.org\u003e",
- upstreamurl: "https://www.mozilla.org/firefox/",
- dependlist: [
- "alsa-lib",
- "at-spi2-core",
- "bash",
- "cairo",
- "dbus",
- "ffmpeg",
- "fontconfig",
- "freetype2",
- "gcc-libs",
- "gdk-pixbuf2",
- "glib2",
- "glibc",
- "gtk3",
- "hicolor-icon-theme",
- "libpulse",
- "libx11",
- "libxcb",
- "libxcomposite",
- "libxdamage",
- "libxext",
- "libxfixes",
- "libxrandr",
- "libxss",
- "libxt",
- "mime-types",
- "nspr",
- "nss",
- "pango",
- "ttf-font",
- ],
- lastupdated: "Jul. 23, 2024, 4 p.m. UTC",
- },
- {
- name: "gimp",
- description: "GNU Image Manipulation Program",
- repository: "extra",
- version: "2.10.38-1",
- maintainer: "Christian Hesse, Christian Heusel",
- lastupdated: "May 3, 2024, 9:48 a.m. UTC",
- dependlist: [
- "aalib",
- "babl",
- "bzip2",
- "cairo",
- "fontconfig",
- "freetype2",
- "gcc-libs",
- "gdk-pixbuf2",
- "gegl",
- "glib2",
- "glibc",
- "gtk2",
- "harfbuzz",
- "hicolor-icon-theme",
- "iso-codes",
- "json-glib",
- "lcms2",
- "libgexiv2",
- "libgudev",
- "libheif",
- "libjpeg-turbo",
- "libjxl",
- "libmng",
- "libmypaint",
- "libpng",
- "librsvg",
- "libtiff",
- "libunwind",
- "libwebp",
- "libwmf",
- "libx11",
- "libxcursor",
- "libxext",
- "libxfixes",
- "libxmu",
- "libxpm",
- "mypaint-brushes1",
- "openexr",
- "openjpeg2",
- "pango",
- "poppler-data",
- "poppler-glib",
- "xz",
- "zlib",
- ],
- upstreamurl: "https://www.gimp.org/",
- },
- {
- name: "vlc",
- version: "3.0.21-1",
- description: "Multi-platform MPEG, VCD/DVD, and DivX player",
- repository: "extra",
- maintainer: "Antonio Rojas \u003carojas@archlinux.org\u003e",
- upstreamurl: "https://www.videolan.org/vlc/",
- dependlist: [
- "a52dec",
- "abseil-cpp",
- "aribb24",
- "bash",
- "cairo",
- "dbus",
- "faad2",
- "ffmpeg4.4",
- "fontconfig",
- "freetype2",
- "fribidi",
- "gcc-libs",
- "gdk-pixbuf2",
- "glib2",
- "glibc",
- "gnutls",
- "harfbuzz",
- "hicolor-icon-theme",
- "libarchive",
- "libdca",
- "libdvbpsi",
- "libglvnd",
- "libidn",
- "libmad",
- "libmatroska",
- "libmpcdec",
- "libmpeg2",
- "libproxy",
- "libsecret",
- "libtar",
- "libupnp",
- "libixml.so",
- "libupnp.so",
- "libva",
- "libx11",
- "libxcb",
- "libxinerama",
- "libxml2",
- "libxpm",
- "lua",
- "qt5-base",
- "qt5-svg",
- "qt5-x11extras",
- "taglib",
- "wayland",
- "xcb-util-keysyms",
- "zlib",
- ],
- lastupdated: "Jun. 16, 2024, 8 p.m. UTC",
- },
- {
- name: "visual-studio-code-bin",
- description:
- "Visual Studio Code (vscode): Editor for building and debugging modern web and cloud applications (official binary version)",
- repository: "AUR",
- version: "1.57.0",
- maintainer: "Microsoft",
- lastupdated: "2023-06-10",
- dependlist: [
- "libxkbfile",
- "gnupg",
- "gtk3",
- "libsecret",
- "nss",
- "gcc-libs",
- "libnotify",
- "libxss",
- "glibc",
- "lsof",
- "shared-mime-info",
- "xdg-utils",
- "alsa-lib",
- ],
- upstreamurl: "",
- },
- {
- name: "libreoffice-still",
- version: "7.6.7-1",
- description: "LibreOffice maintenance branch",
- repository: "extra",
- maintainer: "Andreas Radke \u003candyrtr@archlinux.org\u003e",
- upstreamurl: "https://www.libreoffice.org/",
- dependlist: [
- "curl",
- "hunspell",
- "python",
- "libwpd",
- "libwps",
- "neon",
- "pango",
- "nspr",
- "libjpeg",
- "libxrandr",
- "libgl",
- "redland",
- "hyphen",
- "lpsolve",
- "gcc-libs",
- "sh",
- "graphite",
- "icu",
- "libxslt",
- "lcms2",
- "libvisio",
- "libetonyek",
- "libodfgen",
- "libcdr",
- "libmspub",
- "harfbuzz-icu",
- "nss",
- "clucene",
- "hicolor-icon-theme",
- "desktop-file-utils",
- "shared-mime-info",
- "libpagemaker",
- "libxinerama",
- "libabw",
- "libmwaw",
- "libe-book",
- "libcups",
- "liblangtag",
- "libexttextcat",
- "liborcus",
- "libwebp",
- "libcmis",
- "libtommath",
- "libzmf",
- "libatomic_ops",
- "libnumbertext",
- "gpgme",
- "libfreehand",
- "libstaroffice",
- "libepubgen",
- "libqxp",
- "libepoxy",
- "box2d",
- "zxing-cpp",
- "xdg-utils",
- "libldap",
- "fontconfig",
- "zlib",
- "libpng",
- "freetype2",
- "raptor",
- "libxml2",
- "cairo",
- "libx11",
- "expat",
- "glib2",
- "boost-libs",
- "libtiff",
- "dbus",
- "glibc",
- "librevenge",
- "libxext",
- "openjpeg2",
- ],
- lastupdated: "May. 19, 2024, 7 p.m. UTC",
- },
- {
- name: "blender",
- version: "17:4.2.0-3",
- description: "A fully integrated 3D graphics creation suite",
- repository: "extra",
- maintainer: "Sven-Hendrik Haase \u003csvenstaro@archlinux.org\u003e",
- upstreamurl: "https://www.blender.org",
- dependlist: [
- "alembic",
- "bash",
- "boost-libs",
- "draco",
- "embree",
- "expat",
- "ffmpeg",
- "fftw",
- "freetype2",
- "gcc-libs",
- "glew",
- "glibc",
- "gmp",
- "hicolor-icon-theme",
- "imath",
- "intel-oneapi-compiler-dpcpp-cpp-runtime-libs",
- "intel-oneapi-compiler-shared-runtime-libs",
- "jack",
- "jemalloc",
- "level-zero-loader",
- "libepoxy",
- "libharu",
- "libjpeg-turbo",
- "libpng",
- "libsndfile",
- "libspnav",
- "libtiff",
- "libwebp",
- "libx11",
- "libxfixes",
- "libxi",
- "libxkbcommon",
- "libxml2",
- "libxrender",
- "libxxf86vm",
- "llvm-libs",
- "materialx",
- "onetbb",
- "openal",
- "opencollada",
- "opencolorio",
- "openexr",
- "openimagedenoise",
- "openimageio",
- "openjpeg2",
- "openpgl",
- "openshadinglanguage",
- "opensubdiv",
- "openvdb",
- "openxr",
- "potrace",
- "pugixml",
- "pystring",
- "python",
- "python-numpy",
- "python-requests",
- "sdl2",
- "shared-mime-info",
- "usd",
- "xdg-utils",
- "yaml-cpp",
- "zlib",
- "zstd",
- ],
- lastupdated: "Jul. 17, 2024, 12 p.m. UTC",
- },
- {
- name: "zed",
- version: "0.144.4-1",
- description:
- "A high-performance, multiplayer code editor from the creators of Atom and Tree-sitter",
- repository: "extra",
- maintainer: "Caleb Maclennan \u003calerque@archlinux.org\u003e",
- upstreamurl: "https://zed.dev",
- dependlist: [
- "alsa-lib",
- "libasound.so",
- "fontconfig",
- "gcc-libs",
- "glibc",
- "libxcb",
- "libxkbcommon",
- "libxkbcommon-x11",
- "openssl",
- "libcrypto.so",
- "libssl.so",
- "sqlite",
- "vulkan-driver",
- "vulkan-icd-loader",
- "vulkan-tools",
- "wayland",
- "zlib",
- "libz.so",
- ],
- lastupdated: "Jul. 19, 2024, 9 p.m. UTC",
- },
- {
- name: "git",
- version: "2.45.2-1",
- description: "the fast distributed version control system",
- repository: "extra",
- maintainer: "Christian Hesse \u003ceworm@archlinux.org\u003e",
- upstreamurl: "https://git-scm.com/",
- dependlist: [
- "curl",
- "expat",
- "perl",
- "perl-error",
- "perl-mailtools",
- "openssl",
- "pcre2",
- "grep",
- "shadow",
- "zlib",
- ],
- lastupdated: "Jun. 1, 2024, 9 p.m. UTC",
- },
- {
- name: "google-chrome",
- version: "127.0.6533.72-1",
- description: "The popular web browser by Google (Stable Channel)",
- repository: "AUR",
- maintainer: "gromit",
- upstreamurl: "https://www.google.com/chrome",
- dependlist: [
- "alsa-lib",
- "gtk3",
- "libcups",
- "libxss",
- "libxtst",
- "nss",
- "ttf-liberation",
- "xdg-utils",
- ],
- lastupdated: "23-07-2024",
- },
-];
-
-const Home = () => {
- const [selectedApp, setSelectedApp] = useState(null);
- const [installedApps, setInstalledApps] = useState>(new Set());
-
- const checkInstalledApps = useCallback(async () => {
- try {
- const installedSet = new Set();
- for (const app of featuredApps) {
- try {
- const isInstalled = await CheckPackageInstalled(app.name);
- if (isInstalled) {
- installedSet.add(app.name);
- }
- } catch (error) {
- console.error(`Error checking if ${app.name} is installed:`, error);
- }
- }
- setInstalledApps(installedSet);
- } catch (error) {
- console.error("Error fetching package information:", error);
- }
- }, []);
-
- useEffect(() => {
- checkInstalledApps();
- const interval = setInterval(checkInstalledApps, 3000);
- return () => clearInterval(interval);
- }, [checkInstalledApps]);
-
- const handleInstallStateChange = useCallback(() => {
- checkInstalledApps();
- }, [checkInstalledApps]);
-
- const handleBack = useCallback(() => {
- setSelectedApp(null);
- }, []);
-
- const handleSelectApp = useCallback((app: AppInfo) => {
- setSelectedApp({ ...app });
- }, []);
-
- if (selectedApp) {
- return (
-
-
-
- );
- }
-
- return (
-
-
-
Mentioned Packages
-
-
- {featuredApps.map((app, index) => (
-
handleSelectApp(app)}
- >
-
-
- {app.name}
- {installedApps.has(app.name) && (
-
- Installed
-
- )}
-
-
-
-
- {app.description && app.description.length > 70
- ? `${app.description.substring(0, 80)}...`
- : app.description}
-
-
- Version: {app.version}
-
-
-
-
- {app.repository}
-
-
-
- ))}
-
-
-
-
- );
-};
-
-export default Home;
diff --git a/frontend/src/components/Installed.tsx b/frontend/src/components/Installed.tsx
deleted file mode 100644
index 3e78d9b..0000000
--- a/frontend/src/components/Installed.tsx
+++ /dev/null
@@ -1,214 +0,0 @@
-import React, { useState, useEffect, useCallback, useMemo } from "react";
-import { FixedSizeGrid as Grid } from "react-window";
-import AutoSizer from "react-virtualized-auto-sizer";
-import { Button } from "@/components/ui/button";
-import { Input } from "@/components/ui/input";
-import {
- Card,
- CardContent,
- CardDescription,
- CardFooter,
- CardHeader,
- CardTitle,
-} from "@/components/ui/card";
-import { GetInstalledPackages } from "../../wailsjs/go/main/App";
-import { main } from "wailsjs/go/models";
-import { Badge } from "./ui/badge";
-import { Skeleton } from "./ui/skeleton";
-import PackageDetails from "./PackageDetails";
-import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
-import { AlertCircle } from "lucide-react";
-
-const Installed = () => {
- const [installedPackages, setInstalledPackages] = useState<
- main.PackageInfo[]
- >([]);
- const [isLoading, setIsLoading] = useState(true);
- const [error, setError] = useState(null);
- const [searchTerm, setSearchTerm] = useState("");
- const [selectedPackage, setSelectedPackage] =
- useState(null);
-
- const fetchInstalledPackages = useCallback(async () => {
- setIsLoading(true);
- try {
- const packages = await GetInstalledPackages();
- setInstalledPackages(packages);
- setError(null);
- } catch (err) {
- console.error("Error fetching installed packages:", err);
- setError("Failed to fetch installed packages. Please try again.");
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- useEffect(() => {
- fetchInstalledPackages();
- const intervalId = setInterval(fetchInstalledPackages, 5000);
- return () => clearInterval(intervalId);
- }, [fetchInstalledPackages]);
-
- const filteredPackages = useMemo(() => {
- return installedPackages.filter((pkg) =>
- pkg.name.toLowerCase().includes(searchTerm.toLowerCase())
- );
- }, [installedPackages, searchTerm]);
-
- const PackageItem = useCallback(
- ({
- columnIndex,
- rowIndex,
- style,
- }: {
- columnIndex: number;
- rowIndex: number;
- style: React.CSSProperties;
- }) => {
- const index = rowIndex * 3 + columnIndex;
- const pkg = filteredPackages[index];
- if (!pkg) return null;
-
- return (
-
-
setSelectedPackage(pkg)}
- >
-
- {pkg.name}
-
-
-
- {pkg.description && pkg.description.length > 70
- ? `${pkg.description.substring(0, 80)}...`
- : pkg.description}
-
-
- Last Updated: {pkg.lastupdated}
-
-
-
-
- {pkg.version}
-
-
-
-
- );
- },
- [filteredPackages]
- );
-
- const renderContent = useMemo(() => {
- if (isLoading && installedPackages.length === 0) {
- return (
-
- {Array.from({ length: 9 }, (_, i) => (
-
-
-
-
-
-
-
-
-
-
-
-
- ))}
-
- );
- }
-
- if (error) {
- return (
-
-
- Error
- {error}
-
- );
- }
-
- if (filteredPackages.length === 0) {
- return (
-
-
-
- No packages found
-
-
- {searchTerm
- ? "No packages match your search."
- : "No installed packages found."}
-
-
-
- );
- }
-
- return (
-
-
- {({ height, width }: { height: number; width: number }) => {
- const columnCount = width >= 1024 ? 3 : width >= 768 ? 2 : 1;
- const columnWidth = width / columnCount;
- const rowCount = Math.ceil(filteredPackages.length / columnCount);
- return (
-
- {PackageItem}
-
- );
- }}
-
-
- );
- }, [
- isLoading,
- error,
- filteredPackages,
- PackageItem,
- installedPackages.length,
- searchTerm,
- ]);
-
- return (
-
- );
-};
-
-export default React.memo(Installed);
diff --git a/frontend/src/components/Navbar.tsx b/frontend/src/components/Navbar.tsx
deleted file mode 100644
index 0e0da85..0000000
--- a/frontend/src/components/Navbar.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import React from "react";
-import { Search, Package, PackagePlus, Home, Moon, Sun } from "lucide-react";
-import { Button } from "@/components/ui/button";
-import { useTheme } from "@/components/ui/theme-provider";
-
-type PageType = "home" | "search" | "install" | "updates";
-
-interface NavbarProps {
- setCurrentPage: (page: PageType) => void;
-}
-
-const Navbar: React.FC = ({ setCurrentPage }) => {
- const { setTheme, theme } = useTheme();
-
- return (
-
-
-
setCurrentPage("home")}
- >
- ALG App Store
-
-
-
setCurrentPage("home")}>
- Home
-
-
setCurrentPage("search")}>
- Search
-
-
setCurrentPage("install")}>
- Installed
-
-
setCurrentPage("updates")}>
- Updates
-
-
setTheme(theme === "dark" ? "light" : "dark")}
- className="rounded-full"
- >
- {theme === "dark" ? (
-
- ) : (
-
- )}
-
-
-
-
- );
-};
-
-export default Navbar;
diff --git a/frontend/src/components/PackageDetails.tsx b/frontend/src/components/PackageDetails.tsx
deleted file mode 100644
index 53c1135..0000000
--- a/frontend/src/components/PackageDetails.tsx
+++ /dev/null
@@ -1,399 +0,0 @@
-import React, {
- useEffect,
- useState,
- useCallback,
- useMemo,
- useRef,
-} from "react";
-import { Button } from "@/components/ui/button";
-import { ArrowLeft, Download, Check, Copy, Trash2 } from "lucide-react";
-import {
- Card,
- CardContent,
- CardDescription,
- CardFooter,
- CardHeader,
- CardTitle,
-} from "@/components/ui/card";
-import { Badge } from "@/components/ui/badge";
-import { Separator } from "@/components/ui/separator";
-import { ScrollArea } from "@/components/ui/scroll-area";
-import { main } from "wailsjs/go/models";
-import {
- CheckPackageInstalled,
- Install,
- Uninstall,
-} from "../../wailsjs/go/main/App";
-import ErrorBoundary from "./ErrorBoundary";
-import { Skeleton } from "./ui/skeleton";
-import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs";
-import CircularProgress from "./ui/circular-progress";
-
-interface PackageDetailsProps {
- app: main.PackageInfo | null;
- onBack: () => void;
- onInstallStateChange: () => void;
-}
-
-const PackageDetails: React.FC = ({
- app,
- onBack,
- onInstallStateChange,
-}) => {
- const [isInstalled, setIsInstalled] = useState(false);
- const [isCheckingInstall, setIsCheckingInstall] = useState(false);
- const [isInstalling, setIsInstalling] = useState(false);
- const [installProgress, setInstallProgress] = useState(0);
- const [error, setError] = useState(null);
- const [isLoading, setIsLoading] = useState(true);
- const installInstructionsRef = useRef(null);
- const [copiedCommand, setCopiedCommand] = useState(null);
-
- const handleCopyCommand = (command: string) => {
- navigator.clipboard.writeText(command).then(() => {
- setCopiedCommand(command);
- setTimeout(() => setCopiedCommand(null), 2000);
- });
- };
-
- const checkIfInstalled = useCallback(async (appName: string) => {
- try {
- setIsCheckingInstall(true);
- setError(null);
- const isExist = await CheckPackageInstalled(appName);
- setIsInstalled(isExist);
- } catch (err) {
- console.error("Error checking package installation:", err);
- } finally {
- setIsCheckingInstall(false);
- }
- }, []);
-
- useEffect(() => {
- if (app?.name) {
- setIsLoading(true);
- checkIfInstalled(app.name).finally(() => setIsLoading(false));
- }
- }, [app, checkIfInstalled]);
-
- const handleInstall = useCallback(async () => {
- if (!app?.name) return;
-
- try {
- setIsInstalling(true);
- setInstallProgress(0);
- setError(null);
-
- const installationInterval = setInterval(() => {
- setInstallProgress((prev) => Math.min(prev + 10, 90));
- }, 500);
-
- await Install(app.name);
-
- clearInterval(installationInterval);
- setInstallProgress(100);
- await checkIfInstalled(app.name);
- onInstallStateChange();
- } catch (err) {
- setError("Failed to install package");
- console.error("Error installing package:", err);
- } finally {
- const isExist = await CheckPackageInstalled(app.name);
- setIsInstalled(isExist);
- setIsInstalling(false);
- }
- }, [app, onInstallStateChange]);
-
- const handleUninstall = async () => {
- if (!app?.name) return;
-
- try {
- setIsInstalling(true);
- setInstallProgress(0);
- setError(null);
-
- const installationInterval = setInterval(() => {
- setInstallProgress((prev) => Math.min(prev + 10, 90));
- }, 500);
-
- await Uninstall(app.name);
-
- clearInterval(installationInterval);
- setInstallProgress(100);
- await checkIfInstalled(app.name);
- onInstallStateChange();
- } catch (err) {
- setError("Failed to install package");
- console.error("Error installing package:", err);
- } finally {
- const isExist = await CheckPackageInstalled(app.name);
- setIsInstalled(isExist);
- setIsInstalling(false);
- }
- };
-
- const renderDependencies = useMemo(() => {
- const dependencies = app?.dependlist;
- if (!dependencies || dependencies.length === 0) {
- return No dependencies listed.
;
- }
- return (
-
- {dependencies.map((dependency) => (
- {dependency}
- ))}
-
- );
- }, [app?.dependlist]);
-
- const renderInstallButton = useMemo(() => {
- if (isInstalled) {
- return (
-
- Uninstall
-
- );
- }
-
- if (isInstalling) {
- return (
-
-
- Installing...
-
- );
- }
- return (
-
- Install
-
- );
- }, [
- isCheckingInstall,
- isInstalled,
- isInstalling,
- installProgress,
- handleInstall,
- ]);
-
- if (!app) {
- return No package information available
;
- }
-
- if (isLoading) {
- return (
-
- {Array.from({ length: 9 }, (_, i) => (
-
-
-
-
-
-
-
-
-
-
-
-
- ))}
-
- );
- }
-
- const renderInstallationInstructions = () => {
- const isOfficialRepo =
- app.repository.includes("core") ||
- app.repository.includes("extra") ||
- app.repository.includes("local");
- const installCommand = `${isOfficialRepo ? "sudo pacman" : "yay"} -S ${
- app.name
- }`;
-
- const uninstallCommand = `sudo pacman -Rdd ${app.name}`;
-
- return (
-
-
-
- {isOfficialRepo ? (
- pacman
- ) : (
- <>
- yay
- paru
- >
- )}
-
- {isOfficialRepo ? (
-
-
-
-
- {app.repository.includes("local")
- ? uninstallCommand
- : installCommand}
-
-
-
-
-
- ) : (
-
-
-
- {installCommand}
-
-
-
-
-
- {`paru -S ${app.name}`}
-
-
-
- {/*
-
-
-
- await InstallAUR(aurManager, app.name)
- }
- >
-
-
-
-
- Install {app.name}
-
-
- */}
-
- )}
-
-
- );
- };
-
- return (
-
-
-
-
-
- Back
-
- {renderInstallButton}
-
- {error && (
-
- Error:
- {error}
-
- )}
-
-
-
-
-
- {app.name || "N/A"}
-
-
- {app.description || "No description available."}
-
-
-
- {app.repository || "Unknown"}
-
-
-
-
-
- {[
- { label: "Version", value: app.version },
- { label: "Maintainer", value: app.maintainer },
- { label: "Last Updated", value: app.lastupdated },
- { label: "Upstream URL", value: app.upstreamurl },
- ].map(({ label, value }) => (
-
-
{label}
-
{value || "N/A"}
-
- ))}
-
-
-
-
-
- Details
-
-
- {app.description || "No description available."}
-
- Dependencies
- {renderDependencies}
-
- Command
- {renderInstallationInstructions()}
-
-
-
- Please ensure your system meets the minimum requirements before
- installation.
-
-
-
-
-
-
- );
-};
-
-interface CopyButtonProps {
- command: string;
- copiedCommand: string | null;
- onCopy: (command: string) => void;
-}
-
-const CopyButton: React.FC = ({
- command,
- copiedCommand,
- onCopy,
-}) => (
- onCopy(command)}
- >
- {copiedCommand === command ? (
-
- ) : (
-
- )}
-
-);
-
-export default PackageDetails;
diff --git a/frontend/src/components/Search.tsx b/frontend/src/components/Search.tsx
deleted file mode 100644
index f1b9564..0000000
--- a/frontend/src/components/Search.tsx
+++ /dev/null
@@ -1,348 +0,0 @@
-import React, { useState, useCallback, useRef, useEffect } from "react";
-import { FixedSizeGrid as Grid } from "react-window";
-import AutoSizer from "react-virtualized-auto-sizer";
-import { Input } from "@/components/ui/input";
-import { Button } from "@/components/ui/button";
-import {
- Card,
- CardContent,
- CardDescription,
- CardFooter,
- CardHeader,
- CardTitle,
-} from "@/components/ui/card";
-import { Badge } from "./ui/badge";
-import { SearchPackage, SearchLocalPackage } from "../../wailsjs/go/main/App";
-import { main } from "wailsjs/go/models";
-import PackageDetails from "./PackageDetails";
-import ErrorBoundary from "./ErrorBoundary";
-import { Skeleton } from "./ui/skeleton";
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuTrigger,
- DropdownMenuItem,
- DropdownMenuSeparator,
-} from "./ui/dropdown-menu";
-import { Checkbox } from "@/components/ui/checkbox";
-
-const Search: React.FC = () => {
- const [searchTerm, setSearchTerm] = useState("");
- const [searchResults, setSearchResults] = useState([]);
- const [allResults, setAllResults] = useState([]);
- const [isLoading, setIsLoading] = useState(false);
- const [selectedApp, setSelectedApp] = useState(null);
- const [error, setError] = useState(null);
- const [installedApps, setInstalledApps] = useState>(new Set());
- const [activeFilters, setActiveFilters] = useState([]);
-
- const handleSearch = async (): Promise => {
- if (!searchTerm.trim()) {
- setError("Please enter a search term");
- return;
- }
-
- setSearchResults([]);
- setAllResults([]);
- setSelectedApp(null);
- setIsLoading(true);
- setError(null);
-
- try {
- const res = await SearchPackage(
- searchTerm.toLowerCase().trim().replace(/\s+/g, "-")
- );
- setAllResults(res);
-
- if (activeFilters.length > 0) {
- const filtered = res.filter((pkg) =>
- activeFilters.includes(pkg.repository)
- );
- setSearchResults(filtered);
- if (filtered.length === 0) {
- setError("No results found for selected filters!");
- }
- } else {
- setSearchResults(res);
- }
-
- if (res.length === 0) {
- setError("No results found");
- } else {
- checkInstalledApps(res);
- }
- } catch (error) {
- console.error("Error searching packages:", error);
- setError("An error occurred while searching. Please try again.");
- } finally {
- setIsLoading(false);
- }
- };
-
- const checkInstalledApps = useCallback(async (apps: main.PackageInfo[]) => {
- const installedSet = new Set();
- for (const app of apps) {
- try {
- const isInstalled = await SearchLocalPackage(app.name);
- if (isInstalled) {
- installedSet.add(app.name);
- }
- } catch (error) {
- console.error(`Error checking if ${app.name} is installed:`, error);
- }
- }
- setInstalledApps(installedSet);
- }, []);
-
- const handleKeyPress = (event: React.KeyboardEvent) => {
- if (event.key === "Enter") {
- handleSearch();
- }
- };
-
- const updateFilters = (filter: string, checked: boolean) => {
- let newFilters: string[];
-
- if (filter === "CLEAR_ALL") {
- newFilters = [];
- } else {
- newFilters = checked
- ? [...activeFilters, filter]
- : activeFilters.filter((f) => f !== filter);
- }
-
- setActiveFilters(newFilters);
-
- if (newFilters.length === 0) {
- setSearchResults(allResults);
- setError(null);
- } else {
- const filteredResults = allResults.filter((pkg) =>
- newFilters.includes(pkg.repository)
- );
-
- if (filteredResults.length === 0) {
- setError("No results found for selected filters!");
- } else {
- setError(null);
- setSearchResults(filteredResults);
- }
- }
- };
-
- const handleInstallStateChange = useCallback(() => {
- if (selectedApp) {
- checkInstalledApps([selectedApp]);
- }
- }, [selectedApp, checkInstalledApps]);
-
- const CardItem = useCallback(
- ({
- columnIndex,
- rowIndex,
- style,
- }: {
- columnIndex: number;
- rowIndex: number;
- style: React.CSSProperties;
- }) => {
- const index = rowIndex * 3 + columnIndex;
- const result = searchResults[index];
- if (!result) return null;
-
- const isInstalled = installedApps.has(result.name);
-
- return (
-
-
setSelectedApp({ ...result })}
- >
-
-
- {result.name}
- {isInstalled && (
-
- Installed
-
- )}
-
-
-
-
- {result.description && result.description.length > 70
- ? `${result.description.substring(0, 80)}...`
- : result.description}
-
-
- Version: {result.version}
-
-
-
-
- {result.repository}
-
-
-
-
- );
- },
- [installedApps, searchResults]
- );
-
- const renderContent = () => {
- if (isLoading) {
- return (
-
- {Array.from({ length: 9 }, (_, i) => (
-
-
-
-
-
-
-
-
-
-
-
-
- ))}
-
- );
- }
-
- if (error) {
- return {error}
;
- }
-
- return (
-
-
- {({ height, width }: { height: number; width: number }) => {
- const columnCount = width >= 1024 ? 3 : width >= 768 ? 2 : 1;
- const columnWidth = width / columnCount;
- const rowCount = Math.ceil(searchResults.length / columnCount);
- return (
-
- {CardItem}
-
- );
- }}
-
-
- );
- };
-
- return (
-
-
-
- );
-};
-
-type FilterDropdownProps = {
- activeFilters: string[];
- onFilterChange: (filter: string, checked: boolean) => void;
-};
-
-const FilterDropdown: React.FC = ({
- activeFilters,
- onFilterChange,
-}) => {
- const repositories = ["core", "extra", "AUR"];
-
- return (
-
-
-
- Filter
- {activeFilters.length > 0 && (
-
- {activeFilters.length}
-
- )}
-
-
-
- {repositories.map((repo) => (
- {
- e.preventDefault();
- }}
- className="flex items-center justify-between cursor-pointer"
- >
-
- onFilterChange(repo, checked === true)
- }
- aria-label={`Filter by ${repo}`}
- />
- {repo}
-
- ))}
- {activeFilters.length > 0 && (
- <>
-
- {
- activeFilters.forEach((filter) =>
- onFilterChange("CLEAR_ALL", false)
- );
- }}
- className="text-center text-xs cursor-pointer text-gray-500 hover:text-gray-700"
- >
- Clear all
-
- >
- )}
-
-
- );
-};
-
-export default Search;
diff --git a/frontend/src/components/Updates.tsx b/frontend/src/components/Updates.tsx
deleted file mode 100644
index 9448c68..0000000
--- a/frontend/src/components/Updates.tsx
+++ /dev/null
@@ -1,298 +0,0 @@
-import React, { useState, useEffect, useCallback, useMemo } from "react";
-import { FixedSizeGrid as Grid } from "react-window";
-import AutoSizer from "react-virtualized-auto-sizer";
-import { Button } from "@/components/ui/button";
-import { Input } from "@/components/ui/input";
-import {
- Card,
- CardContent,
- CardDescription,
- CardFooter,
- CardHeader,
- CardTitle,
-} from "@/components/ui/card";
-import {
- GetAvailableUpdates,
- HumanReadableSize,
- UpdateAllPkg,
- UpdateSinglePkg,
-} from "../../wailsjs/go/main/App";
-import { main } from "wailsjs/go/models";
-import { Badge } from "./ui/badge";
-import { Skeleton } from "./ui/skeleton";
-import { ArrowUpCircle, AlertCircle } from "lucide-react";
-import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
-
-const useAvailableUpdates = () => {
- const [availableUpdates, setAvailableUpdates] = useState(
- []
- );
- const [isLoading, setIsLoading] = useState(true);
- const [error, setError] = useState(null);
- const [totalDownloadSize, setTotalDownloadSize] = useState("");
-
- const fetchAvailableUpdates = useCallback(async () => {
- setIsLoading(true);
- try {
- const updates = await GetAvailableUpdates();
- setAvailableUpdates(updates);
- const totalSize = updates.reduce(
- (acc, update) => acc + update.downloadSize,
- 0
- );
- const readableSize = await HumanReadableSize(totalSize);
- setTotalDownloadSize(readableSize);
- setError(null);
- } catch (err) {
- console.error("Error fetching available updates:", err);
- setError("Failed to fetch available updates. Please try again.");
- } finally {
- setIsLoading(false);
- }
- }, []);
-
- useEffect(() => {
- fetchAvailableUpdates();
- const intervalId = setInterval(fetchAvailableUpdates, 5000);
- return () => clearInterval(intervalId);
- }, [fetchAvailableUpdates]);
-
- return {
- availableUpdates,
- isLoading,
- error,
- totalDownloadSize,
- fetchAvailableUpdates,
- };
-};
-
-const useReadableSizes = (availableUpdates: main.UpdateInfo[]) => {
- const [readableSizes, setReadableSizes] = useState<{ [key: string]: string }>(
- {}
- );
-
- useEffect(() => {
- const fetchSizes = async () => {
- const sizes: { [key: string]: string } = {};
- for (const update of availableUpdates) {
- sizes[update.name] = await HumanReadableSize(update.downloadSize);
- }
- setReadableSizes(sizes);
- };
- fetchSizes();
- }, [availableUpdates]);
-
- return readableSizes;
-};
-
-const Updates: React.FC = () => {
- const {
- availableUpdates,
- isLoading,
- error,
- totalDownloadSize,
- fetchAvailableUpdates,
- } = useAvailableUpdates();
- const readableSizes = useReadableSizes(availableUpdates);
- const [searchTerm, setSearchTerm] = useState("");
- const [updatingAll, setUpdatingAll] = useState(false);
- const [updatingPackages, setUpdatingPackages] = useState>(
- new Set()
- );
-
- const filteredUpdates = useMemo(() => {
- return availableUpdates.filter((update) =>
- update.name.toLowerCase().includes(searchTerm.toLowerCase())
- );
- }, [availableUpdates, searchTerm]);
-
- const handleSinglePackageUpdate = async (pkg: string) => {
- setUpdatingPackages((prev) => new Set(prev).add(pkg));
- try {
- await UpdateSinglePkg(pkg);
- } catch (err) {
- console.error(`Error updating package ${pkg}:`, err);
- } finally {
- setUpdatingPackages((prev) => {
- const newSet = new Set(prev);
- newSet.delete(pkg);
- return newSet;
- });
- fetchAvailableUpdates();
- }
- };
-
- const handleAllPackageUpdate = async () => {
- setUpdatingAll(true);
- try {
- await UpdateAllPkg();
- } catch (err) {
- console.error("Error updating all packages:", err);
- } finally {
- setUpdatingAll(false);
- fetchAvailableUpdates();
- }
- };
-
- const UpdateItem = useCallback(
- ({
- columnIndex,
- rowIndex,
- style,
- }: {
- columnIndex: number;
- rowIndex: number;
- style: React.CSSProperties;
- }) => {
- const index = rowIndex * 3 + columnIndex;
- const update = filteredUpdates[index];
- if (!update) return null;
- const isUpdating = updatingPackages.has(update.name) || updatingAll;
- return (
-
-
-
- {update.name}
-
-
-
- Update available: {update.oldVersion} → {update.newVersion}
-
-
- Repository: {update.repository}
-
-
-
-
- {readableSizes[update.name] || "Calculating..."}
-
- handleSinglePackageUpdate(update.name)}
- disabled={isUpdating}
- aria-label={`Update ${update.name}`}
- >
-
- {isUpdating ? "Updating..." : "Update"}
-
-
-
-
- );
- },
- [filteredUpdates, readableSizes, updatingPackages, updatingAll]
- );
-
- const renderContent = useMemo(() => {
- if (isLoading && availableUpdates.length === 0) {
- return (
-
- {Array.from({ length: 9 }, (_, i) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
- ))}
-
- );
- }
-
- if (error) {
- return (
-
-
- Error
- {error}
-
- );
- }
-
- if (filteredUpdates.length === 0) {
- return (
-
-
- No updates available
-
-
- {searchTerm
- ? "No packages match your search."
- : "All packages are up to date!"}
-
-
- );
- }
-
- return (
-
-
- {({ height, width }: { height: number; width: number }) => {
- const columnCount = width >= 1024 ? 3 : width >= 768 ? 2 : 1;
- const columnWidth = width / columnCount;
- const rowCount = Math.ceil(filteredUpdates.length / columnCount);
- return (
-
- {UpdateItem}
-
- );
- }}
-
-
- );
- }, [
- isLoading,
- error,
- filteredUpdates,
- UpdateItem,
- availableUpdates.length,
- searchTerm,
- ]);
-
- return (
-
-
Available Updates
-
-
) =>
- setSearchTerm(e.target.value)
- }
- className="flex-grow"
- aria-label="Search available updates"
- />
-
-
- {updatingAll ? "Updating..." : "Update All"}
-
-
- {totalDownloadSize && (
-
- Total download size: {totalDownloadSize}
-
- )}
- {renderContent}
-
- );
-};
-
-export default React.memo(Updates);
diff --git a/frontend/src/components/ui/alert.tsx b/frontend/src/components/ui/alert.tsx
deleted file mode 100644
index 5afd41d..0000000
--- a/frontend/src/components/ui/alert.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-import * as React from "react"
-import { cva, type VariantProps } from "class-variance-authority"
-
-import { cn } from "@/lib/utils"
-
-const alertVariants = cva(
- "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
- {
- variants: {
- variant: {
- default: "bg-background text-foreground",
- destructive:
- "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
- },
- },
- defaultVariants: {
- variant: "default",
- },
- }
-)
-
-const Alert = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes & VariantProps
->(({ className, variant, ...props }, ref) => (
-
-))
-Alert.displayName = "Alert"
-
-const AlertTitle = React.forwardRef<
- HTMLParagraphElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-))
-AlertTitle.displayName = "AlertTitle"
-
-const AlertDescription = React.forwardRef<
- HTMLParagraphElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-))
-AlertDescription.displayName = "AlertDescription"
-
-export { Alert, AlertTitle, AlertDescription }
diff --git a/frontend/src/components/ui/badge.tsx b/frontend/src/components/ui/badge.tsx
deleted file mode 100644
index f000e3e..0000000
--- a/frontend/src/components/ui/badge.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import * as React from "react"
-import { cva, type VariantProps } from "class-variance-authority"
-
-import { cn } from "@/lib/utils"
-
-const badgeVariants = cva(
- "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
- {
- variants: {
- variant: {
- default:
- "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
- secondary:
- "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
- destructive:
- "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
- outline: "text-foreground",
- },
- },
- defaultVariants: {
- variant: "default",
- },
- }
-)
-
-export interface BadgeProps
- extends React.HTMLAttributes,
- VariantProps {}
-
-function Badge({ className, variant, ...props }: BadgeProps) {
- return (
-
- )
-}
-
-export { Badge, badgeVariants }
diff --git a/frontend/src/components/ui/button.tsx b/frontend/src/components/ui/button.tsx
deleted file mode 100644
index 0ba4277..0000000
--- a/frontend/src/components/ui/button.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import * as React from "react"
-import { Slot } from "@radix-ui/react-slot"
-import { cva, type VariantProps } from "class-variance-authority"
-
-import { cn } from "@/lib/utils"
-
-const buttonVariants = cva(
- "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
- {
- variants: {
- variant: {
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
- destructive:
- "bg-destructive text-destructive-foreground hover:bg-destructive/90",
- outline:
- "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
- secondary:
- "bg-secondary text-secondary-foreground hover:bg-secondary/80",
- ghost: "hover:bg-accent hover:text-accent-foreground",
- link: "text-primary underline-offset-4 hover:underline",
- },
- size: {
- default: "h-10 px-4 py-2",
- sm: "h-9 rounded-md px-3",
- lg: "h-11 rounded-md px-8",
- icon: "h-10 w-10",
- },
- },
- defaultVariants: {
- variant: "default",
- size: "default",
- },
- }
-)
-
-export interface ButtonProps
- extends React.ButtonHTMLAttributes,
- VariantProps {
- asChild?: boolean
-}
-
-const Button = React.forwardRef(
- ({ className, variant, size, asChild = false, ...props }, ref) => {
- const Comp = asChild ? Slot : "button"
- return (
-
- )
- }
-)
-Button.displayName = "Button"
-
-export { Button, buttonVariants }
diff --git a/frontend/src/components/ui/card.tsx b/frontend/src/components/ui/card.tsx
deleted file mode 100644
index 4cb56a6..0000000
--- a/frontend/src/components/ui/card.tsx
+++ /dev/null
@@ -1,86 +0,0 @@
-import * as React from "react";
-
-import { cn } from "@/lib/utils";
-
-const Card = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-));
-Card.displayName = "Card";
-
-const CardHeader = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-));
-CardHeader.displayName = "CardHeader";
-
-const CardTitle = React.forwardRef<
- HTMLParagraphElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-));
-CardTitle.displayName = "CardTitle";
-
-const CardDescription = React.forwardRef<
- HTMLParagraphElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-));
-CardDescription.displayName = "CardDescription";
-
-const CardContent = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-));
-CardContent.displayName = "CardContent";
-
-const CardFooter = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-));
-CardFooter.displayName = "CardFooter";
-
-export {
- Card,
- CardHeader,
- CardFooter,
- CardTitle,
- CardDescription,
- CardContent,
-};
diff --git a/frontend/src/components/ui/checkbox.tsx b/frontend/src/components/ui/checkbox.tsx
deleted file mode 100644
index 8d02b28..0000000
--- a/frontend/src/components/ui/checkbox.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import * as React from "react"
-import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
-import { cn } from "@/lib/utils"
-import { CheckIcon } from "@radix-ui/react-icons"
-
-const Checkbox = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-
-
-
-
-))
-Checkbox.displayName = CheckboxPrimitive.Root.displayName
-
-export { Checkbox }
diff --git a/frontend/src/components/ui/circular-progress.tsx b/frontend/src/components/ui/circular-progress.tsx
deleted file mode 100644
index f6f8e5e..0000000
--- a/frontend/src/components/ui/circular-progress.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import { cn } from "@/lib/utils";
-import React from "react";
-
-interface CircularProgressProps {
- size?: number;
- strokeWidth?: number;
- percentage: number;
-}
-
-const CircularProgress: React.FC = ({
- size = 24,
- strokeWidth = 2,
- percentage,
-}) => {
- const radius = (size - strokeWidth) / 2;
- const circumference = radius * 2 * Math.PI;
- const strokeDashoffset = circumference - (percentage / 100) * circumference;
-
- return (
-
-
-
-
- );
-};
-
-export default CircularProgress;
diff --git a/frontend/src/components/ui/dropdown-menu.tsx b/frontend/src/components/ui/dropdown-menu.tsx
deleted file mode 100644
index d26ae38..0000000
--- a/frontend/src/components/ui/dropdown-menu.tsx
+++ /dev/null
@@ -1,198 +0,0 @@
-import * as React from "react"
-import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
-import { cn } from "@/lib/utils"
-import { CheckIcon, ChevronRightIcon, DotFilledIcon } from "@radix-ui/react-icons"
-
-const DropdownMenu = DropdownMenuPrimitive.Root
-
-const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
-
-const DropdownMenuGroup = DropdownMenuPrimitive.Group
-
-const DropdownMenuPortal = DropdownMenuPrimitive.Portal
-
-const DropdownMenuSub = DropdownMenuPrimitive.Sub
-
-const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
-
-const DropdownMenuSubTrigger = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef & {
- inset?: boolean
- }
->(({ className, inset, children, ...props }, ref) => (
-
- {children}
-
-
-))
-DropdownMenuSubTrigger.displayName =
- DropdownMenuPrimitive.SubTrigger.displayName
-
-const DropdownMenuSubContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-DropdownMenuSubContent.displayName =
- DropdownMenuPrimitive.SubContent.displayName
-
-const DropdownMenuContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, sideOffset = 4, ...props }, ref) => (
-
-
-
-))
-DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
-
-const DropdownMenuItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef & {
- inset?: boolean
- }
->(({ className, inset, ...props }, ref) => (
- svg]:size-4 [&>svg]:shrink-0",
- inset && "pl-8",
- className
- )}
- {...props}
- />
-))
-DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
-
-const DropdownMenuCheckboxItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, children, checked, ...props }, ref) => (
-
-
-
-
-
-
- {children}
-
-))
-DropdownMenuCheckboxItem.displayName =
- DropdownMenuPrimitive.CheckboxItem.displayName
-
-const DropdownMenuRadioItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, children, ...props }, ref) => (
-
-
-
-
-
-
- {children}
-
-))
-DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
-
-const DropdownMenuLabel = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef & {
- inset?: boolean
- }
->(({ className, inset, ...props }, ref) => (
-
-))
-DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
-
-const DropdownMenuSeparator = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
-
-const DropdownMenuShortcut = ({
- className,
- ...props
-}: React.HTMLAttributes) => {
- return (
-
- )
-}
-DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
-
-export {
- DropdownMenu,
- DropdownMenuTrigger,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuCheckboxItem,
- DropdownMenuRadioItem,
- DropdownMenuLabel,
- DropdownMenuSeparator,
- DropdownMenuShortcut,
- DropdownMenuGroup,
- DropdownMenuPortal,
- DropdownMenuSub,
- DropdownMenuSubContent,
- DropdownMenuSubTrigger,
- DropdownMenuRadioGroup,
-}
diff --git a/frontend/src/components/ui/input.tsx b/frontend/src/components/ui/input.tsx
deleted file mode 100644
index 677d05f..0000000
--- a/frontend/src/components/ui/input.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import * as React from "react"
-
-import { cn } from "@/lib/utils"
-
-export interface InputProps
- extends React.InputHTMLAttributes {}
-
-const Input = React.forwardRef(
- ({ className, type, ...props }, ref) => {
- return (
-
- )
- }
-)
-Input.displayName = "Input"
-
-export { Input }
diff --git a/frontend/src/components/ui/label.tsx b/frontend/src/components/ui/label.tsx
deleted file mode 100644
index 683faa7..0000000
--- a/frontend/src/components/ui/label.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import * as React from "react"
-import * as LabelPrimitive from "@radix-ui/react-label"
-import { cva, type VariantProps } from "class-variance-authority"
-
-import { cn } from "@/lib/utils"
-
-const labelVariants = cva(
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
-)
-
-const Label = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef &
- VariantProps
->(({ className, ...props }, ref) => (
-
-))
-Label.displayName = LabelPrimitive.Root.displayName
-
-export { Label }
diff --git a/frontend/src/components/ui/progress.tsx b/frontend/src/components/ui/progress.tsx
deleted file mode 100644
index 105fb65..0000000
--- a/frontend/src/components/ui/progress.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import * as React from "react"
-import * as ProgressPrimitive from "@radix-ui/react-progress"
-
-import { cn } from "@/lib/utils"
-
-const Progress = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, value, ...props }, ref) => (
-
-
-
-))
-Progress.displayName = ProgressPrimitive.Root.displayName
-
-export { Progress }
diff --git a/frontend/src/components/ui/scroll-area.tsx b/frontend/src/components/ui/scroll-area.tsx
deleted file mode 100644
index cf253cf..0000000
--- a/frontend/src/components/ui/scroll-area.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import * as React from "react"
-import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
-
-import { cn } from "@/lib/utils"
-
-const ScrollArea = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, children, ...props }, ref) => (
-
-
- {children}
-
-
-
-
-))
-ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
-
-const ScrollBar = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, orientation = "vertical", ...props }, ref) => (
-
-
-
-))
-ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
-
-export { ScrollArea, ScrollBar }
diff --git a/frontend/src/components/ui/separator.tsx b/frontend/src/components/ui/separator.tsx
deleted file mode 100644
index 6d7f122..0000000
--- a/frontend/src/components/ui/separator.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import * as React from "react"
-import * as SeparatorPrimitive from "@radix-ui/react-separator"
-
-import { cn } from "@/lib/utils"
-
-const Separator = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(
- (
- { className, orientation = "horizontal", decorative = true, ...props },
- ref
- ) => (
-
- )
-)
-Separator.displayName = SeparatorPrimitive.Root.displayName
-
-export { Separator }
diff --git a/frontend/src/components/ui/skeleton.tsx b/frontend/src/components/ui/skeleton.tsx
deleted file mode 100644
index 01b8b6d..0000000
--- a/frontend/src/components/ui/skeleton.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { cn } from "@/lib/utils"
-
-function Skeleton({
- className,
- ...props
-}: React.HTMLAttributes) {
- return (
-
- )
-}
-
-export { Skeleton }
diff --git a/frontend/src/components/ui/tabs.tsx b/frontend/src/components/ui/tabs.tsx
deleted file mode 100644
index 85d83be..0000000
--- a/frontend/src/components/ui/tabs.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import * as React from "react"
-import * as TabsPrimitive from "@radix-ui/react-tabs"
-
-import { cn } from "@/lib/utils"
-
-const Tabs = TabsPrimitive.Root
-
-const TabsList = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-TabsList.displayName = TabsPrimitive.List.displayName
-
-const TabsTrigger = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
-
-const TabsContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-TabsContent.displayName = TabsPrimitive.Content.displayName
-
-export { Tabs, TabsList, TabsTrigger, TabsContent }
diff --git a/frontend/src/components/ui/theme-provider.tsx b/frontend/src/components/ui/theme-provider.tsx
deleted file mode 100644
index 7b9eeb2..0000000
--- a/frontend/src/components/ui/theme-provider.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import { createContext, useContext, useEffect, useState } from "react";
-
-type Theme = "dark" | "light" | "system";
-
-type ThemeProviderProps = {
- children: React.ReactNode;
- defaultTheme?: Theme;
- storageKey?: string;
-};
-
-type ThemeProviderState = {
- theme: Theme;
- setTheme: (theme: Theme) => void;
-};
-
-const initialState: ThemeProviderState = {
- theme: "system",
- setTheme: () => null,
-};
-
-const ThemeProviderContext = createContext(initialState);
-
-export function ThemeProvider({
- children,
- defaultTheme = "system",
- storageKey = "vite-ui-theme",
- ...props
-}: ThemeProviderProps) {
- const [theme, setTheme] = useState(
- () => (localStorage.getItem(storageKey) as Theme) || defaultTheme
- );
-
- useEffect(() => {
- const root = window.document.documentElement;
-
- root.classList.remove("light", "dark");
-
- if (theme === "system") {
- const systemTheme = window.matchMedia("(prefers-color-scheme: dark)")
- .matches
- ? "dark"
- : "light";
-
- root.classList.add(systemTheme);
- return;
- }
-
- root.classList.add(theme);
- }, [theme]);
-
- const value = {
- theme,
- setTheme: (theme: Theme) => {
- localStorage.setItem(storageKey, theme);
- setTheme(theme);
- },
- };
-
- return (
-
- {children}
-
- );
-}
-
-export const useTheme = () => {
- const context = useContext(ThemeProviderContext);
-
- if (context === undefined)
- throw new Error("useTheme must be used within a ThemeProvider");
-
- return context;
-};
diff --git a/frontend/src/components/ui/toast.tsx b/frontend/src/components/ui/toast.tsx
deleted file mode 100644
index a822477..0000000
--- a/frontend/src/components/ui/toast.tsx
+++ /dev/null
@@ -1,127 +0,0 @@
-import * as React from "react"
-import * as ToastPrimitives from "@radix-ui/react-toast"
-import { cva, type VariantProps } from "class-variance-authority"
-import { X } from "lucide-react"
-
-import { cn } from "@/lib/utils"
-
-const ToastProvider = ToastPrimitives.Provider
-
-const ToastViewport = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-ToastViewport.displayName = ToastPrimitives.Viewport.displayName
-
-const toastVariants = cva(
- "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
- {
- variants: {
- variant: {
- default: "border bg-background text-foreground",
- destructive:
- "destructive group border-destructive bg-destructive text-destructive-foreground",
- },
- },
- defaultVariants: {
- variant: "default",
- },
- }
-)
-
-const Toast = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef &
- VariantProps
->(({ className, variant, ...props }, ref) => {
- return (
-
- )
-})
-Toast.displayName = ToastPrimitives.Root.displayName
-
-const ToastAction = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-ToastAction.displayName = ToastPrimitives.Action.displayName
-
-const ToastClose = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-
-
-))
-ToastClose.displayName = ToastPrimitives.Close.displayName
-
-const ToastTitle = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-ToastTitle.displayName = ToastPrimitives.Title.displayName
-
-const ToastDescription = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-ToastDescription.displayName = ToastPrimitives.Description.displayName
-
-type ToastProps = React.ComponentPropsWithoutRef
-
-type ToastActionElement = React.ReactElement
-
-export {
- type ToastProps,
- type ToastActionElement,
- ToastProvider,
- ToastViewport,
- Toast,
- ToastTitle,
- ToastDescription,
- ToastClose,
- ToastAction,
-}
diff --git a/frontend/src/components/ui/toaster.tsx b/frontend/src/components/ui/toaster.tsx
deleted file mode 100644
index a2209ba..0000000
--- a/frontend/src/components/ui/toaster.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import {
- Toast,
- ToastClose,
- ToastDescription,
- ToastProvider,
- ToastTitle,
- ToastViewport,
-} from "@/components/ui/toast"
-import { useToast } from "@/components/ui/use-toast"
-
-export function Toaster() {
- const { toasts } = useToast()
-
- return (
-
- {toasts.map(function ({ id, title, description, action, ...props }) {
- return (
-
-
- {title && {title} }
- {description && (
- {description}
- )}
-
- {action}
-
-
- )
- })}
-
-
- )
-}
diff --git a/frontend/src/components/ui/tooltip.tsx b/frontend/src/components/ui/tooltip.tsx
deleted file mode 100644
index a9c71ba..0000000
--- a/frontend/src/components/ui/tooltip.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import * as React from "react"
-import * as TooltipPrimitive from "@radix-ui/react-tooltip"
-
-import { cn } from "@/lib/utils"
-
-const TooltipProvider = TooltipPrimitive.Provider
-
-const Tooltip = TooltipPrimitive.Root
-
-const TooltipTrigger = TooltipPrimitive.Trigger
-
-const TooltipContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, sideOffset = 4, ...props }, ref) => (
-
-))
-TooltipContent.displayName = TooltipPrimitive.Content.displayName
-
-export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
diff --git a/frontend/src/components/ui/use-toast.ts b/frontend/src/components/ui/use-toast.ts
deleted file mode 100644
index 1671307..0000000
--- a/frontend/src/components/ui/use-toast.ts
+++ /dev/null
@@ -1,192 +0,0 @@
-// Inspired by react-hot-toast library
-import * as React from "react"
-
-import type {
- ToastActionElement,
- ToastProps,
-} from "@/components/ui/toast"
-
-const TOAST_LIMIT = 1
-const TOAST_REMOVE_DELAY = 1000000
-
-type ToasterToast = ToastProps & {
- id: string
- title?: React.ReactNode
- description?: React.ReactNode
- action?: ToastActionElement
-}
-
-const actionTypes = {
- ADD_TOAST: "ADD_TOAST",
- UPDATE_TOAST: "UPDATE_TOAST",
- DISMISS_TOAST: "DISMISS_TOAST",
- REMOVE_TOAST: "REMOVE_TOAST",
-} as const
-
-let count = 0
-
-function genId() {
- count = (count + 1) % Number.MAX_SAFE_INTEGER
- return count.toString()
-}
-
-type ActionType = typeof actionTypes
-
-type Action =
- | {
- type: ActionType["ADD_TOAST"]
- toast: ToasterToast
- }
- | {
- type: ActionType["UPDATE_TOAST"]
- toast: Partial
- }
- | {
- type: ActionType["DISMISS_TOAST"]
- toastId?: ToasterToast["id"]
- }
- | {
- type: ActionType["REMOVE_TOAST"]
- toastId?: ToasterToast["id"]
- }
-
-interface State {
- toasts: ToasterToast[]
-}
-
-const toastTimeouts = new Map>()
-
-const addToRemoveQueue = (toastId: string) => {
- if (toastTimeouts.has(toastId)) {
- return
- }
-
- const timeout = setTimeout(() => {
- toastTimeouts.delete(toastId)
- dispatch({
- type: "REMOVE_TOAST",
- toastId: toastId,
- })
- }, TOAST_REMOVE_DELAY)
-
- toastTimeouts.set(toastId, timeout)
-}
-
-export const reducer = (state: State, action: Action): State => {
- switch (action.type) {
- case "ADD_TOAST":
- return {
- ...state,
- toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
- }
-
- case "UPDATE_TOAST":
- return {
- ...state,
- toasts: state.toasts.map((t) =>
- t.id === action.toast.id ? { ...t, ...action.toast } : t
- ),
- }
-
- case "DISMISS_TOAST": {
- const { toastId } = action
-
- // ! Side effects ! - This could be extracted into a dismissToast() action,
- // but I'll keep it here for simplicity
- if (toastId) {
- addToRemoveQueue(toastId)
- } else {
- state.toasts.forEach((toast) => {
- addToRemoveQueue(toast.id)
- })
- }
-
- return {
- ...state,
- toasts: state.toasts.map((t) =>
- t.id === toastId || toastId === undefined
- ? {
- ...t,
- open: false,
- }
- : t
- ),
- }
- }
- case "REMOVE_TOAST":
- if (action.toastId === undefined) {
- return {
- ...state,
- toasts: [],
- }
- }
- return {
- ...state,
- toasts: state.toasts.filter((t) => t.id !== action.toastId),
- }
- }
-}
-
-const listeners: Array<(state: State) => void> = []
-
-let memoryState: State = { toasts: [] }
-
-function dispatch(action: Action) {
- memoryState = reducer(memoryState, action)
- listeners.forEach((listener) => {
- listener(memoryState)
- })
-}
-
-type Toast = Omit
-
-function toast({ ...props }: Toast) {
- const id = genId()
-
- const update = (props: ToasterToast) =>
- dispatch({
- type: "UPDATE_TOAST",
- toast: { ...props, id },
- })
- const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id })
-
- dispatch({
- type: "ADD_TOAST",
- toast: {
- ...props,
- id,
- open: true,
- onOpenChange: (open) => {
- if (!open) dismiss()
- },
- },
- })
-
- return {
- id: id,
- dismiss,
- update,
- }
-}
-
-function useToast() {
- const [state, setState] = React.useState(memoryState)
-
- React.useEffect(() => {
- listeners.push(setState)
- return () => {
- const index = listeners.indexOf(setState)
- if (index > -1) {
- listeners.splice(index, 1)
- }
- }
- }, [state])
-
- return {
- ...state,
- toast,
- dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }),
- }
-}
-
-export { useToast, toast }
diff --git a/frontend/src/globals.css b/frontend/src/globals.css
deleted file mode 100644
index 3a62e20..0000000
--- a/frontend/src/globals.css
+++ /dev/null
@@ -1,101 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
-
-body {
- font-family: "Geist Sans", sans-serif;
-}
-
-@layer base {
- :root {
- --background: 0 0% 100%;
- --foreground: 222.2 84% 4.9%;
-
- --card: 0 0% 100%;
- --card-foreground: 222.2 84% 4.9%;
-
- --popover: 0 0% 100%;
- --popover-foreground: 222.2 84% 4.9%;
-
- --primary: 222.2 47.4% 11.2%;
- --primary-foreground: 210 40% 98%;
-
- --secondary: 210 40% 96.1%;
- --secondary-foreground: 222.2 47.4% 11.2%;
-
- --muted: 210 40% 96.1%;
- --muted-foreground: 215.4 16.3% 46.9%;
-
- --accent: 210 40% 96.1%;
- --accent-foreground: 222.2 47.4% 11.2%;
-
- --destructive: 0 84.2% 60.2%;
- --destructive-foreground: 210 40% 98%;
-
- --border: 214.3 31.8% 91.4%;
- --input: 214.3 31.8% 91.4%;
- --ring: 222.2 84% 4.9%;
-
- --radius: 0.5rem;
-
- --chart-1: 12 76% 61%;
- --chart-2: 173 58% 39%;
- --chart-3: 197 37% 24%;
- --chart-4: 43 74% 66%;
- --chart-5: 27 87% 67%;
- }
-
- .dark {
- --background: 240 14.3% 3.5%;
- --foreground: 210 40% 98%;
-
- --card: 240 14.3% 5.5%;
- --card-foreground: 210 40% 98%;
-
- --popover: 222.2 84% 4.9%;
- --popover-foreground: 210 40% 98%;
-
- --primary: 210 40% 98%;
- --primary-foreground: 222.2 47.4% 11.2%;
-
- --secondary: 217.2 32.6% 17.5%;
- --secondary-foreground: 210 40% 98%;
-
- --muted: 217.2 32.6% 17.5%;
- --muted-foreground: 215 20.2% 65.1%;
-
- --accent: 217.2 32.6% 17.5%;
- --accent-foreground: 210 40% 98%;
-
- --destructive: 0 62.8% 30.6%;
- --destructive-foreground: 210 40% 98%;
-
- --border: 217.2 32.6% 17.5%;
- --input: 217.2 32.6% 17.5%;
- --ring: 212.7 26.8% 83.9%;
-
- --chart-1: 220 70% 50%;
- --chart-2: 160 60% 45%;
- --chart-3: 30 80% 55%;
- --chart-4: 280 65% 60%;
- --chart-5: 340 75% 55%;
- }
-}
-
-@layer base {
- * {
- @apply border-border;
- }
- body {
- @apply bg-background text-foreground;
- }
-}
-
-html {
- height: 100%;
- overflow: hidden;
-}
-
-.nodrag {
- --wails-draggable: no-drag;
-}
diff --git a/frontend/src/lib/utils.ts b/frontend/src/lib/utils.ts
deleted file mode 100644
index ec79801..0000000
--- a/frontend/src/lib/utils.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { type ClassValue, clsx } from "clsx"
-import { twMerge } from "tailwind-merge"
-
-export function cn(...inputs: ClassValue[]) {
- return twMerge(clsx(inputs))
-}
diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx
deleted file mode 100644
index 277011d..0000000
--- a/frontend/src/main.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import React from 'react'
-import {createRoot} from 'react-dom/client'
-import './globals.css'
-import App from './App'
-
-const container = document.getElementById('root')
-
-const root = createRoot(container!)
-
-root.render(
-
-
-
-)
diff --git a/frontend/src/vite-env.d.ts b/frontend/src/vite-env.d.ts
deleted file mode 100644
index 11f02fe..0000000
--- a/frontend/src/vite-env.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-///
diff --git a/frontend/tailwind.config.cjs b/frontend/tailwind.config.cjs
deleted file mode 100644
index 36a84d5..0000000
--- a/frontend/tailwind.config.cjs
+++ /dev/null
@@ -1,77 +0,0 @@
-/** @type {import('tailwindcss').Config} */
-module.exports = {
- darkMode: ["class"],
- content: [
- "./index.html",
- './pages/**/*.{ts,tsx}',
- './components/**/*.{ts,tsx}',
- './app/**/*.{ts,tsx}',
- './src/**/*.{ts,tsx}',
- ],
- theme: {
- container: {
- center: true,
- padding: "2rem",
- screens: {
- "2xl": "1400px",
- },
- },
- extend: {
- colors: {
- border: "hsl(var(--border))",
- input: "hsl(var(--input))",
- ring: "hsl(var(--ring))",
- background: "hsl(var(--background))",
- foreground: "hsl(var(--foreground))",
- primary: {
- DEFAULT: "hsl(var(--primary))",
- foreground: "hsl(var(--primary-foreground))",
- },
- secondary: {
- DEFAULT: "hsl(var(--secondary))",
- foreground: "hsl(var(--secondary-foreground))",
- },
- destructive: {
- DEFAULT: "hsl(var(--destructive))",
- foreground: "hsl(var(--destructive-foreground))",
- },
- muted: {
- DEFAULT: "hsl(var(--muted))",
- foreground: "hsl(var(--muted-foreground))",
- },
- accent: {
- DEFAULT: "hsl(var(--accent))",
- foreground: "hsl(var(--accent-foreground))",
- },
- popover: {
- DEFAULT: "hsl(var(--popover))",
- foreground: "hsl(var(--popover-foreground))",
- },
- card: {
- DEFAULT: "hsl(var(--card))",
- foreground: "hsl(var(--card-foreground))",
- },
- },
- borderRadius: {
- lg: "var(--radius)",
- md: "calc(var(--radius) - 2px)",
- sm: "calc(var(--radius) - 4px)",
- },
- keyframes: {
- "accordion-down": {
- from: { height: 0 },
- to: { height: "var(--radix-accordion-content-height)" },
- },
- "accordion-up": {
- from: { height: "var(--radix-accordion-content-height)" },
- to: { height: 0 },
- },
- },
- animation: {
- "accordion-down": "accordion-down 0.2s ease-out",
- "accordion-up": "accordion-up 0.2s ease-out",
- },
- },
- },
- plugins: [require("tailwindcss-animate")],
-}
\ No newline at end of file
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json
deleted file mode 100644
index ffd60f8..0000000
--- a/frontend/tsconfig.json
+++ /dev/null
@@ -1,37 +0,0 @@
-{
- "compilerOptions": {
- "baseUrl": ".",
- "paths": {
- "@/*": [
- "./src/*"
- ]
- },
- "target": "ESNext",
- "useDefineForClassFields": true,
- "lib": [
- "DOM",
- "DOM.Iterable",
- "ESNext"
- ],
- "allowJs": false,
- "skipLibCheck": true,
- "esModuleInterop": false,
- "allowSyntheticDefaultImports": true,
- "strict": true,
- "forceConsistentCasingInFileNames": true,
- "module": "ESNext",
- "moduleResolution": "Node",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "react-jsx"
- },
- "include": [
- "src"
- ],
- "references": [
- {
- "path": "./tsconfig.node.json"
- }
- ]
-}
diff --git a/frontend/tsconfig.node.json b/frontend/tsconfig.node.json
deleted file mode 100644
index b8afcc8..0000000
--- a/frontend/tsconfig.node.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "compilerOptions": {
- "composite": true,
- "module": "ESNext",
- "moduleResolution": "Node",
- "allowSyntheticDefaultImports": true
- },
- "include": [
- "vite.config.ts"
- ]
-}
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
deleted file mode 100644
index d36c010..0000000
--- a/frontend/vite.config.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import path from "path"
-import react from "@vitejs/plugin-react"
-import { defineConfig } from "vite"
-
-export default defineConfig({
- plugins: [react()],
- resolve: {
- alias: {
- "@": path.resolve(__dirname, "./src"),
- },
- },
-})
\ No newline at end of file
diff --git a/frontend/wailsjs/go/main/App.d.ts b/frontend/wailsjs/go/main/App.d.ts
deleted file mode 100755
index a58abf5..0000000
--- a/frontend/wailsjs/go/main/App.d.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
-// This file is automatically generated. DO NOT EDIT
-import {main} from '../models';
-
-export function CheckPackageInstalled(arg1:string):Promise;
-
-export function GetAvailableUpdates():Promise>;
-
-export function GetInstalledPackages():Promise>;
-
-export function GetMultiplePackageInfo(arg1:Array):Promise>;
-
-export function HumanReadableSize(arg1:number):Promise;
-
-export function Install(arg1:string):Promise;
-
-export function SearchLocalPackage(arg1:string):Promise;
-
-export function SearchPackage(arg1:string):Promise>;
-
-export function Uninstall(arg1:string):Promise;
-
-export function UpdateAllPkg():Promise;
-
-export function UpdateSinglePkg(arg1:string):Promise;
diff --git a/frontend/wailsjs/go/main/App.js b/frontend/wailsjs/go/main/App.js
deleted file mode 100755
index 65ab958..0000000
--- a/frontend/wailsjs/go/main/App.js
+++ /dev/null
@@ -1,47 +0,0 @@
-// @ts-check
-// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
-// This file is automatically generated. DO NOT EDIT
-
-export function CheckPackageInstalled(arg1) {
- return window['go']['main']['App']['CheckPackageInstalled'](arg1);
-}
-
-export function GetAvailableUpdates() {
- return window['go']['main']['App']['GetAvailableUpdates']();
-}
-
-export function GetInstalledPackages() {
- return window['go']['main']['App']['GetInstalledPackages']();
-}
-
-export function GetMultiplePackageInfo(arg1) {
- return window['go']['main']['App']['GetMultiplePackageInfo'](arg1);
-}
-
-export function HumanReadableSize(arg1) {
- return window['go']['main']['App']['HumanReadableSize'](arg1);
-}
-
-export function Install(arg1) {
- return window['go']['main']['App']['Install'](arg1);
-}
-
-export function SearchLocalPackage(arg1) {
- return window['go']['main']['App']['SearchLocalPackage'](arg1);
-}
-
-export function SearchPackage(arg1) {
- return window['go']['main']['App']['SearchPackage'](arg1);
-}
-
-export function Uninstall(arg1) {
- return window['go']['main']['App']['Uninstall'](arg1);
-}
-
-export function UpdateAllPkg() {
- return window['go']['main']['App']['UpdateAllPkg']();
-}
-
-export function UpdateSinglePkg(arg1) {
- return window['go']['main']['App']['UpdateSinglePkg'](arg1);
-}
diff --git a/frontend/wailsjs/go/models.ts b/frontend/wailsjs/go/models.ts
deleted file mode 100755
index 4977036..0000000
--- a/frontend/wailsjs/go/models.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-export namespace main {
-
- export class PackageInfo {
- name: string;
- version: string;
- description: string;
- repository: string;
- maintainer: string;
- upstreamurl: string;
- dependlist: string[];
- lastupdated: string;
-
- static createFrom(source: any = {}) {
- return new PackageInfo(source);
- }
-
- constructor(source: any = {}) {
- if ('string' === typeof source) source = JSON.parse(source);
- this.name = source["name"];
- this.version = source["version"];
- this.description = source["description"];
- this.repository = source["repository"];
- this.maintainer = source["maintainer"];
- this.upstreamurl = source["upstreamurl"];
- this.dependlist = source["dependlist"];
- this.lastupdated = source["lastupdated"];
- }
- }
- export class UpdateInfo {
- name: string;
- oldVersion: string;
- newVersion: string;
- repository: string;
- downloadSize: number;
-
- static createFrom(source: any = {}) {
- return new UpdateInfo(source);
- }
-
- constructor(source: any = {}) {
- if ('string' === typeof source) source = JSON.parse(source);
- this.name = source["name"];
- this.oldVersion = source["oldVersion"];
- this.newVersion = source["newVersion"];
- this.repository = source["repository"];
- this.downloadSize = source["downloadSize"];
- }
- }
-
-}
-
diff --git a/frontend/wailsjs/runtime/package.json b/frontend/wailsjs/runtime/package.json
deleted file mode 100644
index 1e7c8a5..0000000
--- a/frontend/wailsjs/runtime/package.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "name": "@wailsapp/runtime",
- "version": "2.0.0",
- "description": "Wails Javascript runtime library",
- "main": "runtime.js",
- "types": "runtime.d.ts",
- "scripts": {
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/wailsapp/wails.git"
- },
- "keywords": [
- "Wails",
- "Javascript",
- "Go"
- ],
- "author": "Lea Anthony ",
- "license": "MIT",
- "bugs": {
- "url": "https://github.com/wailsapp/wails/issues"
- },
- "homepage": "https://github.com/wailsapp/wails#readme"
-}
diff --git a/frontend/wailsjs/runtime/runtime.d.ts b/frontend/wailsjs/runtime/runtime.d.ts
deleted file mode 100644
index 94778df..0000000
--- a/frontend/wailsjs/runtime/runtime.d.ts
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- _ __ _ __
-| | / /___ _(_) /____
-| | /| / / __ `/ / / ___/
-| |/ |/ / /_/ / / (__ )
-|__/|__/\__,_/_/_/____/
-The electron alternative for Go
-(c) Lea Anthony 2019-present
-*/
-
-export interface Position {
- x: number;
- y: number;
-}
-
-export interface Size {
- w: number;
- h: number;
-}
-
-export interface Screen {
- isCurrent: boolean;
- isPrimary: boolean;
- width : number
- height : number
-}
-
-// Environment information such as platform, buildtype, ...
-export interface EnvironmentInfo {
- buildType: string;
- platform: string;
- arch: string;
-}
-
-// [EventsEmit](https://wails.io/docs/reference/runtime/events#eventsemit)
-// emits the given event. Optional data may be passed with the event.
-// This will trigger any event listeners.
-export function EventsEmit(eventName: string, ...data: any): void;
-
-// [EventsOn](https://wails.io/docs/reference/runtime/events#eventson) sets up a listener for the given event name.
-export function EventsOn(eventName: string, callback: (...data: any) => void): () => void;
-
-// [EventsOnMultiple](https://wails.io/docs/reference/runtime/events#eventsonmultiple)
-// sets up a listener for the given event name, but will only trigger a given number times.
-export function EventsOnMultiple(eventName: string, callback: (...data: any) => void, maxCallbacks: number): () => void;
-
-// [EventsOnce](https://wails.io/docs/reference/runtime/events#eventsonce)
-// sets up a listener for the given event name, but will only trigger once.
-export function EventsOnce(eventName: string, callback: (...data: any) => void): () => void;
-
-// [EventsOff](https://wails.io/docs/reference/runtime/events#eventsoff)
-// unregisters the listener for the given event name.
-export function EventsOff(eventName: string, ...additionalEventNames: string[]): void;
-
-// [EventsOffAll](https://wails.io/docs/reference/runtime/events#eventsoffall)
-// unregisters all listeners.
-export function EventsOffAll(): void;
-
-// [LogPrint](https://wails.io/docs/reference/runtime/log#logprint)
-// logs the given message as a raw message
-export function LogPrint(message: string): void;
-
-// [LogTrace](https://wails.io/docs/reference/runtime/log#logtrace)
-// logs the given message at the `trace` log level.
-export function LogTrace(message: string): void;
-
-// [LogDebug](https://wails.io/docs/reference/runtime/log#logdebug)
-// logs the given message at the `debug` log level.
-export function LogDebug(message: string): void;
-
-// [LogError](https://wails.io/docs/reference/runtime/log#logerror)
-// logs the given message at the `error` log level.
-export function LogError(message: string): void;
-
-// [LogFatal](https://wails.io/docs/reference/runtime/log#logfatal)
-// logs the given message at the `fatal` log level.
-// The application will quit after calling this method.
-export function LogFatal(message: string): void;
-
-// [LogInfo](https://wails.io/docs/reference/runtime/log#loginfo)
-// logs the given message at the `info` log level.
-export function LogInfo(message: string): void;
-
-// [LogWarning](https://wails.io/docs/reference/runtime/log#logwarning)
-// logs the given message at the `warning` log level.
-export function LogWarning(message: string): void;
-
-// [WindowReload](https://wails.io/docs/reference/runtime/window#windowreload)
-// Forces a reload by the main application as well as connected browsers.
-export function WindowReload(): void;
-
-// [WindowReloadApp](https://wails.io/docs/reference/runtime/window#windowreloadapp)
-// Reloads the application frontend.
-export function WindowReloadApp(): void;
-
-// [WindowSetAlwaysOnTop](https://wails.io/docs/reference/runtime/window#windowsetalwaysontop)
-// Sets the window AlwaysOnTop or not on top.
-export function WindowSetAlwaysOnTop(b: boolean): void;
-
-// [WindowSetSystemDefaultTheme](https://wails.io/docs/next/reference/runtime/window#windowsetsystemdefaulttheme)
-// *Windows only*
-// Sets window theme to system default (dark/light).
-export function WindowSetSystemDefaultTheme(): void;
-
-// [WindowSetLightTheme](https://wails.io/docs/next/reference/runtime/window#windowsetlighttheme)
-// *Windows only*
-// Sets window to light theme.
-export function WindowSetLightTheme(): void;
-
-// [WindowSetDarkTheme](https://wails.io/docs/next/reference/runtime/window#windowsetdarktheme)
-// *Windows only*
-// Sets window to dark theme.
-export function WindowSetDarkTheme(): void;
-
-// [WindowCenter](https://wails.io/docs/reference/runtime/window#windowcenter)
-// Centers the window on the monitor the window is currently on.
-export function WindowCenter(): void;
-
-// [WindowSetTitle](https://wails.io/docs/reference/runtime/window#windowsettitle)
-// Sets the text in the window title bar.
-export function WindowSetTitle(title: string): void;
-
-// [WindowFullscreen](https://wails.io/docs/reference/runtime/window#windowfullscreen)
-// Makes the window full screen.
-export function WindowFullscreen(): void;
-
-// [WindowUnfullscreen](https://wails.io/docs/reference/runtime/window#windowunfullscreen)
-// Restores the previous window dimensions and position prior to full screen.
-export function WindowUnfullscreen(): void;
-
-// [WindowIsFullscreen](https://wails.io/docs/reference/runtime/window#windowisfullscreen)
-// Returns the state of the window, i.e. whether the window is in full screen mode or not.
-export function WindowIsFullscreen(): Promise;
-
-// [WindowSetSize](https://wails.io/docs/reference/runtime/window#windowsetsize)
-// Sets the width and height of the window.
-export function WindowSetSize(width: number, height: number): Promise;
-
-// [WindowGetSize](https://wails.io/docs/reference/runtime/window#windowgetsize)
-// Gets the width and height of the window.
-export function WindowGetSize(): Promise;
-
-// [WindowSetMaxSize](https://wails.io/docs/reference/runtime/window#windowsetmaxsize)
-// Sets the maximum window size. Will resize the window if the window is currently larger than the given dimensions.
-// Setting a size of 0,0 will disable this constraint.
-export function WindowSetMaxSize(width: number, height: number): void;
-
-// [WindowSetMinSize](https://wails.io/docs/reference/runtime/window#windowsetminsize)
-// Sets the minimum window size. Will resize the window if the window is currently smaller than the given dimensions.
-// Setting a size of 0,0 will disable this constraint.
-export function WindowSetMinSize(width: number, height: number): void;
-
-// [WindowSetPosition](https://wails.io/docs/reference/runtime/window#windowsetposition)
-// Sets the window position relative to the monitor the window is currently on.
-export function WindowSetPosition(x: number, y: number): void;
-
-// [WindowGetPosition](https://wails.io/docs/reference/runtime/window#windowgetposition)
-// Gets the window position relative to the monitor the window is currently on.
-export function WindowGetPosition(): Promise;
-
-// [WindowHide](https://wails.io/docs/reference/runtime/window#windowhide)
-// Hides the window.
-export function WindowHide(): void;
-
-// [WindowShow](https://wails.io/docs/reference/runtime/window#windowshow)
-// Shows the window, if it is currently hidden.
-export function WindowShow(): void;
-
-// [WindowMaximise](https://wails.io/docs/reference/runtime/window#windowmaximise)
-// Maximises the window to fill the screen.
-export function WindowMaximise(): void;
-
-// [WindowToggleMaximise](https://wails.io/docs/reference/runtime/window#windowtogglemaximise)
-// Toggles between Maximised and UnMaximised.
-export function WindowToggleMaximise(): void;
-
-// [WindowUnmaximise](https://wails.io/docs/reference/runtime/window#windowunmaximise)
-// Restores the window to the dimensions and position prior to maximising.
-export function WindowUnmaximise(): void;
-
-// [WindowIsMaximised](https://wails.io/docs/reference/runtime/window#windowismaximised)
-// Returns the state of the window, i.e. whether the window is maximised or not.
-export function WindowIsMaximised(): Promise;
-
-// [WindowMinimise](https://wails.io/docs/reference/runtime/window#windowminimise)
-// Minimises the window.
-export function WindowMinimise(): void;
-
-// [WindowUnminimise](https://wails.io/docs/reference/runtime/window#windowunminimise)
-// Restores the window to the dimensions and position prior to minimising.
-export function WindowUnminimise(): void;
-
-// [WindowIsMinimised](https://wails.io/docs/reference/runtime/window#windowisminimised)
-// Returns the state of the window, i.e. whether the window is minimised or not.
-export function WindowIsMinimised(): Promise;
-
-// [WindowIsNormal](https://wails.io/docs/reference/runtime/window#windowisnormal)
-// Returns the state of the window, i.e. whether the window is normal or not.
-export function WindowIsNormal(): Promise;
-
-// [WindowSetBackgroundColour](https://wails.io/docs/reference/runtime/window#windowsetbackgroundcolour)
-// Sets the background colour of the window to the given RGBA colour definition. This colour will show through for all transparent pixels.
-export function WindowSetBackgroundColour(R: number, G: number, B: number, A: number): void;
-
-// [ScreenGetAll](https://wails.io/docs/reference/runtime/window#screengetall)
-// Gets the all screens. Call this anew each time you want to refresh data from the underlying windowing system.
-export function ScreenGetAll(): Promise;
-
-// [BrowserOpenURL](https://wails.io/docs/reference/runtime/browser#browseropenurl)
-// Opens the given URL in the system browser.
-export function BrowserOpenURL(url: string): void;
-
-// [Environment](https://wails.io/docs/reference/runtime/intro#environment)
-// Returns information about the environment
-export function Environment(): Promise;
-
-// [Quit](https://wails.io/docs/reference/runtime/intro#quit)
-// Quits the application.
-export function Quit(): void;
-
-// [Hide](https://wails.io/docs/reference/runtime/intro#hide)
-// Hides the application.
-export function Hide(): void;
-
-// [Show](https://wails.io/docs/reference/runtime/intro#show)
-// Shows the application.
-export function Show(): void;
-
-// [ClipboardGetText](https://wails.io/docs/reference/runtime/clipboard#clipboardgettext)
-// Returns the current text stored on clipboard
-export function ClipboardGetText(): Promise;
-
-// [ClipboardSetText](https://wails.io/docs/reference/runtime/clipboard#clipboardsettext)
-// Sets a text on the clipboard
-export function ClipboardSetText(text: string): Promise;
-
-// [OnFileDrop](https://wails.io/docs/reference/runtime/draganddrop#onfiledrop)
-// OnFileDrop listens to drag and drop events and calls the callback with the coordinates of the drop and an array of path strings.
-export function OnFileDrop(callback: (x: number, y: number ,paths: string[]) => void, useDropTarget: boolean) :void
-
-// [OnFileDropOff](https://wails.io/docs/reference/runtime/draganddrop#dragandddropoff)
-// OnFileDropOff removes the drag and drop listeners and handlers.
-export function OnFileDropOff() :void
-
-// Check if the file path resolver is available
-export function CanResolveFilePaths(): boolean;
-
-// Resolves file paths for an array of files
-export function ResolveFilePaths(files: File[]): void
\ No newline at end of file
diff --git a/frontend/wailsjs/runtime/runtime.js b/frontend/wailsjs/runtime/runtime.js
deleted file mode 100644
index 623397b..0000000
--- a/frontend/wailsjs/runtime/runtime.js
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- _ __ _ __
-| | / /___ _(_) /____
-| | /| / / __ `/ / / ___/
-| |/ |/ / /_/ / / (__ )
-|__/|__/\__,_/_/_/____/
-The electron alternative for Go
-(c) Lea Anthony 2019-present
-*/
-
-export function LogPrint(message) {
- window.runtime.LogPrint(message);
-}
-
-export function LogTrace(message) {
- window.runtime.LogTrace(message);
-}
-
-export function LogDebug(message) {
- window.runtime.LogDebug(message);
-}
-
-export function LogInfo(message) {
- window.runtime.LogInfo(message);
-}
-
-export function LogWarning(message) {
- window.runtime.LogWarning(message);
-}
-
-export function LogError(message) {
- window.runtime.LogError(message);
-}
-
-export function LogFatal(message) {
- window.runtime.LogFatal(message);
-}
-
-export function EventsOnMultiple(eventName, callback, maxCallbacks) {
- return window.runtime.EventsOnMultiple(eventName, callback, maxCallbacks);
-}
-
-export function EventsOn(eventName, callback) {
- return EventsOnMultiple(eventName, callback, -1);
-}
-
-export function EventsOff(eventName, ...additionalEventNames) {
- return window.runtime.EventsOff(eventName, ...additionalEventNames);
-}
-
-export function EventsOnce(eventName, callback) {
- return EventsOnMultiple(eventName, callback, 1);
-}
-
-export function EventsEmit(eventName) {
- let args = [eventName].slice.call(arguments);
- return window.runtime.EventsEmit.apply(null, args);
-}
-
-export function WindowReload() {
- window.runtime.WindowReload();
-}
-
-export function WindowReloadApp() {
- window.runtime.WindowReloadApp();
-}
-
-export function WindowSetAlwaysOnTop(b) {
- window.runtime.WindowSetAlwaysOnTop(b);
-}
-
-export function WindowSetSystemDefaultTheme() {
- window.runtime.WindowSetSystemDefaultTheme();
-}
-
-export function WindowSetLightTheme() {
- window.runtime.WindowSetLightTheme();
-}
-
-export function WindowSetDarkTheme() {
- window.runtime.WindowSetDarkTheme();
-}
-
-export function WindowCenter() {
- window.runtime.WindowCenter();
-}
-
-export function WindowSetTitle(title) {
- window.runtime.WindowSetTitle(title);
-}
-
-export function WindowFullscreen() {
- window.runtime.WindowFullscreen();
-}
-
-export function WindowUnfullscreen() {
- window.runtime.WindowUnfullscreen();
-}
-
-export function WindowIsFullscreen() {
- return window.runtime.WindowIsFullscreen();
-}
-
-export function WindowGetSize() {
- return window.runtime.WindowGetSize();
-}
-
-export function WindowSetSize(width, height) {
- window.runtime.WindowSetSize(width, height);
-}
-
-export function WindowSetMaxSize(width, height) {
- window.runtime.WindowSetMaxSize(width, height);
-}
-
-export function WindowSetMinSize(width, height) {
- window.runtime.WindowSetMinSize(width, height);
-}
-
-export function WindowSetPosition(x, y) {
- window.runtime.WindowSetPosition(x, y);
-}
-
-export function WindowGetPosition() {
- return window.runtime.WindowGetPosition();
-}
-
-export function WindowHide() {
- window.runtime.WindowHide();
-}
-
-export function WindowShow() {
- window.runtime.WindowShow();
-}
-
-export function WindowMaximise() {
- window.runtime.WindowMaximise();
-}
-
-export function WindowToggleMaximise() {
- window.runtime.WindowToggleMaximise();
-}
-
-export function WindowUnmaximise() {
- window.runtime.WindowUnmaximise();
-}
-
-export function WindowIsMaximised() {
- return window.runtime.WindowIsMaximised();
-}
-
-export function WindowMinimise() {
- window.runtime.WindowMinimise();
-}
-
-export function WindowUnminimise() {
- window.runtime.WindowUnminimise();
-}
-
-export function WindowSetBackgroundColour(R, G, B, A) {
- window.runtime.WindowSetBackgroundColour(R, G, B, A);
-}
-
-export function ScreenGetAll() {
- return window.runtime.ScreenGetAll();
-}
-
-export function WindowIsMinimised() {
- return window.runtime.WindowIsMinimised();
-}
-
-export function WindowIsNormal() {
- return window.runtime.WindowIsNormal();
-}
-
-export function BrowserOpenURL(url) {
- window.runtime.BrowserOpenURL(url);
-}
-
-export function Environment() {
- return window.runtime.Environment();
-}
-
-export function Quit() {
- window.runtime.Quit();
-}
-
-export function Hide() {
- window.runtime.Hide();
-}
-
-export function Show() {
- window.runtime.Show();
-}
-
-export function ClipboardGetText() {
- return window.runtime.ClipboardGetText();
-}
-
-export function ClipboardSetText(text) {
- return window.runtime.ClipboardSetText(text);
-}
-
-/**
- * Callback for OnFileDrop returns a slice of file path strings when a drop is finished.
- *
- * @export
- * @callback OnFileDropCallback
- * @param {number} x - x coordinate of the drop
- * @param {number} y - y coordinate of the drop
- * @param {string[]} paths - A list of file paths.
- */
-
-/**
- * OnFileDrop listens to drag and drop events and calls the callback with the coordinates of the drop and an array of path strings.
- *
- * @export
- * @param {OnFileDropCallback} callback - Callback for OnFileDrop returns a slice of file path strings when a drop is finished.
- * @param {boolean} [useDropTarget=true] - Only call the callback when the drop finished on an element that has the drop target style. (--wails-drop-target)
- */
-export function OnFileDrop(callback, useDropTarget) {
- return window.runtime.OnFileDrop(callback, useDropTarget);
-}
-
-/**
- * OnFileDropOff removes the drag and drop listeners and handlers.
- */
-export function OnFileDropOff() {
- return window.runtime.OnFileDropOff();
-}
-
-export function CanResolveFilePaths() {
- return window.runtime.CanResolveFilePaths();
-}
-
-export function ResolveFilePaths(files) {
- return window.runtime.ResolveFilePaths(files);
-}
\ No newline at end of file
diff --git a/go.mod b/go.mod
deleted file mode 100644
index 4f7a7fc..0000000
--- a/go.mod
+++ /dev/null
@@ -1,41 +0,0 @@
-module alg-app-store
-
-go 1.21
-
-require (
- github.com/Jguer/go-alpm/v2 v2.2.2
- github.com/Morganamilo/go-pacmanconf v0.0.0-20210502114700-cff030e927a5
- github.com/wailsapp/wails/v2 v2.10.2
-)
-
-require (
- github.com/bep/debounce v1.2.1 // indirect
- github.com/go-ole/go-ole v1.2.6 // indirect
- github.com/godbus/dbus/v5 v5.1.0 // indirect
- github.com/google/uuid v1.3.0 // indirect
- github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
- github.com/labstack/echo/v4 v4.10.2 // indirect
- github.com/labstack/gommon v0.4.0 // indirect
- github.com/leaanthony/go-ansi-parser v1.6.0 // indirect
- github.com/leaanthony/gosod v1.0.3 // indirect
- github.com/leaanthony/slicer v1.6.0 // indirect
- github.com/leaanthony/u v1.1.0 // indirect
- github.com/mattn/go-colorable v0.1.13 // indirect
- github.com/mattn/go-isatty v0.0.19 // indirect
- github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
- github.com/pkg/errors v0.9.1 // indirect
- github.com/rivo/uniseg v0.4.4 // indirect
- github.com/samber/lo v1.38.1 // indirect
- github.com/tkrajina/go-reflector v0.5.6 // indirect
- github.com/valyala/bytebufferpool v1.0.0 // indirect
- github.com/valyala/fasttemplate v1.2.2 // indirect
- github.com/wailsapp/go-webview2 v1.0.10 // indirect
- github.com/wailsapp/mimetype v1.4.1 // indirect
- golang.org/x/crypto v0.23.0 // indirect
- golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
- golang.org/x/net v0.25.0 // indirect
- golang.org/x/sys v0.20.0 // indirect
- golang.org/x/text v0.15.0 // indirect
-)
-
-// replace github.com/wailsapp/wails/v2 v2.8.2 => /home/harsh/go/pkg/mod
diff --git a/go.sum b/go.sum
deleted file mode 100644
index 56f3f23..0000000
--- a/go.sum
+++ /dev/null
@@ -1,98 +0,0 @@
-github.com/Jguer/go-alpm/v2 v2.2.2 h1:sPwUoZp1X5Tw6K6Ba1lWvVJfcgVNEGVcxARLBttZnC0=
-github.com/Jguer/go-alpm/v2 v2.2.2/go.mod h1:lfe8gSe83F/KERaQvEfrSqQ4n+8bES+ZIyKWR/gm3MI=
-github.com/Morganamilo/go-pacmanconf v0.0.0-20210502114700-cff030e927a5 h1:TMscPjkb1ThXN32LuFY5bEYIcXZx3YlwzhS1GxNpn/c=
-github.com/Morganamilo/go-pacmanconf v0.0.0-20210502114700-cff030e927a5/go.mod h1:Hk55m330jNiwxRodIlMCvw5iEyoRUCIY64W1p9D+tHc=
-github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY=
-github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
-github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
-github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
-github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
-github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck=
-github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
-github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
-github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
-github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
-github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
-github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oOc=
-github.com/leaanthony/debme v1.2.1/go.mod h1:3V+sCm5tYAgQymvSOfYQ5Xx2JCr+OXiD9Jkw3otUjiA=
-github.com/leaanthony/go-ansi-parser v1.6.0 h1:T8TuMhFB6TUMIUm0oRrSbgJudTFw9csT3ZK09w0t4Pg=
-github.com/leaanthony/go-ansi-parser v1.6.0/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU=
-github.com/leaanthony/gosod v1.0.3 h1:Fnt+/B6NjQOVuCWOKYRREZnjGyvg+mEhd1nkkA04aTQ=
-github.com/leaanthony/gosod v1.0.3/go.mod h1:BJ2J+oHsQIyIQpnLPjnqFGTMnOZXDbvWtRCSG7jGxs4=
-github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
-github.com/leaanthony/slicer v1.6.0 h1:1RFP5uiPJvT93TAHi+ipd3NACobkW53yUiBqZheE/Js=
-github.com/leaanthony/slicer v1.6.0/go.mod h1:o/Iz29g7LN0GqH3aMjWAe90381nyZlDNquK+mtH2Fj8=
-github.com/leaanthony/u v1.1.0 h1:2n0d2BwPVXSUq5yhe8lJPHdxevE2qK5G99PMStMZMaI=
-github.com/leaanthony/u v1.1.0/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI=
-github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
-github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
-github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
-github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
-github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
-github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
-github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
-github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
-github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
-github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
-github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
-github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
-github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
-github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
-github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
-github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
-github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
-github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
-github.com/tkrajina/go-reflector v0.5.6 h1:hKQ0gyocG7vgMD2M3dRlYN6WBBOmdoOzJ6njQSepKdE=
-github.com/tkrajina/go-reflector v0.5.6/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4=
-github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
-github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
-github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
-github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
-github.com/wailsapp/go-webview2 v1.0.10 h1:PP5Hug6pnQEAhfRzLCoOh2jJaPdrqeRgJKZhyYyDV/w=
-github.com/wailsapp/go-webview2 v1.0.10/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo=
-github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
-github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
-github.com/wailsapp/wails/v2 v2.9.1 h1:irsXnoQrCpeKzKTYZ2SUVlRRyeMR6I0vCO9Q1cvlEdc=
-github.com/wailsapp/wails/v2 v2.9.1/go.mod h1:7maJV2h+Egl11Ak8QZN/jlGLj2wg05bsQS+ywJPT0gI=
-golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
-golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
-golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
-golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
-golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
-golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
-golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
-golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
-golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/main.go b/main.go
deleted file mode 100644
index 09f1ec9..0000000
--- a/main.go
+++ /dev/null
@@ -1,96 +0,0 @@
-package main
-
-import (
- "embed"
- "log"
-
- "github.com/wailsapp/wails/v2"
- "github.com/wailsapp/wails/v2/pkg/logger"
- "github.com/wailsapp/wails/v2/pkg/options"
- "github.com/wailsapp/wails/v2/pkg/options/assetserver"
- "github.com/wailsapp/wails/v2/pkg/options/linux"
- "github.com/wailsapp/wails/v2/pkg/options/mac"
- "github.com/wailsapp/wails/v2/pkg/options/windows"
-)
-
-//go:embed all:frontend/dist
-var assets embed.FS
-
-//go:embed frontend/src/assets/icon/appicon.png
-var icon []byte
-
-func main() {
- // Create an instance of the app structure
- app := NewApp()
-
- // Create application with options
- err := wails.Run(&options.App{
- Title: "ALG App Store (Beta)",
- Width: 1124,
- Height: 868,
- MinWidth: 1024,
- MinHeight: 768,
- MaxWidth: 0,
- MaxHeight: 0,
- DisableResize: false,
- Fullscreen: true,
- Frameless: false,
- StartHidden: false,
- HideWindowOnClose: false,
- BackgroundColour: &options.RGBA{R: 255, G: 255, B: 255, A: 255},
- CSSDragProperty: "none",
- AssetServer: &assetserver.Options{
- Assets: assets,
- },
- Menu: nil,
- Logger: nil,
- LogLevel: logger.DEBUG,
- OnStartup: app.startup,
- OnDomReady: app.domReady,
- OnBeforeClose: app.beforeClose,
- OnShutdown: app.shutdown,
- WindowStartState: options.Maximised,
- Bind: []interface{}{
- app,
- },
- Debug: options.Debug{
- OpenInspectorOnStartup: true,
- },
- // Windows platform specific options
- Windows: &windows.Options{
- WebviewIsTransparent: false,
- WindowIsTranslucent: false,
- DisableWindowIcon: false,
- // DisableFramelessWindowDecorations: false,
- WebviewUserDataPath: "",
- ZoomFactor: 1.0,
- },
- // Mac platform specific options
- Mac: &mac.Options{
- TitleBar: &mac.TitleBar{
- TitlebarAppearsTransparent: true,
- HideTitle: false,
- HideTitleBar: false,
- FullSizeContent: false,
- UseToolbar: false,
- HideToolbarSeparator: true,
- },
- Appearance: mac.NSAppearanceNameDarkAqua,
- WebviewIsTransparent: true,
- WindowIsTranslucent: true,
- About: &mac.AboutInfo{
- Title: "alg-app-store",
- Message: "",
- Icon: icon,
- },
- },
- Linux: &linux.Options{
- Icon: icon,
- WebviewGpuPolicy: linux.WebviewGpuPolicyOnDemand,
- },
- })
-
- if err != nil {
- log.Fatal(err)
- }
-}
diff --git a/scripts/build-macos-arm.sh b/scripts/build-macos-arm.sh
deleted file mode 100644
index bc6ee0a..0000000
--- a/scripts/build-macos-arm.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /bin/bash
-
-echo -e "Start running the script..."
-cd ../
-
-echo -e "Start building the app for macos platform..."
-wails build --clean --platform darwin/arm64
-
-echo -e "End running the script!"
diff --git a/scripts/build-macos-intel.sh b/scripts/build-macos-intel.sh
deleted file mode 100644
index f359f63..0000000
--- a/scripts/build-macos-intel.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /bin/bash
-
-echo -e "Start running the script..."
-cd ../
-
-echo -e "Start building the app for macos platform..."
-wails build --clean --platform darwin
-
-echo -e "End running the script!"
diff --git a/scripts/build-macos.sh b/scripts/build-macos.sh
deleted file mode 100644
index d61531f..0000000
--- a/scripts/build-macos.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /bin/bash
-
-echo -e "Start running the script..."
-cd ../
-
-echo -e "Start building the app for macos platform..."
-wails build --clean --platform darwin/universal
-
-echo -e "End running the script!"
diff --git a/scripts/build-windows.sh b/scripts/build-windows.sh
deleted file mode 100644
index 47b7789..0000000
--- a/scripts/build-windows.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /bin/bash
-
-echo -e "Start running the script..."
-cd ../
-
-echo -e "Start building the app for windows platform..."
-wails build --clean --platform windows/amd64
-
-echo -e "End running the script!"
diff --git a/scripts/build.sh b/scripts/build.sh
deleted file mode 100644
index 20ab7eb..0000000
--- a/scripts/build.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /bin/bash
-
-echo -e "Start running the script..."
-cd ../
-
-echo -e "Start building the app..."
-wails build --clean
-
-echo -e "End running the script!"
diff --git a/scripts/install-wails-cli.sh b/scripts/install-wails-cli.sh
deleted file mode 100644
index 7539d8e..0000000
--- a/scripts/install-wails-cli.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#! /bin/bash
-
-echo -e "Start running the script..."
-cd ../
-
-echo -e "Current Go version: \c"
-go version
-
-echo -e "Install the Wails command line tool..."
-go install github.com/wailsapp/wails/v2/cmd/wails@latest
-
-echo -e "Successful installation!"
-
-echo -e "End running the script!"
diff --git a/src/core/alpm_wrapper.cpp b/src/core/alpm_wrapper.cpp
new file mode 100644
index 0000000..3fc92b7
--- /dev/null
+++ b/src/core/alpm_wrapper.cpp
@@ -0,0 +1,348 @@
+#include "alpm_wrapper.h"
+#include "../utils/logger.h"
+#include
+#include
+#include
+#include
+
+AlpmWrapper& AlpmWrapper::instance() {
+ static AlpmWrapper instance;
+ return instance;
+}
+
+AlpmWrapper::AlpmWrapper() {
+ // Member initialization is done in header file
+}
+
+AlpmWrapper::~AlpmWrapper() {
+ release();
+}
+
+bool AlpmWrapper::initialize() {
+ std::lock_guard lock(m_mutex);
+
+ if (m_initialized) {
+ return true;
+ }
+
+ alpm_errno_t err;
+ m_handle = alpm_initialize("/", "/var/lib/pacman", &err);
+
+ if (!m_handle) {
+ Logger::error(QString("Failed to initialize ALPM: %1")
+ .arg(alpm_strerror(err)));
+ return false;
+ }
+
+ // Register sync databases - read from enabled repositories
+ QStringList repos = getEnabledRepositories();
+ for (const auto& repo : repos) {
+ alpm_db_t* db = alpm_register_syncdb(m_handle,
+ repo.toStdString().c_str(),
+ ALPM_SIG_USE_DEFAULT);
+ if (!db) {
+ Logger::warning(QString("Failed to register sync db: %1").arg(repo));
+ } else {
+ Logger::info(QString("Registered sync db: %1").arg(repo));
+ }
+ }
+
+ m_syncDbs = alpm_get_syncdbs(m_handle);
+ m_initialized = true;
+
+ Logger::info("ALPM initialized successfully");
+ return true;
+}
+
+void AlpmWrapper::release() {
+ std::lock_guard lock(m_mutex);
+
+ if (m_handle) {
+ alpm_release(m_handle);
+ m_handle = nullptr;
+ m_syncDbs = nullptr;
+ m_initialized = false;
+ Logger::info("ALPM released");
+ }
+}
+
+QVector AlpmWrapper::searchPackages(const QString& query) {
+ std::lock_guard lock(m_mutex);
+
+ if (!m_initialized) {
+ Logger::error("ALPM not initialized");
+ return {};
+ }
+
+ QVector results;
+
+ // Search in sync databases
+ for (alpm_list_t* i = m_syncDbs; i; i = i->next) {
+ auto* db = static_cast(i->data);
+ searchInDatabase(db, query, results);
+ }
+
+ return results;
+}
+
+void AlpmWrapper::searchInDatabase(alpm_db_t* db, const QString& query,
+ QVector& results) {
+ if (!db) return;
+
+ alpm_list_t* pkgs = alpm_db_get_pkgcache(db);
+ QString lowerQuery = query.toLower();
+
+ for (alpm_list_t* i = pkgs; i; i = i->next) {
+ auto* pkg = static_cast(i->data);
+ QString pkgName = QString::fromUtf8(alpm_pkg_get_name(pkg));
+
+ if (pkgName.toLower().contains(lowerQuery)) {
+ PackageInfo info;
+ info.name = pkgName;
+ info.version = QString::fromUtf8(alpm_pkg_get_version(pkg));
+ info.description = QString::fromUtf8(alpm_pkg_get_desc(pkg));
+ info.repository = QString::fromUtf8(alpm_db_get_name(db));
+ info.maintainer = QString::fromUtf8(alpm_pkg_get_packager(pkg));
+ info.upstreamUrl = QString::fromUtf8(alpm_pkg_get_url(pkg));
+ info.dependList = convertDependList(alpm_pkg_get_depends(pkg));
+
+ alpm_time_t buildDate = alpm_pkg_get_builddate(pkg);
+ info.lastUpdated = QDateTime::fromSecsSinceEpoch(buildDate);
+
+ results.push_back(std::move(info));
+ }
+ }
+}
+
+QVector AlpmWrapper::getInstalledPackages() {
+ std::lock_guard lock(m_mutex);
+
+ if (!m_initialized) {
+ Logger::error("ALPM not initialized");
+ return {};
+ }
+
+ QVector packages;
+ alpm_db_t* localDb = alpm_get_localdb(m_handle);
+
+ if (!localDb) {
+ Logger::error("Failed to get local database");
+ return {};
+ }
+
+ alpm_list_t* pkgs = alpm_db_get_pkgcache(localDb);
+
+ for (alpm_list_t* i = pkgs; i; i = i->next) {
+ auto* pkg = static_cast(i->data);
+
+ PackageInfo info;
+ info.name = QString::fromUtf8(alpm_pkg_get_name(pkg));
+ info.version = QString::fromUtf8(alpm_pkg_get_version(pkg));
+ info.description = QString::fromUtf8(alpm_pkg_get_desc(pkg));
+ info.repository = QString::fromUtf8(alpm_db_get_name(alpm_pkg_get_db(pkg)));
+ info.maintainer = QString::fromUtf8(alpm_pkg_get_packager(pkg));
+ info.upstreamUrl = QString::fromUtf8(alpm_pkg_get_url(pkg));
+ info.dependList = convertDependList(alpm_pkg_get_depends(pkg));
+
+ alpm_time_t buildDate = alpm_pkg_get_builddate(pkg);
+ info.lastUpdated = QDateTime::fromSecsSinceEpoch(buildDate);
+
+ packages.push_back(std::move(info));
+ }
+
+ Logger::info(QString("Found %1 installed packages").arg(packages.size()));
+ return packages;
+}
+
+bool AlpmWrapper::isPackageInstalled(const QString& packageName) {
+ std::lock_guard lock(m_mutex);
+
+ if (!m_initialized) {
+ return false;
+ }
+
+ alpm_db_t* localDb = alpm_get_localdb(m_handle);
+ if (!localDb) {
+ return false;
+ }
+
+ alpm_pkg_t* pkg = alpm_db_get_pkg(localDb, packageName.toStdString().c_str());
+ return pkg != nullptr;
+}
+
+PackageInfo AlpmWrapper::getPackageInfo(const QString& packageName) {
+ std::lock_guard lock(m_mutex);
+
+ PackageInfo info;
+ if (!m_initialized) {
+ return info;
+ }
+
+ // First check local database
+ alpm_db_t* localDb = alpm_get_localdb(m_handle);
+ if (localDb) {
+ alpm_pkg_t* pkg = alpm_db_get_pkg(localDb, packageName.toStdString().c_str());
+ if (pkg) {
+ info.name = QString::fromUtf8(alpm_pkg_get_name(pkg));
+ info.version = QString::fromUtf8(alpm_pkg_get_version(pkg));
+ info.description = QString::fromUtf8(alpm_pkg_get_desc(pkg));
+ info.repository = QString::fromUtf8(alpm_db_get_name(alpm_pkg_get_db(pkg)));
+ info.maintainer = QString::fromUtf8(alpm_pkg_get_packager(pkg));
+ info.upstreamUrl = QString::fromUtf8(alpm_pkg_get_url(pkg));
+ info.dependList = convertDependList(alpm_pkg_get_depends(pkg));
+
+ alpm_time_t buildDate = alpm_pkg_get_builddate(pkg);
+ info.lastUpdated = QDateTime::fromSecsSinceEpoch(buildDate);
+
+ return info;
+ }
+ }
+
+ // Check sync databases
+ for (alpm_list_t* i = m_syncDbs; i; i = i->next) {
+ auto* db = static_cast(i->data);
+ alpm_pkg_t* pkg = alpm_db_get_pkg(db, packageName.toStdString().c_str());
+
+ if (pkg) {
+ info.name = QString::fromUtf8(alpm_pkg_get_name(pkg));
+ info.version = QString::fromUtf8(alpm_pkg_get_version(pkg));
+ info.description = QString::fromUtf8(alpm_pkg_get_desc(pkg));
+ info.repository = QString::fromUtf8(alpm_db_get_name(db));
+ info.maintainer = QString::fromUtf8(alpm_pkg_get_packager(pkg));
+ info.upstreamUrl = QString::fromUtf8(alpm_pkg_get_url(pkg));
+ info.dependList = convertDependList(alpm_pkg_get_depends(pkg));
+
+ alpm_time_t buildDate = alpm_pkg_get_builddate(pkg);
+ info.lastUpdated = QDateTime::fromSecsSinceEpoch(buildDate);
+
+ return info;
+ }
+ }
+
+ return info;
+}
+
+QVector AlpmWrapper::getAvailableUpdates() {
+ std::lock_guard lock(m_mutex);
+
+ QVector updates;
+
+ if (!m_initialized) {
+ Logger::error("ALPM not initialized");
+ return updates;
+ }
+
+ alpm_db_t* localDb = alpm_get_localdb(m_handle);
+ if (!localDb) {
+ return updates;
+ }
+
+ alpm_list_t* pkgs = alpm_db_get_pkgcache(localDb);
+
+ for (alpm_list_t* i = pkgs; i; i = i->next) {
+ auto* localPkg = static_cast(i->data);
+ const char* pkgName = alpm_pkg_get_name(localPkg);
+
+ // Check each sync database for newer version
+ for (alpm_list_t* j = m_syncDbs; j; j = j->next) {
+ auto* syncDb = static_cast(j->data);
+ alpm_pkg_t* syncPkg = alpm_db_get_pkg(syncDb, pkgName);
+
+ if (syncPkg) {
+ int cmp = alpm_pkg_vercmp(alpm_pkg_get_version(syncPkg),
+ alpm_pkg_get_version(localPkg));
+
+ if (cmp > 0) {
+ UpdateInfo update;
+ update.name = QString::fromUtf8(pkgName);
+ update.oldVersion = QString::fromUtf8(alpm_pkg_get_version(localPkg));
+ update.newVersion = QString::fromUtf8(alpm_pkg_get_version(syncPkg));
+ update.repository = QString::fromUtf8(alpm_db_get_name(syncDb));
+ update.downloadSize = alpm_pkg_get_size(syncPkg);
+
+ updates.push_back(std::move(update));
+ break;
+ }
+ }
+ }
+ }
+
+ Logger::info(QString("Found %1 available updates").arg(updates.size()));
+ return updates;
+}
+
+QStringList AlpmWrapper::convertDependList(alpm_list_t* deps) {
+ QStringList result;
+
+ for (alpm_list_t* i = deps; i; i = i->next) {
+ auto* dep = static_cast(i->data);
+ result.append(QString::fromUtf8(dep->name));
+ }
+
+ return result;
+}
+
+QStringList AlpmWrapper::getEnabledRepositories() const {
+ QStringList repos;
+
+ // Read /etc/pacman.conf to find enabled repositories
+ QFile file("/etc/pacman.conf");
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ Logger::error("Failed to open /etc/pacman.conf");
+ // Return default repositories
+ return {"core", "extra"};
+ }
+
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ QString line = in.readLine().trimmed();
+
+ // Check for repository sections (not commented out)
+ if (line.startsWith("[") && line.endsWith("]") && !line.startsWith("#")) {
+ QString repo = line.mid(1, line.length() - 2);
+
+ // Filter out non-repository sections
+ if (repo != "options" && repo != "testing" && repo != "core-testing" &&
+ repo != "extra-testing" && repo != "multilib-testing") {
+ repos.append(repo);
+ }
+ }
+ }
+
+ file.close();
+
+ // Ensure core and extra are always present
+ if (!repos.contains("core")) {
+ repos.prepend("core");
+ }
+ if (!repos.contains("extra")) {
+ repos.insert(1, "extra");
+ }
+
+ Logger::info(QString("Enabled repositories: %1").arg(repos.join(", ")));
+ return repos;
+}
+
+void AlpmWrapper::refreshDatabases() {
+ std::lock_guard lock(m_mutex);
+
+ if (!m_initialized) {
+ Logger::error("ALPM not initialized");
+ return;
+ }
+
+ // Release current handle
+ if (m_handle) {
+ alpm_release(m_handle);
+ m_handle = nullptr;
+ m_syncDbs = nullptr;
+ m_initialized = false;
+ }
+
+ // Re-initialize to pick up new repositories
+ m_mutex.unlock();
+ initialize();
+ m_mutex.lock();
+
+ Logger::info("ALPM databases refreshed");
+}
diff --git a/src/core/alpm_wrapper.h b/src/core/alpm_wrapper.h
new file mode 100644
index 0000000..b1f8906
--- /dev/null
+++ b/src/core/alpm_wrapper.h
@@ -0,0 +1,59 @@
+#ifndef ALPM_WRAPPER_H
+#define ALPM_WRAPPER_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../utils/types.h"
+
+/**
+ * @brief Singleton wrapper for libalpm (Arch Linux Package Manager library).
+ *
+ * Memory Management:
+ * - m_handle: Raw pointer to libalpm handle, manually managed via initialize()/release()
+ * - m_syncDbs: Raw pointer to libalpm list, managed by libalpm internally
+ * - Thread-safe via m_mutex
+ *
+ * Note: libalpm uses C-style memory management, so smart pointers are not
+ * directly applicable to the alpm types.
+ */
+class AlpmWrapper {
+public:
+ static AlpmWrapper& instance();
+
+ ~AlpmWrapper();
+
+ // Disable copy and move
+ AlpmWrapper(const AlpmWrapper&) = delete;
+ AlpmWrapper& operator=(const AlpmWrapper&) = delete;
+ AlpmWrapper(AlpmWrapper&&) = delete;
+ AlpmWrapper& operator=(AlpmWrapper&&) = delete;
+
+ bool initialize();
+ void release();
+ void refreshDatabases();
+
+ QVector searchPackages(const QString& query);
+ QVector getInstalledPackages();
+ bool isPackageInstalled(const QString& packageName);
+ PackageInfo getPackageInfo(const QString& packageName);
+ QVector getAvailableUpdates();
+
+private:
+ AlpmWrapper();
+
+ alpm_handle_t* m_handle = nullptr;
+ alpm_list_t* m_syncDbs = nullptr;
+ std::mutex m_mutex;
+ bool m_initialized = false;
+
+ QStringList convertDependList(alpm_list_t* deps);
+ void searchInDatabase(alpm_db_t* db, const QString& query,
+ QVector& results);
+ QStringList getEnabledRepositories() const;
+};
+
+#endif // ALPM_WRAPPER_H
diff --git a/src/core/aur_helper.cpp b/src/core/aur_helper.cpp
new file mode 100644
index 0000000..bdce2a3
--- /dev/null
+++ b/src/core/aur_helper.cpp
@@ -0,0 +1,206 @@
+#include "aur_helper.h"
+#include "../utils/logger.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+AurHelper::AurHelper(QObject* parent)
+ : QObject(parent)
+ , m_networkManager(std::make_unique(this)) {
+}
+
+AurHelper::~AurHelper() = default;
+
+void AurHelper::searchPackages(const QString& query) {
+ Logger::debug(QString("Searching AUR for: %1").arg(query));
+
+ QUrl url("https://aur.archlinux.org/rpc/");
+ QUrlQuery urlQuery;
+ urlQuery.addQueryItem("v", "5");
+ urlQuery.addQueryItem("type", "search");
+ urlQuery.addQueryItem("arg", query);
+ url.setQuery(urlQuery);
+
+ QNetworkRequest request(url);
+ auto* reply = m_networkManager->get(request);
+
+ connect(reply, &QNetworkReply::finished, this, &AurHelper::onSearchFinished);
+}
+
+void AurHelper::onSearchFinished() {
+ auto* reply = qobject_cast(sender());
+ if (!reply) return;
+
+ reply->deleteLater();
+
+ if (reply->error() != QNetworkReply::NoError) {
+ Logger::error(QString("AUR search error: %1").arg(reply->errorString()));
+ emit error(reply->errorString());
+ return;
+ }
+
+ QByteArray data = reply->readAll();
+ QJsonDocument doc = QJsonDocument::fromJson(data);
+
+ if (!doc.isObject()) {
+ Logger::error("Invalid AUR response format");
+ emit error("Invalid response from AUR");
+ return;
+ }
+
+ QJsonObject root = doc.object();
+ QJsonArray results = root["results"].toArray();
+
+ QVector packages;
+ for (const auto& result : results) {
+ packages.push_back(parseAurPackage(result.toObject()));
+ }
+
+ Logger::info(QString("Found %1 AUR packages").arg(packages.size()));
+ emit searchCompleted(packages);
+}
+
+void AurHelper::getPackageInfo(const QString& packageName) {
+ Logger::debug(QString("Getting AUR package info for: %1").arg(packageName));
+
+ QUrl url("https://aur.archlinux.org/rpc/");
+ QUrlQuery urlQuery;
+ urlQuery.addQueryItem("v", "5");
+ urlQuery.addQueryItem("type", "info");
+ urlQuery.addQueryItem("arg", packageName);
+ url.setQuery(urlQuery);
+
+ QNetworkRequest request(url);
+ auto* reply = m_networkManager->get(request);
+
+ connect(reply, &QNetworkReply::finished, this, &AurHelper::onPackageInfoFinished);
+}
+
+void AurHelper::onPackageInfoFinished() {
+ auto* reply = qobject_cast(sender());
+ if (!reply) return;
+
+ reply->deleteLater();
+
+ if (reply->error() != QNetworkReply::NoError) {
+ Logger::error(QString("AUR package info error: %1").arg(reply->errorString()));
+ emit error(reply->errorString());
+ return;
+ }
+
+ QByteArray data = reply->readAll();
+ QJsonDocument doc = QJsonDocument::fromJson(data);
+
+ if (!doc.isObject()) {
+ emit error("Invalid response from AUR");
+ return;
+ }
+
+ QJsonObject root = doc.object();
+ QJsonArray results = root["results"].toArray();
+
+ if (results.isEmpty()) {
+ emit error("Package not found in AUR");
+ return;
+ }
+
+ PackageInfo info = parseAurPackage(results[0].toObject());
+ emit packageInfoReceived(info);
+}
+
+PackageInfo AurHelper::parseAurPackage(const QJsonObject& obj) {
+ PackageInfo info;
+ info.name = obj["Name"].toString();
+ info.version = obj["Version"].toString();
+ info.description = obj["Description"].toString();
+ info.repository = "AUR";
+ info.maintainer = obj["Maintainer"].toString();
+ info.upstreamUrl = obj["URL"].toString();
+
+ qint64 lastModified = obj["LastModified"].toInteger();
+ info.lastUpdated = QDateTime::fromSecsSinceEpoch(lastModified);
+
+ // Parse dependencies
+ QJsonArray depends = obj["Depends"].toArray();
+ for (const auto& dep : depends) {
+ info.dependList.append(dep.toString());
+ }
+
+ // Also add make dependencies if available
+ QJsonArray makeDepends = obj["MakeDepends"].toArray();
+ for (const auto& dep : makeDepends) {
+ QString depStr = dep.toString() + " (make)";
+ info.dependList.append(depStr);
+ }
+
+ return info;
+}
+
+QVector AurHelper::checkAurUpdates() {
+ QVector updates;
+
+ // Get list of foreign (AUR) packages
+ QProcess process;
+ process.start("pacman", QStringList() << "-Qm");
+ process.waitForFinished();
+
+ if (process.exitCode() != 0) {
+ Logger::warning("Failed to get list of foreign packages");
+ return updates;
+ }
+
+ QString output = process.readAllStandardOutput();
+ QStringList lines = output.split('\n', Qt::SkipEmptyParts);
+
+ for (const auto& line : lines) {
+ QStringList parts = line.split(' ', Qt::SkipEmptyParts);
+ if (parts.size() < 2) continue;
+
+ QString name = parts[0];
+ QString version = parts[1];
+
+ // Query AUR for latest version
+ QUrl url("https://aur.archlinux.org/rpc/");
+ QUrlQuery urlQuery;
+ urlQuery.addQueryItem("v", "5");
+ urlQuery.addQueryItem("type", "info");
+ urlQuery.addQueryItem("arg", name);
+ url.setQuery(urlQuery);
+
+ QNetworkRequest request(url);
+ auto reply = m_networkManager->get(request);
+
+ QEventLoop loop;
+ connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+ loop.exec();
+
+ if (reply->error() == QNetworkReply::NoError) {
+ QByteArray data = reply->readAll();
+ QJsonDocument doc = QJsonDocument::fromJson(data);
+ QJsonObject root = doc.object();
+ QJsonArray results = root["results"].toArray();
+
+ if (!results.isEmpty()) {
+ QString newVersion = results[0].toObject()["Version"].toString();
+ if (newVersion != version) {
+ UpdateInfo update;
+ update.name = name;
+ update.oldVersion = version;
+ update.newVersion = newVersion;
+ update.repository = "AUR";
+ update.downloadSize = 0;
+ updates.push_back(std::move(update));
+ }
+ }
+ }
+
+ reply->deleteLater();
+ }
+
+ return updates;
+}
diff --git a/src/core/aur_helper.h b/src/core/aur_helper.h
new file mode 100644
index 0000000..e29321f
--- /dev/null
+++ b/src/core/aur_helper.h
@@ -0,0 +1,45 @@
+#ifndef AUR_HELPER_H
+#define AUR_HELPER_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../utils/types.h"
+
+/**
+ * @brief Helper class for interacting with the Arch User Repository (AUR).
+ *
+ * Memory Management:
+ * - m_networkManager: Owned by std::unique_ptr for RAII-style cleanup
+ * - Network replies are managed via Qt parent-child and deleteLater()
+ */
+class AurHelper : public QObject {
+ Q_OBJECT
+
+public:
+ explicit AurHelper(QObject* parent = nullptr);
+ ~AurHelper() override;
+
+ void searchPackages(const QString& query);
+ void getPackageInfo(const QString& packageName);
+ QVector checkAurUpdates();
+
+signals:
+ void searchCompleted(const QVector& results);
+ void packageInfoReceived(const PackageInfo& info);
+ void error(const QString& message);
+
+private slots:
+ void onSearchFinished();
+ void onPackageInfoFinished();
+
+private:
+ std::unique_ptr m_networkManager;
+
+ PackageInfo parseAurPackage(const QJsonObject& obj);
+};
+
+#endif // AUR_HELPER_H
diff --git a/src/core/package_manager.cpp b/src/core/package_manager.cpp
new file mode 100644
index 0000000..5b50364
--- /dev/null
+++ b/src/core/package_manager.cpp
@@ -0,0 +1,226 @@
+#include "package_manager.h"
+#include "../utils/logger.h"
+#include
+#include
+
+PackageManager& PackageManager::instance() {
+ static PackageManager instance;
+ return instance;
+}
+
+PackageManager::PackageManager()
+ : QObject(nullptr)
+ , m_process(std::make_unique()) {
+
+ detectHelper();
+
+ connect(m_process.get(), &QProcess::finished,
+ this, &PackageManager::onProcessFinished);
+ connect(m_process.get(), &QProcess::errorOccurred,
+ this, &PackageManager::onProcessError);
+ connect(m_process.get(), &QProcess::readyReadStandardOutput,
+ this, &PackageManager::onProcessOutput);
+ connect(m_process.get(), &QProcess::readyReadStandardError,
+ this, &PackageManager::onProcessOutput);
+}
+
+PackageManager::~PackageManager() {
+ if (m_process && m_process->state() != QProcess::NotRunning) {
+ m_process->terminate();
+ m_process->waitForFinished(3000);
+ }
+}
+
+void PackageManager::detectHelper() {
+ // Check for yay first
+ QString yayPath = QStandardPaths::findExecutable("yay");
+ if (!yayPath.isEmpty()) {
+ m_helper = Helper::Yay;
+ Logger::info("Using yay as package helper");
+ return;
+ }
+
+ // Check for paru - deprecate because paru doesn't allow running with pkexec
+ // QString paruPath = QStandardPaths::findExecutable("paru");
+ // if (!paruPath.isEmpty()) {
+ // m_helper = Helper::Paru;
+ // Logger::info("Using paru as package helper");
+ // return;
+ // }
+
+ // Default to pacman
+ m_helper = Helper::Pacman;
+ Logger::info("Using pacman as package helper");
+}
+
+QString PackageManager::getHelperName() const {
+ switch (m_helper) {
+ case Helper::Yay: return "yay";
+ case Helper::Pacman: return "pacman";
+ default: return "pacman";
+ }
+}
+
+void PackageManager::installPackage(const QString& packageName, const QString& repository) {
+ std::lock_guard lock(m_mutex);
+
+ Logger::info(QString("Installing package: %1 from %2").arg(packageName, repository.isEmpty() ? "default" : repository));
+ emit operationStarted(QString("Installing %1...").arg(packageName));
+
+ // Determine if this is an AUR package (not from official repos or chaotic-aur)
+ QString repoLower = repository.toLower();
+ bool isAUR = repoLower == "aur";
+ QString helper = getHelperName();
+
+ QString command;
+ if (isAUR && (m_helper == Helper::Yay)) {
+ // AUR packages - use pkexec to get userpassword before hand
+ // Paru has a problem here, so default to yay
+ command = QString("pkexec %1 -S %2 --noconfirm").arg(helper, packageName);
+ } else {
+ // Official repos and chaotic-aur need root access and use pacman
+ command = QString("pkexec pacman -S %1 --noconfirm").arg(packageName);
+ }
+
+ executeCommand("sh", QStringList() << "-c" << command);
+}
+
+void PackageManager::uninstallPackage(const QString& packageName, const QString& repository) {
+ std::lock_guard lock(m_mutex);
+
+ Logger::info(QString("Uninstalling package: %1 from %2").arg(packageName, repository.isEmpty() ? "default" : repository));
+ emit operationStarted(QString("Uninstalling %1...").arg(packageName));
+
+ // Uninstall always needs root (even for AUR packages, they're in the system db once installed)
+ QString command = QString("pkexec pacman -Rdd %1 --noconfirm").arg(packageName);
+
+ executeCommand("sh", QStringList() << "-c" << command);
+}
+
+void PackageManager::updatePackage(const QString& packageName, const QString& repository) {
+ std::lock_guard lock(m_mutex);
+
+ Logger::info(QString("Updating package: %1 from %2").arg(packageName, repository.isEmpty() ? "default" : repository));
+ emit operationStarted(QString("Updating %1...").arg(packageName));
+
+ // Determine if this is an AUR package (not from official repos or chaotic-aur)
+ QString repoLower = repository.toLower();
+ bool isAUR = repoLower == "aur";
+ QString helper = getHelperName();
+
+ QString command;
+ if (isAUR && (m_helper == Helper::Yay)) {
+ // AUR packages - run helper as regular user (no pkexec)
+ command = QString("%1 -S %2 --noconfirm").arg(helper, packageName);
+ } else {
+ // Official repos and chaotic-aur need root access and use pacman
+ command = QString("pkexec pacman -S %1 --noconfirm").arg(packageName);
+ }
+
+ executeCommand("sh", QStringList() << "-c" << command);
+}
+
+void PackageManager::updateAllPackages() {
+ std::lock_guard lock(m_mutex);
+
+ Logger::info("Updating all packages");
+ emit operationStarted("Updating all packages...");
+
+ QString command = QString("pkexec %1 -Syu --noconfirm")
+ .arg(getHelperName());
+
+ executeCommand("sh", QStringList() << "-c" << command);
+}
+
+void PackageManager::executeCommand(const QString& command, const QStringList& args) {
+ if (m_process->state() != QProcess::NotRunning) {
+ Logger::warning("Another operation is already running");
+ emit operationError("Another operation is already in progress");
+ return;
+ }
+
+ // Merge stdout and stderr so we capture all output
+ m_process->setProcessChannelMode(QProcess::MergedChannels);
+
+ Logger::debug(QString("Executing: %1 %2").arg(command, args.join(" ")));
+
+ // Emit the actual command being executed to the UI for visibility
+ QString fullCommand = command + " " + args.join(" ");
+ emit operationOutput(QString(">> Executing: %1\n").arg(fullCommand));
+
+ m_process->start(command, args);
+
+ // Check if process started successfully
+ if (!m_process->waitForStarted(3000)) {
+ QString error = QString("Failed to start process: %1").arg(m_process->errorString());
+ Logger::error(error);
+ emit operationError(error);
+ }
+}
+
+void PackageManager::onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) {
+ QString output = m_process->readAllStandardOutput();
+ QString error = m_process->readAllStandardError();
+
+ if (exitStatus == QProcess::NormalExit && exitCode == 0) {
+ Logger::info("Operation completed successfully");
+ emit operationCompleted(true, "Operation completed successfully");
+ } else {
+ Logger::error(QString("Operation failed with exit code %1").arg(exitCode));
+ Logger::error(QString("Error output: %1").arg(error));
+ emit operationCompleted(false, QString("Operation failed: %1").arg(error));
+ }
+}
+
+void PackageManager::onProcessError(QProcess::ProcessError /*error*/) {
+ QString errorString = m_process->errorString();
+ Logger::error(QString("Process error: %1").arg(errorString));
+ emit operationError(errorString);
+}
+
+void PackageManager::onProcessOutput() {
+ // Since we merged channels, only read stdout (which includes stderr)
+ QString output = m_process->readAll();
+ if (!output.isEmpty()) {
+ Logger::debug(QString("Process output: %1").arg(output.trimmed()));
+ emit operationOutput(output);
+ }
+}
+
+void PackageManager::cancelRunningOperation() {
+ if (m_process && m_process->state() != QProcess::NotRunning) {
+ Logger::warning("Cancelling running operation...");
+ emit operationOutput("\n>>> Operation cancelled by user <<<\n");
+
+ // When using pkexec, we need to kill the actual pacman/yay/paru process
+ // not just the pkexec wrapper. Use pkill to terminate all package manager processes.
+ QProcess killProcess;
+ killProcess.start("pkexec", QStringList() << "bash" << "-c"
+ << "pkill -TERM pacman; pkill -TERM yay; pkill -TERM paru");
+ killProcess.waitForFinished(2000);
+
+ // Also terminate the QProcess wrapper
+ m_process->terminate();
+
+ // Wait up to 3 seconds for graceful termination
+ if (!m_process->waitForFinished(3000)) {
+ // Force kill if still running
+ Logger::warning("Process did not terminate gracefully, forcing kill...");
+ killProcess.start("pkexec", QStringList() << "bash" << "-c"
+ << "pkill -KILL pacman; pkill -KILL yay; pkill -KILL paru");
+ killProcess.waitForFinished(2000);
+
+ m_process->kill();
+ m_process->waitForFinished(1000);
+ }
+
+ emit operationCompleted(false, "Operation cancelled by user");
+ Logger::info("Operation cancelled successfully");
+ } else {
+ Logger::warning("No operation is currently running");
+ }
+}
+
+bool PackageManager::isOperationRunning() const {
+ return m_process && m_process->state() != QProcess::NotRunning;
+}
diff --git a/src/core/package_manager.h b/src/core/package_manager.h
new file mode 100644
index 0000000..0e86a9b
--- /dev/null
+++ b/src/core/package_manager.h
@@ -0,0 +1,69 @@
+#ifndef PACKAGE_MANAGER_H
+#define PACKAGE_MANAGER_H
+
+#include
+#include
+#include
+#include
+#include
+
+/**
+ * @brief Singleton class for managing package operations (install, uninstall, update).
+ *
+ * Memory Management:
+ * - m_process: Owned by std::unique_ptr for RAII-style cleanup and clear ownership
+ * - Thread-safe via m_mutex for operation serialization
+ */
+class PackageManager : public QObject {
+ Q_OBJECT
+
+public:
+ enum class Helper {
+ Pacman,
+ Yay,
+ Paru
+ };
+
+ static PackageManager& instance();
+
+ ~PackageManager() override;
+
+ // Disable copy and move
+ PackageManager(const PackageManager&) = delete;
+ PackageManager& operator=(const PackageManager&) = delete;
+ PackageManager(PackageManager&&) = delete;
+ PackageManager& operator=(PackageManager&&) = delete;
+
+ void installPackage(const QString& packageName, const QString& repository = QString());
+ void uninstallPackage(const QString& packageName, const QString& repository = QString());
+ void updatePackage(const QString& packageName, const QString& repository = QString());
+ void updateAllPackages();
+ void cancelRunningOperation();
+ bool isOperationRunning() const;
+
+ Helper getHelper() const { return m_helper; }
+ QString getHelperName() const;
+
+signals:
+ void operationStarted(const QString& message);
+ void operationOutput(const QString& output);
+ void operationCompleted(bool success, const QString& message);
+ void operationError(const QString& error);
+
+private:
+ PackageManager();
+
+ void detectHelper();
+ void executeCommand(const QString& command, const QStringList& args);
+
+ Helper m_helper = Helper::Pacman;
+ std::unique_ptr m_process;
+ mutable std::mutex m_mutex;
+
+private slots:
+ void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
+ void onProcessError(QProcess::ProcessError error);
+ void onProcessOutput();
+};
+
+#endif // PACKAGE_MANAGER_H
diff --git a/src/gui/home_widget.cpp b/src/gui/home_widget.cpp
new file mode 100644
index 0000000..cba1315
--- /dev/null
+++ b/src/gui/home_widget.cpp
@@ -0,0 +1,170 @@
+#include "home_widget.h"
+#include "package_card.h"
+#include "package_details_dialog.h"
+#include "../core/alpm_wrapper.h"
+#include "../core/aur_helper.h"
+#include "../utils/logger.h"
+#include
+#include
+#include
+
+HomeWidget::HomeWidget(QWidget* parent)
+ : QWidget(parent)
+ , m_scrollArea(new QScrollArea(this))
+ , m_contentWidget(new QWidget())
+ , m_gridLayout(new QGridLayout(m_contentWidget))
+ , m_updateTimer(new QTimer(this)) {
+
+ setupUi();
+ loadFeaturedPackages();
+ createPackageCards();
+
+ // Setup timer to periodically check installation status
+ connect(m_updateTimer, &QTimer::timeout, this, &HomeWidget::onUpdateTimer);
+ m_updateTimer->start(3000); // Check every 3 seconds
+
+ // Initial check
+ checkInstalledPackages();
+}
+
+void HomeWidget::setupUi() {
+ auto* mainLayout = new QVBoxLayout(this);
+
+ auto* titleLabel = new QLabel("Featured Packages", this);
+ auto titleFont = titleLabel->font();
+ titleFont.setPointSize(24);
+ titleFont.setBold(true);
+ titleLabel->setFont(titleFont);
+ mainLayout->addWidget(titleLabel);
+
+ m_scrollArea->setWidget(m_contentWidget);
+ m_scrollArea->setWidgetResizable(true);
+ m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ m_gridLayout->setSpacing(15);
+ m_gridLayout->setContentsMargins(10, 10, 10, 10);
+
+ mainLayout->addWidget(m_scrollArea);
+ setLayout(mainLayout);
+}
+
+void HomeWidget::loadFeaturedPackages() {
+ // Featured packages list with initial repositories
+ m_featuredPackages = {
+ {"firefox", "Latest", "Fast, Private & Safe Web Browser", "extra"},
+ {"gimp", "Latest", "GNU Image Manipulation Program", "extra"},
+ {"vlc", "Latest", "Multi-platform MPEG, VCD/DVD, and DivX player", "extra"},
+ {"telegram-desktop", "Latest", "Official Telegram Desktop client", "extra"},
+ {"obs-studio", "Latest", "Free, open source software for live streaming and recording", "extra"},
+ {"blender", "Latest", "A fully integrated 3D graphics creation suite", "extra"},
+ {"spotify", "Latest", "A proprietary music streaming service", "AUR"},
+ {"discord", "Latest", "All-in-one voice and text chat for gamers", "extra"},
+ {"google-chrome", "Latest", "The popular web browser by Google", "AUR"},
+ {"visual-studio-code-bin", "Latest", "Visual Studio Code (official binary version)", "AUR"},
+ {"libreoffice-still", "Latest", "Free and Open Source Office Suite", "extra"},
+ {"zoom", "Latest", "Video Conferencing and Web Conferencing Service", "AUR"}
+ };
+
+ // Fetch actual package information from repositories
+ for (auto& pkg : m_featuredPackages) {
+ PackageInfo repoInfo = AlpmWrapper::instance().getPackageInfo(pkg.name);
+
+ if (!repoInfo.name.isEmpty() && !repoInfo.repository.isEmpty()) {
+ // Package found in official repos (including chaotic-aur), update with actual information
+ pkg.repository = repoInfo.repository;
+ pkg.version = repoInfo.version;
+ pkg.description = repoInfo.description;
+
+ if (pkg.repository.toLower() != "aur") {
+ Logger::debug(QString("Package %1 found in %2 repository with version %3")
+ .arg(pkg.name, pkg.repository, pkg.version));
+ }
+ } else if (pkg.repository.toLower() == "aur") {
+ // Package not found in official repos (including chaotic-aur)
+ // Default to AUR helper (yay/paru) since chaotic-aur is not enabled or doesn't have this package
+ pkg.repository = "aur";
+ Logger::debug(QString("Package %1 not found in enabled repositories, defaulting to AUR helper").arg(pkg.name));
+ }
+ }
+
+ Logger::info(QString("Loaded %1 featured packages").arg(m_featuredPackages.size()));
+}
+
+void HomeWidget::createPackageCards() {
+ int row = 0;
+ int col = 0;
+ const int columns = 3;
+
+ for (const auto& pkg : m_featuredPackages) {
+ auto* card = new PackageCard(pkg, m_contentWidget);
+ connect(card, &PackageCard::clicked, this, &HomeWidget::onPackageClicked);
+
+ m_gridLayout->addWidget(card, row, col);
+ m_packageCards.append(card);
+
+ col++;
+ if (col >= columns) {
+ col = 0;
+ row++;
+ }
+ }
+
+ // Add stretch to push cards to the top
+ m_gridLayout->setRowStretch(row + 1, 1);
+}
+
+void HomeWidget::checkInstalledPackages() {
+ for (auto* card : m_packageCards) {
+ card->checkInstallStatus();
+ }
+}
+
+void HomeWidget::onUpdateTimer() {
+ checkInstalledPackages();
+}
+
+void HomeWidget::onPackageClicked(const PackageInfo& info) {
+ Logger::info(QString("Package clicked: %1").arg(info.name));
+
+ // Fetch full package details including dependencies
+ PackageInfo fullInfo;
+
+ if (info.repository.toLower() == "aur") {
+ // For AUR packages, query AUR API for full details
+ AurHelper aurHelper;
+ QEventLoop loop;
+
+ connect(&aurHelper, &AurHelper::packageInfoReceived, [&fullInfo, &loop](const PackageInfo& aurInfo) {
+ fullInfo = aurInfo;
+ loop.quit();
+ });
+
+ connect(&aurHelper, &AurHelper::error, [&fullInfo, &info, &loop](const QString& error) {
+ Logger::warning(QString("Failed to fetch AUR package info: %1").arg(error));
+ fullInfo = info; // Fallback to basic info
+ loop.quit();
+ });
+
+ aurHelper.getPackageInfo(info.name);
+ loop.exec(); // Wait for response
+
+ // If we didn't get full info, use the basic info
+ if (fullInfo.name.isEmpty()) {
+ fullInfo = info;
+ }
+ } else {
+ // For official repos, fetch full details from ALPM
+ fullInfo = AlpmWrapper::instance().getPackageInfo(info.name);
+ // If not found, use the basic info
+ if (fullInfo.name.isEmpty()) {
+ fullInfo = info;
+ }
+ }
+
+ auto* dialog = new PackageDetailsDialog(fullInfo, this);
+ dialog->exec();
+ dialog->deleteLater();
+
+ // Update installation status after dialog closes
+ checkInstalledPackages();
+}
diff --git a/src/gui/home_widget.h b/src/gui/home_widget.h
new file mode 100644
index 0000000..08684a2
--- /dev/null
+++ b/src/gui/home_widget.h
@@ -0,0 +1,47 @@
+#ifndef HOME_WIDGET_H
+#define HOME_WIDGET_H
+
+#include
+#include
+#include
+#include
+#include
+#include "../utils/types.h"
+
+class PackageCard;
+
+/**
+ * @brief Widget displaying featured packages on the home screen.
+ *
+ * Memory Management:
+ * - All Qt widget members use Qt parent-child ownership (raw pointers are non-owning)
+ * - m_packageCards contains non-owning pointers to cards owned by m_contentWidget
+ */
+class HomeWidget : public QWidget {
+ Q_OBJECT
+
+public:
+ explicit HomeWidget(QWidget* parent = nullptr);
+ ~HomeWidget() override = default;
+
+private:
+ void setupUi();
+ void loadFeaturedPackages();
+ void createPackageCards();
+ void checkInstalledPackages();
+
+ QVector m_featuredPackages;
+ QVector m_packageCards; // Non-owning pointers, owned by m_contentWidget
+
+ // Qt parent-child managed widgets (non-owning pointers)
+ QScrollArea* m_scrollArea = nullptr;
+ QWidget* m_contentWidget = nullptr;
+ QGridLayout* m_gridLayout = nullptr;
+ QTimer* m_updateTimer = nullptr;
+
+private slots:
+ void onPackageClicked(const PackageInfo& info);
+ void onUpdateTimer();
+};
+
+#endif // HOME_WIDGET_H
diff --git a/src/gui/installed_widget.cpp b/src/gui/installed_widget.cpp
new file mode 100644
index 0000000..075b404
--- /dev/null
+++ b/src/gui/installed_widget.cpp
@@ -0,0 +1,174 @@
+#include "installed_widget.h"
+#include "package_card.h"
+#include "package_details_dialog.h"
+#include "../core/alpm_wrapper.h"
+#include "../utils/logger.h"
+#include
+#include
+#include
+#include
+
+InstalledWidget::InstalledWidget(QWidget* parent)
+ : QWidget(parent)
+ , m_filterInput(new QLineEdit(this))
+ , m_scrollArea(new QScrollArea(this))
+ , m_contentWidget(new QWidget())
+ , m_gridLayout(new QGridLayout(m_contentWidget))
+ , m_statusLabel(new QLabel(this))
+ , m_countLabel(new QLabel(this)) {
+
+ setupUi();
+ loadInstalledPackages();
+}
+
+void InstalledWidget::setupUi() {
+ auto* mainLayout = new QVBoxLayout(this);
+
+ // Header
+ auto* headerLayout = new QHBoxLayout();
+
+ auto* titleLabel = new QLabel("Installed Packages", this);
+ auto titleFont = titleLabel->font();
+ titleFont.setPointSize(24);
+ titleFont.setBold(true);
+ titleLabel->setFont(titleFont);
+ headerLayout->addWidget(titleLabel);
+
+ headerLayout->addStretch();
+
+ m_countLabel->setStyleSheet("font-size: 14px; color: #888;");
+ headerLayout->addWidget(m_countLabel);
+
+ auto* refreshButton = new QPushButton("Refresh", this);
+ connect(refreshButton, &QPushButton::clicked, this, &InstalledWidget::refreshPackages);
+ headerLayout->addWidget(refreshButton);
+
+ mainLayout->addLayout(headerLayout);
+
+ // Filter
+ m_filterInput->setPlaceholderText("Filter installed packages...");
+ m_filterInput->setMinimumHeight(35);
+ m_filterInput->setClearButtonEnabled(true);
+ connect(m_filterInput, &QLineEdit::textChanged,
+ this, &InstalledWidget::onFilterTextChanged);
+ mainLayout->addWidget(m_filterInput);
+
+ // Status label
+ m_statusLabel->setAlignment(Qt::AlignCenter);
+ m_statusLabel->setText("Loading installed packages...");
+ mainLayout->addWidget(m_statusLabel);
+
+ // Results area
+ m_scrollArea->setWidget(m_contentWidget);
+ m_scrollArea->setWidgetResizable(true);
+ m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ m_gridLayout->setSpacing(15);
+ m_gridLayout->setContentsMargins(10, 10, 10, 10);
+
+ mainLayout->addWidget(m_scrollArea);
+ setLayout(mainLayout);
+}
+
+void InstalledWidget::loadInstalledPackages() {
+ m_statusLabel->setText("Loading installed packages...");
+ m_statusLabel->show();
+
+ (void)QtConcurrent::run([this]() {
+ auto packages = AlpmWrapper::instance().getInstalledPackages();
+
+ QMetaObject::invokeMethod(this, [this, packages]() {
+ m_allPackages = packages;
+ m_filteredPackages = packages;
+
+ m_statusLabel->hide();
+ m_countLabel->setText(QString("%1 packages installed")
+ .arg(packages.size()));
+
+ displayPackages(packages);
+
+ Logger::info(QString("Loaded %1 installed packages").arg(packages.size()));
+ }, Qt::QueuedConnection);
+ });
+}
+
+void InstalledWidget::refreshPackages() {
+ clearResults();
+ loadInstalledPackages();
+}
+
+void InstalledWidget::displayPackages(const QVector& packages) {
+ clearResults();
+
+ if (packages.isEmpty()) {
+ m_statusLabel->setText("No packages found");
+ m_statusLabel->show();
+ return;
+ }
+
+ int row = 0;
+ int col = 0;
+ const int columns = 3;
+
+ for (const auto& pkg : packages) {
+ auto* card = new PackageCard(pkg, m_contentWidget);
+ card->updateInstallStatus(true);
+ connect(card, &PackageCard::clicked, this, &InstalledWidget::onPackageClicked);
+
+ m_gridLayout->addWidget(card, row, col);
+
+ col++;
+ if (col >= columns) {
+ col = 0;
+ row++;
+ }
+ }
+
+ m_gridLayout->setRowStretch(row + 1, 1);
+}
+
+void InstalledWidget::clearResults() {
+ while (auto* item = m_gridLayout->takeAt(0)) {
+ if (auto* widget = item->widget()) {
+ widget->deleteLater();
+ }
+ delete item;
+ }
+}
+
+void InstalledWidget::filterPackages(const QString& query) {
+ if (query.isEmpty()) {
+ m_filteredPackages = m_allPackages;
+ } else {
+ m_filteredPackages.clear();
+ QString lowerQuery = query.toLower();
+
+ for (const auto& pkg : m_allPackages) {
+ if (pkg.name.toLower().contains(lowerQuery) ||
+ pkg.description.toLower().contains(lowerQuery)) {
+ m_filteredPackages.append(pkg);
+ }
+ }
+ }
+
+ m_countLabel->setText(QString("%1 of %2 packages")
+ .arg(m_filteredPackages.size())
+ .arg(m_allPackages.size()));
+
+ displayPackages(m_filteredPackages);
+}
+
+void InstalledWidget::onFilterTextChanged(const QString& text) {
+ filterPackages(text);
+}
+
+void InstalledWidget::onPackageClicked(const PackageInfo& info) {
+ Logger::info(QString("Package clicked: %1").arg(info.name));
+
+ auto* dialog = new PackageDetailsDialog(info, this);
+ dialog->exec();
+ dialog->deleteLater();
+
+ // Refresh after dialog closes in case package was uninstalled
+ refreshPackages();
+}
diff --git a/src/gui/installed_widget.h b/src/gui/installed_widget.h
new file mode 100644
index 0000000..d4cbe0b
--- /dev/null
+++ b/src/gui/installed_widget.h
@@ -0,0 +1,51 @@
+#ifndef INSTALLED_WIDGET_H
+#define INSTALLED_WIDGET_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../utils/types.h"
+
+/**
+ * @brief Widget displaying installed packages.
+ *
+ * Memory Management:
+ * - All Qt widget members use Qt parent-child ownership (raw pointers are non-owning)
+ * - Package cards are dynamically created/destroyed in displayPackages/clearResults
+ */
+class InstalledWidget : public QWidget {
+ Q_OBJECT
+
+public:
+ explicit InstalledWidget(QWidget* parent = nullptr);
+ ~InstalledWidget() override = default;
+
+ void refreshPackages();
+
+private:
+ void setupUi();
+ void loadInstalledPackages();
+ void displayPackages(const QVector& packages);
+ void filterPackages(const QString& query);
+ void clearResults();
+
+ // Qt parent-child managed widgets (non-owning pointers)
+ QLineEdit* m_filterInput = nullptr;
+ QScrollArea* m_scrollArea = nullptr;
+ QWidget* m_contentWidget = nullptr;
+ QGridLayout* m_gridLayout = nullptr;
+ QLabel* m_statusLabel = nullptr;
+ QLabel* m_countLabel = nullptr;
+
+ QVector m_allPackages;
+ QVector m_filteredPackages;
+
+private slots:
+ void onPackageClicked(const PackageInfo& info);
+ void onFilterTextChanged(const QString& text);
+};
+
+#endif // INSTALLED_WIDGET_H
diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp
new file mode 100644
index 0000000..dd71d18
--- /dev/null
+++ b/src/gui/mainwindow.cpp
@@ -0,0 +1,148 @@
+#include "mainwindow.h"
+#include "home_widget.h"
+#include "search_widget.h"
+#include "installed_widget.h"
+#include "updates_widget.h"
+#include "settings_widget.h"
+#include "../utils/logger.h"
+#include "../core/alpm_wrapper.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+MainWindow::MainWindow(QWidget* parent)
+ : QMainWindow(parent)
+ , m_tabWidget(std::make_unique(this)) {
+
+ // Initialize ALPM before creating widgets that might need it
+ if (!AlpmWrapper::instance().initialize()) {
+ QMessageBox::critical(this, "Error",
+ "Failed to initialize package manager. Please check your system configuration.");
+ Logger::error("Failed to initialize ALPM in MainWindow");
+ }
+
+ setupUi();
+ loadStyleSheet();
+
+ Logger::info("MainWindow created successfully");
+}
+
+MainWindow::~MainWindow() {
+ AlpmWrapper::instance().release();
+ Logger::info("MainWindow destroyed");
+}
+
+void MainWindow::setupUi() {
+ setWindowTitle("ALG App Store (Beta)");
+ setMinimumSize(1024, 768);
+ resize(1124, 868);
+
+ // Create widgets
+ m_homeWidget = new HomeWidget(this);
+ m_searchWidget = new SearchWidget(this);
+ m_installedWidget = new InstalledWidget(this);
+ m_updatesWidget = new UpdatesWidget(this);
+ m_settingsWidget = new SettingsWidget(this);
+
+ // Add tabs
+ m_tabWidget->addTab(m_homeWidget, "Home");
+ m_tabWidget->addTab(m_searchWidget, "Search");
+ m_tabWidget->addTab(m_installedWidget, "Installed");
+ m_tabWidget->addTab(m_updatesWidget, "Updates");
+ m_tabWidget->addTab(m_settingsWidget, "Settings");
+
+ // Connect settings signals
+ connect(m_settingsWidget, &SettingsWidget::multilibStatusChanged,
+ this, [this]() {
+ m_searchWidget->updateRepositoryList(
+ m_settingsWidget->isMultilibEnabled(),
+ m_settingsWidget->isChaoticAurEnabled()
+ );
+ });
+
+ connect(m_settingsWidget, &SettingsWidget::chaoticAurStatusChanged,
+ this, [this]() {
+ m_searchWidget->updateRepositoryList(
+ m_settingsWidget->isMultilibEnabled(),
+ m_settingsWidget->isChaoticAurEnabled()
+ );
+ });
+
+ // Initialize search widget with current repository states
+ m_searchWidget->updateRepositoryList(
+ m_settingsWidget->isMultilibEnabled(),
+ m_settingsWidget->isChaoticAurEnabled()
+ );
+
+ m_tabWidget->setTabPosition(QTabWidget::North);
+ m_tabWidget->setMovable(false);
+
+ setCentralWidget(m_tabWidget.get());
+ createMenuBar();
+}
+
+void MainWindow::createMenuBar() {
+ auto* fileMenu = menuBar()->addMenu("&File");
+
+ auto* refreshAction = new QAction("&Refresh", this);
+ refreshAction->setShortcut(QKeySequence::Refresh);
+ connect(refreshAction, &QAction::triggered, [this]() {
+ int currentIndex = m_tabWidget->currentIndex();
+ if (currentIndex == 0) {
+ // Home widget refresh
+ } else if (currentIndex == 1) {
+ // Search widget refresh
+ } else if (currentIndex == 2) {
+ m_installedWidget->refreshPackages();
+ } else if (currentIndex == 3) {
+ m_updatesWidget->checkForUpdates();
+ }
+ });
+ fileMenu->addAction(refreshAction);
+
+ fileMenu->addSeparator();
+
+ auto* quitAction = new QAction("&Quit", this);
+ quitAction->setShortcut(QKeySequence::Quit);
+ connect(quitAction, &QAction::triggered, this, &QMainWindow::close);
+ fileMenu->addAction(quitAction);
+
+ auto* helpMenu = menuBar()->addMenu("&Help");
+
+ auto* aboutAction = new QAction("&About", this);
+ connect(aboutAction, &QAction::triggered, [this]() {
+ QMessageBox::about(this, "About ALG App Store",
+ "ALG App Store (Beta)\n\n"
+ "A modern package manager for Arch Linux\n"
+ "Version: 0.2.28\n"
+ "Built with Qt6 and C++17\n\n"
+ "© 2025 Arka Linux GUI");
+ });
+ helpMenu->addAction(aboutAction);
+}
+
+void MainWindow::loadStyleSheet() {
+ QFile styleFile(":/stylesheet.qss");
+
+ if (!styleFile.exists()) {
+ // Try loading from current directory (for development)
+ styleFile.setFileName("stylesheet.qss");
+ }
+
+ if (!styleFile.exists()) {
+ // Try loading from system installation path
+ styleFile.setFileName("/usr/share/alg-app-store/stylesheet.qss");
+ }
+
+ if (styleFile.open(QFile::ReadOnly)) {
+ QString styleSheet = QLatin1String(styleFile.readAll());
+ qApp->setStyleSheet(styleSheet);
+ styleFile.close();
+ Logger::info(QString("Stylesheet loaded successfully from: %1").arg(styleFile.fileName()));
+ } else {
+ Logger::warning("Could not load stylesheet");
+ }
+}
diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h
new file mode 100644
index 0000000..cf6d531
--- /dev/null
+++ b/src/gui/mainwindow.h
@@ -0,0 +1,45 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include
+#include
+#include
+#include
+
+class HomeWidget;
+class SearchWidget;
+class InstalledWidget;
+class UpdatesWidget;
+class SettingsWidget;
+
+/**
+ * @brief Main application window for ALG App Store.
+ *
+ * Memory Management:
+ * - m_tabWidget: Owned by std::unique_ptr (central widget)
+ * - Child widgets (m_homeWidget, etc.): Owned by Qt parent-child hierarchy
+ * through m_tabWidget. Raw pointers are used as non-owning references.
+ */
+class MainWindow : public QMainWindow {
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget* parent = nullptr);
+ ~MainWindow() override;
+
+private:
+ void setupUi();
+ void createMenuBar();
+ void loadStyleSheet();
+
+ std::unique_ptr m_tabWidget;
+
+ // Non-owning pointers - owned by m_tabWidget via Qt parent-child hierarchy
+ HomeWidget* m_homeWidget = nullptr;
+ SearchWidget* m_searchWidget = nullptr;
+ InstalledWidget* m_installedWidget = nullptr;
+ UpdatesWidget* m_updatesWidget = nullptr;
+ SettingsWidget* m_settingsWidget = nullptr;
+};
+
+#endif // MAINWINDOW_H
diff --git a/src/gui/package_card.cpp b/src/gui/package_card.cpp
new file mode 100644
index 0000000..62cdee8
--- /dev/null
+++ b/src/gui/package_card.cpp
@@ -0,0 +1,111 @@
+#include "package_card.h"
+#include "../core/alpm_wrapper.h"
+#include
+#include
+#include
+#include