├── .gitignore
├── LICENSE
├── README.md
├── app.go
├── clipcapsule.gif
├── favicon.ico
├── frontend
├── index.html
├── package.json
├── package.json.md5
├── pnpm-lock.yaml
├── postcss.config.cjs
├── src
│ ├── App.css
│ ├── App.tsx
│ ├── assets
│ │ ├── logo-2.png
│ │ ├── logo.png
│ │ └── wails.png
│ ├── index.css
│ ├── main.tsx
│ └── vite-env.d.ts
├── tailwind.config.cjs
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
├── go.mod
├── go.sum
├── main.go
├── scripts
├── build-macos-arm.sh
├── build-macos-intel.sh
├── build-macos.sh
├── build-windows.sh
├── build.sh
└── install-wails-cli.sh
├── utils
├── db.go
└── monitorClipboard.go
├── wails.json
└── wails.toml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Go
2 | *.exe
3 | *.test
4 | *.out
5 | *.log
6 | *.db
7 | *.sqlite
8 | *.sqlite3
9 |
10 | # Go build artifacts
11 | /build
12 | /bin
13 | /dist
14 | *.so
15 | *.dll
16 | *.a
17 |
18 | # Wails build artifacts
19 | frontend/dist/
20 | frontend/node_modules/
21 | wailsjs/
22 |
23 | # Runtime files
24 | .DS_Store
25 | *.tmp
26 | *.pid
27 | *.lock
28 |
29 | # Logs and debug
30 | *.log
31 | debug/
32 | *.swp
33 | *.swo
34 |
35 | # VSCode/JetBrains/Editor stuff
36 | .vscode/
37 | .idea/
38 | *.code-workspace
39 |
40 | # OS files
41 | Thumbs.db
42 | ehthumbs.db
43 | Desktop.ini
44 |
45 | # npm / yarn
46 | node_modules/
47 | package-lock.json
48 | yarn.lock
49 |
50 | # Environment / config
51 | .env
52 | .env.*
53 | .config
54 | *.local
55 |
56 | # Clipboard device or udev paths (if cached)
57 | keyboardid*
58 | deviceinfo*
59 |
60 | # Backup files
61 | *.bak
62 | *.old
63 | *~
64 |
65 | # Repomix files (AI tools)
66 | repomix-output.xml
67 |
68 | # Wails build folders (depending on Wails version)
69 | frontend/wailsjs/go/
70 | frontend/wailsjs/runtime/
71 |
72 | # System generated
73 | *.crash
74 |
75 |
76 | frontend/vite.config.ts.timestamp-1745062894951.mjs
77 |
78 | .repomix*
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 Victor Evogor
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 📋 ClipCapsule
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | **ClipCapsule** is a minimalist clipboard manager for Linux, built with **Go** and **WailsJS**. It supercharges your productivity by allowing you to manage and switch clipboard entries using only keyboard shortcuts—no mouse or GUI required.
10 |
11 | > ⚠️ This is a **work-in-progress** project. Currently, the GUI must be open for shortcuts to work, but we're actively working on a background daemon to make the app run seamlessly without launching the interface.
12 |
13 | ---
14 |
15 | ## ✨ Features
16 |
17 | - 🚀 **Keyboard-first Workflow**: Switch clipboard items instantly with `CTRL + SHIFT + 1~9`.
18 | - 📜 **Clipboard History**: Automatically saves your recent copies in an embedded database.
19 | - 🔄 **Dynamic Reordering**: Selecting an item with a shortcut moves it to the top of the stack.
20 | - 🔐 **Local-Only**: Your data stays on your machine, no cloud syncing or telemetry.
21 |
22 | ---
23 |
24 | ## 🖥️ Example Use
25 |
26 | When you copy items, the database stores them like this:
27 |
28 | | text | pos |
29 | |------------|-----|
30 | | item1text | 1 |
31 | | item2text | 2 |
32 | | item3text | 3 |
33 | | item4text | 4 |
34 | | item5text | 5 |
35 | | ... | ... |
36 |
37 | - The item at `pos = 1` is the active clipboard item (what gets pasted on `CTRL + V`).
38 | - Pressing `CTRL + SHIFT + 3`:
39 | - Moves `item3text` to position 1.
40 | - Reorders the rest accordingly.
41 |
42 | ---
43 |
44 | ## ⚙️ Installation
45 |
46 | ### 1. Clone the repo
47 | ```bash
48 | git clone https://github.com/Victor-Evogor/clipcapsule.git
49 | cd clipcapsule
50 | ```
51 |
52 | ### 2. Install Wails
53 |
54 | Follow instructions from the [Wails documentation](https://wails.io/docs/gettingstarted/installation).
55 |
56 | ### 3. Build the application
57 |
58 | You'll need to build with elevated privileges to allow the app to listen for global key events:
59 |
60 | ```bash
61 | sudo wails build
62 | ```
63 |
64 | > 🛑 Alternatively, give your user access to the keyboard input device path (e.g. `/dev/input/eventX`) by adding appropriate udev rules or group permissions.
65 |
66 | Example (for testing):
67 | ```bash
68 | sudo chmod a+r /dev/input/eventX
69 | ```
70 |
71 | (Replace `/dev/input/eventX` with your actual keyboard event device.)
72 |
73 | > ⚠️ A proper fix for permissions will be added soon. For now, elevated privileges or manual access setup is required.
74 |
75 | ---
76 |
77 | ## ⌨️ Keyboard Shortcuts
78 |
79 | | Shortcut | Action |
80 | |----------------------|---------------------------------------------|
81 | | `CTRL + V` | Paste current top clipboard entry |
82 | | `CTRL + SHIFT + 1-9` | Move selected item to the top of the stack |
83 |
84 | ---
85 |
86 | ## 🛠️ Development
87 |
88 | - Frontend: Wails + JS/TS (see `frontend/`)
89 | - Backend: Go
90 | - Clipboard access and keyboard interception handled natively
91 |
92 | ---
93 |
94 | ## 🧱 Tech Stack
95 |
96 | - [Go](https://golang.org/)
97 | - [Wails](https://wails.io/)
98 | - [X11 Input](https://wiki.archlinux.org/title/X_keyboard_extension) (via raw device read)
99 |
100 | ---
101 |
102 | ## 🚧 Roadmap
103 |
104 | - [x] Core clipboard logic
105 | - [x] Keyboard shortcut mapping
106 | - [X] Clipboard preview UI
107 | - [ ] Daemon mode (run in background without GUI)
108 | - [ ] Tray icon & preferences
109 | - [ ] Configurable shortcuts
110 | - [ ] Exclude sensitive entries (e.g., passwords)
111 |
112 | ---
113 |
114 | ## 🐞 Known Issues
115 |
116 | - You need to run the app as `sudo` or manually allow access to keyboard input devices.
117 | - No daemon yet — GUI must be open for shortcuts to work.
118 |
119 | ---
120 |
121 | ## 🙌 Contributing
122 |
123 | PRs and issues are welcome! If you have ideas or find bugs, open an issue or submit a patch.
124 |
125 | ---
126 |
127 | ## 📄 License
128 |
129 | MIT License — see `LICENSE` file for details.
130 |
--------------------------------------------------------------------------------
/app.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "clipcapsule/utils"
5 | "context"
6 | "fmt"
7 |
8 | "golang.design/x/clipboard"
9 | )
10 |
11 | // App struct
12 | type App struct {
13 | ctx context.Context
14 | }
15 |
16 | // NewApp creates a new App application struct
17 | func NewApp() *App {
18 | return &App{}
19 | }
20 |
21 | // startup is called at application startup
22 | func (a *App) startup(ctx context.Context) {
23 | // Perform your setup here
24 | a.ctx = ctx
25 | }
26 |
27 | // domReady is called after front-end resources have been loaded
28 | func (a App) domReady(ctx context.Context) {
29 | // Add your action here
30 | }
31 |
32 | // beforeClose is called when the application is about to quit,
33 | // either by clicking the window close button or calling runtime.Quit.
34 | // Returning true will cause the application to continue, false will continue shutdown as normal.
35 | func (a *App) beforeClose(ctx context.Context) (prevent bool) {
36 | return false
37 | }
38 |
39 | // shutdown is called at application termination
40 | func (a *App) shutdown(ctx context.Context) {
41 | // Perform your teardown here
42 | }
43 |
44 | // Greet returns a greeting for the given name
45 | func (a *App) Greet(name string) string {
46 | return fmt.Sprintf("Hello %s, It's show time!", name)
47 | }
48 |
49 | func (a *App) GetHistory() []string {
50 | db := &utils.Db{}
51 | if err := db.New(); err != nil {
52 | panic(err)
53 | }
54 | history, err := db.FetchAllItems()
55 |
56 | if err != nil {
57 | return nil
58 | }
59 |
60 | var historyContents = []string{}
61 | for _, item := range history {
62 | historyContents = append(historyContents, item.Content)
63 | }
64 |
65 | return historyContents
66 | }
67 |
68 | func (a *App) UpdateHistory(newOrder []string) ([]utils.ClipboardItem, error) {
69 | db := utils.Db{}
70 | if err := db.New(); err != nil {
71 | return nil, err
72 | }
73 | items := db.UpdateAllItems(newOrder)
74 | if clipboard.Init() != nil {
75 | panic("failed to initialize clipboard")
76 | }
77 | if len((items)) > 0 {
78 | clipboard.Write(clipboard.FmtText, []byte(items[0].Content))
79 | } else {
80 | clipboard.Write(clipboard.FmtText, []byte(""))
81 | }
82 | return items, nil
83 | }
84 |
--------------------------------------------------------------------------------
/clipcapsule.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Victor-Evogor/clipcapsule/5370e2b20f46ce75f7f3a6254fc5c570fc7ffeed/clipcapsule.gif
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Victor-Evogor/clipcapsule/5370e2b20f46ce75f7f3a6254fc5c570fc7ffeed/favicon.ico
--------------------------------------------------------------------------------
/frontend/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Vite + React + TS + Tailwind
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clipcapsule",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "tsc && vite build",
9 | "preview": "vite preview"
10 | },
11 | "dependencies": {
12 | "@dnd-kit/core": "^6.3.1",
13 | "@dnd-kit/modifiers": "^9.0.0",
14 | "@dnd-kit/sortable": "^10.0.0",
15 | "@dnd-kit/utilities": "^3.2.2",
16 | "react": "^18.2.0",
17 | "react-dom": "^18.2.0"
18 | },
19 | "devDependencies": {
20 | "@types/react": "^18.0.17",
21 | "@types/react-dom": "^18.0.6",
22 | "@vitejs/plugin-react": "^2.1.0",
23 | "autoprefixer": "^10.4.12",
24 | "postcss": "^8.4.17",
25 | "tailwindcss": "^3.1.8",
26 | "typescript": "^4.6.4",
27 | "vite": "^3.1.0"
28 | },
29 | "author": "Victor Evogor"
30 | }
--------------------------------------------------------------------------------
/frontend/package.json.md5:
--------------------------------------------------------------------------------
1 | 671c2da1020f77e38834876a970b75a6
--------------------------------------------------------------------------------
/frontend/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .:
10 | dependencies:
11 | '@dnd-kit/core':
12 | specifier: ^6.3.1
13 | version: 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
14 | '@dnd-kit/modifiers':
15 | specifier: ^9.0.0
16 | version: 9.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
17 | '@dnd-kit/sortable':
18 | specifier: ^10.0.0
19 | version: 10.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
20 | '@dnd-kit/utilities':
21 | specifier: ^3.2.2
22 | version: 3.2.2(react@18.3.1)
23 | react:
24 | specifier: ^18.2.0
25 | version: 18.3.1
26 | react-dom:
27 | specifier: ^18.2.0
28 | version: 18.3.1(react@18.3.1)
29 | devDependencies:
30 | '@types/react':
31 | specifier: ^18.0.17
32 | version: 18.3.20
33 | '@types/react-dom':
34 | specifier: ^18.0.6
35 | version: 18.3.6(@types/react@18.3.20)
36 | '@vitejs/plugin-react':
37 | specifier: ^2.1.0
38 | version: 2.2.0(vite@3.2.11)
39 | autoprefixer:
40 | specifier: ^10.4.12
41 | version: 10.4.21(postcss@8.5.3)
42 | postcss:
43 | specifier: ^8.4.17
44 | version: 8.5.3
45 | tailwindcss:
46 | specifier: ^3.1.8
47 | version: 3.4.17
48 | typescript:
49 | specifier: ^4.6.4
50 | version: 4.9.5
51 | vite:
52 | specifier: ^3.1.0
53 | version: 3.2.11
54 |
55 | packages:
56 |
57 | '@alloc/quick-lru@5.2.0':
58 | resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
59 | engines: {node: '>=10'}
60 |
61 | '@ampproject/remapping@2.3.0':
62 | resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
63 | engines: {node: '>=6.0.0'}
64 |
65 | '@babel/code-frame@7.26.2':
66 | resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==}
67 | engines: {node: '>=6.9.0'}
68 |
69 | '@babel/compat-data@7.26.8':
70 | resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==}
71 | engines: {node: '>=6.9.0'}
72 |
73 | '@babel/core@7.26.10':
74 | resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==}
75 | engines: {node: '>=6.9.0'}
76 |
77 | '@babel/generator@7.27.0':
78 | resolution: {integrity: sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==}
79 | engines: {node: '>=6.9.0'}
80 |
81 | '@babel/helper-annotate-as-pure@7.25.9':
82 | resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==}
83 | engines: {node: '>=6.9.0'}
84 |
85 | '@babel/helper-compilation-targets@7.27.0':
86 | resolution: {integrity: sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==}
87 | engines: {node: '>=6.9.0'}
88 |
89 | '@babel/helper-module-imports@7.25.9':
90 | resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==}
91 | engines: {node: '>=6.9.0'}
92 |
93 | '@babel/helper-module-transforms@7.26.0':
94 | resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==}
95 | engines: {node: '>=6.9.0'}
96 | peerDependencies:
97 | '@babel/core': ^7.0.0
98 |
99 | '@babel/helper-plugin-utils@7.26.5':
100 | resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==}
101 | engines: {node: '>=6.9.0'}
102 |
103 | '@babel/helper-string-parser@7.25.9':
104 | resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==}
105 | engines: {node: '>=6.9.0'}
106 |
107 | '@babel/helper-validator-identifier@7.25.9':
108 | resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
109 | engines: {node: '>=6.9.0'}
110 |
111 | '@babel/helper-validator-option@7.25.9':
112 | resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==}
113 | engines: {node: '>=6.9.0'}
114 |
115 | '@babel/helpers@7.27.0':
116 | resolution: {integrity: sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==}
117 | engines: {node: '>=6.9.0'}
118 |
119 | '@babel/parser@7.27.0':
120 | resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==}
121 | engines: {node: '>=6.0.0'}
122 | hasBin: true
123 |
124 | '@babel/plugin-syntax-jsx@7.25.9':
125 | resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==}
126 | engines: {node: '>=6.9.0'}
127 | peerDependencies:
128 | '@babel/core': ^7.0.0-0
129 |
130 | '@babel/plugin-transform-react-jsx-development@7.25.9':
131 | resolution: {integrity: sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw==}
132 | engines: {node: '>=6.9.0'}
133 | peerDependencies:
134 | '@babel/core': ^7.0.0-0
135 |
136 | '@babel/plugin-transform-react-jsx-self@7.25.9':
137 | resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==}
138 | engines: {node: '>=6.9.0'}
139 | peerDependencies:
140 | '@babel/core': ^7.0.0-0
141 |
142 | '@babel/plugin-transform-react-jsx-source@7.25.9':
143 | resolution: {integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==}
144 | engines: {node: '>=6.9.0'}
145 | peerDependencies:
146 | '@babel/core': ^7.0.0-0
147 |
148 | '@babel/plugin-transform-react-jsx@7.25.9':
149 | resolution: {integrity: sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==}
150 | engines: {node: '>=6.9.0'}
151 | peerDependencies:
152 | '@babel/core': ^7.0.0-0
153 |
154 | '@babel/template@7.27.0':
155 | resolution: {integrity: sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==}
156 | engines: {node: '>=6.9.0'}
157 |
158 | '@babel/traverse@7.27.0':
159 | resolution: {integrity: sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==}
160 | engines: {node: '>=6.9.0'}
161 |
162 | '@babel/types@7.27.0':
163 | resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==}
164 | engines: {node: '>=6.9.0'}
165 |
166 | '@dnd-kit/accessibility@3.1.1':
167 | resolution: {integrity: sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==}
168 | peerDependencies:
169 | react: '>=16.8.0'
170 |
171 | '@dnd-kit/core@6.3.1':
172 | resolution: {integrity: sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==}
173 | peerDependencies:
174 | react: '>=16.8.0'
175 | react-dom: '>=16.8.0'
176 |
177 | '@dnd-kit/modifiers@9.0.0':
178 | resolution: {integrity: sha512-ybiLc66qRGuZoC20wdSSG6pDXFikui/dCNGthxv4Ndy8ylErY0N3KVxY2bgo7AWwIbxDmXDg3ylAFmnrjcbVvw==}
179 | peerDependencies:
180 | '@dnd-kit/core': ^6.3.0
181 | react: '>=16.8.0'
182 |
183 | '@dnd-kit/sortable@10.0.0':
184 | resolution: {integrity: sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==}
185 | peerDependencies:
186 | '@dnd-kit/core': ^6.3.0
187 | react: '>=16.8.0'
188 |
189 | '@dnd-kit/utilities@3.2.2':
190 | resolution: {integrity: sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==}
191 | peerDependencies:
192 | react: '>=16.8.0'
193 |
194 | '@esbuild/android-arm@0.15.18':
195 | resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==}
196 | engines: {node: '>=12'}
197 | cpu: [arm]
198 | os: [android]
199 |
200 | '@esbuild/linux-loong64@0.15.18':
201 | resolution: {integrity: sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==}
202 | engines: {node: '>=12'}
203 | cpu: [loong64]
204 | os: [linux]
205 |
206 | '@isaacs/cliui@8.0.2':
207 | resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
208 | engines: {node: '>=12'}
209 |
210 | '@jridgewell/gen-mapping@0.3.8':
211 | resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==}
212 | engines: {node: '>=6.0.0'}
213 |
214 | '@jridgewell/resolve-uri@3.1.2':
215 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
216 | engines: {node: '>=6.0.0'}
217 |
218 | '@jridgewell/set-array@1.2.1':
219 | resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
220 | engines: {node: '>=6.0.0'}
221 |
222 | '@jridgewell/sourcemap-codec@1.5.0':
223 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
224 |
225 | '@jridgewell/trace-mapping@0.3.25':
226 | resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
227 |
228 | '@nodelib/fs.scandir@2.1.5':
229 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
230 | engines: {node: '>= 8'}
231 |
232 | '@nodelib/fs.stat@2.0.5':
233 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
234 | engines: {node: '>= 8'}
235 |
236 | '@nodelib/fs.walk@1.2.8':
237 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
238 | engines: {node: '>= 8'}
239 |
240 | '@pkgjs/parseargs@0.11.0':
241 | resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
242 | engines: {node: '>=14'}
243 |
244 | '@types/prop-types@15.7.14':
245 | resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==}
246 |
247 | '@types/react-dom@18.3.6':
248 | resolution: {integrity: sha512-nf22//wEbKXusP6E9pfOCDwFdHAX4u172eaJI4YkDRQEZiorm6KfYnSC2SWLDMVWUOWPERmJnN0ujeAfTBLvrw==}
249 | peerDependencies:
250 | '@types/react': ^18.0.0
251 |
252 | '@types/react@18.3.20':
253 | resolution: {integrity: sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==}
254 |
255 | '@vitejs/plugin-react@2.2.0':
256 | resolution: {integrity: sha512-FFpefhvExd1toVRlokZgxgy2JtnBOdp4ZDsq7ldCWaqGSGn9UhWMAVm/1lxPL14JfNS5yGz+s9yFrQY6shoStA==}
257 | engines: {node: ^14.18.0 || >=16.0.0}
258 | peerDependencies:
259 | vite: ^3.0.0
260 |
261 | ansi-regex@5.0.1:
262 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
263 | engines: {node: '>=8'}
264 |
265 | ansi-regex@6.1.0:
266 | resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
267 | engines: {node: '>=12'}
268 |
269 | ansi-styles@4.3.0:
270 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
271 | engines: {node: '>=8'}
272 |
273 | ansi-styles@6.2.1:
274 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
275 | engines: {node: '>=12'}
276 |
277 | any-promise@1.3.0:
278 | resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
279 |
280 | anymatch@3.1.3:
281 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
282 | engines: {node: '>= 8'}
283 |
284 | arg@5.0.2:
285 | resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
286 |
287 | autoprefixer@10.4.21:
288 | resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==}
289 | engines: {node: ^10 || ^12 || >=14}
290 | hasBin: true
291 | peerDependencies:
292 | postcss: ^8.1.0
293 |
294 | balanced-match@1.0.2:
295 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
296 |
297 | binary-extensions@2.3.0:
298 | resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
299 | engines: {node: '>=8'}
300 |
301 | brace-expansion@2.0.1:
302 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
303 |
304 | braces@3.0.3:
305 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
306 | engines: {node: '>=8'}
307 |
308 | browserslist@4.24.4:
309 | resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==}
310 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
311 | hasBin: true
312 |
313 | camelcase-css@2.0.1:
314 | resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
315 | engines: {node: '>= 6'}
316 |
317 | caniuse-lite@1.0.30001712:
318 | resolution: {integrity: sha512-MBqPpGYYdQ7/hfKiet9SCI+nmN5/hp4ZzveOJubl5DTAMa5oggjAuoi0Z4onBpKPFI2ePGnQuQIzF3VxDjDJig==}
319 |
320 | chokidar@3.6.0:
321 | resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
322 | engines: {node: '>= 8.10.0'}
323 |
324 | color-convert@2.0.1:
325 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
326 | engines: {node: '>=7.0.0'}
327 |
328 | color-name@1.1.4:
329 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
330 |
331 | commander@4.1.1:
332 | resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
333 | engines: {node: '>= 6'}
334 |
335 | convert-source-map@2.0.0:
336 | resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
337 |
338 | cross-spawn@7.0.6:
339 | resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
340 | engines: {node: '>= 8'}
341 |
342 | cssesc@3.0.0:
343 | resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
344 | engines: {node: '>=4'}
345 | hasBin: true
346 |
347 | csstype@3.1.3:
348 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
349 |
350 | debug@4.4.0:
351 | resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
352 | engines: {node: '>=6.0'}
353 | peerDependencies:
354 | supports-color: '*'
355 | peerDependenciesMeta:
356 | supports-color:
357 | optional: true
358 |
359 | didyoumean@1.2.2:
360 | resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
361 |
362 | dlv@1.1.3:
363 | resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
364 |
365 | eastasianwidth@0.2.0:
366 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
367 |
368 | electron-to-chromium@1.5.132:
369 | resolution: {integrity: sha512-QgX9EBvWGmvSRa74zqfnG7+Eno0Ak0vftBll0Pt2/z5b3bEGYL6OUXLgKPtvx73dn3dvwrlyVkjPKRRlhLYTEg==}
370 |
371 | emoji-regex@8.0.0:
372 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
373 |
374 | emoji-regex@9.2.2:
375 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
376 |
377 | esbuild-android-64@0.15.18:
378 | resolution: {integrity: sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==}
379 | engines: {node: '>=12'}
380 | cpu: [x64]
381 | os: [android]
382 |
383 | esbuild-android-arm64@0.15.18:
384 | resolution: {integrity: sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==}
385 | engines: {node: '>=12'}
386 | cpu: [arm64]
387 | os: [android]
388 |
389 | esbuild-darwin-64@0.15.18:
390 | resolution: {integrity: sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==}
391 | engines: {node: '>=12'}
392 | cpu: [x64]
393 | os: [darwin]
394 |
395 | esbuild-darwin-arm64@0.15.18:
396 | resolution: {integrity: sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==}
397 | engines: {node: '>=12'}
398 | cpu: [arm64]
399 | os: [darwin]
400 |
401 | esbuild-freebsd-64@0.15.18:
402 | resolution: {integrity: sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==}
403 | engines: {node: '>=12'}
404 | cpu: [x64]
405 | os: [freebsd]
406 |
407 | esbuild-freebsd-arm64@0.15.18:
408 | resolution: {integrity: sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==}
409 | engines: {node: '>=12'}
410 | cpu: [arm64]
411 | os: [freebsd]
412 |
413 | esbuild-linux-32@0.15.18:
414 | resolution: {integrity: sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==}
415 | engines: {node: '>=12'}
416 | cpu: [ia32]
417 | os: [linux]
418 |
419 | esbuild-linux-64@0.15.18:
420 | resolution: {integrity: sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==}
421 | engines: {node: '>=12'}
422 | cpu: [x64]
423 | os: [linux]
424 |
425 | esbuild-linux-arm64@0.15.18:
426 | resolution: {integrity: sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==}
427 | engines: {node: '>=12'}
428 | cpu: [arm64]
429 | os: [linux]
430 |
431 | esbuild-linux-arm@0.15.18:
432 | resolution: {integrity: sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==}
433 | engines: {node: '>=12'}
434 | cpu: [arm]
435 | os: [linux]
436 |
437 | esbuild-linux-mips64le@0.15.18:
438 | resolution: {integrity: sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==}
439 | engines: {node: '>=12'}
440 | cpu: [mips64el]
441 | os: [linux]
442 |
443 | esbuild-linux-ppc64le@0.15.18:
444 | resolution: {integrity: sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==}
445 | engines: {node: '>=12'}
446 | cpu: [ppc64]
447 | os: [linux]
448 |
449 | esbuild-linux-riscv64@0.15.18:
450 | resolution: {integrity: sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==}
451 | engines: {node: '>=12'}
452 | cpu: [riscv64]
453 | os: [linux]
454 |
455 | esbuild-linux-s390x@0.15.18:
456 | resolution: {integrity: sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==}
457 | engines: {node: '>=12'}
458 | cpu: [s390x]
459 | os: [linux]
460 |
461 | esbuild-netbsd-64@0.15.18:
462 | resolution: {integrity: sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==}
463 | engines: {node: '>=12'}
464 | cpu: [x64]
465 | os: [netbsd]
466 |
467 | esbuild-openbsd-64@0.15.18:
468 | resolution: {integrity: sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==}
469 | engines: {node: '>=12'}
470 | cpu: [x64]
471 | os: [openbsd]
472 |
473 | esbuild-sunos-64@0.15.18:
474 | resolution: {integrity: sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==}
475 | engines: {node: '>=12'}
476 | cpu: [x64]
477 | os: [sunos]
478 |
479 | esbuild-windows-32@0.15.18:
480 | resolution: {integrity: sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==}
481 | engines: {node: '>=12'}
482 | cpu: [ia32]
483 | os: [win32]
484 |
485 | esbuild-windows-64@0.15.18:
486 | resolution: {integrity: sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==}
487 | engines: {node: '>=12'}
488 | cpu: [x64]
489 | os: [win32]
490 |
491 | esbuild-windows-arm64@0.15.18:
492 | resolution: {integrity: sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==}
493 | engines: {node: '>=12'}
494 | cpu: [arm64]
495 | os: [win32]
496 |
497 | esbuild@0.15.18:
498 | resolution: {integrity: sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==}
499 | engines: {node: '>=12'}
500 | hasBin: true
501 |
502 | escalade@3.2.0:
503 | resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
504 | engines: {node: '>=6'}
505 |
506 | fast-glob@3.3.3:
507 | resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
508 | engines: {node: '>=8.6.0'}
509 |
510 | fastq@1.19.1:
511 | resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
512 |
513 | fill-range@7.1.1:
514 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
515 | engines: {node: '>=8'}
516 |
517 | foreground-child@3.3.1:
518 | resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
519 | engines: {node: '>=14'}
520 |
521 | fraction.js@4.3.7:
522 | resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
523 |
524 | fsevents@2.3.3:
525 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
526 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
527 | os: [darwin]
528 |
529 | function-bind@1.1.2:
530 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
531 |
532 | gensync@1.0.0-beta.2:
533 | resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
534 | engines: {node: '>=6.9.0'}
535 |
536 | glob-parent@5.1.2:
537 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
538 | engines: {node: '>= 6'}
539 |
540 | glob-parent@6.0.2:
541 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
542 | engines: {node: '>=10.13.0'}
543 |
544 | glob@10.4.5:
545 | resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
546 | hasBin: true
547 |
548 | globals@11.12.0:
549 | resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
550 | engines: {node: '>=4'}
551 |
552 | hasown@2.0.2:
553 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
554 | engines: {node: '>= 0.4'}
555 |
556 | is-binary-path@2.1.0:
557 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
558 | engines: {node: '>=8'}
559 |
560 | is-core-module@2.16.1:
561 | resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
562 | engines: {node: '>= 0.4'}
563 |
564 | is-extglob@2.1.1:
565 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
566 | engines: {node: '>=0.10.0'}
567 |
568 | is-fullwidth-code-point@3.0.0:
569 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
570 | engines: {node: '>=8'}
571 |
572 | is-glob@4.0.3:
573 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
574 | engines: {node: '>=0.10.0'}
575 |
576 | is-number@7.0.0:
577 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
578 | engines: {node: '>=0.12.0'}
579 |
580 | isexe@2.0.0:
581 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
582 |
583 | jackspeak@3.4.3:
584 | resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
585 |
586 | jiti@1.21.7:
587 | resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
588 | hasBin: true
589 |
590 | js-tokens@4.0.0:
591 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
592 |
593 | jsesc@3.1.0:
594 | resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
595 | engines: {node: '>=6'}
596 | hasBin: true
597 |
598 | json5@2.2.3:
599 | resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
600 | engines: {node: '>=6'}
601 | hasBin: true
602 |
603 | lilconfig@3.1.3:
604 | resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
605 | engines: {node: '>=14'}
606 |
607 | lines-and-columns@1.2.4:
608 | resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
609 |
610 | loose-envify@1.4.0:
611 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
612 | hasBin: true
613 |
614 | lru-cache@10.4.3:
615 | resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
616 |
617 | lru-cache@5.1.1:
618 | resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
619 |
620 | magic-string@0.26.7:
621 | resolution: {integrity: sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==}
622 | engines: {node: '>=12'}
623 |
624 | merge2@1.4.1:
625 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
626 | engines: {node: '>= 8'}
627 |
628 | micromatch@4.0.8:
629 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
630 | engines: {node: '>=8.6'}
631 |
632 | minimatch@9.0.5:
633 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
634 | engines: {node: '>=16 || 14 >=14.17'}
635 |
636 | minipass@7.1.2:
637 | resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
638 | engines: {node: '>=16 || 14 >=14.17'}
639 |
640 | ms@2.1.3:
641 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
642 |
643 | mz@2.7.0:
644 | resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
645 |
646 | nanoid@3.3.11:
647 | resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
648 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
649 | hasBin: true
650 |
651 | node-releases@2.0.19:
652 | resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==}
653 |
654 | normalize-path@3.0.0:
655 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
656 | engines: {node: '>=0.10.0'}
657 |
658 | normalize-range@0.1.2:
659 | resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
660 | engines: {node: '>=0.10.0'}
661 |
662 | object-assign@4.1.1:
663 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
664 | engines: {node: '>=0.10.0'}
665 |
666 | object-hash@3.0.0:
667 | resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
668 | engines: {node: '>= 6'}
669 |
670 | package-json-from-dist@1.0.1:
671 | resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
672 |
673 | path-key@3.1.1:
674 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
675 | engines: {node: '>=8'}
676 |
677 | path-parse@1.0.7:
678 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
679 |
680 | path-scurry@1.11.1:
681 | resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
682 | engines: {node: '>=16 || 14 >=14.18'}
683 |
684 | picocolors@1.1.1:
685 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
686 |
687 | picomatch@2.3.1:
688 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
689 | engines: {node: '>=8.6'}
690 |
691 | pify@2.3.0:
692 | resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
693 | engines: {node: '>=0.10.0'}
694 |
695 | pirates@4.0.7:
696 | resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
697 | engines: {node: '>= 6'}
698 |
699 | postcss-import@15.1.0:
700 | resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
701 | engines: {node: '>=14.0.0'}
702 | peerDependencies:
703 | postcss: ^8.0.0
704 |
705 | postcss-js@4.0.1:
706 | resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
707 | engines: {node: ^12 || ^14 || >= 16}
708 | peerDependencies:
709 | postcss: ^8.4.21
710 |
711 | postcss-load-config@4.0.2:
712 | resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
713 | engines: {node: '>= 14'}
714 | peerDependencies:
715 | postcss: '>=8.0.9'
716 | ts-node: '>=9.0.0'
717 | peerDependenciesMeta:
718 | postcss:
719 | optional: true
720 | ts-node:
721 | optional: true
722 |
723 | postcss-nested@6.2.0:
724 | resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==}
725 | engines: {node: '>=12.0'}
726 | peerDependencies:
727 | postcss: ^8.2.14
728 |
729 | postcss-selector-parser@6.1.2:
730 | resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
731 | engines: {node: '>=4'}
732 |
733 | postcss-value-parser@4.2.0:
734 | resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
735 |
736 | postcss@8.5.3:
737 | resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
738 | engines: {node: ^10 || ^12 || >=14}
739 |
740 | queue-microtask@1.2.3:
741 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
742 |
743 | react-dom@18.3.1:
744 | resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
745 | peerDependencies:
746 | react: ^18.3.1
747 |
748 | react-refresh@0.14.2:
749 | resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
750 | engines: {node: '>=0.10.0'}
751 |
752 | react@18.3.1:
753 | resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
754 | engines: {node: '>=0.10.0'}
755 |
756 | read-cache@1.0.0:
757 | resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
758 |
759 | readdirp@3.6.0:
760 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
761 | engines: {node: '>=8.10.0'}
762 |
763 | resolve@1.22.10:
764 | resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==}
765 | engines: {node: '>= 0.4'}
766 | hasBin: true
767 |
768 | reusify@1.1.0:
769 | resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
770 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
771 |
772 | rollup@2.79.2:
773 | resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==}
774 | engines: {node: '>=10.0.0'}
775 | hasBin: true
776 |
777 | run-parallel@1.2.0:
778 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
779 |
780 | scheduler@0.23.2:
781 | resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
782 |
783 | semver@6.3.1:
784 | resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
785 | hasBin: true
786 |
787 | shebang-command@2.0.0:
788 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
789 | engines: {node: '>=8'}
790 |
791 | shebang-regex@3.0.0:
792 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
793 | engines: {node: '>=8'}
794 |
795 | signal-exit@4.1.0:
796 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
797 | engines: {node: '>=14'}
798 |
799 | source-map-js@1.2.1:
800 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
801 | engines: {node: '>=0.10.0'}
802 |
803 | sourcemap-codec@1.4.8:
804 | resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
805 | deprecated: Please use @jridgewell/sourcemap-codec instead
806 |
807 | string-width@4.2.3:
808 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
809 | engines: {node: '>=8'}
810 |
811 | string-width@5.1.2:
812 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
813 | engines: {node: '>=12'}
814 |
815 | strip-ansi@6.0.1:
816 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
817 | engines: {node: '>=8'}
818 |
819 | strip-ansi@7.1.0:
820 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
821 | engines: {node: '>=12'}
822 |
823 | sucrase@3.35.0:
824 | resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
825 | engines: {node: '>=16 || 14 >=14.17'}
826 | hasBin: true
827 |
828 | supports-preserve-symlinks-flag@1.0.0:
829 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
830 | engines: {node: '>= 0.4'}
831 |
832 | tailwindcss@3.4.17:
833 | resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==}
834 | engines: {node: '>=14.0.0'}
835 | hasBin: true
836 |
837 | thenify-all@1.6.0:
838 | resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
839 | engines: {node: '>=0.8'}
840 |
841 | thenify@3.3.1:
842 | resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
843 |
844 | to-regex-range@5.0.1:
845 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
846 | engines: {node: '>=8.0'}
847 |
848 | ts-interface-checker@0.1.13:
849 | resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
850 |
851 | tslib@2.8.1:
852 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
853 |
854 | typescript@4.9.5:
855 | resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==}
856 | engines: {node: '>=4.2.0'}
857 | hasBin: true
858 |
859 | update-browserslist-db@1.1.3:
860 | resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==}
861 | hasBin: true
862 | peerDependencies:
863 | browserslist: '>= 4.21.0'
864 |
865 | util-deprecate@1.0.2:
866 | resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
867 |
868 | vite@3.2.11:
869 | resolution: {integrity: sha512-K/jGKL/PgbIgKCiJo5QbASQhFiV02X9Jh+Qq0AKCRCRKZtOTVi4t6wh75FDpGf2N9rYOnzH87OEFQNaFy6pdxQ==}
870 | engines: {node: ^14.18.0 || >=16.0.0}
871 | hasBin: true
872 | peerDependencies:
873 | '@types/node': '>= 14'
874 | less: '*'
875 | sass: '*'
876 | stylus: '*'
877 | sugarss: '*'
878 | terser: ^5.4.0
879 | peerDependenciesMeta:
880 | '@types/node':
881 | optional: true
882 | less:
883 | optional: true
884 | sass:
885 | optional: true
886 | stylus:
887 | optional: true
888 | sugarss:
889 | optional: true
890 | terser:
891 | optional: true
892 |
893 | which@2.0.2:
894 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
895 | engines: {node: '>= 8'}
896 | hasBin: true
897 |
898 | wrap-ansi@7.0.0:
899 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
900 | engines: {node: '>=10'}
901 |
902 | wrap-ansi@8.1.0:
903 | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
904 | engines: {node: '>=12'}
905 |
906 | yallist@3.1.1:
907 | resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
908 |
909 | yaml@2.7.1:
910 | resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==}
911 | engines: {node: '>= 14'}
912 | hasBin: true
913 |
914 | snapshots:
915 |
916 | '@alloc/quick-lru@5.2.0': {}
917 |
918 | '@ampproject/remapping@2.3.0':
919 | dependencies:
920 | '@jridgewell/gen-mapping': 0.3.8
921 | '@jridgewell/trace-mapping': 0.3.25
922 |
923 | '@babel/code-frame@7.26.2':
924 | dependencies:
925 | '@babel/helper-validator-identifier': 7.25.9
926 | js-tokens: 4.0.0
927 | picocolors: 1.1.1
928 |
929 | '@babel/compat-data@7.26.8': {}
930 |
931 | '@babel/core@7.26.10':
932 | dependencies:
933 | '@ampproject/remapping': 2.3.0
934 | '@babel/code-frame': 7.26.2
935 | '@babel/generator': 7.27.0
936 | '@babel/helper-compilation-targets': 7.27.0
937 | '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10)
938 | '@babel/helpers': 7.27.0
939 | '@babel/parser': 7.27.0
940 | '@babel/template': 7.27.0
941 | '@babel/traverse': 7.27.0
942 | '@babel/types': 7.27.0
943 | convert-source-map: 2.0.0
944 | debug: 4.4.0
945 | gensync: 1.0.0-beta.2
946 | json5: 2.2.3
947 | semver: 6.3.1
948 | transitivePeerDependencies:
949 | - supports-color
950 |
951 | '@babel/generator@7.27.0':
952 | dependencies:
953 | '@babel/parser': 7.27.0
954 | '@babel/types': 7.27.0
955 | '@jridgewell/gen-mapping': 0.3.8
956 | '@jridgewell/trace-mapping': 0.3.25
957 | jsesc: 3.1.0
958 |
959 | '@babel/helper-annotate-as-pure@7.25.9':
960 | dependencies:
961 | '@babel/types': 7.27.0
962 |
963 | '@babel/helper-compilation-targets@7.27.0':
964 | dependencies:
965 | '@babel/compat-data': 7.26.8
966 | '@babel/helper-validator-option': 7.25.9
967 | browserslist: 4.24.4
968 | lru-cache: 5.1.1
969 | semver: 6.3.1
970 |
971 | '@babel/helper-module-imports@7.25.9':
972 | dependencies:
973 | '@babel/traverse': 7.27.0
974 | '@babel/types': 7.27.0
975 | transitivePeerDependencies:
976 | - supports-color
977 |
978 | '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.10)':
979 | dependencies:
980 | '@babel/core': 7.26.10
981 | '@babel/helper-module-imports': 7.25.9
982 | '@babel/helper-validator-identifier': 7.25.9
983 | '@babel/traverse': 7.27.0
984 | transitivePeerDependencies:
985 | - supports-color
986 |
987 | '@babel/helper-plugin-utils@7.26.5': {}
988 |
989 | '@babel/helper-string-parser@7.25.9': {}
990 |
991 | '@babel/helper-validator-identifier@7.25.9': {}
992 |
993 | '@babel/helper-validator-option@7.25.9': {}
994 |
995 | '@babel/helpers@7.27.0':
996 | dependencies:
997 | '@babel/template': 7.27.0
998 | '@babel/types': 7.27.0
999 |
1000 | '@babel/parser@7.27.0':
1001 | dependencies:
1002 | '@babel/types': 7.27.0
1003 |
1004 | '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.10)':
1005 | dependencies:
1006 | '@babel/core': 7.26.10
1007 | '@babel/helper-plugin-utils': 7.26.5
1008 |
1009 | '@babel/plugin-transform-react-jsx-development@7.25.9(@babel/core@7.26.10)':
1010 | dependencies:
1011 | '@babel/core': 7.26.10
1012 | '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.10)
1013 | transitivePeerDependencies:
1014 | - supports-color
1015 |
1016 | '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.10)':
1017 | dependencies:
1018 | '@babel/core': 7.26.10
1019 | '@babel/helper-plugin-utils': 7.26.5
1020 |
1021 | '@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.10)':
1022 | dependencies:
1023 | '@babel/core': 7.26.10
1024 | '@babel/helper-plugin-utils': 7.26.5
1025 |
1026 | '@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10)':
1027 | dependencies:
1028 | '@babel/core': 7.26.10
1029 | '@babel/helper-annotate-as-pure': 7.25.9
1030 | '@babel/helper-module-imports': 7.25.9
1031 | '@babel/helper-plugin-utils': 7.26.5
1032 | '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10)
1033 | '@babel/types': 7.27.0
1034 | transitivePeerDependencies:
1035 | - supports-color
1036 |
1037 | '@babel/template@7.27.0':
1038 | dependencies:
1039 | '@babel/code-frame': 7.26.2
1040 | '@babel/parser': 7.27.0
1041 | '@babel/types': 7.27.0
1042 |
1043 | '@babel/traverse@7.27.0':
1044 | dependencies:
1045 | '@babel/code-frame': 7.26.2
1046 | '@babel/generator': 7.27.0
1047 | '@babel/parser': 7.27.0
1048 | '@babel/template': 7.27.0
1049 | '@babel/types': 7.27.0
1050 | debug: 4.4.0
1051 | globals: 11.12.0
1052 | transitivePeerDependencies:
1053 | - supports-color
1054 |
1055 | '@babel/types@7.27.0':
1056 | dependencies:
1057 | '@babel/helper-string-parser': 7.25.9
1058 | '@babel/helper-validator-identifier': 7.25.9
1059 |
1060 | '@dnd-kit/accessibility@3.1.1(react@18.3.1)':
1061 | dependencies:
1062 | react: 18.3.1
1063 | tslib: 2.8.1
1064 |
1065 | '@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
1066 | dependencies:
1067 | '@dnd-kit/accessibility': 3.1.1(react@18.3.1)
1068 | '@dnd-kit/utilities': 3.2.2(react@18.3.1)
1069 | react: 18.3.1
1070 | react-dom: 18.3.1(react@18.3.1)
1071 | tslib: 2.8.1
1072 |
1073 | '@dnd-kit/modifiers@9.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
1074 | dependencies:
1075 | '@dnd-kit/core': 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1076 | '@dnd-kit/utilities': 3.2.2(react@18.3.1)
1077 | react: 18.3.1
1078 | tslib: 2.8.1
1079 |
1080 | '@dnd-kit/sortable@10.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
1081 | dependencies:
1082 | '@dnd-kit/core': 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
1083 | '@dnd-kit/utilities': 3.2.2(react@18.3.1)
1084 | react: 18.3.1
1085 | tslib: 2.8.1
1086 |
1087 | '@dnd-kit/utilities@3.2.2(react@18.3.1)':
1088 | dependencies:
1089 | react: 18.3.1
1090 | tslib: 2.8.1
1091 |
1092 | '@esbuild/android-arm@0.15.18':
1093 | optional: true
1094 |
1095 | '@esbuild/linux-loong64@0.15.18':
1096 | optional: true
1097 |
1098 | '@isaacs/cliui@8.0.2':
1099 | dependencies:
1100 | string-width: 5.1.2
1101 | string-width-cjs: string-width@4.2.3
1102 | strip-ansi: 7.1.0
1103 | strip-ansi-cjs: strip-ansi@6.0.1
1104 | wrap-ansi: 8.1.0
1105 | wrap-ansi-cjs: wrap-ansi@7.0.0
1106 |
1107 | '@jridgewell/gen-mapping@0.3.8':
1108 | dependencies:
1109 | '@jridgewell/set-array': 1.2.1
1110 | '@jridgewell/sourcemap-codec': 1.5.0
1111 | '@jridgewell/trace-mapping': 0.3.25
1112 |
1113 | '@jridgewell/resolve-uri@3.1.2': {}
1114 |
1115 | '@jridgewell/set-array@1.2.1': {}
1116 |
1117 | '@jridgewell/sourcemap-codec@1.5.0': {}
1118 |
1119 | '@jridgewell/trace-mapping@0.3.25':
1120 | dependencies:
1121 | '@jridgewell/resolve-uri': 3.1.2
1122 | '@jridgewell/sourcemap-codec': 1.5.0
1123 |
1124 | '@nodelib/fs.scandir@2.1.5':
1125 | dependencies:
1126 | '@nodelib/fs.stat': 2.0.5
1127 | run-parallel: 1.2.0
1128 |
1129 | '@nodelib/fs.stat@2.0.5': {}
1130 |
1131 | '@nodelib/fs.walk@1.2.8':
1132 | dependencies:
1133 | '@nodelib/fs.scandir': 2.1.5
1134 | fastq: 1.19.1
1135 |
1136 | '@pkgjs/parseargs@0.11.0':
1137 | optional: true
1138 |
1139 | '@types/prop-types@15.7.14': {}
1140 |
1141 | '@types/react-dom@18.3.6(@types/react@18.3.20)':
1142 | dependencies:
1143 | '@types/react': 18.3.20
1144 |
1145 | '@types/react@18.3.20':
1146 | dependencies:
1147 | '@types/prop-types': 15.7.14
1148 | csstype: 3.1.3
1149 |
1150 | '@vitejs/plugin-react@2.2.0(vite@3.2.11)':
1151 | dependencies:
1152 | '@babel/core': 7.26.10
1153 | '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.10)
1154 | '@babel/plugin-transform-react-jsx-development': 7.25.9(@babel/core@7.26.10)
1155 | '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.10)
1156 | '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.10)
1157 | magic-string: 0.26.7
1158 | react-refresh: 0.14.2
1159 | vite: 3.2.11
1160 | transitivePeerDependencies:
1161 | - supports-color
1162 |
1163 | ansi-regex@5.0.1: {}
1164 |
1165 | ansi-regex@6.1.0: {}
1166 |
1167 | ansi-styles@4.3.0:
1168 | dependencies:
1169 | color-convert: 2.0.1
1170 |
1171 | ansi-styles@6.2.1: {}
1172 |
1173 | any-promise@1.3.0: {}
1174 |
1175 | anymatch@3.1.3:
1176 | dependencies:
1177 | normalize-path: 3.0.0
1178 | picomatch: 2.3.1
1179 |
1180 | arg@5.0.2: {}
1181 |
1182 | autoprefixer@10.4.21(postcss@8.5.3):
1183 | dependencies:
1184 | browserslist: 4.24.4
1185 | caniuse-lite: 1.0.30001712
1186 | fraction.js: 4.3.7
1187 | normalize-range: 0.1.2
1188 | picocolors: 1.1.1
1189 | postcss: 8.5.3
1190 | postcss-value-parser: 4.2.0
1191 |
1192 | balanced-match@1.0.2: {}
1193 |
1194 | binary-extensions@2.3.0: {}
1195 |
1196 | brace-expansion@2.0.1:
1197 | dependencies:
1198 | balanced-match: 1.0.2
1199 |
1200 | braces@3.0.3:
1201 | dependencies:
1202 | fill-range: 7.1.1
1203 |
1204 | browserslist@4.24.4:
1205 | dependencies:
1206 | caniuse-lite: 1.0.30001712
1207 | electron-to-chromium: 1.5.132
1208 | node-releases: 2.0.19
1209 | update-browserslist-db: 1.1.3(browserslist@4.24.4)
1210 |
1211 | camelcase-css@2.0.1: {}
1212 |
1213 | caniuse-lite@1.0.30001712: {}
1214 |
1215 | chokidar@3.6.0:
1216 | dependencies:
1217 | anymatch: 3.1.3
1218 | braces: 3.0.3
1219 | glob-parent: 5.1.2
1220 | is-binary-path: 2.1.0
1221 | is-glob: 4.0.3
1222 | normalize-path: 3.0.0
1223 | readdirp: 3.6.0
1224 | optionalDependencies:
1225 | fsevents: 2.3.3
1226 |
1227 | color-convert@2.0.1:
1228 | dependencies:
1229 | color-name: 1.1.4
1230 |
1231 | color-name@1.1.4: {}
1232 |
1233 | commander@4.1.1: {}
1234 |
1235 | convert-source-map@2.0.0: {}
1236 |
1237 | cross-spawn@7.0.6:
1238 | dependencies:
1239 | path-key: 3.1.1
1240 | shebang-command: 2.0.0
1241 | which: 2.0.2
1242 |
1243 | cssesc@3.0.0: {}
1244 |
1245 | csstype@3.1.3: {}
1246 |
1247 | debug@4.4.0:
1248 | dependencies:
1249 | ms: 2.1.3
1250 |
1251 | didyoumean@1.2.2: {}
1252 |
1253 | dlv@1.1.3: {}
1254 |
1255 | eastasianwidth@0.2.0: {}
1256 |
1257 | electron-to-chromium@1.5.132: {}
1258 |
1259 | emoji-regex@8.0.0: {}
1260 |
1261 | emoji-regex@9.2.2: {}
1262 |
1263 | esbuild-android-64@0.15.18:
1264 | optional: true
1265 |
1266 | esbuild-android-arm64@0.15.18:
1267 | optional: true
1268 |
1269 | esbuild-darwin-64@0.15.18:
1270 | optional: true
1271 |
1272 | esbuild-darwin-arm64@0.15.18:
1273 | optional: true
1274 |
1275 | esbuild-freebsd-64@0.15.18:
1276 | optional: true
1277 |
1278 | esbuild-freebsd-arm64@0.15.18:
1279 | optional: true
1280 |
1281 | esbuild-linux-32@0.15.18:
1282 | optional: true
1283 |
1284 | esbuild-linux-64@0.15.18:
1285 | optional: true
1286 |
1287 | esbuild-linux-arm64@0.15.18:
1288 | optional: true
1289 |
1290 | esbuild-linux-arm@0.15.18:
1291 | optional: true
1292 |
1293 | esbuild-linux-mips64le@0.15.18:
1294 | optional: true
1295 |
1296 | esbuild-linux-ppc64le@0.15.18:
1297 | optional: true
1298 |
1299 | esbuild-linux-riscv64@0.15.18:
1300 | optional: true
1301 |
1302 | esbuild-linux-s390x@0.15.18:
1303 | optional: true
1304 |
1305 | esbuild-netbsd-64@0.15.18:
1306 | optional: true
1307 |
1308 | esbuild-openbsd-64@0.15.18:
1309 | optional: true
1310 |
1311 | esbuild-sunos-64@0.15.18:
1312 | optional: true
1313 |
1314 | esbuild-windows-32@0.15.18:
1315 | optional: true
1316 |
1317 | esbuild-windows-64@0.15.18:
1318 | optional: true
1319 |
1320 | esbuild-windows-arm64@0.15.18:
1321 | optional: true
1322 |
1323 | esbuild@0.15.18:
1324 | optionalDependencies:
1325 | '@esbuild/android-arm': 0.15.18
1326 | '@esbuild/linux-loong64': 0.15.18
1327 | esbuild-android-64: 0.15.18
1328 | esbuild-android-arm64: 0.15.18
1329 | esbuild-darwin-64: 0.15.18
1330 | esbuild-darwin-arm64: 0.15.18
1331 | esbuild-freebsd-64: 0.15.18
1332 | esbuild-freebsd-arm64: 0.15.18
1333 | esbuild-linux-32: 0.15.18
1334 | esbuild-linux-64: 0.15.18
1335 | esbuild-linux-arm: 0.15.18
1336 | esbuild-linux-arm64: 0.15.18
1337 | esbuild-linux-mips64le: 0.15.18
1338 | esbuild-linux-ppc64le: 0.15.18
1339 | esbuild-linux-riscv64: 0.15.18
1340 | esbuild-linux-s390x: 0.15.18
1341 | esbuild-netbsd-64: 0.15.18
1342 | esbuild-openbsd-64: 0.15.18
1343 | esbuild-sunos-64: 0.15.18
1344 | esbuild-windows-32: 0.15.18
1345 | esbuild-windows-64: 0.15.18
1346 | esbuild-windows-arm64: 0.15.18
1347 |
1348 | escalade@3.2.0: {}
1349 |
1350 | fast-glob@3.3.3:
1351 | dependencies:
1352 | '@nodelib/fs.stat': 2.0.5
1353 | '@nodelib/fs.walk': 1.2.8
1354 | glob-parent: 5.1.2
1355 | merge2: 1.4.1
1356 | micromatch: 4.0.8
1357 |
1358 | fastq@1.19.1:
1359 | dependencies:
1360 | reusify: 1.1.0
1361 |
1362 | fill-range@7.1.1:
1363 | dependencies:
1364 | to-regex-range: 5.0.1
1365 |
1366 | foreground-child@3.3.1:
1367 | dependencies:
1368 | cross-spawn: 7.0.6
1369 | signal-exit: 4.1.0
1370 |
1371 | fraction.js@4.3.7: {}
1372 |
1373 | fsevents@2.3.3:
1374 | optional: true
1375 |
1376 | function-bind@1.1.2: {}
1377 |
1378 | gensync@1.0.0-beta.2: {}
1379 |
1380 | glob-parent@5.1.2:
1381 | dependencies:
1382 | is-glob: 4.0.3
1383 |
1384 | glob-parent@6.0.2:
1385 | dependencies:
1386 | is-glob: 4.0.3
1387 |
1388 | glob@10.4.5:
1389 | dependencies:
1390 | foreground-child: 3.3.1
1391 | jackspeak: 3.4.3
1392 | minimatch: 9.0.5
1393 | minipass: 7.1.2
1394 | package-json-from-dist: 1.0.1
1395 | path-scurry: 1.11.1
1396 |
1397 | globals@11.12.0: {}
1398 |
1399 | hasown@2.0.2:
1400 | dependencies:
1401 | function-bind: 1.1.2
1402 |
1403 | is-binary-path@2.1.0:
1404 | dependencies:
1405 | binary-extensions: 2.3.0
1406 |
1407 | is-core-module@2.16.1:
1408 | dependencies:
1409 | hasown: 2.0.2
1410 |
1411 | is-extglob@2.1.1: {}
1412 |
1413 | is-fullwidth-code-point@3.0.0: {}
1414 |
1415 | is-glob@4.0.3:
1416 | dependencies:
1417 | is-extglob: 2.1.1
1418 |
1419 | is-number@7.0.0: {}
1420 |
1421 | isexe@2.0.0: {}
1422 |
1423 | jackspeak@3.4.3:
1424 | dependencies:
1425 | '@isaacs/cliui': 8.0.2
1426 | optionalDependencies:
1427 | '@pkgjs/parseargs': 0.11.0
1428 |
1429 | jiti@1.21.7: {}
1430 |
1431 | js-tokens@4.0.0: {}
1432 |
1433 | jsesc@3.1.0: {}
1434 |
1435 | json5@2.2.3: {}
1436 |
1437 | lilconfig@3.1.3: {}
1438 |
1439 | lines-and-columns@1.2.4: {}
1440 |
1441 | loose-envify@1.4.0:
1442 | dependencies:
1443 | js-tokens: 4.0.0
1444 |
1445 | lru-cache@10.4.3: {}
1446 |
1447 | lru-cache@5.1.1:
1448 | dependencies:
1449 | yallist: 3.1.1
1450 |
1451 | magic-string@0.26.7:
1452 | dependencies:
1453 | sourcemap-codec: 1.4.8
1454 |
1455 | merge2@1.4.1: {}
1456 |
1457 | micromatch@4.0.8:
1458 | dependencies:
1459 | braces: 3.0.3
1460 | picomatch: 2.3.1
1461 |
1462 | minimatch@9.0.5:
1463 | dependencies:
1464 | brace-expansion: 2.0.1
1465 |
1466 | minipass@7.1.2: {}
1467 |
1468 | ms@2.1.3: {}
1469 |
1470 | mz@2.7.0:
1471 | dependencies:
1472 | any-promise: 1.3.0
1473 | object-assign: 4.1.1
1474 | thenify-all: 1.6.0
1475 |
1476 | nanoid@3.3.11: {}
1477 |
1478 | node-releases@2.0.19: {}
1479 |
1480 | normalize-path@3.0.0: {}
1481 |
1482 | normalize-range@0.1.2: {}
1483 |
1484 | object-assign@4.1.1: {}
1485 |
1486 | object-hash@3.0.0: {}
1487 |
1488 | package-json-from-dist@1.0.1: {}
1489 |
1490 | path-key@3.1.1: {}
1491 |
1492 | path-parse@1.0.7: {}
1493 |
1494 | path-scurry@1.11.1:
1495 | dependencies:
1496 | lru-cache: 10.4.3
1497 | minipass: 7.1.2
1498 |
1499 | picocolors@1.1.1: {}
1500 |
1501 | picomatch@2.3.1: {}
1502 |
1503 | pify@2.3.0: {}
1504 |
1505 | pirates@4.0.7: {}
1506 |
1507 | postcss-import@15.1.0(postcss@8.5.3):
1508 | dependencies:
1509 | postcss: 8.5.3
1510 | postcss-value-parser: 4.2.0
1511 | read-cache: 1.0.0
1512 | resolve: 1.22.10
1513 |
1514 | postcss-js@4.0.1(postcss@8.5.3):
1515 | dependencies:
1516 | camelcase-css: 2.0.1
1517 | postcss: 8.5.3
1518 |
1519 | postcss-load-config@4.0.2(postcss@8.5.3):
1520 | dependencies:
1521 | lilconfig: 3.1.3
1522 | yaml: 2.7.1
1523 | optionalDependencies:
1524 | postcss: 8.5.3
1525 |
1526 | postcss-nested@6.2.0(postcss@8.5.3):
1527 | dependencies:
1528 | postcss: 8.5.3
1529 | postcss-selector-parser: 6.1.2
1530 |
1531 | postcss-selector-parser@6.1.2:
1532 | dependencies:
1533 | cssesc: 3.0.0
1534 | util-deprecate: 1.0.2
1535 |
1536 | postcss-value-parser@4.2.0: {}
1537 |
1538 | postcss@8.5.3:
1539 | dependencies:
1540 | nanoid: 3.3.11
1541 | picocolors: 1.1.1
1542 | source-map-js: 1.2.1
1543 |
1544 | queue-microtask@1.2.3: {}
1545 |
1546 | react-dom@18.3.1(react@18.3.1):
1547 | dependencies:
1548 | loose-envify: 1.4.0
1549 | react: 18.3.1
1550 | scheduler: 0.23.2
1551 |
1552 | react-refresh@0.14.2: {}
1553 |
1554 | react@18.3.1:
1555 | dependencies:
1556 | loose-envify: 1.4.0
1557 |
1558 | read-cache@1.0.0:
1559 | dependencies:
1560 | pify: 2.3.0
1561 |
1562 | readdirp@3.6.0:
1563 | dependencies:
1564 | picomatch: 2.3.1
1565 |
1566 | resolve@1.22.10:
1567 | dependencies:
1568 | is-core-module: 2.16.1
1569 | path-parse: 1.0.7
1570 | supports-preserve-symlinks-flag: 1.0.0
1571 |
1572 | reusify@1.1.0: {}
1573 |
1574 | rollup@2.79.2:
1575 | optionalDependencies:
1576 | fsevents: 2.3.3
1577 |
1578 | run-parallel@1.2.0:
1579 | dependencies:
1580 | queue-microtask: 1.2.3
1581 |
1582 | scheduler@0.23.2:
1583 | dependencies:
1584 | loose-envify: 1.4.0
1585 |
1586 | semver@6.3.1: {}
1587 |
1588 | shebang-command@2.0.0:
1589 | dependencies:
1590 | shebang-regex: 3.0.0
1591 |
1592 | shebang-regex@3.0.0: {}
1593 |
1594 | signal-exit@4.1.0: {}
1595 |
1596 | source-map-js@1.2.1: {}
1597 |
1598 | sourcemap-codec@1.4.8: {}
1599 |
1600 | string-width@4.2.3:
1601 | dependencies:
1602 | emoji-regex: 8.0.0
1603 | is-fullwidth-code-point: 3.0.0
1604 | strip-ansi: 6.0.1
1605 |
1606 | string-width@5.1.2:
1607 | dependencies:
1608 | eastasianwidth: 0.2.0
1609 | emoji-regex: 9.2.2
1610 | strip-ansi: 7.1.0
1611 |
1612 | strip-ansi@6.0.1:
1613 | dependencies:
1614 | ansi-regex: 5.0.1
1615 |
1616 | strip-ansi@7.1.0:
1617 | dependencies:
1618 | ansi-regex: 6.1.0
1619 |
1620 | sucrase@3.35.0:
1621 | dependencies:
1622 | '@jridgewell/gen-mapping': 0.3.8
1623 | commander: 4.1.1
1624 | glob: 10.4.5
1625 | lines-and-columns: 1.2.4
1626 | mz: 2.7.0
1627 | pirates: 4.0.7
1628 | ts-interface-checker: 0.1.13
1629 |
1630 | supports-preserve-symlinks-flag@1.0.0: {}
1631 |
1632 | tailwindcss@3.4.17:
1633 | dependencies:
1634 | '@alloc/quick-lru': 5.2.0
1635 | arg: 5.0.2
1636 | chokidar: 3.6.0
1637 | didyoumean: 1.2.2
1638 | dlv: 1.1.3
1639 | fast-glob: 3.3.3
1640 | glob-parent: 6.0.2
1641 | is-glob: 4.0.3
1642 | jiti: 1.21.7
1643 | lilconfig: 3.1.3
1644 | micromatch: 4.0.8
1645 | normalize-path: 3.0.0
1646 | object-hash: 3.0.0
1647 | picocolors: 1.1.1
1648 | postcss: 8.5.3
1649 | postcss-import: 15.1.0(postcss@8.5.3)
1650 | postcss-js: 4.0.1(postcss@8.5.3)
1651 | postcss-load-config: 4.0.2(postcss@8.5.3)
1652 | postcss-nested: 6.2.0(postcss@8.5.3)
1653 | postcss-selector-parser: 6.1.2
1654 | resolve: 1.22.10
1655 | sucrase: 3.35.0
1656 | transitivePeerDependencies:
1657 | - ts-node
1658 |
1659 | thenify-all@1.6.0:
1660 | dependencies:
1661 | thenify: 3.3.1
1662 |
1663 | thenify@3.3.1:
1664 | dependencies:
1665 | any-promise: 1.3.0
1666 |
1667 | to-regex-range@5.0.1:
1668 | dependencies:
1669 | is-number: 7.0.0
1670 |
1671 | ts-interface-checker@0.1.13: {}
1672 |
1673 | tslib@2.8.1: {}
1674 |
1675 | typescript@4.9.5: {}
1676 |
1677 | update-browserslist-db@1.1.3(browserslist@4.24.4):
1678 | dependencies:
1679 | browserslist: 4.24.4
1680 | escalade: 3.2.0
1681 | picocolors: 1.1.1
1682 |
1683 | util-deprecate@1.0.2: {}
1684 |
1685 | vite@3.2.11:
1686 | dependencies:
1687 | esbuild: 0.15.18
1688 | postcss: 8.5.3
1689 | resolve: 1.22.10
1690 | rollup: 2.79.2
1691 | optionalDependencies:
1692 | fsevents: 2.3.3
1693 |
1694 | which@2.0.2:
1695 | dependencies:
1696 | isexe: 2.0.0
1697 |
1698 | wrap-ansi@7.0.0:
1699 | dependencies:
1700 | ansi-styles: 4.3.0
1701 | string-width: 4.2.3
1702 | strip-ansi: 6.0.1
1703 |
1704 | wrap-ansi@8.1.0:
1705 | dependencies:
1706 | ansi-styles: 6.2.1
1707 | string-width: 5.1.2
1708 | strip-ansi: 7.1.0
1709 |
1710 | yallist@3.1.1: {}
1711 |
1712 | yaml@2.7.1: {}
1713 |
--------------------------------------------------------------------------------
/frontend/postcss.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/frontend/src/App.css:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/frontend/src/App.tsx:
--------------------------------------------------------------------------------
1 | // ClipboardHistory.tsx
2 | import { useEffect, useState, memo } from 'react';
3 | import { GetHistory, UpdateHistory } from '../wailsjs/go/main/App';
4 | import { DndContext, closestCenter, useSensor, useSensors, PointerSensor } from '@dnd-kit/core';
5 | import {
6 | arrayMove,
7 | SortableContext,
8 | useSortable,
9 | verticalListSortingStrategy
10 | } from '@dnd-kit/sortable';
11 | import { CSS } from '@dnd-kit/utilities';
12 |
13 | // Pre-rendered static SVG components with memoization
14 | const ScrollBackground = memo(() => (
15 |
16 | {/* Simple texture pattern instead of complex SVG filter */}
17 |
23 |
24 |
25 | ));
26 |
27 | const InkwellIcon = memo(() => (
28 |
40 | ));
41 |
42 | const QuillIcon = memo(() => (
43 |
51 | ));
52 |
53 | const DeleteIcon = memo(() => (
54 |
57 | ));
58 |
59 | // Memoized sortable item component
60 | const SortableItem = memo(({ id, onDelete }: { id: string, onDelete: (id: string) => void }) => {
61 | const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id });
62 | const style = {
63 | transform: CSS.Transform.toString(transform),
64 | transition,
65 | };
66 |
67 | const handleDelete = (e: React.MouseEvent) => {
68 | e.stopPropagation();
69 | onDelete(id);
70 | };
71 |
72 | return (
73 |
80 |
81 |
82 |
83 |
84 | {id}
85 |
86 |
87 |
94 |
95 | {/* Simplified decorative elements */}
96 |
97 |
98 | );
99 | });
100 |
101 | // Main component with performance optimizations
102 | export default function ClipboardHistory() {
103 | const [items, setItems] = useState([]);
104 | const [isRefreshing, setIsRefreshing] = useState(false);
105 | const [isClearing, setIsClearing] = useState(false);
106 | const [confirmClear, setConfirmClear] = useState(false);
107 |
108 | const sensors = useSensors(useSensor(PointerSensor, {
109 | activationConstraint: {
110 | distance: 5, // Small distance threshold to avoid accidental drags
111 | },
112 | }));
113 |
114 | const fetchHistory = async () => {
115 | if (isRefreshing) return; // Prevent multiple simultaneous requests
116 |
117 | setIsRefreshing(true);
118 | try {
119 | const history = await GetHistory();
120 | setItems(history);
121 | } catch (error) {
122 | console.error("Failed to fetch history:", error);
123 | } finally {
124 | // Use requestAnimationFrame for smoother UI updates
125 | requestAnimationFrame(() => {
126 | setTimeout(() => setIsRefreshing(false), 300);
127 | });
128 | }
129 | };
130 |
131 | useEffect(() => {
132 | fetchHistory();
133 | }, []);
134 |
135 | const handleDragEnd = async (event: any) => {
136 | const { active, over } = event;
137 | if (!active || !over || active.id === over.id) return;
138 |
139 | const oldIndex = items.indexOf(active.id);
140 | const newIndex = items.indexOf(over.id);
141 |
142 | if (oldIndex !== -1 && newIndex !== -1) {
143 | const newItems = arrayMove(items, oldIndex, newIndex);
144 | setItems(newItems);
145 |
146 | // Optimistic UI update, then sync with backend
147 | try {
148 | await UpdateHistory(newItems);
149 | } catch (error) {
150 | console.error("Failed to update history:", error);
151 | // Could revert items here on error
152 | }
153 | }
154 | };
155 |
156 | const handleDeleteItem = async (id: string) => {
157 | const newItems = items.filter(item => item !== id);
158 | setItems(newItems);
159 |
160 | try {
161 | await UpdateHistory(newItems);
162 | } catch (error) {
163 | console.error("Failed to delete item:", error);
164 | // Rollback on error
165 | await fetchHistory();
166 | }
167 | };
168 |
169 | const handleClearAll = async () => {
170 | if (!confirmClear) {
171 | setConfirmClear(true);
172 | setTimeout(() => setConfirmClear(false), 3000); // Reset after 3 seconds
173 | return;
174 | }
175 |
176 | setIsClearing(true);
177 | try {
178 | await UpdateHistory([]);
179 | setItems([]);
180 | setConfirmClear(false);
181 | } catch (error) {
182 | console.error("Failed to clear all items:", error);
183 | await fetchHistory();
184 | } finally {
185 | setIsClearing(false);
186 | }
187 | };
188 |
189 | return (
190 |
191 |
192 |
193 |
194 |
195 |
196 | ClipCapsule
197 |
198 |
199 |
216 |
217 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
Clipboard History
235 |
236 |
237 | Use CTRL+SHIFT+[1-9] to select an item
238 |
239 |
240 |
241 |
242 |
247 |
248 | {items.length > 0 ? (
249 |
250 | {items.map((text) => (
251 |
256 | ))}
257 |
258 | ) : (
259 |
260 | {isRefreshing ? "Loading..." : "No clipboard history found. Copy something to see it here."}
261 |
262 | )}
263 |
264 |
265 |
266 |
267 |
268 |
ClipCapsule · A Vintage Clipboard Manager
269 |
270 |
271 |
272 | );
273 | }
--------------------------------------------------------------------------------
/frontend/src/assets/logo-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Victor-Evogor/clipcapsule/5370e2b20f46ce75f7f3a6254fc5c570fc7ffeed/frontend/src/assets/logo-2.png
--------------------------------------------------------------------------------
/frontend/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Victor-Evogor/clipcapsule/5370e2b20f46ce75f7f3a6254fc5c570fc7ffeed/frontend/src/assets/logo.png
--------------------------------------------------------------------------------
/frontend/src/assets/wails.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Victor-Evogor/clipcapsule/5370e2b20f46ce75f7f3a6254fc5c570fc7ffeed/frontend/src/assets/wails.png
--------------------------------------------------------------------------------
/frontend/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
--------------------------------------------------------------------------------
/frontend/src/main.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
7 |
8 |
9 |
10 | )
11 |
--------------------------------------------------------------------------------
/frontend/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/frontend/tailwind.config.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: [
4 | "./src/**/*.{js,jsx,ts,tsx}",
5 | ],
6 | theme: {
7 | extend: {},
8 | },
9 | plugins: [],
10 | }
11 |
--------------------------------------------------------------------------------
/frontend/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
6 | "allowJs": false,
7 | "skipLibCheck": true,
8 | "esModuleInterop": false,
9 | "allowSyntheticDefaultImports": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "module": "ESNext",
13 | "moduleResolution": "Node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx"
18 | },
19 | "include": ["src"],
20 | "references": [{ "path": "./tsconfig.node.json" }]
21 | }
22 |
--------------------------------------------------------------------------------
/frontend/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "allowSyntheticDefaultImports": true
7 | },
8 | "include": ["vite.config.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/frontend/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()]
7 | })
8 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module clipcapsule
2 |
3 | go 1.23.0
4 |
5 | toolchain go1.23.8
6 |
7 | require (
8 | github.com/MarinX/keylogger v0.0.0-20240620105846-48ca9d01f566
9 | github.com/mattn/go-sqlite3 v1.14.27
10 | github.com/wailsapp/wails/v2 v2.10.1
11 | golang.design/x/clipboard v0.7.0
12 | )
13 |
14 | require (
15 | github.com/bep/debounce v1.2.1 // indirect
16 | github.com/go-ole/go-ole v1.3.0 // indirect
17 | github.com/godbus/dbus/v5 v5.1.0 // indirect
18 | github.com/google/uuid v1.6.0 // indirect
19 | github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
20 | github.com/labstack/echo/v4 v4.13.3 // indirect
21 | github.com/labstack/gommon v0.4.2 // indirect
22 | github.com/leaanthony/go-ansi-parser v1.6.1 // indirect
23 | github.com/leaanthony/gosod v1.0.4 // indirect
24 | github.com/leaanthony/slicer v1.6.0 // indirect
25 | github.com/leaanthony/u v1.1.1 // indirect
26 | github.com/mattn/go-colorable v0.1.13 // indirect
27 | github.com/mattn/go-isatty v0.0.20 // indirect
28 | github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
29 | github.com/pkg/errors v0.9.1 // indirect
30 | github.com/rivo/uniseg v0.4.7 // indirect
31 | github.com/samber/lo v1.49.1 // indirect
32 | github.com/tkrajina/go-reflector v0.5.8 // indirect
33 | github.com/valyala/bytebufferpool v1.0.0 // indirect
34 | github.com/valyala/fasttemplate v1.2.2 // indirect
35 | github.com/wailsapp/go-webview2 v1.0.19 // indirect
36 | github.com/wailsapp/mimetype v1.4.1 // indirect
37 | golang.org/x/crypto v0.33.0 // indirect
38 | golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 // indirect
39 | golang.org/x/image v0.12.0 // indirect
40 | golang.org/x/mobile v0.0.0-20230301163155-e0f57694e12c // indirect
41 | golang.org/x/net v0.35.0 // indirect
42 | golang.org/x/sys v0.32.0 // indirect
43 | golang.org/x/text v0.22.0 // indirect
44 | )
45 |
46 | // replace github.com/wailsapp/wails/v2 v2.10.1 => /home/victor/go/pkg/mod
47 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
2 | github.com/MarinX/keylogger v0.0.0-20240620105846-48ca9d01f566 h1:3uD1lmRbdt8Ho73IcAUTxRQtksuupGMigYG0x+yOi+o=
3 | github.com/MarinX/keylogger v0.0.0-20240620105846-48ca9d01f566/go.mod h1:aKzZ7D15UvH5LboXkeLmcNi+s/f805vUfB+BfW1fqd4=
4 | github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY=
5 | github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0=
6 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
7 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
8 | github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
9 | github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
10 | github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
11 | github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
12 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
13 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
14 | github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck=
15 | github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
16 | github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY=
17 | github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g=
18 | github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
19 | github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
20 | github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oOc=
21 | github.com/leaanthony/debme v1.2.1/go.mod h1:3V+sCm5tYAgQymvSOfYQ5Xx2JCr+OXiD9Jkw3otUjiA=
22 | github.com/leaanthony/go-ansi-parser v1.6.1 h1:xd8bzARK3dErqkPFtoF9F3/HgN8UQk0ed1YDKpEz01A=
23 | github.com/leaanthony/go-ansi-parser v1.6.1/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU=
24 | github.com/leaanthony/gosod v1.0.4 h1:YLAbVyd591MRffDgxUOU1NwLhT9T1/YiwjKZpkNFeaI=
25 | github.com/leaanthony/gosod v1.0.4/go.mod h1:GKuIL0zzPj3O1SdWQOdgURSuhkF+Urizzxh26t9f1cw=
26 | github.com/leaanthony/slicer v1.6.0 h1:1RFP5uiPJvT93TAHi+ipd3NACobkW53yUiBqZheE/Js=
27 | github.com/leaanthony/slicer v1.6.0/go.mod h1:o/Iz29g7LN0GqH3aMjWAe90381nyZlDNquK+mtH2Fj8=
28 | github.com/leaanthony/u v1.1.1 h1:TUFjwDGlNX+WuwVEzDqQwC2lOv0P4uhTQw7CMFdiK7M=
29 | github.com/leaanthony/u v1.1.1/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI=
30 | github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
31 | github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ=
32 | github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
33 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
34 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
35 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
36 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
37 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
38 | github.com/mattn/go-sqlite3 v1.14.27 h1:drZCnuvf37yPfs95E5jd9s3XhdVWLal+6BOK6qrv6IU=
39 | github.com/mattn/go-sqlite3 v1.14.27/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
40 | github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
41 | github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
42 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
43 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
44 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
45 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
46 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
47 | github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
48 | github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
49 | github.com/samber/lo v1.49.1 h1:4BIFyVfuQSEpluc7Fua+j1NolZHiEHEpaSEKdsH0tew=
50 | github.com/samber/lo v1.49.1/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd6o=
51 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
52 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
53 | github.com/tkrajina/go-reflector v0.5.8 h1:yPADHrwmUbMq4RGEyaOUpz2H90sRsETNVpjzo3DLVQQ=
54 | github.com/tkrajina/go-reflector v0.5.8/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4=
55 | github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
56 | github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
57 | github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
58 | github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
59 | github.com/wailsapp/go-webview2 v1.0.19 h1:7U3QcDj1PrBPaxJNCui2k1SkWml+Q5kvFUFyTImA6NU=
60 | github.com/wailsapp/go-webview2 v1.0.19/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc=
61 | github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
62 | github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
63 | github.com/wailsapp/wails/v2 v2.10.1 h1:QWHvWMXII2nI/nXz77gpPG8P3ehl6zKe+u4su5BWIns=
64 | github.com/wailsapp/wails/v2 v2.10.1/go.mod h1:zrebnFV6MQf9kx8HI4iAv63vsR5v67oS7GTEZ7Pz1TY=
65 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
66 | golang.design/x/clipboard v0.7.0 h1:4Je8M/ys9AJumVnl8m+rZnIvstSnYj1fvzqYrU3TXvo=
67 | golang.design/x/clipboard v0.7.0/go.mod h1:PQIvqYO9GP29yINEfsEn5zSQKAz3UgXmZKzDA6dnq2E=
68 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
69 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
70 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
71 | golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
72 | golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
73 | golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 h1:estk1glOnSVeJ9tdEZZc5mAMDZk5lNJNyJ6DvrBkTEU=
74 | golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
75 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
76 | golang.org/x/image v0.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ=
77 | golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk=
78 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
79 | golang.org/x/mobile v0.0.0-20230301163155-e0f57694e12c h1:Gk61ECugwEHL6IiyyNLXNzmu8XslmRP2dS0xjIYhbb4=
80 | golang.org/x/mobile v0.0.0-20230301163155-e0f57694e12c/go.mod h1:aAjjkJNdrh3PMckS4B10TGS2nag27cbKR1y2BpUxsiY=
81 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
82 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
83 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
84 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
85 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
86 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
87 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
88 | golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
89 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
90 | golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
91 | golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
92 | golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
93 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
94 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
95 | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
96 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
97 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
98 | golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
99 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
100 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
101 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
102 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
103 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
104 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
105 | golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
106 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
107 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
108 | golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
109 | golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
110 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
111 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
112 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
113 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
114 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
115 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
116 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
117 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
118 | golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
119 | golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
120 | golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
121 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
122 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
123 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
124 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
125 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
126 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
127 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
128 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
129 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "clipcapsule/utils"
5 | "embed"
6 |
7 | "github.com/wailsapp/wails/v2"
8 | "github.com/wailsapp/wails/v2/pkg/options"
9 | "github.com/wailsapp/wails/v2/pkg/options/linux"
10 | )
11 |
12 | //go:embed all:frontend/dist
13 | var assets embed.FS
14 |
15 | //go:embed favicon.ico
16 | var logo_embed embed.FS
17 |
18 | func main() {
19 | // Create an instance of the app structure
20 | app := NewApp()
21 |
22 | go utils.MonitorKeyboardGlobal()
23 |
24 | logo, logo_err := logo_embed.ReadFile("favicon.ico")
25 | if logo_err != nil {
26 | panic(logo_err)
27 | }
28 |
29 | // Create application with options
30 | err := wails.Run(&options.App{
31 | Title: "clipcapsule",
32 | Width: 1024,
33 | Height: 768,
34 | Assets: assets,
35 | BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1},
36 | OnStartup: app.startup,
37 | Bind: []interface{}{
38 | app,
39 | },
40 | Linux: &linux.Options{
41 | Icon: logo,
42 | ProgramName: "clipcapsule",
43 | },
44 | })
45 |
46 | if err != nil {
47 | println("Error:", err.Error())
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/scripts/build-macos-arm.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | echo -e "Start running the script..."
4 | cd ../
5 |
6 | echo -e "Start building the app for macos platform..."
7 | wails build --clean --platform darwin/arm64
8 |
9 | echo -e "End running the script!"
10 |
--------------------------------------------------------------------------------
/scripts/build-macos-intel.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | echo -e "Start running the script..."
4 | cd ../
5 |
6 | echo -e "Start building the app for macos platform..."
7 | wails build --clean --platform darwin
8 |
9 | echo -e "End running the script!"
10 |
--------------------------------------------------------------------------------
/scripts/build-macos.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | echo -e "Start running the script..."
4 | cd ../
5 |
6 | echo -e "Start building the app for macos platform..."
7 | wails build --clean --platform darwin/universal
8 |
9 | echo -e "End running the script!"
10 |
--------------------------------------------------------------------------------
/scripts/build-windows.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | echo -e "Start running the script..."
4 | cd ../
5 |
6 | echo -e "Start building the app for windows platform..."
7 | wails build --clean --platform windows/amd64
8 |
9 | echo -e "End running the script!"
10 |
--------------------------------------------------------------------------------
/scripts/build.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | echo -e "Start running the script..."
4 | cd ../
5 |
6 | echo -e "Start building the app..."
7 | wails build --clean
8 |
9 | echo -e "End running the script!"
10 |
--------------------------------------------------------------------------------
/scripts/install-wails-cli.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | echo -e "Start running the script..."
4 | cd ../
5 |
6 | echo -e "Current Go version: \c"
7 | go version
8 |
9 | echo -e "Install the Wails command line tool..."
10 | go install github.com/wailsapp/wails/v2/cmd/wails@latest
11 |
12 | echo -e "Successful installation!"
13 |
14 | echo -e "End running the script!"
15 |
--------------------------------------------------------------------------------
/utils/db.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "database/sql"
5 | "fmt"
6 |
7 | _ "github.com/mattn/go-sqlite3"
8 | )
9 |
10 | var dbURL = "db/cliphistory.db"
11 |
12 | type ClipboardItem struct {
13 | ID int
14 | Content string
15 | Position int
16 | }
17 |
18 | type Db struct {
19 | conn *sql.DB
20 | }
21 |
22 | // New initializes the database connection and creates the table if it doesn't exist
23 | func (d *Db) New() error {
24 | db, err := sql.Open("sqlite3", dbURL)
25 | if err != nil {
26 | return fmt.Errorf("failed to open database: %w", err)
27 | }
28 | d.conn = db
29 |
30 | return d.createTable()
31 | }
32 |
33 | // createTable ensures the clipboard_items table exists
34 | func (d *Db) createTable() error {
35 | query := `
36 | CREATE TABLE IF NOT EXISTS clipboard_items (
37 | id INTEGER PRIMARY KEY AUTOINCREMENT,
38 | content TEXT NOT NULL,
39 | position INTEGER NOT NULL
40 | );
41 | `
42 | _, err := d.conn.Exec(query)
43 | return err
44 | }
45 |
46 | func CopyFirstDbEntryToClipboard(d *Db) {
47 |
48 | }
49 |
50 | // UpdateAllItems replaces all clipboard items with the provided ordered texts
51 | func (d *Db) UpdateAllItems(texts []string) []ClipboardItem {
52 | tx, err := d.conn.Begin()
53 | if err != nil {
54 | panic(fmt.Sprint("failed to begin transaction: %w", err))
55 | }
56 |
57 | // Clear existing records
58 | if _, err := tx.Exec(`DELETE FROM clipboard_items`); err != nil {
59 | tx.Rollback()
60 | panic(fmt.Sprint("failed to clear clipboard_items: %w", err))
61 | }
62 |
63 | // Insert all new items in order
64 | stmt, err := tx.Prepare(`INSERT INTO clipboard_items (content, position) VALUES (?, ?)`)
65 | if err != nil {
66 | tx.Rollback()
67 | panic(fmt.Sprint("failed to prepare insert: %w", err))
68 | }
69 | defer stmt.Close()
70 |
71 | for i, text := range texts {
72 | if _, err := stmt.Exec(text, i); err != nil {
73 | tx.Rollback()
74 | panic(fmt.Sprint("failed to insert item %d: %w", i, err))
75 | }
76 | }
77 |
78 | if tx.Commit() != nil {
79 | panic("Failed to commit transaction")
80 | }
81 |
82 | items, err := d.FetchAllItems()
83 | if err != nil {
84 | panic(err)
85 | }
86 |
87 | return items
88 | }
89 |
90 | // Optional: FetchAllItems returns all clipboard items in order
91 | func (d *Db) FetchAllItems() ([]ClipboardItem, error) {
92 | rows, err := d.conn.Query(`SELECT id, content, position FROM clipboard_items ORDER BY position ASC`)
93 | if err != nil {
94 | return nil, err
95 | }
96 | defer rows.Close()
97 |
98 | var items []ClipboardItem
99 | for rows.Next() {
100 | var item ClipboardItem
101 | if err := rows.Scan(&item.ID, &item.Content, &item.Position); err != nil {
102 | return nil, err
103 | }
104 | items = append(items, item)
105 | }
106 |
107 | return items, nil
108 | }
109 |
110 | // GetItemByPosition returns a clipboard item based on its position
111 | func (d *Db) GetItemByPosition(position int) (ClipboardItem, error) {
112 | var item ClipboardItem
113 | query := `SELECT id, content, position FROM clipboard_items WHERE position = ? LIMIT 1`
114 |
115 | row := d.conn.QueryRow(query, position)
116 | err := row.Scan(&item.ID, &item.Content, &item.Position)
117 | if err != nil {
118 | if err == sql.ErrNoRows {
119 | return item, fmt.Errorf("no item found at position %d", position)
120 | }
121 | return item, fmt.Errorf("failed to get item by position: %w", err)
122 | }
123 |
124 | return item, nil
125 | }
126 |
--------------------------------------------------------------------------------
/utils/monitorClipboard.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "context"
5 | "log"
6 | "strconv"
7 |
8 | "github.com/MarinX/keylogger"
9 | "golang.design/x/clipboard"
10 | )
11 |
12 | func MonitorKeyboardGlobal() {
13 | eventPath := keylogger.FindKeyboardDevice()
14 | if eventPath == "" {
15 | log.Fatal("No keyboard found")
16 | }
17 |
18 | keyLogger, err := keylogger.New(eventPath)
19 | if err != nil {
20 | log.Fatal("Failed to open keyboard:", err)
21 | }
22 |
23 | keysPressed := map[string]bool{}
24 |
25 | if clErr := clipboard.Init(); clErr != nil {
26 | log.Fatal(clErr)
27 | }
28 |
29 | db := Db{}
30 | if err := db.New(); err != nil {
31 | log.Fatal(err)
32 | }
33 |
34 | // Start the clipboard monitoring in a separate goroutine
35 | go MonitorClipboardChanges(&db)
36 |
37 | for event := range keyLogger.Read() {
38 | key := event.KeyString()
39 |
40 | if event.Type == keylogger.EvKey {
41 | if event.Value == 1 {
42 | keysPressed[key] = true
43 | }
44 | if event.Value == 0 {
45 | keysPressed[key] = false
46 | }
47 |
48 | isCtrl := keysPressed["L_CTRL"] || keysPressed["R_CTRL"]
49 | isShift := keysPressed["L_SHIFT"] || keysPressed["R_SHIFT"]
50 |
51 | // Handle Ctrl + Shift + [1-9]
52 | if isCtrl && isShift {
53 | for i := 1; i <= 9; i++ {
54 | keyStr := strconv.Itoa(i)
55 | if keysPressed[keyStr] {
56 | items, err := db.FetchAllItems()
57 | if err != nil {
58 | log.Println("Error fetching items:", err)
59 | continue
60 | }
61 | if i > len(items) {
62 | log.Printf("No item at position %d\n", i)
63 | continue
64 | }
65 |
66 | selected := items[i-1].Content
67 | newList := []string{selected}
68 | for _, item := range items {
69 | if item.Content != selected {
70 | newList = append(newList, item.Content)
71 | }
72 | }
73 |
74 | db.UpdateAllItems(newList)
75 |
76 | clipboard.Write(clipboard.FmtText, []byte(selected)) // set new #1 as clipboard
77 | }
78 | }
79 | }
80 |
81 | }
82 | }
83 | }
84 |
85 | // MonitorClipboardChanges watches for any changes to the clipboard content
86 | func MonitorClipboardChanges(db *Db) {
87 | // Create a channel to receive clipboard change notifications
88 | ch := clipboard.Watch(context.Background(), clipboard.FmtText)
89 |
90 | var lastContent string
91 |
92 | for data := range ch {
93 | clipboardText := string(data)
94 |
95 | // Skip if clipboard is empty or same as last content
96 | if clipboardText == "" || clipboardText == lastContent {
97 | continue
98 | }
99 |
100 | log.Printf("Clipboard changed, new content: %s", clipboardText[:min(20, len(clipboardText))])
101 | lastContent = clipboardText
102 |
103 | // Update database
104 | items, err := db.FetchAllItems()
105 | if err != nil {
106 | log.Println("Error fetching items:", err)
107 | continue
108 | }
109 |
110 | // Check if content already at position 1
111 | if len(items) > 0 && items[0].Content == clipboardText {
112 | log.Println("Content already at top position, no update needed")
113 | continue
114 | }
115 |
116 | newList := []string{clipboardText}
117 | for _, item := range items {
118 | if item.Content != clipboardText {
119 | newList = append(newList, item.Content)
120 | }
121 | }
122 |
123 | db.UpdateAllItems(newList)
124 | }
125 | }
126 |
127 | // Helper function for string length limiting
128 | func min(a, b int) int {
129 | if a < b {
130 | return a
131 | }
132 | return b
133 | }
134 |
--------------------------------------------------------------------------------
/wails.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "clipcapsule",
3 | "outputfilename": "clipcapsule",
4 | "frontend:install": "npm install",
5 | "frontend:build": "npm run build",
6 | "frontend:dev:watcher": "npm run dev",
7 | "frontend:dev:serverUrl": "auto",
8 | "author": {
9 | "name": "Victor Evogor",
10 | "email": "victorevogor0001@gmail.com"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/wails.toml:
--------------------------------------------------------------------------------
1 | [platform.windows]
2 | icon = "frontend/src/assets/logo-2.png"
3 |
4 | [platform.darwin]
5 | icon = "frontend/src/assets/logo-2.png"
6 |
7 | [platform.linux]
8 | icon = "frontend/src/assets/logo-2.png"
9 |
--------------------------------------------------------------------------------