From 1c38fd970e97ca9c54004af70fb9ce58d8f8b083 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Sun, 4 Dec 2022 17:04:08 +0800 Subject: [PATCH 01/19] feat(picker): save and read configuration on disk. #2. --- src-tauri/Cargo.lock | 10 ++ src-tauri/Cargo.toml | 3 + .../{config.rs => config/display_config.rs} | 17 +-- src-tauri/src/picker/config/manger.rs | 122 ++++++++++++++++++ src-tauri/src/picker/config/mod.rs | 5 + src-tauri/src/picker/manager.rs | 5 +- 6 files changed, 145 insertions(+), 17 deletions(-) rename src-tauri/src/picker/{config.rs => config/display_config.rs} (83%) create mode 100644 src-tauri/src/picker/config/manger.rs create mode 100644 src-tauri/src/picker/config/mod.rs diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 8b811dc..fa48eb6 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -584,6 +584,7 @@ dependencies = [ "serde_json", "tauri", "tauri-build", + "test_dir", "time", "tokio", "tracing", @@ -3165,6 +3166,15 @@ dependencies = [ "utf-8", ] +[[package]] +name = "test_dir" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc19daf9fc57fadcf740c4abaaa0cd08d9ce22a2a0629aaf6cbd9ae4b80683a" +dependencies = [ + "rand 0.8.5", +] + [[package]] name = "thin-slice" version = "0.1.1" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 69306a8..25ea562 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -41,3 +41,6 @@ default = [ "custom-protocol" ] # this feature is used used for production builds where `devPath` points to the filesystem # DO NOT remove this custom-protocol = [ "tauri/custom-protocol" ] + +[dev-dependencies] +test_dir = "0.2.0" diff --git a/src-tauri/src/picker/config.rs b/src-tauri/src/picker/config/display_config.rs similarity index 83% rename from src-tauri/src/picker/config.rs rename to src-tauri/src/picker/config/display_config.rs index 2b1dea5..09586e8 100644 --- a/src-tauri/src/picker/config.rs +++ b/src-tauri/src/picker/config/display_config.rs @@ -1,11 +1,13 @@ -#[derive(Clone, Copy)] +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Copy, Serialize, Deserialize)] pub struct LedStripConfig { pub index: usize, pub global_start_position: usize, pub global_end_position: usize, } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Serialize, Deserialize)] pub struct DisplayConfig { pub index_of_display: usize, pub display_width: usize, @@ -16,17 +18,6 @@ pub struct DisplayConfig { pub right_led_strip: LedStripConfig, } -#[derive(Clone, Copy)] -pub enum LedFlowX { - LR, // from left to right - RL, // from right to left -} -#[derive(Clone, Copy)] -pub enum LedFlowY { - TB, // from top to bottom - BT, // from bottom to top -} - impl DisplayConfig { pub fn default(index_of_display: usize, display_width: usize, display_height: usize) -> Self { Self { diff --git a/src-tauri/src/picker/config/manger.rs b/src-tauri/src/picker/config/manger.rs new file mode 100644 index 0000000..25c090d --- /dev/null +++ b/src-tauri/src/picker/config/manger.rs @@ -0,0 +1,122 @@ +use std::{ + env::current_dir, + fs::{self, File}, + io::Read, + path::PathBuf, +}; + +use once_cell::sync::OnceCell; +use serde::{Deserialize, Serialize}; +use tauri::api::path::config_dir; + +use super::DisplayConfig; + +#[derive(Serialize, Deserialize, Clone)] +pub struct Configuration { + config_version: u8, + display_configs: Vec, +} + +impl Configuration { + pub fn default() -> Self { + Self { + config_version: 1, + display_configs: vec![], + } + } +} + +#[derive(Serialize, Deserialize)] +pub struct Manager { + config: Configuration, +} + +impl Manager { + pub fn global() -> &'static Manager { + static DISPLAY_CONFIG_MANAGE: OnceCell = OnceCell::new(); + + DISPLAY_CONFIG_MANAGE.get_or_init(|| Self::init_from_disk()) + } + + pub fn default() -> Self { + Self::new(Configuration::default()) + } + + pub fn new(config: Configuration) -> Self { + Self { config } + } + + pub fn get_config_file_path() -> PathBuf { + config_dir() + .unwrap_or(current_dir().unwrap()) + .join("display_config.json") + } + + pub fn init_from_disk() -> Self { + let config_file_path = Self::get_config_file_path(); + match Self::read_config_from_disk(config_file_path) { + Ok(config) => Self::new(config), + Err(_) => Self::default(), + } + } + + pub fn read_config_from_disk(config_file_path: PathBuf) -> anyhow::Result { + let mut file = File::open(config_file_path) + .map_err(|error| anyhow::anyhow!("config file is not existed. {}", error))?; + let mut contents = String::new(); + file.read_to_string(&mut contents) + .map_err(|error| anyhow::anyhow!("can not read config file. {}", error))?; + serde_json::from_str(&contents) + .map_err(|error| anyhow::anyhow!("can not parse config file contents. {}", error)) + } + + pub fn write_config_to_disk(&self, config_file_path: PathBuf) -> anyhow::Result<()> { + let contents = serde_json::to_string(&self.config) + .map_err(|error| anyhow::anyhow!("can not serialize config. {}", error))?; + fs::write(config_file_path, contents.as_bytes()) + .map_err(|error| anyhow::anyhow!("can not write config file. {}", error))?; + Ok(()) + } +} + +#[cfg(test)] +mod tests { + + use std::fs; + + use serde_json::json; + use test_dir::{DirBuilder, TestDir}; + + use crate::picker::config::Configuration; + + #[test] + fn write_config_to_disk_should_be_successful() { + let temp = TestDir::temp().create("config_dir", test_dir::FileType::Dir); + let config_file_path = temp.path("config_dir").join("picker.config.json"); + let manager = crate::picker::config::manger::Manager::default(); + manager + .write_config_to_disk(config_file_path.clone()) + .unwrap(); + + let contents = fs::read_to_string(config_file_path.clone()).unwrap(); + let _config: Configuration = serde_json::from_str(contents.as_str()).unwrap(); + } + + #[test] + fn read_config_to_disk_should_be_successful() { + let temp = TestDir::temp().create("config_dir", test_dir::FileType::Dir); + let config_file_path = temp.path("config_dir").join("picker.config.json"); + fs::write( + config_file_path.clone(), + json!({ + "config_version": 1, + "display_configs": [] + }) + .to_string() + .as_bytes(), + ).unwrap(); + let _manager = + crate::picker::config::manger::Manager::read_config_from_disk(config_file_path.clone()) + .unwrap(); + } +} diff --git a/src-tauri/src/picker/config/mod.rs b/src-tauri/src/picker/config/mod.rs new file mode 100644 index 0000000..f1c53a0 --- /dev/null +++ b/src-tauri/src/picker/config/mod.rs @@ -0,0 +1,5 @@ +mod display_config; +mod manger; + +pub use display_config::*; +pub use manger::*; \ No newline at end of file diff --git a/src-tauri/src/picker/manager.rs b/src-tauri/src/picker/manager.rs index 328d461..9157103 100644 --- a/src-tauri/src/picker/manager.rs +++ b/src-tauri/src/picker/manager.rs @@ -5,10 +5,7 @@ use scrap::Display; use std::sync::Arc; use tokio::{sync::Mutex, task}; -use crate::picker::{ - config::{LedFlowX, LedFlowY, LedStripConfig}, - screen::Screen, -}; +use crate::picker::{config::LedStripConfig, screen::Screen}; use super::{ config::DisplayConfig, display_picker::DisplayPicker, led_color::LedColor, From 082fcaee20bb94cf58ef72cc3279ed009f2a3133 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Sat, 17 Dec 2022 19:31:22 +0800 Subject: [PATCH 02/19] =?UTF-8?q?feat:=20WIP=20=E7=95=8C=E9=9D=A2=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + pnpm-lock.yaml | 515 +++++++++--------- src-tauri/src/main.rs | 29 +- src-tauri/src/picker/config/display_config.rs | 4 +- src-tauri/src/picker/config/manger.rs | 13 +- src-tauri/src/picker/manager.rs | 123 +---- src/App.tsx | 13 +- .../components/display-with-led-strips.tsx | 25 + src/configurator/components/led-strip.tsx | 11 + src/configurator/configurator.tsx | 46 ++ src/configurator/models/display-config.ts | 11 + src/configurator/models/led-strip-config.ts | 5 + .../models/picker-configuration.ts | 6 + 13 files changed, 400 insertions(+), 402 deletions(-) create mode 100644 src/configurator/components/display-with-led-strips.tsx create mode 100644 src/configurator/components/led-strip.tsx create mode 100644 src/configurator/configurator.tsx create mode 100644 src/configurator/models/display-config.ts create mode 100644 src/configurator/models/led-strip-config.ts create mode 100644 src/configurator/models/picker-configuration.ts diff --git a/package.json b/package.json index 89bffa9..c3cefaa 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@tauri-apps/api": "^1.1.0", "clsx": "^1.2.1", "react": "^18.2.0", + "react-async-hook": "^4.0.0", "react-dom": "^18.2.0" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fab2d4c..d657ef8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,12 +1,12 @@ lockfileVersion: 5.4 specifiers: - '@tauri-apps/api': ^1.2.0 - '@tauri-apps/cli': ^1.2.1 - '@types/node': ^18.11.9 - '@types/react': ^18.0.25 - '@types/react-dom': ^18.0.9 - '@vitejs/plugin-react': ^2.2.0 + '@tauri-apps/api': ^1.1.0 + '@tauri-apps/cli': ^1.1.0 + '@types/node': ^18.7.10 + '@types/react': ^18.0.15 + '@types/react-dom': ^18.0.6 + '@vitejs/plugin-react': ^2.0.0 autoprefixer: ^10.4.13 clsx: ^1.2.1 eslint-config-prettier: ^8.5.0 @@ -15,36 +15,38 @@ specifiers: eslint-plugin-prettier: ^4.2.1 eslint-plugin-simple-import-sort: ^8.0.0 postcss: ^8.4.19 - prettier: ^2.8.0 + prettier: ^2.7.1 react: ^18.2.0 + react-async-hook: ^4.0.0 react-dom: ^18.2.0 tailwindcss: ^3.2.4 - typescript: ^4.9.3 - vite: ^3.2.4 + typescript: ^4.6.4 + vite: ^3.0.2 dependencies: '@tauri-apps/api': 1.2.0 clsx: 1.2.1 react: 18.2.0 + react-async-hook: 4.0.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0 devDependencies: - '@tauri-apps/cli': 1.2.1 - '@types/node': 18.11.9 - '@types/react': 18.0.25 + '@tauri-apps/cli': 1.2.2 + '@types/node': 18.11.16 + '@types/react': 18.0.26 '@types/react-dom': 18.0.9 - '@vitejs/plugin-react': 2.2.0_vite@3.2.4 - autoprefixer: 10.4.13_postcss@8.4.19 + '@vitejs/plugin-react': 2.2.0_vite@3.2.5 + autoprefixer: 10.4.13_postcss@8.4.20 eslint-config-prettier: 8.5.0 eslint-plugin-import: 2.26.0 eslint-plugin-jsx-a11y: 6.6.1 - eslint-plugin-prettier: 4.2.1_woggxqa3l645ufel4grhxgids4 + eslint-plugin-prettier: 4.2.1_oixrjny4ajrp742454blm2dh6q eslint-plugin-simple-import-sort: 8.0.0 - postcss: 8.4.19 - prettier: 2.8.0 - tailwindcss: 3.2.4_postcss@8.4.19 - typescript: 4.9.3 - vite: 3.2.4_@types+node@18.11.9 + postcss: 8.4.20 + prettier: 2.8.1 + tailwindcss: 3.2.4_postcss@8.4.20 + typescript: 4.9.4 + vite: 3.2.5_@types+node@18.11.16 packages: @@ -63,39 +65,39 @@ packages: '@babel/highlight': 7.18.6 dev: true - /@babel/compat-data/7.20.1: - resolution: {integrity: sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==} + /@babel/compat-data/7.20.5: + resolution: {integrity: sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==} engines: {node: '>=6.9.0'} dev: true - /@babel/core/7.20.2: - resolution: {integrity: sha512-w7DbG8DtMrJcFOi4VrLm+8QM4az8Mo+PuLBKLp2zrYRCow8W/f9xiXm5sN53C8HksCyDQwCKha9JiDoIyPjT2g==} + /@babel/core/7.20.5: + resolution: {integrity: sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.0 '@babel/code-frame': 7.18.6 - '@babel/generator': 7.20.4 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.2 + '@babel/generator': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 '@babel/helper-module-transforms': 7.20.2 - '@babel/helpers': 7.20.1 - '@babel/parser': 7.20.3 + '@babel/helpers': 7.20.6 + '@babel/parser': 7.20.5 '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 convert-source-map: 1.9.0 debug: 4.3.4 gensync: 1.0.0-beta.2 - json5: 2.2.1 + json5: 2.2.2 semver: 6.3.0 transitivePeerDependencies: - supports-color dev: true - /@babel/generator/7.20.4: - resolution: {integrity: sha512-luCf7yk/cm7yab6CAW1aiFnmEfBJplb/JojV56MYEK7ziWfGmFlTfmL9Ehwfy4gFhbjBfWO1wj7/TuSbVNEEtA==} + /@babel/generator/7.20.5: + resolution: {integrity: sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 '@jridgewell/gen-mapping': 0.3.2 jsesc: 2.5.2 dev: true @@ -104,17 +106,17 @@ packages: resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true - /@babel/helper-compilation-targets/7.20.0_@babel+core@7.20.2: + /@babel/helper-compilation-targets/7.20.0_@babel+core@7.20.5: resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/compat-data': 7.20.1 - '@babel/core': 7.20.2 + '@babel/compat-data': 7.20.5 + '@babel/core': 7.20.5 '@babel/helper-validator-option': 7.18.6 browserslist: 4.21.4 semver: 6.3.0 @@ -130,21 +132,21 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.18.10 - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true /@babel/helper-hoist-variables/7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true /@babel/helper-module-imports/7.18.6: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true /@babel/helper-module-transforms/7.20.2: @@ -157,8 +159,8 @@ packages: '@babel/helper-split-export-declaration': 7.18.6 '@babel/helper-validator-identifier': 7.19.1 '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 transitivePeerDependencies: - supports-color dev: true @@ -172,14 +174,14 @@ packages: resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true /@babel/helper-split-export-declaration/7.18.6: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true /@babel/helper-string-parser/7.19.4: @@ -197,13 +199,13 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/helpers/7.20.1: - resolution: {integrity: sha512-J77mUVaDTUJFZ5BpP6mMn6OIl3rEWymk2ZxDBQJUG3P+PbmyMcF3bYWvz0ma69Af1oobDqT/iAsvzhB58xhQUg==} + /@babel/helpers/7.20.6: + resolution: {integrity: sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==} engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.18.10 - '@babel/traverse': 7.20.1 - '@babel/types': 7.20.2 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 transitivePeerDependencies: - supports-color dev: true @@ -217,78 +219,78 @@ packages: js-tokens: 4.0.0 dev: true - /@babel/parser/7.20.3: - resolution: {integrity: sha512-OP/s5a94frIPXwjzEcv5S/tpQfc6XhxYUnmWpgdqMWGgYCuErA3SzozaRAMQgSZWKeTJxht9aWAkUY+0UzvOFg==} + /@babel/parser/7.20.5: + resolution: {integrity: sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.20.2 + '@babel/types': 7.20.5 dev: true - /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.20.2: + /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 - '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.5 dev: true - /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.20.2: + /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-react-jsx-source/7.19.6_@babel+core@7.20.2: + /@babel/plugin-transform-react-jsx-source/7.19.6_@babel+core@7.20.5: resolution: {integrity: sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.20.2: + /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.20.5: resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.2 + '@babel/core': 7.20.5 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-module-imports': 7.18.6 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.20.2 - '@babel/types': 7.20.2 + '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.20.5 + '@babel/types': 7.20.5 dev: true - /@babel/runtime-corejs3/7.20.1: - resolution: {integrity: sha512-CGulbEDcg/ND1Im7fUNRZdGXmX2MTWVVZacQi/6DiKE5HNwZ3aVTm5PV4lO8HHz0B2h8WQyvKKjbX5XgTtydsg==} + /@babel/runtime-corejs3/7.20.6: + resolution: {integrity: sha512-tqeujPiuEfcH067mx+7otTQWROVMKHXEaOQcAeNV5dDdbPWvPcFA8/W9LXw2NfjNmOetqLl03dfnG2WALPlsRQ==} engines: {node: '>=6.9.0'} dependencies: core-js-pure: 3.26.1 regenerator-runtime: 0.13.11 dev: true - /@babel/runtime/7.20.1: - resolution: {integrity: sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==} + /@babel/runtime/7.20.6: + resolution: {integrity: sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.13.11 @@ -299,30 +301,30 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/parser': 7.20.3 - '@babel/types': 7.20.2 + '@babel/parser': 7.20.5 + '@babel/types': 7.20.5 dev: true - /@babel/traverse/7.20.1: - resolution: {integrity: sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==} + /@babel/traverse/7.20.5: + resolution: {integrity: sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/generator': 7.20.4 + '@babel/generator': 7.20.5 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.19.0 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.20.3 - '@babel/types': 7.20.2 + '@babel/parser': 7.20.5 + '@babel/types': 7.20.5 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: - supports-color dev: true - /@babel/types/7.20.2: - resolution: {integrity: sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==} + /@babel/types/7.20.5: + resolution: {integrity: sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-string-parser': 7.19.4 @@ -330,8 +332,8 @@ packages: to-fast-properties: 2.0.0 dev: true - /@esbuild/android-arm/0.15.15: - resolution: {integrity: sha512-JJjZjJi2eBL01QJuWjfCdZxcIgot+VoK6Fq7eKF9w4YHm9hwl7nhBR1o2Wnt/WcANk5l9SkpvrldW1PLuXxcbw==} + /@esbuild/android-arm/0.15.18: + resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==} engines: {node: '>=12'} cpu: [arm] os: [android] @@ -339,8 +341,8 @@ packages: dev: true optional: true - /@esbuild/linux-loong64/0.15.15: - resolution: {integrity: sha512-lhz6UNPMDXUhtXSulw8XlFAtSYO26WmHQnCi2Lg2p+/TMiJKNLtZCYUxV4wG6rZMzXmr8InGpNwk+DLT2Hm0PA==} + /@esbuild/linux-loong64/0.15.18: + resolution: {integrity: sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -404,7 +406,7 @@ packages: engines: {node: '>= 8'} dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.13.0 + fastq: 1.14.0 dev: true /@tauri-apps/api/1.2.0: @@ -412,8 +414,8 @@ packages: engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'} dev: false - /@tauri-apps/cli-darwin-arm64/1.2.1: - resolution: {integrity: sha512-WiAxSON52owFI65Whd3NjcKjXdO1zJfafBVZ3v+Y3F2zlXhRPiirXbtefAc3mvN56zDz/pfi018Qb4XesuVzHA==} + /@tauri-apps/cli-darwin-arm64/1.2.2: + resolution: {integrity: sha512-W+Cp2weUMlvmGkRJeUjypbz9Lpl6o98xkgKAtobZSum5SNwpsBQfawJTESakNoD+FXyVg/snIk5sRdHge+tAaA==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] @@ -421,8 +423,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-darwin-x64/1.2.1: - resolution: {integrity: sha512-jfumnrn7RYKVtDmHgrQhImoxpqT51bDrO4KxgpIXaYSaf6MdG2JT72dwUovPrURw0JX2Z/Elihq+dYbrsKoV/w==} + /@tauri-apps/cli-darwin-x64/1.2.2: + resolution: {integrity: sha512-vmVAqt+ECH2d6cbcGJ7ddcCAZgmKe5xmxlL5r4xoaphu7OqU4gnv4VFURYkVltOfwzIFQVOPVSqwYyIDToCYNQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] @@ -430,8 +432,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-linux-arm-gnueabihf/1.2.1: - resolution: {integrity: sha512-n4p6Ekn6Wa9X/klUGevEGgoWAGApGGsLrJYE4c8bKTbAUfQ9Nyzjh8gK/GDii1dg9oRW0FdXDa6BJa7aEEj9sA==} + /@tauri-apps/cli-linux-arm-gnueabihf/1.2.2: + resolution: {integrity: sha512-yYTdQurgi4QZR8z+fANjl522jdQz/VtesFpw+C/A0+zXg7tiRjicsywBDdPsvNzCqFeGKKkmTR+Lny5qxhGaeQ==} engines: {node: '>= 10'} cpu: [arm] os: [linux] @@ -439,8 +441,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-linux-arm64-gnu/1.2.1: - resolution: {integrity: sha512-oAHkQQGfNCh8pQQHuDzzqt+S5sOj3tiUkySaquR2z/AQEHeDGAMrRGLZwOiDw9Xvu7qxFiF9H0e5OMK7BkncDw==} + /@tauri-apps/cli-linux-arm64-gnu/1.2.2: + resolution: {integrity: sha512-ZSOVT6Eq1ay2+27B8KfA0MnpO7KYzONU6TjenH7DNcQki6eWGG5JoNu8QQ9Mdn3dAzY0XBP9i1ZHQOFu4iPtEg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -448,8 +450,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-linux-arm64-musl/1.2.1: - resolution: {integrity: sha512-1dEZ5fdFYkMyB1U7ZkDJUlwYwCeqy9Y3vXmtZ6pCxrvgs844s8+RIFDuMU42pTN+lUxfFeQARmv0LpS4eF/QWQ==} + /@tauri-apps/cli-linux-arm64-musl/1.2.2: + resolution: {integrity: sha512-/NHSkqNQ+Pr4PshvyD1CeNFaPCaCpe1OeuAQgVi0rboSecC9fXN96G5dQbSBoxOUcCo6f8aTVE7zkZ4WchFVog==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] @@ -457,8 +459,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-linux-x64-gnu/1.2.1: - resolution: {integrity: sha512-wkgCD3s5P6tgBPnn0/gDx7MXMx2Hx+jdA+JP8zdCq4cIeYXlxdZG/zXbHb5ldPadNh582lzHiGg+Pmc+wDg2fA==} + /@tauri-apps/cli-linux-x64-gnu/1.2.2: + resolution: {integrity: sha512-4YTmfPuyvlHsvCkATDMwhklfuQm3HKxYXv/IOW9H0ra6pS9efVhrFYIC9Vfv6XaKN85Vnn/FYTEGMJLwCxZw2Q==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -466,8 +468,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-linux-x64-musl/1.2.1: - resolution: {integrity: sha512-zD+a+5cSlYVU0ECOojWp71ok/9jE0DJufzb9oky17XIKV/oiOAG60z4OYRe+oqxYS1TcBt+pUa1/2zlu/6SRdA==} + /@tauri-apps/cli-linux-x64-musl/1.2.2: + resolution: {integrity: sha512-wr46tbscwFuCcA931R+ItOiUTT0djMmgKLd1HFCmFF82V9BKE2reIjr6O9l0NCXCo2WeD4pe3jA/Pt1dxDu+JA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] @@ -475,8 +477,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-win32-ia32-msvc/1.2.1: - resolution: {integrity: sha512-nEgdRd8czaKL1RQfj946dsfzlk6atmD95Fm7NVTVOe77PFHTS3ztHeWK7X6jirCaOF3h/F7qpJVCU6JMnq2tfA==} + /@tauri-apps/cli-win32-ia32-msvc/1.2.2: + resolution: {integrity: sha512-6VmbVJOWUZJK5/JKhb3mNFKrKGfq0KV7lJGumfN95WJgkHeyL61p8bZit+o6ZgUGUhrOabkAawhDkrRY+ZQhIw==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] @@ -484,8 +486,8 @@ packages: dev: true optional: true - /@tauri-apps/cli-win32-x64-msvc/1.2.1: - resolution: {integrity: sha512-ceWiQkmNNRrnfgbLMnndT4QF1IyLK7aOJsMqS/HueshAwmVQWnC1DUE0C58Taetgq38Cavc4gGnZOCHuH6ZuTw==} + /@tauri-apps/cli-win32-x64-msvc/1.2.2: + resolution: {integrity: sha512-YRPJguJma+zSuRZpFoSZqls6+laggG1vqG0FPQWQTi+ywATgMpai2b2RZnffDlpHKp9mt4V/s2dtqOy6bpGZHg==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -493,28 +495,28 @@ packages: dev: true optional: true - /@tauri-apps/cli/1.2.1: - resolution: {integrity: sha512-JrFFT1/4V+AGSRjKdgszZwOr+/a1519LDhNxBkbsIg6D/kFK+3kk1qImaQBY9DvvIWK6IV4whc8OAkgxm+Sl3w==} + /@tauri-apps/cli/1.2.2: + resolution: {integrity: sha512-D8zib3A0vWCvPPSyYLxww/OdDlVcY7fpcDVBH6qUvheOjj2aCyU7H9AYMRBwpgCfz8zY5+vomee+laLeB0H13w==} engines: {node: '>= 10'} hasBin: true optionalDependencies: - '@tauri-apps/cli-darwin-arm64': 1.2.1 - '@tauri-apps/cli-darwin-x64': 1.2.1 - '@tauri-apps/cli-linux-arm-gnueabihf': 1.2.1 - '@tauri-apps/cli-linux-arm64-gnu': 1.2.1 - '@tauri-apps/cli-linux-arm64-musl': 1.2.1 - '@tauri-apps/cli-linux-x64-gnu': 1.2.1 - '@tauri-apps/cli-linux-x64-musl': 1.2.1 - '@tauri-apps/cli-win32-ia32-msvc': 1.2.1 - '@tauri-apps/cli-win32-x64-msvc': 1.2.1 + '@tauri-apps/cli-darwin-arm64': 1.2.2 + '@tauri-apps/cli-darwin-x64': 1.2.2 + '@tauri-apps/cli-linux-arm-gnueabihf': 1.2.2 + '@tauri-apps/cli-linux-arm64-gnu': 1.2.2 + '@tauri-apps/cli-linux-arm64-musl': 1.2.2 + '@tauri-apps/cli-linux-x64-gnu': 1.2.2 + '@tauri-apps/cli-linux-x64-musl': 1.2.2 + '@tauri-apps/cli-win32-ia32-msvc': 1.2.2 + '@tauri-apps/cli-win32-x64-msvc': 1.2.2 dev: true /@types/json5/0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true - /@types/node/18.11.9: - resolution: {integrity: sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==} + /@types/node/18.11.16: + resolution: {integrity: sha512-6T7P5bDkRhqRxrQtwj7vru+bWTpelgtcETAZEUSdq0YISKz8WKdoBukQLYQQ6DFHvU9JRsbFq0JH5C51X2ZdnA==} dev: true /@types/prop-types/15.7.5: @@ -524,11 +526,11 @@ packages: /@types/react-dom/18.0.9: resolution: {integrity: sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==} dependencies: - '@types/react': 18.0.25 + '@types/react': 18.0.26 dev: true - /@types/react/18.0.25: - resolution: {integrity: sha512-xD6c0KDT4m7n9uD4ZHi02lzskaiqcBxf4zi+tXZY98a04wvc0hi/TcCPC2FOESZi51Nd7tlUeOJY8RofL799/g==} + /@types/react/18.0.26: + resolution: {integrity: sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==} dependencies: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.2 @@ -539,20 +541,20 @@ packages: resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} dev: true - /@vitejs/plugin-react/2.2.0_vite@3.2.4: + /@vitejs/plugin-react/2.2.0_vite@3.2.5: resolution: {integrity: sha512-FFpefhvExd1toVRlokZgxgy2JtnBOdp4ZDsq7ldCWaqGSGn9UhWMAVm/1lxPL14JfNS5yGz+s9yFrQY6shoStA==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: ^3.0.0 dependencies: - '@babel/core': 7.20.2 - '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.2 - '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.20.2 - '@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.20.2 + '@babel/core': 7.20.5 + '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.5 + '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.20.5 magic-string: 0.26.7 react-refresh: 0.14.0 - vite: 3.2.4_@types+node@18.11.9 + vite: 3.2.5_@types+node@18.11.16 transitivePeerDependencies: - supports-color dev: true @@ -599,8 +601,8 @@ packages: resolution: {integrity: sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==} engines: {node: '>=6.0'} dependencies: - '@babel/runtime': 7.20.1 - '@babel/runtime-corejs3': 7.20.1 + '@babel/runtime': 7.20.6 + '@babel/runtime-corejs3': 7.20.6 dev: true /array-includes/3.1.6: @@ -609,7 +611,7 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.4 + es-abstract: 1.20.5 get-intrinsic: 1.1.3 is-string: 1.0.7 dev: true @@ -620,7 +622,7 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.4 + es-abstract: 1.20.5 es-shim-unscopables: 1.0.0 dev: true @@ -628,7 +630,7 @@ packages: resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==} dev: true - /autoprefixer/10.4.13_postcss@8.4.19: + /autoprefixer/10.4.13_postcss@8.4.20: resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} engines: {node: ^10 || ^12 || >=14} hasBin: true @@ -636,16 +638,16 @@ packages: postcss: ^8.1.0 dependencies: browserslist: 4.21.4 - caniuse-lite: 1.0.30001434 + caniuse-lite: 1.0.30001439 fraction.js: 4.2.0 normalize-range: 0.1.2 picocolors: 1.0.0 - postcss: 8.4.19 + postcss: 8.4.20 postcss-value-parser: 4.2.0 dev: true - /axe-core/4.5.2: - resolution: {integrity: sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA==} + /axe-core/4.6.1: + resolution: {integrity: sha512-lCZN5XRuOnpG4bpMq8v0khrWtUOn+i8lZSb6wHZH56ZfbIEv6XwJV84AAueh9/zi7qPVJ/E4yz6fmsiyOmXR4w==} engines: {node: '>=4'} dev: true @@ -681,9 +683,9 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001434 + caniuse-lite: 1.0.30001439 electron-to-chromium: 1.4.284 - node-releases: 2.0.6 + node-releases: 2.0.8 update-browserslist-db: 1.0.10_browserslist@4.21.4 dev: true @@ -699,8 +701,8 @@ packages: engines: {node: '>= 6'} dev: true - /caniuse-lite/1.0.30001434: - resolution: {integrity: sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA==} + /caniuse-lite/1.0.30001439: + resolution: {integrity: sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==} dev: true /chalk/2.4.2: @@ -852,8 +854,8 @@ packages: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} dev: true - /es-abstract/1.20.4: - resolution: {integrity: sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==} + /es-abstract/1.20.5: + resolution: {integrity: sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 @@ -862,10 +864,11 @@ packages: function.prototype.name: 1.1.5 get-intrinsic: 1.1.3 get-symbol-description: 1.0.0 + gopd: 1.0.1 has: 1.0.3 has-property-descriptors: 1.0.0 has-symbols: 1.0.3 - internal-slot: 1.0.3 + internal-slot: 1.0.4 is-callable: 1.2.7 is-negative-zero: 2.0.2 is-regex: 1.1.4 @@ -897,8 +900,8 @@ packages: is-symbol: 1.0.4 dev: true - /esbuild-android-64/0.15.15: - resolution: {integrity: sha512-F+WjjQxO+JQOva3tJWNdVjouFMLK6R6i5gjDvgUthLYJnIZJsp1HlF523k73hELY20WPyEO8xcz7aaYBVkeg5Q==} + /esbuild-android-64/0.15.18: + resolution: {integrity: sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==} engines: {node: '>=12'} cpu: [x64] os: [android] @@ -906,8 +909,8 @@ packages: dev: true optional: true - /esbuild-android-arm64/0.15.15: - resolution: {integrity: sha512-attlyhD6Y22jNyQ0fIIQ7mnPvDWKw7k6FKnsXlBvQE6s3z6s6cuEHcSgoirquQc7TmZgVCK5fD/2uxmRN+ZpcQ==} + /esbuild-android-arm64/0.15.18: + resolution: {integrity: sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -915,8 +918,8 @@ packages: dev: true optional: true - /esbuild-darwin-64/0.15.15: - resolution: {integrity: sha512-ohZtF8W1SHJ4JWldsPVdk8st0r9ExbAOSrBOh5L+Mq47i696GVwv1ab/KlmbUoikSTNoXEhDzVpxUR/WIO19FQ==} + /esbuild-darwin-64/0.15.18: + resolution: {integrity: sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -924,8 +927,8 @@ packages: dev: true optional: true - /esbuild-darwin-arm64/0.15.15: - resolution: {integrity: sha512-P8jOZ5zshCNIuGn+9KehKs/cq5uIniC+BeCykvdVhx/rBXSxmtj3CUIKZz4sDCuESMbitK54drf/2QX9QHG5Ag==} + /esbuild-darwin-arm64/0.15.18: + resolution: {integrity: sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -933,8 +936,8 @@ packages: dev: true optional: true - /esbuild-freebsd-64/0.15.15: - resolution: {integrity: sha512-KkTg+AmDXz1IvA9S1gt8dE24C8Thx0X5oM0KGF322DuP+P3evwTL9YyusHAWNsh4qLsR80nvBr/EIYs29VSwuA==} + /esbuild-freebsd-64/0.15.18: + resolution: {integrity: sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -942,8 +945,8 @@ packages: dev: true optional: true - /esbuild-freebsd-arm64/0.15.15: - resolution: {integrity: sha512-FUcML0DRsuyqCMfAC+HoeAqvWxMeq0qXvclZZ/lt2kLU6XBnDA5uKTLUd379WYEyVD4KKFctqWd9tTuk8C/96g==} + /esbuild-freebsd-arm64/0.15.18: + resolution: {integrity: sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -951,8 +954,8 @@ packages: dev: true optional: true - /esbuild-linux-32/0.15.15: - resolution: {integrity: sha512-q28Qn5pZgHNqug02aTkzw5sW9OklSo96b5nm17Mq0pDXrdTBcQ+M6Q9A1B+dalFeynunwh/pvfrNucjzwDXj+Q==} + /esbuild-linux-32/0.15.18: + resolution: {integrity: sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -960,8 +963,8 @@ packages: dev: true optional: true - /esbuild-linux-64/0.15.15: - resolution: {integrity: sha512-217KPmWMirkf8liO+fj2qrPwbIbhNTGNVtvqI1TnOWJgcMjUWvd677Gq3fTzXEjilkx2yWypVnTswM2KbXgoAg==} + /esbuild-linux-64/0.15.18: + resolution: {integrity: sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -969,8 +972,8 @@ packages: dev: true optional: true - /esbuild-linux-arm/0.15.15: - resolution: {integrity: sha512-RYVW9o2yN8yM7SB1yaWr378CwrjvGCyGybX3SdzPHpikUHkME2AP55Ma20uNwkNyY2eSYFX9D55kDrfQmQBR4w==} + /esbuild-linux-arm/0.15.18: + resolution: {integrity: sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -978,8 +981,8 @@ packages: dev: true optional: true - /esbuild-linux-arm64/0.15.15: - resolution: {integrity: sha512-/ltmNFs0FivZkYsTzAsXIfLQX38lFnwJTWCJts0IbCqWZQe+jjj0vYBNbI0kmXLb3y5NljiM5USVAO1NVkdh2g==} + /esbuild-linux-arm64/0.15.18: + resolution: {integrity: sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -987,8 +990,8 @@ packages: dev: true optional: true - /esbuild-linux-mips64le/0.15.15: - resolution: {integrity: sha512-PksEPb321/28GFFxtvL33yVPfnMZihxkEv5zME2zapXGp7fA1X2jYeiTUK+9tJ/EGgcNWuwvtawPxJG7Mmn86A==} + /esbuild-linux-mips64le/0.15.18: + resolution: {integrity: sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -996,8 +999,8 @@ packages: dev: true optional: true - /esbuild-linux-ppc64le/0.15.15: - resolution: {integrity: sha512-ek8gJBEIhcpGI327eAZigBOHl58QqrJrYYIZBWQCnH3UnXoeWMrMZLeeZL8BI2XMBhP+sQ6ERctD5X+ajL/AIA==} + /esbuild-linux-ppc64le/0.15.18: + resolution: {integrity: sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -1005,8 +1008,8 @@ packages: dev: true optional: true - /esbuild-linux-riscv64/0.15.15: - resolution: {integrity: sha512-H5ilTZb33/GnUBrZMNJtBk7/OXzDHDXjIzoLXHSutwwsLxSNaLxzAaMoDGDd/keZoS+GDBqNVxdCkpuiRW4OSw==} + /esbuild-linux-riscv64/0.15.18: + resolution: {integrity: sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -1014,8 +1017,8 @@ packages: dev: true optional: true - /esbuild-linux-s390x/0.15.15: - resolution: {integrity: sha512-jKaLUg78mua3rrtrkpv4Or2dNTJU7bgHN4bEjT4OX4GR7nLBSA9dfJezQouTxMmIW7opwEC5/iR9mpC18utnxQ==} + /esbuild-linux-s390x/0.15.18: + resolution: {integrity: sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -1023,8 +1026,8 @@ packages: dev: true optional: true - /esbuild-netbsd-64/0.15.15: - resolution: {integrity: sha512-aOvmF/UkjFuW6F36HbIlImJTTx45KUCHJndtKo+KdP8Dhq3mgLRKW9+6Ircpm8bX/RcS3zZMMmaBLkvGY06Gvw==} + /esbuild-netbsd-64/0.15.18: + resolution: {integrity: sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -1032,8 +1035,8 @@ packages: dev: true optional: true - /esbuild-openbsd-64/0.15.15: - resolution: {integrity: sha512-HFFX+WYedx1w2yJ1VyR1Dfo8zyYGQZf1cA69bLdrHzu9svj6KH6ZLK0k3A1/LFPhcEY9idSOhsB2UyU0tHPxgQ==} + /esbuild-openbsd-64/0.15.18: + resolution: {integrity: sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -1041,8 +1044,8 @@ packages: dev: true optional: true - /esbuild-sunos-64/0.15.15: - resolution: {integrity: sha512-jOPBudffG4HN8yJXcK9rib/ZTFoTA5pvIKbRrt3IKAGMq1EpBi4xoVoSRrq/0d4OgZLaQbmkHp8RO9eZIn5atA==} + /esbuild-sunos-64/0.15.18: + resolution: {integrity: sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -1050,8 +1053,8 @@ packages: dev: true optional: true - /esbuild-windows-32/0.15.15: - resolution: {integrity: sha512-MDkJ3QkjnCetKF0fKxCyYNBnOq6dmidcwstBVeMtXSgGYTy8XSwBeIE4+HuKiSsG6I/mXEb++px3IGSmTN0XiA==} + /esbuild-windows-32/0.15.18: + resolution: {integrity: sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -1059,8 +1062,8 @@ packages: dev: true optional: true - /esbuild-windows-64/0.15.15: - resolution: {integrity: sha512-xaAUIB2qllE888SsMU3j9nrqyLbkqqkpQyWVkfwSil6BBPgcPk3zOFitTTncEKCLTQy3XV9RuH7PDj3aJDljWA==} + /esbuild-windows-64/0.15.18: + resolution: {integrity: sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -1068,8 +1071,8 @@ packages: dev: true optional: true - /esbuild-windows-arm64/0.15.15: - resolution: {integrity: sha512-ttuoCYCIJAFx4UUKKWYnFdrVpoXa3+3WWkXVI6s09U+YjhnyM5h96ewTq/WgQj9LFSIlABQvadHSOQyAVjW5xQ==} + /esbuild-windows-arm64/0.15.18: + resolution: {integrity: sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -1077,34 +1080,34 @@ packages: dev: true optional: true - /esbuild/0.15.15: - resolution: {integrity: sha512-TEw/lwK4Zzld9x3FedV6jy8onOUHqcEX3ADFk4k+gzPUwrxn8nWV62tH0udo8jOtjFodlEfc4ypsqX3e+WWO6w==} + /esbuild/0.15.18: + resolution: {integrity: sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.15.15 - '@esbuild/linux-loong64': 0.15.15 - esbuild-android-64: 0.15.15 - esbuild-android-arm64: 0.15.15 - esbuild-darwin-64: 0.15.15 - esbuild-darwin-arm64: 0.15.15 - esbuild-freebsd-64: 0.15.15 - esbuild-freebsd-arm64: 0.15.15 - esbuild-linux-32: 0.15.15 - esbuild-linux-64: 0.15.15 - esbuild-linux-arm: 0.15.15 - esbuild-linux-arm64: 0.15.15 - esbuild-linux-mips64le: 0.15.15 - esbuild-linux-ppc64le: 0.15.15 - esbuild-linux-riscv64: 0.15.15 - esbuild-linux-s390x: 0.15.15 - esbuild-netbsd-64: 0.15.15 - esbuild-openbsd-64: 0.15.15 - esbuild-sunos-64: 0.15.15 - esbuild-windows-32: 0.15.15 - esbuild-windows-64: 0.15.15 - esbuild-windows-arm64: 0.15.15 + '@esbuild/android-arm': 0.15.18 + '@esbuild/linux-loong64': 0.15.18 + esbuild-android-64: 0.15.18 + esbuild-android-arm64: 0.15.18 + esbuild-darwin-64: 0.15.18 + esbuild-darwin-arm64: 0.15.18 + esbuild-freebsd-64: 0.15.18 + esbuild-freebsd-arm64: 0.15.18 + esbuild-linux-32: 0.15.18 + esbuild-linux-64: 0.15.18 + esbuild-linux-arm: 0.15.18 + esbuild-linux-arm64: 0.15.18 + esbuild-linux-mips64le: 0.15.18 + esbuild-linux-ppc64le: 0.15.18 + esbuild-linux-riscv64: 0.15.18 + esbuild-linux-s390x: 0.15.18 + esbuild-netbsd-64: 0.15.18 + esbuild-openbsd-64: 0.15.18 + esbuild-sunos-64: 0.15.18 + esbuild-windows-32: 0.15.18 + esbuild-windows-64: 0.15.18 + esbuild-windows-arm64: 0.15.18 dev: true /escalade/3.1.1: @@ -1195,22 +1198,22 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 dependencies: - '@babel/runtime': 7.20.1 + '@babel/runtime': 7.20.6 aria-query: 4.2.2 array-includes: 3.1.6 ast-types-flow: 0.0.7 - axe-core: 4.5.2 + axe-core: 4.6.1 axobject-query: 2.2.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 has: 1.0.3 jsx-ast-utils: 3.3.3 - language-tags: 1.0.5 + language-tags: 1.0.7 minimatch: 3.1.2 semver: 6.3.0 dev: true - /eslint-plugin-prettier/4.2.1_woggxqa3l645ufel4grhxgids4: + /eslint-plugin-prettier/4.2.1_oixrjny4ajrp742454blm2dh6q: resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1222,7 +1225,7 @@ packages: optional: true dependencies: eslint-config-prettier: 8.5.0 - prettier: 2.8.0 + prettier: 2.8.1 prettier-linter-helpers: 1.0.0 dev: true @@ -1252,8 +1255,8 @@ packages: micromatch: 4.0.5 dev: true - /fastq/1.13.0: - resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} + /fastq/1.14.0: + resolution: {integrity: sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==} dependencies: reusify: 1.0.4 dev: true @@ -1287,7 +1290,7 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.4 + es-abstract: 1.20.5 functions-have-names: 1.2.3 dev: true @@ -1335,6 +1338,12 @@ packages: engines: {node: '>=4'} dev: true + /gopd/1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.1.3 + dev: true + /has-bigints/1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} dev: true @@ -1369,8 +1378,8 @@ packages: function-bind: 1.1.1 dev: true - /internal-slot/1.0.3: - resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} + /internal-slot/1.0.4: + resolution: {integrity: sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==} engines: {node: '>= 0.4'} dependencies: get-intrinsic: 1.1.3 @@ -1496,8 +1505,8 @@ packages: minimist: 1.2.7 dev: true - /json5/2.2.1: - resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} + /json5/2.2.2: + resolution: {integrity: sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==} engines: {node: '>=6'} hasBin: true dev: true @@ -1514,8 +1523,8 @@ packages: resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} dev: true - /language-tags/1.0.5: - resolution: {integrity: sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==} + /language-tags/1.0.7: + resolution: {integrity: sha512-bSytju1/657hFjgUzPAPqszxH62ouE8nQFoFaVlIQfne4wO/wXC9A4+m8jYve7YBBvi59eq0SUpcshvG8h5Usw==} dependencies: language-subtag-registry: 0.3.22 dev: true @@ -1580,8 +1589,8 @@ packages: hasBin: true dev: true - /node-releases/2.0.6: - resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} + /node-releases/2.0.8: + resolution: {integrity: sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==} dev: true /normalize-path/3.0.0: @@ -1624,7 +1633,7 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.4 + es-abstract: 1.20.5 dev: true /path-parse/1.0.7: @@ -1645,29 +1654,29 @@ packages: engines: {node: '>=0.10.0'} dev: true - /postcss-import/14.1.0_postcss@8.4.19: + /postcss-import/14.1.0_postcss@8.4.20: resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==} engines: {node: '>=10.0.0'} peerDependencies: postcss: ^8.0.0 dependencies: - postcss: 8.4.19 + postcss: 8.4.20 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.1 dev: true - /postcss-js/4.0.0_postcss@8.4.19: + /postcss-js/4.0.0_postcss@8.4.20: resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.3.3 dependencies: camelcase-css: 2.0.1 - postcss: 8.4.19 + postcss: 8.4.20 dev: true - /postcss-load-config/3.1.4_postcss@8.4.19: + /postcss-load-config/3.1.4_postcss@8.4.20: resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} engines: {node: '>= 10'} peerDependencies: @@ -1680,17 +1689,17 @@ packages: optional: true dependencies: lilconfig: 2.0.6 - postcss: 8.4.19 + postcss: 8.4.20 yaml: 1.10.2 dev: true - /postcss-nested/6.0.0_postcss@8.4.19: + /postcss-nested/6.0.0_postcss@8.4.20: resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.2.14 dependencies: - postcss: 8.4.19 + postcss: 8.4.20 postcss-selector-parser: 6.0.11 dev: true @@ -1706,8 +1715,8 @@ packages: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} dev: true - /postcss/8.4.19: - resolution: {integrity: sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==} + /postcss/8.4.20: + resolution: {integrity: sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.4 @@ -1722,8 +1731,8 @@ packages: fast-diff: 1.2.0 dev: true - /prettier/2.8.0: - resolution: {integrity: sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==} + /prettier/2.8.1: + resolution: {integrity: sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==} engines: {node: '>=10.13.0'} hasBin: true dev: true @@ -1737,6 +1746,15 @@ packages: engines: {node: '>=10'} dev: true + /react-async-hook/4.0.0_react@18.2.0: + resolution: {integrity: sha512-97lgjFkOcHCTYSrsKBpsXg3iVWM0LnzedB749iP76sb3/8Ouu4nHIkCLEOrQWHVYqrYxjF05NN6GHoXWFkB3Kw==} + engines: {node: '>=8', npm: '>=5'} + peerDependencies: + react: '>=16.8' + dependencies: + react: 18.2.0 + dev: false + /react-dom/18.2.0_react@18.2.0: resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: @@ -1847,6 +1865,7 @@ packages: /sourcemap-codec/1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead dev: true /string.prototype.trimend/1.0.6: @@ -1854,7 +1873,7 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.4 + es-abstract: 1.20.5 dev: true /string.prototype.trimstart/1.0.6: @@ -1862,7 +1881,7 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.4 + es-abstract: 1.20.5 dev: true /strip-bom/3.0.0: @@ -1882,7 +1901,7 @@ packages: engines: {node: '>= 0.4'} dev: true - /tailwindcss/3.2.4_postcss@8.4.19: + /tailwindcss/3.2.4_postcss@8.4.20: resolution: {integrity: sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==} engines: {node: '>=12.13.0'} hasBin: true @@ -1903,11 +1922,11 @@ packages: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.0.0 - postcss: 8.4.19 - postcss-import: 14.1.0_postcss@8.4.19 - postcss-js: 4.0.0_postcss@8.4.19 - postcss-load-config: 3.1.4_postcss@8.4.19 - postcss-nested: 6.0.0_postcss@8.4.19 + postcss: 8.4.20 + postcss-import: 14.1.0_postcss@8.4.20 + postcss-js: 4.0.0_postcss@8.4.20 + postcss-load-config: 3.1.4_postcss@8.4.20 + postcss-nested: 6.0.0_postcss@8.4.20 postcss-selector-parser: 6.0.11 postcss-value-parser: 4.2.0 quick-lru: 5.1.1 @@ -1937,8 +1956,8 @@ packages: strip-bom: 3.0.0 dev: true - /typescript/4.9.3: - resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} + /typescript/4.9.4: + resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==} engines: {node: '>=4.2.0'} hasBin: true dev: true @@ -1967,8 +1986,8 @@ packages: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true - /vite/3.2.4_@types+node@18.11.9: - resolution: {integrity: sha512-Z2X6SRAffOUYTa+sLy3NQ7nlHFU100xwanq1WDwqaiFiCe+25zdxP1TfCS5ojPV2oDDcXudHIoPnI1Z/66B7Yw==} + /vite/3.2.5_@types+node@18.11.16: + resolution: {integrity: sha512-4mVEpXpSOgrssFZAOmGIr85wPHKvaDAcXqxVxVRZhljkJOMZi1ibLibzjLHzJvcok8BMguLc7g1W6W/GqZbLdQ==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true peerDependencies: @@ -1992,9 +2011,9 @@ packages: terser: optional: true dependencies: - '@types/node': 18.11.9 - esbuild: 0.15.15 - postcss: 8.4.19 + '@types/node': 18.11.16 + esbuild: 0.15.18 + postcss: 8.4.20 resolve: 1.22.1 rollup: 2.79.1 optionalDependencies: diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 033f184..94ca7c4 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -10,20 +10,9 @@ mod rpc; use crate::core::AmbientLightMode; use crate::core::CoreManager; use paris::*; -use picker::led_color::LedColor; use picker::manager::Picker; use std::vec; -#[tauri::command] -async fn refresh_displays() { - match Picker::global().refresh_displays().await { - Ok(_) => {} - Err(error) => { - error!("{}", error) - } - } -} - #[tauri::command] async fn take_snapshot() -> Vec { let manager = Picker::global(); @@ -45,17 +34,10 @@ async fn take_snapshot() -> Vec { } #[tauri::command] -async fn get_led_strip_colors() -> Result, String> { - let colors = Picker::global().get_led_strip_colors().await; - match colors { - Ok(colors) => { - rpc::manager::Manager::global() - .publish_led_colors(&colors.to_vec()) - .await; - Ok(colors) - } - Err(error) => Err(format!("{}", error)), - } +fn get_picker_config() -> picker::config::Configuration { + let configuration = picker::config::Manager::global().get_config(); + info!("configuration: {:?}", configuration); + configuration } #[tauri::command] @@ -71,9 +53,8 @@ async fn main() { tauri::Builder::default() .invoke_handler(tauri::generate_handler![ take_snapshot, - refresh_displays, - get_led_strip_colors, play_mode, + get_picker_config, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/picker/config/display_config.rs b/src-tauri/src/picker/config/display_config.rs index 09586e8..cd2c9eb 100644 --- a/src-tauri/src/picker/config/display_config.rs +++ b/src-tauri/src/picker/config/display_config.rs @@ -1,13 +1,13 @@ use serde::{Deserialize, Serialize}; -#[derive(Clone, Copy, Serialize, Deserialize)] +#[derive(Clone, Copy, Serialize, Deserialize, Debug)] pub struct LedStripConfig { pub index: usize, pub global_start_position: usize, pub global_end_position: usize, } -#[derive(Clone, Copy, Serialize, Deserialize)] +#[derive(Clone, Copy, Serialize, Deserialize, Debug)] pub struct DisplayConfig { pub index_of_display: usize, pub display_width: usize, diff --git a/src-tauri/src/picker/config/manger.rs b/src-tauri/src/picker/config/manger.rs index 25c090d..d21b704 100644 --- a/src-tauri/src/picker/config/manger.rs +++ b/src-tauri/src/picker/config/manger.rs @@ -11,10 +11,10 @@ use tauri::api::path::config_dir; use super::DisplayConfig; -#[derive(Serialize, Deserialize, Clone)] +#[derive(Serialize, Deserialize, Clone, Debug)] pub struct Configuration { - config_version: u8, - display_configs: Vec, + pub config_version: u8, + pub display_configs: Vec, } impl Configuration { @@ -77,6 +77,10 @@ impl Manager { .map_err(|error| anyhow::anyhow!("can not write config file. {}", error))?; Ok(()) } + + pub fn get_config(&self) -> Configuration { + self.config.clone() + } } #[cfg(test)] @@ -114,7 +118,8 @@ mod tests { }) .to_string() .as_bytes(), - ).unwrap(); + ) + .unwrap(); let _manager = crate::picker::config::manger::Manager::read_config_from_disk(config_file_path.clone()) .unwrap(); diff --git a/src-tauri/src/picker/manager.rs b/src-tauri/src/picker/manager.rs index 9157103..1300807 100644 --- a/src-tauri/src/picker/manager.rs +++ b/src-tauri/src/picker/manager.rs @@ -2,15 +2,12 @@ use futures::{stream::FuturesUnordered, StreamExt}; use once_cell::sync::OnceCell; use paris::info; use scrap::Display; -use std::sync::Arc; +use std::{sync::Arc, borrow::Borrow}; use tokio::{sync::Mutex, task}; -use crate::picker::{config::LedStripConfig, screen::Screen}; +use crate::picker::{config, screen::Screen}; -use super::{ - config::DisplayConfig, display_picker::DisplayPicker, led_color::LedColor, - screenshot::Screenshot, -}; +use super::{config::DisplayConfig, display_picker::DisplayPicker, screenshot::Screenshot}; pub struct Picker { pub screens: Arc>>, @@ -25,64 +22,14 @@ impl Picker { SCREEN_COLOR_PICKER.get_or_init(|| Picker { screens: Arc::new(Mutex::new(vec![])), screenshots: Arc::new(Mutex::new(vec![])), - display_configs: Arc::new(Mutex::new(vec![ - DisplayConfig { - index_of_display: 1, - display_width: 1920, - display_height: 1200, - top_led_strip: LedStripConfig { - index: 1, - global_start_position: 59, - global_end_position: 32, - }, - bottom_led_strip: LedStripConfig { - index: 0, - global_start_position: 0, - global_end_position: 0, - }, - left_led_strip: LedStripConfig { - index: 0, - global_start_position: 0, - global_end_position: 0, - }, - right_led_strip: LedStripConfig { - index: 0, - global_start_position: 0, - global_end_position: 0, - }, - }, - DisplayConfig { - index_of_display: 0, - display_width: 3008, - display_height: 1692, - top_led_strip: LedStripConfig { - index: 0, - global_start_position: 31, - global_end_position: 0, - }, - bottom_led_strip: LedStripConfig { - index: 0, - global_start_position: 0, - global_end_position: 0, - }, - left_led_strip: LedStripConfig { - index: 0, - global_start_position: 0, - global_end_position: 0, - }, - right_led_strip: LedStripConfig { - index: 0, - global_start_position: 0, - global_end_position: 0, - }, - }, - ])), + display_configs: Arc::new(Mutex::new( + config::Manager::global().get_config().display_configs, + )), }) } pub async fn list_displays(&self) -> anyhow::Result> { let mut configs = self.display_configs.lock().await; - let screenshots = self.screenshots.lock().await; let displays = Display::all() .map_err(|error| anyhow::anyhow!("Can not get all of displays. {}", error))?; @@ -97,12 +44,9 @@ impl Picker { configs.push(config); } - for (index, display) in displays.iter().enumerate() { - let height = display.height(); - let width = display.width(); - let config = configs[index]; + for config in configs.iter() { futs.push(async move { - let join = task::spawn(Self::preview_display_by_config(config)); + let join = task::spawn(Self::preview_display_by_config(config.clone())); join.await? }); } @@ -128,55 +72,4 @@ impl Picker { anyhow::Ok(screenshot.to_webp_base64().await) } - - pub async fn refresh_displays(&self) -> anyhow::Result<()> { - // let displays = Display::all() - // .map_err(|error| anyhow::anyhow!("Can not get all of displays. {}", error))?; - // let mut screens = self.screens.lock().await; - // let mut screenshots = self.screenshots.lock().await; - // screens.clear(); - // info!("number of displays: {}", displays.len()); - // for display in displays { - // let height = display.height(); - // let width = display.width(); - // match Capturer::new(display) { - // Ok(capturer) => screens.push(Screen::new(capturer, width, height)), - // Err(error) => screens.push(Screen::new_failed( - // anyhow::anyhow!("{}", error), - // width, - // height, - // )), - // }; - // screenshots.push(Screenshot::new(width, height)); - // } - - // screens.reverse(); - // screenshots.reverse(); - - Ok(()) - } - - pub async fn take_screenshots_for_all(&self) -> anyhow::Result> { - let mut screens = self.screens.lock().await; - let screenshots = self.screenshots.lock().await; - for (index, screen) in screens.iter_mut().enumerate() { - let bitmap = screen.take().map_err(|error| { - anyhow::anyhow!("take screenshot for display failed. {}", error) - })?; - } - Ok(screenshots.to_vec()) - } - - pub async fn get_led_strip_colors(&self) -> anyhow::Result> { - let screenshots = self.screenshots.lock().await; - let mut colors = Vec::new(); - for screenshot in screenshots.iter() { - let result = screenshot - .get_top_colors() - .await - .map_err(|error| anyhow::anyhow!("get top colors failed. {}", error))?; - colors.extend_from_slice(&result); - } - Ok(colors) - } } diff --git a/src/App.tsx b/src/App.tsx index 4c6ecde..777144e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,8 +1,9 @@ -import { useCallback, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import reactLogo from './assets/react.svg'; import { invoke } from '@tauri-apps/api/tauri'; import './App.css'; import clsx from 'clsx'; +import { Configurator } from './configurator/configurator'; type Mode = 'Flowing' | 'Follow' | null; @@ -17,10 +18,6 @@ function App() { setScreenshots(base64TextList.map((text) => `data:image/webp;base64,${text}`)); } - const refreshDisplays = useCallback(async () => { - await invoke('refresh_displays'); - }, []); - const getLedStripColors = useCallback(async () => { setLedStripColors(await invoke('get_led_strip_colors')); }, []); @@ -60,7 +57,7 @@ function App() { @@ -99,9 +96,7 @@ function App() {
- Vite logo - Tauri logo - React logo +
); diff --git a/src/configurator/components/display-with-led-strips.tsx b/src/configurator/components/display-with-led-strips.tsx new file mode 100644 index 0000000..18d9c05 --- /dev/null +++ b/src/configurator/components/display-with-led-strips.tsx @@ -0,0 +1,25 @@ +import { HTMLAttributes } from 'react'; +import { FC } from 'react'; +import { DisplayConfig } from '../models/display-config'; +import { LedStrip } from './led-strip'; + +export interface DisplayWithLedStripsProps extends HTMLAttributes { + config: DisplayConfig; + screenshot: string; +} + +export const DisplayWithLedStrips: FC = ({ + config, + screenshot, + ...htmlAttrs +}) => { + return ( +
+ + + + + +
+ ); +}; diff --git a/src/configurator/components/led-strip.tsx b/src/configurator/components/led-strip.tsx new file mode 100644 index 0000000..3293e29 --- /dev/null +++ b/src/configurator/components/led-strip.tsx @@ -0,0 +1,11 @@ +import { HTMLAttributes } from 'react'; +import { FC } from 'react'; +import { LedStripConfig } from '../models/led-strip-config'; + +export interface LedStripProps extends HTMLAttributes { + config: LedStripConfig; +} + +export const LedStrip: FC = ({ config, ...htmlAttrs }) => { + return
...
; +}; diff --git a/src/configurator/configurator.tsx b/src/configurator/configurator.tsx new file mode 100644 index 0000000..7f8c4a2 --- /dev/null +++ b/src/configurator/configurator.tsx @@ -0,0 +1,46 @@ +import { invoke } from '@tauri-apps/api'; +import { FC, useMemo } from 'react'; +import { useAsync } from 'react-async-hook'; +import { DisplayWithLedStrips } from './components/display-with-led-strips'; +import { PickerConfiguration } from './models/picker-configuration'; + +const getPickerConfig = () => invoke('get_picker_config'); +const getScreenshotOfDisplays = () => + invoke('take_snapshot').then((items) => + items?.map((it) => `data:image/webp;base64,${it}`), + ); + +export const Configurator: FC = () => { + const { loading: pendingPickerConfig, result: pickerConfig } = useAsync( + getPickerConfig, + [], + ); + + const { loading: pendingScreenshotOfDisplays, result: screenshotOfDisplays } = useAsync( + getScreenshotOfDisplays, + [], + ); + + const displays = useMemo(() => { + if (pickerConfig && screenshotOfDisplays) { + return screenshotOfDisplays.map((screenshot, index) => ( + + )); + } + }, [pickerConfig, screenshotOfDisplays]); + + if (pendingPickerConfig || pendingScreenshotOfDisplays) { + return ( +
+ 等待 {JSON.stringify({ pendingPickerConfig, pendingScreenshotOfDisplays })} + {displays} +
+ ); + } + + return
{displays}
; +}; diff --git a/src/configurator/models/display-config.ts b/src/configurator/models/display-config.ts new file mode 100644 index 0000000..f98a4fb --- /dev/null +++ b/src/configurator/models/display-config.ts @@ -0,0 +1,11 @@ +import { LedStripConfig } from './led-strip-config'; + +export class DisplayConfig { + index_of_display!: number; + display_width!: number; + display_height!: number; + top_led_strip!: LedStripConfig; + bottom_led_strip!: LedStripConfig; + left_led_strip!: LedStripConfig; + right_led_strip!: LedStripConfig; +} diff --git a/src/configurator/models/led-strip-config.ts b/src/configurator/models/led-strip-config.ts new file mode 100644 index 0000000..5b2ff8f --- /dev/null +++ b/src/configurator/models/led-strip-config.ts @@ -0,0 +1,5 @@ +export class LedStripConfig { + index!: number; + global_start_position!: number; + global_end_position!: number; +} diff --git a/src/configurator/models/picker-configuration.ts b/src/configurator/models/picker-configuration.ts new file mode 100644 index 0000000..4b989d0 --- /dev/null +++ b/src/configurator/models/picker-configuration.ts @@ -0,0 +1,6 @@ +import { DisplayConfig } from './display-config'; + +export class PickerConfiguration { + config_version!: number; + display_configs!: DisplayConfig[]; +} From 5042ff8bfb36564c124c992fba76bb02cdbe989d Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Sat, 17 Dec 2022 20:34:49 +0800 Subject: [PATCH 03/19] =?UTF-8?q?build:=20=E6=94=AF=E6=8C=81=20twin?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- babel-plugin-macros.config.cjs | 5 + package.json | 7 + pnpm-lock.yaml | 334 ++++++++++++++++++++++++++++++--- postcss.config.cjs | 6 - src/styles/global-styles.tsx | 19 ++ tsconfig.json | 8 +- types/twin.d.ts | 18 ++ vite.config.ts | 30 ++- 8 files changed, 392 insertions(+), 35 deletions(-) create mode 100644 babel-plugin-macros.config.cjs delete mode 100644 postcss.config.cjs create mode 100644 src/styles/global-styles.tsx create mode 100644 types/twin.d.ts diff --git a/babel-plugin-macros.config.cjs b/babel-plugin-macros.config.cjs new file mode 100644 index 0000000..6df67fd --- /dev/null +++ b/babel-plugin-macros.config.cjs @@ -0,0 +1,5 @@ +module.exports = { + twin: { + preset: 'emotion', + }, +}; diff --git a/package.json b/package.json index c3cefaa..4a7ea86 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,8 @@ "tauri": "tauri" }, "dependencies": { + "@emotion/react": "^11.10.5", + "@emotion/styled": "^11.10.5", "@tauri-apps/api": "^1.1.0", "clsx": "^1.2.1", "react": "^18.2.0", @@ -17,12 +19,16 @@ "react-dom": "^18.2.0" }, "devDependencies": { + "@babel/plugin-transform-react-jsx": "^7.19.0", + "@emotion/babel-plugin-jsx-pragmatic": "^0.2.0", + "@emotion/serialize": "^1.1.1", "@tauri-apps/cli": "^1.1.0", "@types/node": "^18.7.10", "@types/react": "^18.0.15", "@types/react-dom": "^18.0.6", "@vitejs/plugin-react": "^2.0.0", "autoprefixer": "^10.4.13", + "babel-plugin-macros": "^3.1.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-jsx-a11y": "^6.6.1", @@ -31,6 +37,7 @@ "postcss": "^8.4.19", "prettier": "^2.7.1", "tailwindcss": "^3.2.4", + "twin.macro": "^3.1.0", "typescript": "^4.6.4", "vite": "^3.0.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d657ef8..0f6cee2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,6 +1,11 @@ lockfileVersion: 5.4 specifiers: + '@babel/plugin-transform-react-jsx': ^7.19.0 + '@emotion/babel-plugin-jsx-pragmatic': ^0.2.0 + '@emotion/react': ^11.10.5 + '@emotion/serialize': ^1.1.1 + '@emotion/styled': ^11.10.5 '@tauri-apps/api': ^1.1.0 '@tauri-apps/cli': ^1.1.0 '@types/node': ^18.7.10 @@ -8,6 +13,7 @@ specifiers: '@types/react-dom': ^18.0.6 '@vitejs/plugin-react': ^2.0.0 autoprefixer: ^10.4.13 + babel-plugin-macros: ^3.1.0 clsx: ^1.2.1 eslint-config-prettier: ^8.5.0 eslint-plugin-import: ^2.26.0 @@ -20,10 +26,13 @@ specifiers: react-async-hook: ^4.0.0 react-dom: ^18.2.0 tailwindcss: ^3.2.4 + twin.macro: ^3.1.0 typescript: ^4.6.4 vite: ^3.0.2 dependencies: + '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 + '@emotion/styled': 11.10.5_qvatmowesywn4ye42qoh247szu '@tauri-apps/api': 1.2.0 clsx: 1.2.1 react: 18.2.0 @@ -31,12 +40,16 @@ dependencies: react-dom: 18.2.0_react@18.2.0 devDependencies: + '@babel/plugin-transform-react-jsx': 7.19.0 + '@emotion/babel-plugin-jsx-pragmatic': 0.2.0 + '@emotion/serialize': 1.1.1 '@tauri-apps/cli': 1.2.2 '@types/node': 18.11.16 '@types/react': 18.0.26 '@types/react-dom': 18.0.9 '@vitejs/plugin-react': 2.2.0_vite@3.2.5 autoprefixer: 10.4.13_postcss@8.4.20 + babel-plugin-macros: 3.1.0 eslint-config-prettier: 8.5.0 eslint-plugin-import: 2.26.0 eslint-plugin-jsx-a11y: 6.6.1 @@ -45,6 +58,7 @@ devDependencies: postcss: 8.4.20 prettier: 2.8.1 tailwindcss: 3.2.4_postcss@8.4.20 + twin.macro: 3.1.0_tailwindcss@3.2.4 typescript: 4.9.4 vite: 3.2.5_@types+node@18.11.16 @@ -63,7 +77,6 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/highlight': 7.18.6 - dev: true /@babel/compat-data/7.20.5: resolution: {integrity: sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==} @@ -147,7 +160,6 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.20.5 - dev: true /@babel/helper-module-transforms/7.20.2: resolution: {integrity: sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==} @@ -168,7 +180,6 @@ packages: /@babel/helper-plugin-utils/7.20.2: resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-simple-access/7.20.2: resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} @@ -187,12 +198,10 @@ packages: /@babel/helper-string-parser/7.19.4: resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-validator-identifier/7.19.1: resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-validator-option/7.18.6: resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} @@ -217,7 +226,6 @@ packages: '@babel/helper-validator-identifier': 7.19.1 chalk: 2.4.2 js-tokens: 4.0.0 - dev: true /@babel/parser/7.20.5: resolution: {integrity: sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==} @@ -227,6 +235,14 @@ packages: '@babel/types': 7.20.5 dev: true + /@babel/plugin-syntax-jsx/7.18.6: + resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/helper-plugin-utils': 7.20.2 + /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.20.5: resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} engines: {node: '>=6.9.0'} @@ -267,6 +283,19 @@ packages: '@babel/helper-plugin-utils': 7.20.2 dev: true + /@babel/plugin-transform-react-jsx/7.19.0: + resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-jsx': 7.18.6 + '@babel/types': 7.20.5 + dev: true + /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.20.5: resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==} engines: {node: '>=6.9.0'} @@ -294,7 +323,6 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.13.11 - dev: true /@babel/template/7.18.10: resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} @@ -330,8 +358,135 @@ packages: '@babel/helper-string-parser': 7.19.4 '@babel/helper-validator-identifier': 7.19.1 to-fast-properties: 2.0.0 + + /@emotion/babel-plugin-jsx-pragmatic/0.2.0: + resolution: {integrity: sha512-VPfKAtb/bVyu5y+HzCPj9bb2nHnj9yX5mMAU7N0pIDcrFZo8aqDyHXLYF8BD7tY4pNL09N87dygVLKIkQvshJw==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/plugin-syntax-jsx': 7.18.6 dev: true + /@emotion/babel-plugin/11.10.5: + resolution: {integrity: sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/helper-module-imports': 7.18.6 + '@babel/plugin-syntax-jsx': 7.18.6 + '@babel/runtime': 7.20.6 + '@emotion/hash': 0.9.0 + '@emotion/memoize': 0.8.0 + '@emotion/serialize': 1.1.1 + babel-plugin-macros: 3.1.0 + convert-source-map: 1.9.0 + escape-string-regexp: 4.0.0 + find-root: 1.1.0 + source-map: 0.5.7 + stylis: 4.1.3 + dev: false + + /@emotion/cache/11.10.5: + resolution: {integrity: sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==} + dependencies: + '@emotion/memoize': 0.8.0 + '@emotion/sheet': 1.2.1 + '@emotion/utils': 1.2.0 + '@emotion/weak-memoize': 0.3.0 + stylis: 4.1.3 + dev: false + + /@emotion/hash/0.9.0: + resolution: {integrity: sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==} + + /@emotion/is-prop-valid/1.2.0: + resolution: {integrity: sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==} + dependencies: + '@emotion/memoize': 0.8.0 + dev: false + + /@emotion/memoize/0.8.0: + resolution: {integrity: sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==} + + /@emotion/react/11.10.5_kzbn2opkn2327fwg5yzwzya5o4: + resolution: {integrity: sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A==} + peerDependencies: + '@babel/core': ^7.0.0 + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@babel/core': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.20.6 + '@emotion/babel-plugin': 11.10.5 + '@emotion/cache': 11.10.5 + '@emotion/serialize': 1.1.1 + '@emotion/use-insertion-effect-with-fallbacks': 1.0.0_react@18.2.0 + '@emotion/utils': 1.2.0 + '@emotion/weak-memoize': 0.3.0 + '@types/react': 18.0.26 + hoist-non-react-statics: 3.3.2 + react: 18.2.0 + dev: false + + /@emotion/serialize/1.1.1: + resolution: {integrity: sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==} + dependencies: + '@emotion/hash': 0.9.0 + '@emotion/memoize': 0.8.0 + '@emotion/unitless': 0.8.0 + '@emotion/utils': 1.2.0 + csstype: 3.1.1 + + /@emotion/sheet/1.2.1: + resolution: {integrity: sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==} + dev: false + + /@emotion/styled/11.10.5_qvatmowesywn4ye42qoh247szu: + resolution: {integrity: sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw==} + peerDependencies: + '@babel/core': ^7.0.0 + '@emotion/react': ^11.0.0-rc.0 + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@babel/core': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.20.6 + '@emotion/babel-plugin': 11.10.5 + '@emotion/is-prop-valid': 1.2.0 + '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 + '@emotion/serialize': 1.1.1 + '@emotion/use-insertion-effect-with-fallbacks': 1.0.0_react@18.2.0 + '@emotion/utils': 1.2.0 + '@types/react': 18.0.26 + react: 18.2.0 + dev: false + + /@emotion/unitless/0.8.0: + resolution: {integrity: sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==} + + /@emotion/use-insertion-effect-with-fallbacks/1.0.0_react@18.2.0: + resolution: {integrity: sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==} + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 18.2.0 + dev: false + + /@emotion/utils/1.2.0: + resolution: {integrity: sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==} + + /@emotion/weak-memoize/0.3.0: + resolution: {integrity: sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==} + dev: false + /@esbuild/android-arm/0.15.18: resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==} engines: {node: '>=12'} @@ -519,9 +674,11 @@ packages: resolution: {integrity: sha512-6T7P5bDkRhqRxrQtwj7vru+bWTpelgtcETAZEUSdq0YISKz8WKdoBukQLYQQ6DFHvU9JRsbFq0JH5C51X2ZdnA==} dev: true + /@types/parse-json/4.0.0: + resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} + /@types/prop-types/15.7.5: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} - dev: true /@types/react-dom/18.0.9: resolution: {integrity: sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==} @@ -535,11 +692,9 @@ packages: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.2 csstype: 3.1.1 - dev: true /@types/scheduler/0.16.2: resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} - dev: true /@vitejs/plugin-react/2.2.0_vite@3.2.5: resolution: {integrity: sha512-FFpefhvExd1toVRlokZgxgy2JtnBOdp4ZDsq7ldCWaqGSGn9UhWMAVm/1lxPL14JfNS5yGz+s9yFrQY6shoStA==} @@ -583,6 +738,12 @@ packages: engines: {node: '>=4'} dependencies: color-convert: 1.9.3 + + /ansi-styles/4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 dev: true /anymatch/3.1.3: @@ -655,6 +816,14 @@ packages: resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==} dev: true + /babel-plugin-macros/3.1.0: + resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} + engines: {node: '>=10', npm: '>=6'} + dependencies: + '@babel/runtime': 7.20.6 + cosmiconfig: 7.1.0 + resolve: 1.22.1 + /balanced-match/1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true @@ -696,6 +865,10 @@ packages: get-intrinsic: 1.1.3 dev: true + /callsites/3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + /camelcase-css/2.0.1: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} @@ -712,6 +885,13 @@ packages: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 supports-color: 5.5.0 + + /chalk/4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 dev: true /chokidar/3.5.3: @@ -738,11 +918,16 @@ packages: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: color-name: 1.1.3 + + /color-convert/2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 dev: true /color-name/1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - dev: true /color-name/1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} @@ -754,13 +939,22 @@ packages: /convert-source-map/1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: true /core-js-pure/3.26.1: resolution: {integrity: sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==} requiresBuild: true dev: true + /cosmiconfig/7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + dependencies: + '@types/parse-json': 4.0.0 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + /cssesc/3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -769,7 +963,6 @@ packages: /csstype/3.1.1: resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} - dev: true /damerau-levenshtein/1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} @@ -854,6 +1047,11 @@ packages: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} dev: true + /error-ex/1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + /es-abstract/1.20.5: resolution: {integrity: sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ==} engines: {node: '>= 0.4'} @@ -1118,7 +1316,11 @@ packages: /escape-string-regexp/1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} - dev: true + + /escape-string-regexp/4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: false /eslint-config-prettier/8.5.0: resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} @@ -1268,6 +1470,10 @@ packages: to-regex-range: 5.0.1 dev: true + /find-root/1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + dev: false + /fraction.js/4.2.0: resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} dev: true @@ -1282,7 +1488,6 @@ packages: /function-bind/1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - dev: true /function.prototype.name/1.1.5: resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} @@ -1351,6 +1556,10 @@ packages: /has-flag/3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} + + /has-flag/4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} dev: true /has-property-descriptors/1.0.0: @@ -1376,7 +1585,19 @@ packages: engines: {node: '>= 0.4.0'} dependencies: function-bind: 1.1.1 - dev: true + + /hoist-non-react-statics/3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + dependencies: + react-is: 16.13.1 + dev: false + + /import-fresh/3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 /internal-slot/1.0.4: resolution: {integrity: sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==} @@ -1387,6 +1608,9 @@ packages: side-channel: 1.0.4 dev: true + /is-arrayish/0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + /is-bigint/1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} dependencies: @@ -1417,7 +1641,6 @@ packages: resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} dependencies: has: 1.0.3 - dev: true /is-date-object/1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} @@ -1498,6 +1721,9 @@ packages: hasBin: true dev: true + /json-parse-even-better-errors/2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + /json5/1.0.1: resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} hasBin: true @@ -1534,6 +1760,17 @@ packages: engines: {node: '>=10'} dev: true + /lines-and-columns/1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + /lodash.get/4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + dev: true + + /lodash.merge/4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + /loose-envify/1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -1636,9 +1873,27 @@ packages: es-abstract: 1.20.5 dev: true + /parent-module/1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + + /parse-json/5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.18.6 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + /path-parse/1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true + + /path-type/4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} /picocolors/1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} @@ -1765,6 +2020,10 @@ packages: scheduler: 0.23.0 dev: false + /react-is/16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: false + /react-refresh/0.14.0: resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} engines: {node: '>=0.10.0'} @@ -1792,7 +2051,6 @@ packages: /regenerator-runtime/0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} - dev: true /regexp.prototype.flags/1.4.3: resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} @@ -1803,6 +2061,10 @@ packages: functions-have-names: 1.2.3 dev: true + /resolve-from/4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + /resolve/1.22.1: resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} hasBin: true @@ -1810,7 +2072,6 @@ packages: is-core-module: 2.11.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - dev: true /reusify/1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} @@ -1863,6 +2124,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /source-map/0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + dev: false + /sourcemap-codec/1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} deprecated: Please use @jridgewell/sourcemap-codec instead @@ -1889,17 +2155,26 @@ packages: engines: {node: '>=4'} dev: true + /stylis/4.1.3: + resolution: {integrity: sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==} + dev: false + /supports-color/5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} dependencies: has-flag: 3.0.0 + + /supports-color/7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 dev: true /supports-preserve-symlinks-flag/1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - dev: true /tailwindcss/3.2.4_postcss@8.4.20: resolution: {integrity: sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==} @@ -1938,7 +2213,6 @@ packages: /to-fast-properties/2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} - dev: true /to-regex-range/5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} @@ -1956,6 +2230,21 @@ packages: strip-bom: 3.0.0 dev: true + /twin.macro/3.1.0_tailwindcss@3.2.4: + resolution: {integrity: sha512-7DSR/xdvSaAqhTM4JptBgI+1IzXQR5v+2hp0CDMmHMjlm44IBEewU8MeqPlXmFgQI06zpLyJMaKRbJu96drAJw==} + engines: {node: '>=16.14.0'} + peerDependencies: + tailwindcss: ^3.2.4 + dependencies: + '@babel/template': 7.18.10 + babel-plugin-macros: 3.1.0 + chalk: 4.1.2 + lodash.get: 4.4.2 + lodash.merge: 4.6.2 + postcss-selector-parser: 6.0.11 + tailwindcss: 3.2.4_postcss@8.4.20 + dev: true + /typescript/4.9.4: resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==} engines: {node: '>=4.2.0'} @@ -2038,4 +2327,3 @@ packages: /yaml/1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - dev: true diff --git a/postcss.config.cjs b/postcss.config.cjs deleted file mode 100644 index 33ad091..0000000 --- a/postcss.config.cjs +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -} diff --git a/src/styles/global-styles.tsx b/src/styles/global-styles.tsx new file mode 100644 index 0000000..1479d4b --- /dev/null +++ b/src/styles/global-styles.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Global, css } from '@emotion/react'; +import tw, { theme, GlobalStyles as BaseStyles } from 'twin.macro'; + +const customStyles = css({ + body: { + WebkitTapHighlightColor: theme`colors.purple.500`, + ...tw`antialiased dark:bg-dark-800 bg-dark-100`, + }, +}); + +const GlobalStyles = () => ( + <> + + + +); + +export default GlobalStyles; diff --git a/tsconfig.json b/tsconfig.json index 3d0a51a..0a0400a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,8 +14,12 @@ "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, - "jsx": "react-jsx" + "jsx": "react-jsx", + "jsxImportSource": "@emotion/react" }, - "include": ["src"], + "include": [ + "src", + "types" + ], "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/types/twin.d.ts b/types/twin.d.ts new file mode 100644 index 0000000..b0426a1 --- /dev/null +++ b/types/twin.d.ts @@ -0,0 +1,18 @@ +import 'twin.macro'; +import { css as cssImport } from '@emotion/react'; +import styledImport from '@emotion/styled'; +import { CSSInterpolation } from '@emotion/serialize'; + +declare module 'twin.macro' { + // The styled and css imports + const styled: typeof styledImport; + const css: typeof cssImport; +} + +declare module 'react' { + // The tw and css prop + interface DOMAttributes { + tw?: string; + css?: CSSInterpolation; + } +} diff --git a/vite.config.ts b/vite.config.ts index db75d21..d016957 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -3,7 +3,29 @@ import react from "@vitejs/plugin-react"; // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react()], + optimizeDeps: { + esbuildOptions: { + target: 'es2020', + }, + }, + plugins: [ + react({ + babel: { + plugins: [ + 'babel-plugin-macros', + [ + '@emotion/babel-plugin-jsx-pragmatic', + { + export: 'jsx', + import: '__cssprop', + module: '@emotion/react', + }, + ], + ['@babel/plugin-transform-react-jsx', { pragma: '__cssprop' }, 'twin.macro'], + ], + }, + }), + ], // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build` // prevent vite from obscuring rust errors @@ -15,12 +37,12 @@ export default defineConfig({ }, // to make use of `TAURI_DEBUG` and other env variables // https://tauri.studio/v1/api/config#buildconfig.beforedevcommand - envPrefix: ["VITE_", "TAURI_"], + envPrefix: ['VITE_', 'TAURI_'], build: { // Tauri supports es2021 - target: ["es2021", "chrome100", "safari13"], + target: ['es2021', 'chrome100', 'safari13'], // don't minify for debug builds - minify: !process.env.TAURI_DEBUG ? "esbuild" : false, + minify: !process.env.TAURI_DEBUG ? 'esbuild' : false, // produce sourcemaps for debug builds sourcemap: !!process.env.TAURI_DEBUG, }, From 4ad78ae5cc9b17a0b3646749305b8e07b091a018 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Sun, 18 Dec 2022 18:10:21 +0800 Subject: [PATCH 04/19] =?UTF-8?q?chore:=20=E9=87=8D=E6=9E=84=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6=E7=BB=93=E6=9E=84=E5=92=8C=E7=81=AF?= =?UTF-8?q?=E6=9D=A1=E8=89=B2=E5=BD=A9=E8=8E=B7=E5=8F=96=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/core/core.rs | 58 ++-- src-tauri/src/main.rs | 6 +- src-tauri/src/picker/config/display_config.rs | 32 +- src-tauri/src/picker/led_color.rs | 2 +- src-tauri/src/picker/manager.rs | 14 +- src-tauri/src/picker/screenshot.rs | 299 +++++++++++++----- 6 files changed, 278 insertions(+), 133 deletions(-) diff --git a/src-tauri/src/core/core.rs b/src-tauri/src/core/core.rs index b89074d..3495b9f 100644 --- a/src-tauri/src/core/core.rs +++ b/src-tauri/src/core/core.rs @@ -118,38 +118,40 @@ impl CoreManager { let mut global_colors = HashMap::new(); while let Some(screenshot) = rx.recv().await { let start_at = Instant::now(); - match screenshot.get_top_colors().await { - Ok(colors) => { - let start = screenshot.get_top_of_led_start_at().min(screenshot.get_top_of_led_end_at()); + let colors = screenshot.get_top_colors(); + let start = screenshot + .get_top_of_led_start_at() + .min(screenshot.get_top_of_led_end_at()); - let colors_len = colors.len(); - for (index, color) in colors.into_iter().enumerate() { - global_colors.insert(index + start, color); + let colors_len = colors.len(); + for (index, color) in colors.into_iter().enumerate() { + global_colors.insert(index + start, color); + } + + info!( + "led count: {}, spend: {:?}", + global_colors.len(), + start_at.elapsed() + ); + + if global_colors.len() == 60 { + let mut colors = vec![]; + for index in 0..global_colors.len() { + colors.push(*global_colors.get(&index).unwrap()); + } + global_colors = HashMap::new(); + match rpc::manager::Manager::global() + .publish_led_colors(&colors) + .await + { + Ok(_) => { + info!("publish successful",); } - - info!("led count: {}, spend: {:?}", global_colors.len(), start_at.elapsed()); - - if global_colors.len() == 60 { - let mut colors = vec![]; - for index in 0..global_colors.len() { - colors.push(*global_colors.get(&index).unwrap()); - } - global_colors = HashMap::new(); - match rpc::manager::Manager::global() - .publish_led_colors(&colors) - .await - { - Ok(_) => { - info!("publish successful",); - } - Err(error) => { - warn!("publish led colors failed. {}", error); - } - } + Err(error) => { + warn!("publish led colors failed. {}", error); } } - Err(_) => {} - }; + } } }); diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 94ca7c4..35a81c6 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -2,6 +2,7 @@ all(not(debug_assertions), target_os = "windows"), windows_subsystem = "windows" )] +#![feature(bool_to_option)] mod core; mod picker; @@ -11,10 +12,11 @@ use crate::core::AmbientLightMode; use crate::core::CoreManager; use paris::*; use picker::manager::Picker; +use picker::screenshot::ScreenshotDto; use std::vec; #[tauri::command] -async fn take_snapshot() -> Vec { +async fn take_snapshot() -> Vec { let manager = Picker::global(); let start = time::Instant::now(); @@ -29,7 +31,7 @@ async fn take_snapshot() -> Vec { vec![] } }; - info!("截图花费 {} s", start.elapsed().as_seconds_f32()); + info!("截图耗时 {} s", start.elapsed().as_seconds_f32()); base64_bitmap_list } diff --git a/src-tauri/src/picker/config/display_config.rs b/src-tauri/src/picker/config/display_config.rs index cd2c9eb..ec1be7a 100644 --- a/src-tauri/src/picker/config/display_config.rs +++ b/src-tauri/src/picker/config/display_config.rs @@ -12,10 +12,10 @@ pub struct DisplayConfig { pub index_of_display: usize, pub display_width: usize, pub display_height: usize, - pub top_led_strip: LedStripConfig, - pub bottom_led_strip: LedStripConfig, - pub left_led_strip: LedStripConfig, - pub right_led_strip: LedStripConfig, + pub top_led_strip: Option, + pub bottom_led_strip: Option, + pub left_led_strip: Option, + pub right_led_strip: Option, } impl DisplayConfig { @@ -24,26 +24,10 @@ impl DisplayConfig { index_of_display, display_width, display_height, - top_led_strip: LedStripConfig { - index: 0, - global_start_position: 0, - global_end_position: 0, - }, - bottom_led_strip: LedStripConfig { - index: 0, - global_start_position: 0, - global_end_position: 0, - }, - left_led_strip: LedStripConfig { - index: 0, - global_start_position: 0, - global_end_position: 0, - }, - right_led_strip: LedStripConfig { - index: 0, - global_start_position: 0, - global_end_position: 0, - }, + top_led_strip: None, + bottom_led_strip: None, + left_led_strip: None, + right_led_strip: None, } } } diff --git a/src-tauri/src/picker/led_color.rs b/src-tauri/src/picker/led_color.rs index 073c841..98c371c 100644 --- a/src-tauri/src/picker/led_color.rs +++ b/src-tauri/src/picker/led_color.rs @@ -1,7 +1,7 @@ use color_space::{Hsv, Rgb}; use serde::Serialize; -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub struct LedColor { bits: [u8; 3], } diff --git a/src-tauri/src/picker/manager.rs b/src-tauri/src/picker/manager.rs index 1300807..5963f6d 100644 --- a/src-tauri/src/picker/manager.rs +++ b/src-tauri/src/picker/manager.rs @@ -2,12 +2,16 @@ use futures::{stream::FuturesUnordered, StreamExt}; use once_cell::sync::OnceCell; use paris::info; use scrap::Display; -use std::{sync::Arc, borrow::Borrow}; +use std::{borrow::Borrow, sync::Arc}; use tokio::{sync::Mutex, task}; use crate::picker::{config, screen::Screen}; -use super::{config::DisplayConfig, display_picker::DisplayPicker, screenshot::Screenshot}; +use super::{ + config::DisplayConfig, + display_picker::DisplayPicker, + screenshot::{Screenshot, ScreenshotDto}, +}; pub struct Picker { pub screens: Arc>>, @@ -28,7 +32,7 @@ impl Picker { }) } - pub async fn list_displays(&self) -> anyhow::Result> { + pub async fn list_displays(&self) -> anyhow::Result> { let mut configs = self.display_configs.lock().await; let displays = Display::all() @@ -64,12 +68,12 @@ impl Picker { Ok(bitmap_string_list) } - pub async fn preview_display_by_config(config: DisplayConfig) -> anyhow::Result { + pub async fn preview_display_by_config(config: DisplayConfig) -> anyhow::Result { let start = time::Instant::now(); let mut picker = DisplayPicker::from_config(config)?; let screenshot = picker.take_screenshot()?; info!("Take Screenshot Spend: {}", start.elapsed()); - anyhow::Ok(screenshot.to_webp_base64().await) + anyhow::Ok(screenshot.to_dto().await) } } diff --git a/src-tauri/src/picker/screenshot.rs b/src-tauri/src/picker/screenshot.rs index 31a713f..b054c58 100644 --- a/src-tauri/src/picker/screenshot.rs +++ b/src-tauri/src/picker/screenshot.rs @@ -1,101 +1,233 @@ -use std::ops::Range; +use std::iter; use color_space::{Hsv, Rgb}; use either::Either; +use serde::{Deserialize, Serialize}; use super::{ config::{DisplayConfig, LedStripConfig}, led_color::LedColor, }; -#[derive(Clone)] +type Point = (usize, usize); +type LedSamplePoints = Vec; + +#[derive(Clone, Serialize, Deserialize, Debug)] +struct ScreenSamplePoints { + pub top: Vec, + pub bottom: Vec, + pub left: Vec, + pub right: Vec, +} + +#[derive(Clone, Serialize, Deserialize, Debug)] pub struct Screenshot { bitmap: Vec, config: DisplayConfig, + sample_points: ScreenSamplePoints, } impl Screenshot { pub fn new(bitmap: Vec, config: DisplayConfig) -> Self { - Self { bitmap, config } - } - - pub async fn get_top_colors(&self) -> anyhow::Result> { - self.get_x_colors(XPosition::Top, self.config.top_led_strip) - .await - } - pub async fn get_bottom_colors(&self) -> anyhow::Result> { - self.get_x_colors(XPosition::Bottom, self.config.bottom_led_strip) - .await - } - - pub fn get_top_of_led_start_at(&self) -> usize { - self.config.top_led_strip.global_start_position - } - pub fn get_top_of_led_end_at(&self) -> usize { - self.config.top_led_strip.global_end_position - } - - async fn get_x_colors( - &self, - position: XPosition, - strip_config: LedStripConfig, - ) -> anyhow::Result> { - let bitmap = &self.bitmap; - let number_of_leds = strip_config - .global_start_position - .abs_diff(strip_config.global_end_position) - + 1; - if number_of_leds == 0 { - return Ok(vec![]); + Self { + bitmap, + config, + sample_points: Self::get_sample_points(config), } - let cell_size_x = self.config.display_width / number_of_leds; - let cell_size_y = self.config.display_height / 8; - let cell_size = cell_size_x * cell_size_y; - let y_range = match position { - XPosition::Top => 20..cell_size_y + 20, - XPosition::Bottom => { - self.config.display_height - 20 - cell_size_y..self.config.display_height - 20 + } + + fn get_sample_points(config: DisplayConfig) -> ScreenSamplePoints { + let top = match config.top_led_strip { + Some(led_strip_config) => Self::get_one_edge_sample_points( + config.display_height / 8, + config.display_width, + led_strip_config + .global_start_position + .abs_diff(led_strip_config.global_end_position), + 5, + ), + None => { + vec![] } - } - .step_by(5); - - let x_range = if strip_config.global_start_position < strip_config.global_end_position { - Either::Left(strip_config.global_start_position..=strip_config.global_end_position) - } else { - Either::Right( - (strip_config.global_end_position..=strip_config.global_start_position).rev(), - ) }; - let mut colors = Vec::new(); - let stride = bitmap.len() / self.config.display_height; + let bottom: Vec = match config.top_led_strip { + Some(led_strip_config) => { + let points = Self::get_one_edge_sample_points( + config.display_height / 9, + config.display_width, + led_strip_config + .global_start_position + .abs_diff(led_strip_config.global_end_position), + 5, + ); + points + .into_iter() + .map(|groups| -> Vec { + groups + .into_iter() + .map(|(x, y)| (x, config.display_height - y)) + .collect() + }) + .collect() + } + None => { + vec![] + } + }; - for pos in x_range { + let left: Vec = match config.top_led_strip { + Some(led_strip_config) => { + let points = Self::get_one_edge_sample_points( + config.display_width / 16, + config.display_height, + led_strip_config + .global_start_position + .abs_diff(led_strip_config.global_end_position), + 5, + ); + points + .into_iter() + .map(|groups| -> Vec { + groups.into_iter().map(|(x, y)| (y, x)).collect() + }) + .collect() + } + None => { + vec![] + } + }; + + let right: Vec = match config.top_led_strip { + Some(led_strip_config) => { + let points = Self::get_one_edge_sample_points( + config.display_width / 16, + config.display_height, + led_strip_config + .global_start_position + .abs_diff(led_strip_config.global_end_position), + 5, + ); + points + .into_iter() + .map(|groups| -> Vec { + groups + .into_iter() + .map(|(x, y)| (y, config.display_width - x)) + .collect() + }) + .collect() + } + None => { + vec![] + } + }; + + ScreenSamplePoints { + top, + bottom, + left, + right, + } + } + + fn get_one_edge_sample_points( + width: usize, + length: usize, + leds: usize, + single_axis_points: usize, + ) -> Vec { + let cell_size_x = length as f64 / single_axis_points as f64 / leds as f64; + let cell_size_y = width / single_axis_points; + + let point_start_y = cell_size_y / 2; + let point_start_x = cell_size_x / 2.0; + let point_y_list: Vec = (point_start_y..width).step_by(cell_size_y).collect(); + let point_x_list: Vec = iter::successors(Some(point_start_x), |i| { + let next = i + cell_size_x; + (next < (width as f64)).then_some(next) + }) + .map(|i| i as usize) + .collect(); + + let points: Vec = point_x_list + .into_iter() + .zip(point_y_list.into_iter()) + .collect(); + points + .chunks(single_axis_points * single_axis_points) + .into_iter() + .map(|points| Vec::from(points)) + .collect() + } + + pub fn get_colors(&self) -> DisplayColorsOfLedStrips { + let top = self + .get_one_edge_colors(&self.sample_points.top) + .into_iter() + .flat_map(|color| color.get_rgb()) + .collect(); + let bottom = self + .get_one_edge_colors(&self.sample_points.bottom) + .into_iter() + .flat_map(|color| color.get_rgb()) + .collect(); + let left = self + .get_one_edge_colors(&self.sample_points.left) + .into_iter() + .flat_map(|color| color.get_rgb()) + .collect(); + let right = self + .get_one_edge_colors(&self.sample_points.right) + .into_iter() + .flat_map(|color| color.get_rgb()) + .collect(); + DisplayColorsOfLedStrips { + top, + bottom, + left, + right, + } + } + + pub fn get_one_edge_colors( + &self, + sample_points_of_leds: &Vec, + ) -> Vec { + let mut colors = vec![]; + for led_points in sample_points_of_leds { let mut r = 0.0; let mut g = 0.0; let mut b = 0.0; - let mut count = 0; - for x in (pos * cell_size_x..(pos + 1) * cell_size_x).step_by(5) { - for y in y_range.to_owned() { - let i = stride * y + 4 * x; - r += bitmap[i + 2] as f64; - g += bitmap[i + 1] as f64; - b += bitmap[i] as f64; - count+=1; - } + let len = led_points.len() as f64; + for (x, y) in led_points { + let position = (x + y * self.config.display_width) * 4; + r += self.bitmap[position + 2] as f64; + g += self.bitmap[position + 1] as f64; + b += self.bitmap[position] as f64; } - let rgb = Rgb::new( - r / count as f64, - g / count as f64, - b / count as f64, - ); - let hsv = Hsv::from(rgb); - // info!("HSV: {:?}", [hsv.h, hsv.s, hsv.v]); - let color = LedColor::from_hsv(hsv.h, hsv.s, hsv.v); + let color = LedColor::new((r / len) as u8, (g / len) as u8, (b / len) as u8); // paris::info!("color: {:?}", color.get_rgb()); colors.push(color); } - return Ok(colors); + colors + } + + pub fn get_top_colors(&self) -> Vec { + self.get_one_edge_colors(&self.sample_points.top) + } + + pub fn get_top_of_led_start_at(&self) -> usize { + self.config + .top_led_strip + .and_then(|c| Some(c.global_start_position)) + .unwrap_or(0) + } + pub fn get_top_of_led_end_at(&self) -> usize { + self.config + .top_led_strip + .and_then(|c| Some(c.global_end_position)) + .unwrap_or(0) } pub async fn to_webp_base64(&self) -> String { @@ -119,9 +251,30 @@ impl Screenshot { .encode(100.0); return base64::encode(&*webp_memory); } + + pub async fn to_dto(&self) -> ScreenshotDto { + let encode_image = self.to_webp_base64().await; + let config = self.config.clone(); + let colors = self.get_colors(); + ScreenshotDto { + encode_image, + config, + colors, + } + } } -enum XPosition { - Top, - Bottom, +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct ScreenshotDto { + pub config: DisplayConfig, + pub encode_image: String, + pub colors: DisplayColorsOfLedStrips, +} + +#[derive(Clone, Serialize, Deserialize, Debug)] +pub struct DisplayColorsOfLedStrips { + pub top: Vec, + pub bottom: Vec, + pub left: Vec, + pub right: Vec, } From 366b1372582a1862d8d425a7fddc54c242d2e40a Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Mon, 2 Jan 2023 16:53:20 +0800 Subject: [PATCH 05/19] =?UTF-8?q?feat:=20GUI=20=E9=85=8D=E7=BD=AE=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=B7=BB=E5=8A=A0=E5=92=8C=E5=87=8F=E5=B0=91=20LED?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 7 + pnpm-lock.yaml | 281 ++++++++++++++++++ src-tauri/src/core/core.rs | 6 +- src-tauri/src/main.rs | 22 ++ src-tauri/src/picker/config/display_config.rs | 4 +- src-tauri/src/picker/manager.rs | 16 +- src-tauri/src/picker/preview_manager.rs | 83 ++++++ src-tauri/src/picker/screenshot.rs | 15 +- src/App.tsx | 58 +--- src/commons/components/button.tsx | 21 ++ .../components/display-with-led-strips.tsx | 92 +++++- .../components/led-strip-editor.tsx | 57 ++++ src/configurator/components/led-strip.tsx | 33 +- src/configurator/configurator.tsx | 80 ++++- src/configurator/models/display-config.ts | 18 +- src/configurator/models/led-strip-config.ts | 8 +- .../models/picker-configuration.ts | 6 +- src/configurator/models/screenshot.dto.ts | 12 + src/main.tsx | 3 +- src/styles/global-styles.tsx | 3 +- tailwind.config.cjs | 13 +- 21 files changed, 732 insertions(+), 106 deletions(-) create mode 100644 src-tauri/src/picker/preview_manager.rs create mode 100644 src/commons/components/button.tsx create mode 100644 src/configurator/components/led-strip-editor.tsx create mode 100644 src/configurator/models/screenshot.dto.ts diff --git a/package.json b/package.json index 4a7ea86..a279d32 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,14 @@ "dependencies": { "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", + "@fortawesome/fontawesome-svg-core": "^6.2.1", + "@fortawesome/free-regular-svg-icons": "^6.2.1", + "@fortawesome/free-solid-svg-icons": "^6.2.1", + "@fortawesome/react-fontawesome": "^0.2.0", + "@mui/material": "^5.11.1", "@tauri-apps/api": "^1.1.0", "clsx": "^1.2.1", + "ramda": "^0.28.0", "react": "^18.2.0", "react-async-hook": "^4.0.0", "react-dom": "^18.2.0" @@ -24,6 +30,7 @@ "@emotion/serialize": "^1.1.1", "@tauri-apps/cli": "^1.1.0", "@types/node": "^18.7.10", + "@types/ramda": "^0.28.20", "@types/react": "^18.0.15", "@types/react-dom": "^18.0.6", "@vitejs/plugin-react": "^2.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0f6cee2..2c4f8e8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,9 +6,15 @@ specifiers: '@emotion/react': ^11.10.5 '@emotion/serialize': ^1.1.1 '@emotion/styled': ^11.10.5 + '@fortawesome/fontawesome-svg-core': ^6.2.1 + '@fortawesome/free-regular-svg-icons': ^6.2.1 + '@fortawesome/free-solid-svg-icons': ^6.2.1 + '@fortawesome/react-fontawesome': ^0.2.0 + '@mui/material': ^5.11.1 '@tauri-apps/api': ^1.1.0 '@tauri-apps/cli': ^1.1.0 '@types/node': ^18.7.10 + '@types/ramda': ^0.28.20 '@types/react': ^18.0.15 '@types/react-dom': ^18.0.6 '@vitejs/plugin-react': ^2.0.0 @@ -22,6 +28,7 @@ specifiers: eslint-plugin-simple-import-sort: ^8.0.0 postcss: ^8.4.19 prettier: ^2.7.1 + ramda: ^0.28.0 react: ^18.2.0 react-async-hook: ^4.0.0 react-dom: ^18.2.0 @@ -33,8 +40,14 @@ specifiers: dependencies: '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 '@emotion/styled': 11.10.5_qvatmowesywn4ye42qoh247szu + '@fortawesome/fontawesome-svg-core': 6.2.1 + '@fortawesome/free-regular-svg-icons': 6.2.1 + '@fortawesome/free-solid-svg-icons': 6.2.1 + '@fortawesome/react-fontawesome': 0.2.0_z27bm67dtmuyyvss23ckjdrcuy + '@mui/material': 5.11.1_lskpmcsdi7ipu6qpuapyu56ihm '@tauri-apps/api': 1.2.0 clsx: 1.2.1 + ramda: 0.28.0 react: 18.2.0 react-async-hook: 4.0.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0 @@ -45,6 +58,7 @@ devDependencies: '@emotion/serialize': 1.1.1 '@tauri-apps/cli': 1.2.2 '@types/node': 18.11.16 + '@types/ramda': 0.28.20 '@types/react': 18.0.26 '@types/react-dom': 18.0.9 '@vitejs/plugin-react': 2.2.0_vite@3.2.5 @@ -505,6 +519,47 @@ packages: dev: true optional: true + /@fortawesome/fontawesome-common-types/6.2.1: + resolution: {integrity: sha512-Sz07mnQrTekFWLz5BMjOzHl/+NooTdW8F8kDQxjWwbpOJcnoSg4vUDng8d/WR1wOxM0O+CY9Zw0nR054riNYtQ==} + engines: {node: '>=6'} + requiresBuild: true + dev: false + + /@fortawesome/fontawesome-svg-core/6.2.1: + resolution: {integrity: sha512-HELwwbCz6C1XEcjzyT1Jugmz2NNklMrSPjZOWMlc+ZsHIVk+XOvOXLGGQtFBwSyqfJDNgRq4xBCwWOaZ/d9DEA==} + engines: {node: '>=6'} + requiresBuild: true + dependencies: + '@fortawesome/fontawesome-common-types': 6.2.1 + dev: false + + /@fortawesome/free-regular-svg-icons/6.2.1: + resolution: {integrity: sha512-wiqcNDNom75x+pe88FclpKz7aOSqS2lOivZeicMV5KRwOAeypxEYWAK/0v+7r+LrEY30+qzh8r2XDaEHvoLsMA==} + engines: {node: '>=6'} + requiresBuild: true + dependencies: + '@fortawesome/fontawesome-common-types': 6.2.1 + dev: false + + /@fortawesome/free-solid-svg-icons/6.2.1: + resolution: {integrity: sha512-oKuqrP5jbfEPJWTij4sM+/RvgX+RMFwx3QZCZcK9PrBDgxC35zuc7AOFsyMjMd/PIFPeB2JxyqDr5zs/DZFPPw==} + engines: {node: '>=6'} + requiresBuild: true + dependencies: + '@fortawesome/fontawesome-common-types': 6.2.1 + dev: false + + /@fortawesome/react-fontawesome/0.2.0_z27bm67dtmuyyvss23ckjdrcuy: + resolution: {integrity: sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==} + peerDependencies: + '@fortawesome/fontawesome-svg-core': ~1 || ~6 + react: '>=16.3' + dependencies: + '@fortawesome/fontawesome-svg-core': 6.2.1 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + /@jridgewell/gen-mapping/0.1.1: resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} engines: {node: '>=6.0.0'} @@ -543,6 +598,164 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true + /@mui/base/5.0.0-alpha.111_ib3m5ricvtkl2cll7qpr2f6lvq: + resolution: {integrity: sha512-2wfIPpl97S4dPzD0QOM3UIzQ/EuXCYQvHmXxTpfKxev/cfkzOe7Ik/McoYUBbtM1bSOqH3W276R/L2LF9cyXqQ==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.20.6 + '@emotion/is-prop-valid': 1.2.0 + '@mui/types': 7.2.3_@types+react@18.0.26 + '@mui/utils': 5.11.1_react@18.2.0 + '@popperjs/core': 2.11.6 + '@types/react': 18.0.26 + clsx: 1.2.1 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + react-is: 18.2.0 + dev: false + + /@mui/core-downloads-tracker/5.11.1: + resolution: {integrity: sha512-QVqVNlZ2K+LqUDE5kFgYd0r4KekR/dv2cNYbAutQWbfOA8VPVUVrDz0ELrEcoe8TjM/CwnsmGvaDh/YSNl/ALA==} + dev: false + + /@mui/material/5.11.1_lskpmcsdi7ipu6qpuapyu56ihm: + resolution: {integrity: sha512-yaZiXvcrl2vgUK+VO24780BWRgwdAMmAyuMVZnRTts1Yu0tWd6PjIYq2ZtaOlpj6/LbaSS+Q2kSfxYnDQ20CEQ==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.20.6 + '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 + '@emotion/styled': 11.10.5_qvatmowesywn4ye42qoh247szu + '@mui/base': 5.0.0-alpha.111_ib3m5ricvtkl2cll7qpr2f6lvq + '@mui/core-downloads-tracker': 5.11.1 + '@mui/system': 5.11.1_ogriz7mfahdh34qnfautfro5yu + '@mui/types': 7.2.3_@types+react@18.0.26 + '@mui/utils': 5.11.1_react@18.2.0 + '@types/react': 18.0.26 + '@types/react-transition-group': 4.4.5 + clsx: 1.2.1 + csstype: 3.1.1 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + react-is: 18.2.0 + react-transition-group: 4.4.5_biqbaboplfbrettd7655fr4n2y + dev: false + + /@mui/private-theming/5.11.1_kzbn2opkn2327fwg5yzwzya5o4: + resolution: {integrity: sha512-nnHg7kA5RwFRhy0wiDYe59sLCVGORpPypL1JcEdhv0+N0Zbmc2E/y4z2zqMRZ62MAEscpro7cQbvv244ThA84A==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.20.6 + '@mui/utils': 5.11.1_react@18.2.0 + '@types/react': 18.0.26 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /@mui/styled-engine/5.11.0_dovxhg2tvkkxkdnqyoum6wzcxm: + resolution: {integrity: sha512-AF06K60Zc58qf0f7X+Y/QjaHaZq16znliLnGc9iVrV/+s8Ln/FCoeNuFvhlCbZZQ5WQcJvcy59zp0nXrklGGPQ==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.4.1 + '@emotion/styled': ^11.3.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + dependencies: + '@babel/runtime': 7.20.6 + '@emotion/cache': 11.10.5 + '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 + '@emotion/styled': 11.10.5_qvatmowesywn4ye42qoh247szu + csstype: 3.1.1 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /@mui/system/5.11.1_ogriz7mfahdh34qnfautfro5yu: + resolution: {integrity: sha512-BEA2S0hay8n8CcZftkeAVsi0nsb5ZjdnZRCahv5lX7QJYwDjO4ucJ6lnvxHe2v/9Te1LLjTO7ojxu/qM6CE5Cg==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.20.6 + '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 + '@emotion/styled': 11.10.5_qvatmowesywn4ye42qoh247szu + '@mui/private-theming': 5.11.1_kzbn2opkn2327fwg5yzwzya5o4 + '@mui/styled-engine': 5.11.0_dovxhg2tvkkxkdnqyoum6wzcxm + '@mui/types': 7.2.3_@types+react@18.0.26 + '@mui/utils': 5.11.1_react@18.2.0 + '@types/react': 18.0.26 + clsx: 1.2.1 + csstype: 3.1.1 + prop-types: 15.8.1 + react: 18.2.0 + dev: false + + /@mui/types/7.2.3_@types+react@18.0.26: + resolution: {integrity: sha512-tZ+CQggbe9Ol7e/Fs5RcKwg/woU+o8DCtOnccX6KmbBc7YrfqMYEYuaIcXHuhpT880QwNkZZ3wQwvtlDFA2yOw==} + peerDependencies: + '@types/react': '*' + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.0.26 + dev: false + + /@mui/utils/5.11.1_react@18.2.0: + resolution: {integrity: sha512-lMAPgIJoil8V9ZxsMbEflMsvZmWcHbRVMc4JDY9jPO9V4welpF43h/O267b1RqlcRnC5MEbVQV605GYkTZY29Q==} + engines: {node: '>=12.0.0'} + peerDependencies: + react: ^17.0.0 || ^18.0.0 + dependencies: + '@babel/runtime': 7.20.6 + '@types/prop-types': 15.7.5 + '@types/react-is': 17.0.3 + prop-types: 15.8.1 + react: 18.2.0 + react-is: 18.2.0 + dev: false + /@nodelib/fs.scandir/2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -564,6 +777,10 @@ packages: fastq: 1.14.0 dev: true + /@popperjs/core/2.11.6: + resolution: {integrity: sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==} + dev: false + /@tauri-apps/api/1.2.0: resolution: {integrity: sha512-lsI54KI6HGf7VImuf/T9pnoejfgkNoXveP14pVV7XarrQ46rOejIVJLFqHI9sRReJMGdh2YuCoI3cc/yCWCsrw==} engines: {node: '>= 14.6.0', npm: '>= 6.6.0', yarn: '>= 1.19.1'} @@ -680,12 +897,30 @@ packages: /@types/prop-types/15.7.5: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + /@types/ramda/0.28.20: + resolution: {integrity: sha512-MeUhzGSXQTRsY19JGn5LIBTLxVEnyF6HDNr08KSJqybsm4DlfLIgK1jBHjhpiSyk252tXYmp+UOe0UFg0UiFsA==} + dependencies: + ts-toolbelt: 6.15.5 + dev: true + /@types/react-dom/18.0.9: resolution: {integrity: sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==} dependencies: '@types/react': 18.0.26 dev: true + /@types/react-is/17.0.3: + resolution: {integrity: sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==} + dependencies: + '@types/react': 18.0.26 + dev: false + + /@types/react-transition-group/4.4.5: + resolution: {integrity: sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==} + dependencies: + '@types/react': 18.0.26 + dev: false + /@types/react/18.0.26: resolution: {integrity: sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==} dependencies: @@ -1039,6 +1274,13 @@ packages: esutils: 2.0.3 dev: true + /dom-helpers/5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dependencies: + '@babel/runtime': 7.20.6 + csstype: 3.1.1 + dev: false + /electron-to-chromium/1.4.284: resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} dev: true @@ -1840,6 +2082,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /object-assign/4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: false + /object-hash/3.0.0: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} @@ -1992,6 +2239,14 @@ packages: hasBin: true dev: true + /prop-types/15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: false + /queue-microtask/1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true @@ -2001,6 +2256,10 @@ packages: engines: {node: '>=10'} dev: true + /ramda/0.28.0: + resolution: {integrity: sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA==} + dev: false + /react-async-hook/4.0.0_react@18.2.0: resolution: {integrity: sha512-97lgjFkOcHCTYSrsKBpsXg3iVWM0LnzedB749iP76sb3/8Ouu4nHIkCLEOrQWHVYqrYxjF05NN6GHoXWFkB3Kw==} engines: {node: '>=8', npm: '>=5'} @@ -2024,11 +2283,29 @@ packages: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} dev: false + /react-is/18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + dev: false + /react-refresh/0.14.0: resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} engines: {node: '>=0.10.0'} dev: true + /react-transition-group/4.4.5_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} + peerDependencies: + react: '>=16.6.0' + react-dom: '>=16.6.0' + dependencies: + '@babel/runtime': 7.20.6 + dom-helpers: 5.2.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + /react/18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} @@ -2221,6 +2498,10 @@ packages: is-number: 7.0.0 dev: true + /ts-toolbelt/6.15.5: + resolution: {integrity: sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==} + dev: true + /tsconfig-paths/3.14.1: resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} dependencies: diff --git a/src-tauri/src/core/core.rs b/src-tauri/src/core/core.rs index 3495b9f..ef5c2d1 100644 --- a/src-tauri/src/core/core.rs +++ b/src-tauri/src/core/core.rs @@ -1,9 +1,9 @@ -use futures::{future::join_all, stream::FuturesUnordered, StreamExt}; +use futures::future::join_all; use once_cell::sync::OnceCell; use paris::info; use serde::{Deserialize, Serialize}; -use serde_json::value::Index; -use std::{collections::HashMap, iter::Map, sync::Arc, thread, time::Duration}; + +use std::{collections::HashMap, sync::Arc, time::Duration}; use tauri::async_runtime::RwLock; use tokio::{ join, diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 35a81c6..e5f809b 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -11,6 +11,7 @@ mod rpc; use crate::core::AmbientLightMode; use crate::core::CoreManager; use paris::*; +use picker::config::DisplayConfig; use picker::manager::Picker; use picker::screenshot::ScreenshotDto; use std::vec; @@ -35,6 +36,26 @@ async fn take_snapshot() -> Vec { base64_bitmap_list } +#[tauri::command] +async fn get_screenshot_by_config(config: DisplayConfig) -> Result { + info!("Hi"); + let manager = Picker::global(); + + let start = time::Instant::now(); + let screenshot_dto = manager.get_screenshot_by_config(config).await; + info!("截图耗时 {} s", start.elapsed().as_seconds_f32()); + match screenshot_dto { + Ok(screenshot_dto) => { + info!("截图耗时 {} s", start.elapsed().as_seconds_f32()); + Ok(screenshot_dto) + } + Err(error) => { + error!("get_screenshot_by_config failed. {}", error); + Err(format!("get_screenshot_by_config failed. {}", error)) + } + } +} + #[tauri::command] fn get_picker_config() -> picker::config::Configuration { let configuration = picker::config::Manager::global().get_config(); @@ -57,6 +78,7 @@ async fn main() { take_snapshot, play_mode, get_picker_config, + get_screenshot_by_config, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/picker/config/display_config.rs b/src-tauri/src/picker/config/display_config.rs index ec1be7a..1bb664e 100644 --- a/src-tauri/src/picker/config/display_config.rs +++ b/src-tauri/src/picker/config/display_config.rs @@ -9,6 +9,7 @@ pub struct LedStripConfig { #[derive(Clone, Copy, Serialize, Deserialize, Debug)] pub struct DisplayConfig { + pub id: usize, pub index_of_display: usize, pub display_width: usize, pub display_height: usize, @@ -19,8 +20,9 @@ pub struct DisplayConfig { } impl DisplayConfig { - pub fn default(index_of_display: usize, display_width: usize, display_height: usize) -> Self { + pub fn default(id: usize, index_of_display: usize, display_width: usize, display_height: usize) -> Self { Self { + id, index_of_display, display_width, display_height, diff --git a/src-tauri/src/picker/manager.rs b/src-tauri/src/picker/manager.rs index 5963f6d..0cfb114 100644 --- a/src-tauri/src/picker/manager.rs +++ b/src-tauri/src/picker/manager.rs @@ -2,7 +2,7 @@ use futures::{stream::FuturesUnordered, StreamExt}; use once_cell::sync::OnceCell; use paris::info; use scrap::Display; -use std::{borrow::Borrow, sync::Arc}; +use std::sync::Arc; use tokio::{sync::Mutex, task}; use crate::picker::{config, screen::Screen}; @@ -44,7 +44,7 @@ impl Picker { for (index, display) in displays.iter().enumerate() { let height = display.height(); let width = display.width(); - let config = DisplayConfig::default(index, width, height); + let config = DisplayConfig::default(index, index, width, height); configs.push(config); } @@ -76,4 +76,16 @@ impl Picker { anyhow::Ok(screenshot.to_dto().await) } + + pub async fn get_screenshot_by_config( + &self, + config: DisplayConfig, + ) -> anyhow::Result { + let start = time::Instant::now(); + let mut picker = DisplayPicker::from_config(config)?; + let screenshot = picker.take_screenshot()?; + info!("Take Screenshot Spend: {}", start.elapsed()); + + anyhow::Ok(screenshot.to_dto().await) + } } diff --git a/src-tauri/src/picker/preview_manager.rs b/src-tauri/src/picker/preview_manager.rs new file mode 100644 index 0000000..7d46fa2 --- /dev/null +++ b/src-tauri/src/picker/preview_manager.rs @@ -0,0 +1,83 @@ +use futures::{stream::FuturesUnordered, StreamExt}; +use once_cell::sync::OnceCell; +use paris::{info, warn}; +use scrap::Display; +use std::{borrow::Borrow, sync::Arc}; +use tokio::{sync::Mutex, task}; + +use crate::picker::{config, screen::Screen}; + +use super::{ + config::DisplayConfig, + display_picker::DisplayPicker, + manager::Picker, + screenshot::{Screenshot, ScreenshotDto}, +}; + +pub struct PreviewPicker { + pub pickers: Arc>>>>, + pub screenshots: Arc>>, +} + +impl PreviewPicker { + pub fn global() -> &'static PreviewPicker { + static SCREEN_COLOR_PREVIEW_PICKER: OnceCell = OnceCell::new(); + + SCREEN_COLOR_PREVIEW_PICKER.get_or_init(|| PreviewPicker { + pickers: Arc::new(Mutex::new(vec![])), + screenshots: Arc::new(Mutex::new(vec![])), + }) + } + + pub async fn list_displays(&self) { + let mut pickers = self.pickers.lock().await; + let displays = Display::all() + .map_err(|error| anyhow::anyhow!("Can not get all of displays. {}", error))?; + + let mut configs = vec![]; + let mut futs = FuturesUnordered::new(); + + for (index, display) in displays.iter().enumerate() { + let height = display.height(); + let width = display.width(); + let config = DisplayConfig::default(index, width, height); + configs.push(config); + } + + for config in configs.iter() { + let picker = DisplayPicker::from_config(*config); + match picker { + Ok(picker) => { + pickers.push(Arc::new(Mutex::new(picker))); + } + Err(_) => { + warn!( + "can not create DisplayPicker from config. config: {:?}", + config + ); + } + } + } + } + + pub async fn get_screenshot_by_config( + &self, + config: DisplayConfig, + ) -> anyhow::Result { + let start = time::Instant::now(); + let mut picker = DisplayPicker::from_config(config)?; + let screenshot = picker.take_screenshot()?; + info!("Take Screenshot Spend: {}", start.elapsed()); + + anyhow::Ok(screenshot.to_dto().await) + } + + pub async fn preview_display_by_config(config: DisplayConfig) -> anyhow::Result { + let start = time::Instant::now(); + let mut picker = DisplayPicker::from_config(config)?; + let screenshot = picker.take_screenshot()?; + info!("Take Screenshot Spend: {}", start.elapsed()); + + anyhow::Ok(screenshot.to_dto().await) + } +} diff --git a/src-tauri/src/picker/screenshot.rs b/src-tauri/src/picker/screenshot.rs index b054c58..4b1a4a9 100644 --- a/src-tauri/src/picker/screenshot.rs +++ b/src-tauri/src/picker/screenshot.rs @@ -51,7 +51,7 @@ impl Screenshot { } }; - let bottom: Vec = match config.top_led_strip { + let bottom: Vec = match config.bottom_led_strip { Some(led_strip_config) => { let points = Self::get_one_edge_sample_points( config.display_height / 9, @@ -76,7 +76,7 @@ impl Screenshot { } }; - let left: Vec = match config.top_led_strip { + let left: Vec = match config.left_led_strip { Some(led_strip_config) => { let points = Self::get_one_edge_sample_points( config.display_width / 16, @@ -98,7 +98,7 @@ impl Screenshot { } }; - let right: Vec = match config.top_led_strip { + let right: Vec = match config.right_led_strip { Some(led_strip_config) => { let points = Self::get_one_edge_sample_points( config.display_width / 16, @@ -113,7 +113,7 @@ impl Screenshot { .map(|groups| -> Vec { groups .into_iter() - .map(|(x, y)| (y, config.display_width - x)) + .map(|(x, y)| (config.display_width - y, x)) .collect() }) .collect() @@ -145,14 +145,15 @@ impl Screenshot { let point_y_list: Vec = (point_start_y..width).step_by(cell_size_y).collect(); let point_x_list: Vec = iter::successors(Some(point_start_x), |i| { let next = i + cell_size_x; - (next < (width as f64)).then_some(next) + (next < (length as f64)).then_some(next) }) .map(|i| i as usize) .collect(); let points: Vec = point_x_list - .into_iter() - .zip(point_y_list.into_iter()) + .iter() + .map(|&x| point_y_list.iter().map(move |&y| (x, y))) + .flatten() .collect(); points .chunks(single_axis_points * single_axis_points) diff --git a/src/App.tsx b/src/App.tsx index 777144e..e916cf8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,9 +1,10 @@ import { useCallback, useEffect, useState } from 'react'; -import reactLogo from './assets/react.svg'; +import tw from 'twin.macro'; import { invoke } from '@tauri-apps/api/tauri'; import './App.css'; import clsx from 'clsx'; import { Configurator } from './configurator/configurator'; +import { ButtonSwitch } from './commons/components/button'; type Mode = 'Flowing' | 'Follow' | null; @@ -39,63 +40,30 @@ function App() { return (
-
+
{ledStripColors.map((it) => ( - + ))}
-
+
{screenshots.map((screenshot) => ( -
+
))}
-
- - - - - + + switchCurrentMode('Follow')}>Follow
-
+
diff --git a/src/commons/components/button.tsx b/src/commons/components/button.tsx new file mode 100644 index 0000000..ac7cff4 --- /dev/null +++ b/src/commons/components/button.tsx @@ -0,0 +1,21 @@ +import { FC } from 'react'; +import styled from '@emotion/styled'; +import tw, { theme } from 'twin.macro'; +import { css } from '@emotion/react'; + +interface ButtonProps { + value?: boolean; + isSmall?: boolean; +} + +export const ButtonSwitch = styled.button(({ value, isSmall }: ButtonProps) => [ + // The common button styles + tw`px-8 py-2 rounded-xl transform duration-75 dark:bg-black m-2 shadow-lg text-opacity-95 dark:shadow-gray-800`, + + tw`hover:(scale-105)`, + tw`focus:(scale-100)`, + + value && 'bg-gradient-to-r from-purple-500 to-blue-500', + + isSmall ? tw`text-sm` : tw`text-lg`, +]); diff --git a/src/configurator/components/display-with-led-strips.tsx b/src/configurator/components/display-with-led-strips.tsx index 18d9c05..b3b2ab5 100644 --- a/src/configurator/components/display-with-led-strips.tsx +++ b/src/configurator/components/display-with-led-strips.tsx @@ -1,25 +1,97 @@ -import { HTMLAttributes } from 'react'; +import { HTMLAttributes, useCallback, useMemo } from 'react'; import { FC } from 'react'; import { DisplayConfig } from '../models/display-config'; import { LedStrip } from './led-strip'; +import tw, { css, styled, theme } from 'twin.macro'; +import { ScreenshotDto } from '../models/screenshot.dto'; +import { LedStripEditor } from './led-strip-editor'; +import { LedStripConfig } from '../models/led-strip-config'; -export interface DisplayWithLedStripsProps extends HTMLAttributes { +export interface DisplayWithLedStripsProps + extends Omit, 'onChange'> { config: DisplayConfig; - screenshot: string; + screenshot: ScreenshotDto; + onChange?: (config: DisplayConfig) => void; } +const StyledContainer = styled.section( + tw`m-4 grid gap-1`, + css` + grid-template-columns: ${theme`width.5`} ${theme`width.3`} auto ${theme`width.3`} ${theme`width.5`}; + `, + css` + grid-template-rows: ${theme`width.5`} ${theme`width.3`} auto ${theme`width.3`} ${theme`width.5`}; + `, +); + export const DisplayWithLedStrips: FC = ({ config, screenshot, + onChange, ...htmlAttrs }) => { + const screenshotUrl = useMemo( + () => `data:image/png;base64,${screenshot.encode_image}`, + [screenshot.encode_image], + ); + + const onLedStripConfigChange = useCallback( + ( + position: + | 'top_led_strip' + | 'left_led_strip' + | 'right_led_strip' + | 'bottom_led_strip', + value: LedStripConfig | null, + ) => { + const c = { ...config, [position]: value }; + onChange?.(c); + }, + [config], + ); return ( -
- - - - - -
+ + + + + + + onLedStripConfigChange('top_led_strip', value)} + /> + onLedStripConfigChange('left_led_strip', value)} + /> + onLedStripConfigChange('right_led_strip', value)} + /> + onLedStripConfigChange('bottom_led_strip', value)} + /> + ); }; diff --git a/src/configurator/components/led-strip-editor.tsx b/src/configurator/components/led-strip-editor.tsx new file mode 100644 index 0000000..f88ce86 --- /dev/null +++ b/src/configurator/components/led-strip-editor.tsx @@ -0,0 +1,57 @@ +import { HTMLAttributes, useCallback } from 'react'; +import { FC } from 'react'; +import { LedStripConfig } from '../models/led-strip-config'; +import tw, { css, styled, theme } from 'twin.macro'; +import { faLeftRight, faMinus, faPlus } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; + +export interface LedStripEditorProps + extends Omit, 'onChange'> { + config: LedStripConfig | null; + onChange?: (config: LedStripConfig | null) => void; +} + +const StyledContainer = styled.section( + tw`flex flex-wrap gap-2 self-start justify-self-start`, +); + +const StyledButton = styled.button( + tw` +bg-yellow-500 rounded-full h-4 w-4 text-xs shadow select-none`, + tw`hocus:scale-105 hocus:active:scale-95 active:bg-amber-600`, +); + +export const LedStripEditor: FC = ({ + config, + onChange, + ...htmlAttrs +}) => { + const addLed = useCallback(() => { + if (config) { + onChange?.({ ...config, global_end_position: config.global_end_position + 1 }); + } else { + onChange?.(new LedStripConfig(0, 0, 1)); + } + }, [config, onChange]); + const removeLed = useCallback(() => { + if (!config) { + onChange?.(null); + } else { + onChange?.({ ...config, global_end_position: config.global_end_position - 1 }); + } + }, [config, onChange]); + + return ( + + + + + + + + + + + + ); +}; diff --git a/src/configurator/components/led-strip.tsx b/src/configurator/components/led-strip.tsx index 3293e29..be256cd 100644 --- a/src/configurator/components/led-strip.tsx +++ b/src/configurator/components/led-strip.tsx @@ -1,11 +1,36 @@ -import { HTMLAttributes } from 'react'; +import { HTMLAttributes, useMemo } from 'react'; import { FC } from 'react'; import { LedStripConfig } from '../models/led-strip-config'; +import tw, { css, styled, theme } from 'twin.macro'; +import { splitEvery } from 'ramda'; export interface LedStripProps extends HTMLAttributes { - config: LedStripConfig; + config: LedStripConfig | null; + colors: Uint8Array; } -export const LedStrip: FC = ({ config, ...htmlAttrs }) => { - return
...
; +const StyledContainer = styled.section( + tw`dark:bg-transparent shadow-xl border-gray-500 border rounded-full flex flex-wrap justify-around items-center`, + css``, +); + +const StyledPixel = styled.span( + ({ rgb: [r, g, b] }: { rgb: [number, number, number] }) => [ + tw`rounded-full h-3 w-3 bg-current block border border-gray-700`, + css` + color: rgb(${r}, ${g}, ${b}); + `, + ], +); + +export const LedStrip: FC = ({ config, colors, ...htmlAttrs }) => { + const pixels = useMemo(() => { + const pixels = splitEvery(3, Array.from(colors)) as Array<[number, number, number]>; + return pixels.map((rgb, index) => ); + }, [colors]); + return ( + + {pixels} + + ); }; diff --git a/src/configurator/configurator.tsx b/src/configurator/configurator.tsx index 7f8c4a2..ea51bd7 100644 --- a/src/configurator/configurator.tsx +++ b/src/configurator/configurator.tsx @@ -1,46 +1,96 @@ import { invoke } from '@tauri-apps/api'; -import { FC, useMemo } from 'react'; -import { useAsync } from 'react-async-hook'; +import { FC, Fragment, useCallback, useEffect, useMemo, useState } from 'react'; +import tw from 'twin.macro'; +import { useAsync, useAsyncCallback } from 'react-async-hook'; import { DisplayWithLedStrips } from './components/display-with-led-strips'; import { PickerConfiguration } from './models/picker-configuration'; +import { DisplayConfig } from './models/display-config'; +import { ScreenshotDto } from './models/screenshot.dto'; +import { Alert, Snackbar } from '@mui/material'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faSpinner } from '@fortawesome/free-solid-svg-icons'; +import { update } from 'ramda'; const getPickerConfig = () => invoke('get_picker_config'); const getScreenshotOfDisplays = () => - invoke('take_snapshot').then((items) => - items?.map((it) => `data:image/webp;base64,${it}`), - ); + invoke('take_snapshot').then((items) => { + console.log(items); + return items; + }); +const getScreenshotByConfig = async (config: DisplayConfig) => { + return await invoke('get_screenshot_by_config', { + config, + }); +}; export const Configurator: FC = () => { - const { loading: pendingPickerConfig, result: pickerConfig } = useAsync( + const { loading: pendingPickerConfig, result: savedPickerConfig } = useAsync( getPickerConfig, [], ); - const { loading: pendingScreenshotOfDisplays, result: screenshotOfDisplays } = useAsync( - getScreenshotOfDisplays, - [], - ); + const { loading: pendingScreenshotOfDisplays, result: defaultScreenshotOfDisplays } = + useAsync(getScreenshotOfDisplays, []); + + const [screenshotOfDisplays, setScreenshotOfDisplays] = useState([]); + + const { loading: pendingGetLedColorsByConfig, execute: onPickerChange } = + useAsyncCallback(async (value: DisplayConfig) => { + console.log(value); + const screenshot = await getScreenshotByConfig(value); + setScreenshotOfDisplays((old) => { + const index = old.findIndex((it) => it.config.id === screenshot.config.id); + console.log({ old, n: update(index, screenshot, old) }); + return update(index, screenshot, old); + }); + + console.log('screenshot', screenshot); + }); + + const [displayConfigs, setDisplayConfigs] = useState([]); + + useEffect(() => { + const displayConfigs = savedPickerConfig?.display_configs; + if (displayConfigs) { + setDisplayConfigs(displayConfigs); + } + }, [savedPickerConfig]); + useEffect(() => { + if (defaultScreenshotOfDisplays) { + setScreenshotOfDisplays(defaultScreenshotOfDisplays); + } + }, [defaultScreenshotOfDisplays]); const displays = useMemo(() => { - if (pickerConfig && screenshotOfDisplays) { + if (screenshotOfDisplays) { + console.log({ c: screenshotOfDisplays }); return screenshotOfDisplays.map((screenshot, index) => ( onPickerChange(value)} /> )); } - }, [pickerConfig, screenshotOfDisplays]); + }, [displayConfigs, screenshotOfDisplays]); if (pendingPickerConfig || pendingScreenshotOfDisplays) { return (
等待 {JSON.stringify({ pendingPickerConfig, pendingScreenshotOfDisplays })} - {displays}
); } - return
{displays}
; + return ( + +
{displays}
; + + } sx={{ width: '100%' }}> + This is a success message! + + +
+ ); }; diff --git a/src/configurator/models/display-config.ts b/src/configurator/models/display-config.ts index f98a4fb..ef2ad54 100644 --- a/src/configurator/models/display-config.ts +++ b/src/configurator/models/display-config.ts @@ -1,11 +1,15 @@ import { LedStripConfig } from './led-strip-config'; export class DisplayConfig { - index_of_display!: number; - display_width!: number; - display_height!: number; - top_led_strip!: LedStripConfig; - bottom_led_strip!: LedStripConfig; - left_led_strip!: LedStripConfig; - right_led_strip!: LedStripConfig; + top_led_strip: LedStripConfig | null = null; + bottom_led_strip: LedStripConfig | null = null; + left_led_strip: LedStripConfig | null = null; + right_led_strip: LedStripConfig | null = null; + + constructor( + public id: number, + public index_of_display: number, + public display_width: number, + public display_height: number, + ) {} } diff --git a/src/configurator/models/led-strip-config.ts b/src/configurator/models/led-strip-config.ts index 5b2ff8f..c3945b5 100644 --- a/src/configurator/models/led-strip-config.ts +++ b/src/configurator/models/led-strip-config.ts @@ -1,5 +1,7 @@ export class LedStripConfig { - index!: number; - global_start_position!: number; - global_end_position!: number; + constructor( + public index: number, + public global_start_position: number, + public global_end_position: number, + ) {} } diff --git a/src/configurator/models/picker-configuration.ts b/src/configurator/models/picker-configuration.ts index 4b989d0..5d5c426 100644 --- a/src/configurator/models/picker-configuration.ts +++ b/src/configurator/models/picker-configuration.ts @@ -1,6 +1,8 @@ import { DisplayConfig } from './display-config'; export class PickerConfiguration { - config_version!: number; - display_configs!: DisplayConfig[]; + constructor( + public display_configs: DisplayConfig[] = [], + public config_version: number = 1, + ) {} } diff --git a/src/configurator/models/screenshot.dto.ts b/src/configurator/models/screenshot.dto.ts new file mode 100644 index 0000000..eb245e5 --- /dev/null +++ b/src/configurator/models/screenshot.dto.ts @@ -0,0 +1,12 @@ +import { DisplayConfig } from './display-config'; + +export class ScreenshotDto { + encode_image!: string; + config!: DisplayConfig; + colors!: { + top: Uint8Array; + bottom: Uint8Array; + left: Uint8Array; + right: Uint8Array; + }; +} diff --git a/src/main.tsx b/src/main.tsx index 1085049..16c8ee2 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,10 +1,11 @@ import React from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; -import "./style.css"; +import GlobalStyles from './styles/global-styles'; ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( + , ); \ No newline at end of file diff --git a/src/styles/global-styles.tsx b/src/styles/global-styles.tsx index 1479d4b..aa78d4d 100644 --- a/src/styles/global-styles.tsx +++ b/src/styles/global-styles.tsx @@ -5,7 +5,8 @@ import tw, { theme, GlobalStyles as BaseStyles } from 'twin.macro'; const customStyles = css({ body: { WebkitTapHighlightColor: theme`colors.purple.500`, - ...tw`antialiased dark:bg-dark-800 bg-dark-100`, + ...tw`antialiased`, + ...tw`dark:bg-dark-800 bg-dark-100 dark:text-gray-100 text-gray-800`, }, }); diff --git a/tailwind.config.cjs b/tailwind.config.cjs index 8b35f96..70464ef 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -1,12 +1,15 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: [ - "./index.html", - "./src/**/*.{js,ts,jsx,tsx}", - ], + content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], theme: { extend: { + colors: { + dark: { + 800: '#0f0f0f', + 100: '#f6f6f6', + }, + }, }, }, plugins: [], -} +}; From 9030d48e21612bb4f3f077da7875ca8b5f656a37 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Mon, 2 Jan 2023 20:59:32 +0800 Subject: [PATCH 06/19] =?UTF-8?q?feat:=20=E6=9B=B4=E6=8D=A2=E7=94=A8?= =?UTF-8?q?=E4=BA=8E=E5=89=8D=E7=AB=AF=E6=98=BE=E7=A4=BA=E7=9A=84=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E6=A0=BC=E5=BC=8F=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 24 +- pnpm-lock.yaml | 315 ++++++----- src-tauri/Cargo.lock | 521 ++++++++++-------- src-tauri/Cargo.toml | 1 + src-tauri/src/main.rs | 1 - src-tauri/src/picker/screenshot.rs | 53 +- .../components/display-with-led-strips.tsx | 2 +- src/configurator/components/led-strip.tsx | 2 +- 8 files changed, 498 insertions(+), 421 deletions(-) diff --git a/package.json b/package.json index a279d32..c276125 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ "@fortawesome/free-regular-svg-icons": "^6.2.1", "@fortawesome/free-solid-svg-icons": "^6.2.1", "@fortawesome/react-fontawesome": "^0.2.0", - "@mui/material": "^5.11.1", - "@tauri-apps/api": "^1.1.0", + "@mui/material": "^5.11.2", + "@tauri-apps/api": "^1.2.0", "clsx": "^1.2.1", "ramda": "^0.28.0", "react": "^18.2.0", @@ -25,15 +25,15 @@ "react-dom": "^18.2.0" }, "devDependencies": { - "@babel/plugin-transform-react-jsx": "^7.19.0", + "@babel/plugin-transform-react-jsx": "^7.20.7", "@emotion/babel-plugin-jsx-pragmatic": "^0.2.0", "@emotion/serialize": "^1.1.1", - "@tauri-apps/cli": "^1.1.0", - "@types/node": "^18.7.10", + "@tauri-apps/cli": "^1.2.2", + "@types/node": "^18.11.18", "@types/ramda": "^0.28.20", - "@types/react": "^18.0.15", - "@types/react-dom": "^18.0.6", - "@vitejs/plugin-react": "^2.0.0", + "@types/react": "^18.0.26", + "@types/react-dom": "^18.0.10", + "@vitejs/plugin-react": "^2.2.0", "autoprefixer": "^10.4.13", "babel-plugin-macros": "^3.1.0", "eslint-config-prettier": "^8.5.0", @@ -41,11 +41,11 @@ "eslint-plugin-jsx-a11y": "^6.6.1", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-simple-import-sort": "^8.0.0", - "postcss": "^8.4.19", - "prettier": "^2.7.1", + "postcss": "^8.4.20", + "prettier": "^2.8.1", "tailwindcss": "^3.2.4", "twin.macro": "^3.1.0", - "typescript": "^4.6.4", - "vite": "^3.0.2" + "typescript": "^4.9.4", + "vite": "^3.2.5" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2c4f8e8..1d13e74 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,7 +1,7 @@ lockfileVersion: 5.4 specifiers: - '@babel/plugin-transform-react-jsx': ^7.19.0 + '@babel/plugin-transform-react-jsx': ^7.20.7 '@emotion/babel-plugin-jsx-pragmatic': ^0.2.0 '@emotion/react': ^11.10.5 '@emotion/serialize': ^1.1.1 @@ -10,14 +10,14 @@ specifiers: '@fortawesome/free-regular-svg-icons': ^6.2.1 '@fortawesome/free-solid-svg-icons': ^6.2.1 '@fortawesome/react-fontawesome': ^0.2.0 - '@mui/material': ^5.11.1 - '@tauri-apps/api': ^1.1.0 - '@tauri-apps/cli': ^1.1.0 - '@types/node': ^18.7.10 + '@mui/material': ^5.11.2 + '@tauri-apps/api': ^1.2.0 + '@tauri-apps/cli': ^1.2.2 + '@types/node': ^18.11.18 '@types/ramda': ^0.28.20 - '@types/react': ^18.0.15 - '@types/react-dom': ^18.0.6 - '@vitejs/plugin-react': ^2.0.0 + '@types/react': ^18.0.26 + '@types/react-dom': ^18.0.10 + '@vitejs/plugin-react': ^2.2.0 autoprefixer: ^10.4.13 babel-plugin-macros: ^3.1.0 clsx: ^1.2.1 @@ -26,16 +26,16 @@ specifiers: eslint-plugin-jsx-a11y: ^6.6.1 eslint-plugin-prettier: ^4.2.1 eslint-plugin-simple-import-sort: ^8.0.0 - postcss: ^8.4.19 - prettier: ^2.7.1 + postcss: ^8.4.20 + prettier: ^2.8.1 ramda: ^0.28.0 react: ^18.2.0 react-async-hook: ^4.0.0 react-dom: ^18.2.0 tailwindcss: ^3.2.4 twin.macro: ^3.1.0 - typescript: ^4.6.4 - vite: ^3.0.2 + typescript: ^4.9.4 + vite: ^3.2.5 dependencies: '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 @@ -44,7 +44,7 @@ dependencies: '@fortawesome/free-regular-svg-icons': 6.2.1 '@fortawesome/free-solid-svg-icons': 6.2.1 '@fortawesome/react-fontawesome': 0.2.0_z27bm67dtmuyyvss23ckjdrcuy - '@mui/material': 5.11.1_lskpmcsdi7ipu6qpuapyu56ihm + '@mui/material': 5.11.2_lskpmcsdi7ipu6qpuapyu56ihm '@tauri-apps/api': 1.2.0 clsx: 1.2.1 ramda: 0.28.0 @@ -53,14 +53,14 @@ dependencies: react-dom: 18.2.0_react@18.2.0 devDependencies: - '@babel/plugin-transform-react-jsx': 7.19.0 + '@babel/plugin-transform-react-jsx': 7.20.7 '@emotion/babel-plugin-jsx-pragmatic': 0.2.0 '@emotion/serialize': 1.1.1 '@tauri-apps/cli': 1.2.2 - '@types/node': 18.11.16 + '@types/node': 18.11.18 '@types/ramda': 0.28.20 '@types/react': 18.0.26 - '@types/react-dom': 18.0.9 + '@types/react-dom': 18.0.10 '@vitejs/plugin-react': 2.2.0_vite@3.2.5 autoprefixer: 10.4.13_postcss@8.4.20 babel-plugin-macros: 3.1.0 @@ -74,7 +74,7 @@ devDependencies: tailwindcss: 3.2.4_postcss@8.4.20 twin.macro: 3.1.0_tailwindcss@3.2.4 typescript: 4.9.4 - vite: 3.2.5_@types+node@18.11.16 + vite: 3.2.5_@types+node@18.11.18 packages: @@ -92,39 +92,39 @@ packages: dependencies: '@babel/highlight': 7.18.6 - /@babel/compat-data/7.20.5: - resolution: {integrity: sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==} + /@babel/compat-data/7.20.10: + resolution: {integrity: sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==} engines: {node: '>=6.9.0'} dev: true - /@babel/core/7.20.5: - resolution: {integrity: sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==} + /@babel/core/7.20.7: + resolution: {integrity: sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.0 '@babel/code-frame': 7.18.6 - '@babel/generator': 7.20.5 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 - '@babel/helper-module-transforms': 7.20.2 - '@babel/helpers': 7.20.6 - '@babel/parser': 7.20.5 - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.5 - '@babel/types': 7.20.5 + '@babel/generator': 7.20.7 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.7 + '@babel/helper-module-transforms': 7.20.11 + '@babel/helpers': 7.20.7 + '@babel/parser': 7.20.7 + '@babel/template': 7.20.7 + '@babel/traverse': 7.20.10 + '@babel/types': 7.20.7 convert-source-map: 1.9.0 debug: 4.3.4 gensync: 1.0.0-beta.2 - json5: 2.2.2 + json5: 2.2.3 semver: 6.3.0 transitivePeerDependencies: - supports-color dev: true - /@babel/generator/7.20.5: - resolution: {integrity: sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==} + /@babel/generator/7.20.7: + resolution: {integrity: sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.5 + '@babel/types': 7.20.7 '@jridgewell/gen-mapping': 0.3.2 jsesc: 2.5.2 dev: true @@ -133,19 +133,20 @@ packages: resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.5 + '@babel/types': 7.20.7 dev: true - /@babel/helper-compilation-targets/7.20.0_@babel+core@7.20.5: - resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==} + /@babel/helper-compilation-targets/7.20.7_@babel+core@7.20.7: + resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/compat-data': 7.20.5 - '@babel/core': 7.20.5 + '@babel/compat-data': 7.20.10 + '@babel/core': 7.20.7 '@babel/helper-validator-option': 7.18.6 browserslist: 4.21.4 + lru-cache: 5.1.1 semver: 6.3.0 dev: true @@ -158,25 +159,25 @@ packages: resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.18.10 - '@babel/types': 7.20.5 + '@babel/template': 7.20.7 + '@babel/types': 7.20.7 dev: true /@babel/helper-hoist-variables/7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.5 + '@babel/types': 7.20.7 dev: true /@babel/helper-module-imports/7.18.6: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.5 + '@babel/types': 7.20.7 - /@babel/helper-module-transforms/7.20.2: - resolution: {integrity: sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==} + /@babel/helper-module-transforms/7.20.11: + resolution: {integrity: sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-environment-visitor': 7.18.9 @@ -184,9 +185,9 @@ packages: '@babel/helper-simple-access': 7.20.2 '@babel/helper-split-export-declaration': 7.18.6 '@babel/helper-validator-identifier': 7.19.1 - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.5 - '@babel/types': 7.20.5 + '@babel/template': 7.20.7 + '@babel/traverse': 7.20.10 + '@babel/types': 7.20.7 transitivePeerDependencies: - supports-color dev: true @@ -199,14 +200,14 @@ packages: resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.5 + '@babel/types': 7.20.7 dev: true /@babel/helper-split-export-declaration/7.18.6: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.5 + '@babel/types': 7.20.7 dev: true /@babel/helper-string-parser/7.19.4: @@ -222,13 +223,13 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/helpers/7.20.6: - resolution: {integrity: sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==} + /@babel/helpers/7.20.7: + resolution: {integrity: sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.5 - '@babel/types': 7.20.5 + '@babel/template': 7.20.7 + '@babel/traverse': 7.20.10 + '@babel/types': 7.20.7 transitivePeerDependencies: - supports-color dev: true @@ -241,12 +242,12 @@ packages: chalk: 2.4.2 js-tokens: 4.0.0 - /@babel/parser/7.20.5: - resolution: {integrity: sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==} + /@babel/parser/7.20.7: + resolution: {integrity: sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.20.5 + '@babel/types': 7.20.7 dev: true /@babel/plugin-syntax-jsx/7.18.6: @@ -257,48 +258,48 @@ packages: dependencies: '@babel/helper-plugin-utils': 7.20.2 - /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.20.5: + /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.20.7: resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.20.7 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.20.5: + /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.20.7: resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 - '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.5 + '@babel/core': 7.20.7 + '@babel/plugin-transform-react-jsx': 7.20.7_@babel+core@7.20.7 dev: true - /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.20.5: + /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.20.7: resolution: {integrity: sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.20.7 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-react-jsx-source/7.19.6_@babel+core@7.20.5: + /@babel/plugin-transform-react-jsx-source/7.19.6_@babel+core@7.20.7: resolution: {integrity: sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.20.7 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-react-jsx/7.19.0: - resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==} + /@babel/plugin-transform-react-jsx/7.20.7: + resolution: {integrity: sha512-Tfq7qqD+tRj3EoDhY00nn2uP2hsRxgYGi5mLQ5TimKav0a9Lrpd4deE+fcLXU8zFYRjlKPHZhpCvfEA6qnBxqQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -307,66 +308,66 @@ packages: '@babel/helper-module-imports': 7.18.6 '@babel/helper-plugin-utils': 7.20.2 '@babel/plugin-syntax-jsx': 7.18.6 - '@babel/types': 7.20.5 + '@babel/types': 7.20.7 dev: true - /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.20.5: - resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==} + /@babel/plugin-transform-react-jsx/7.20.7_@babel+core@7.20.7: + resolution: {integrity: sha512-Tfq7qqD+tRj3EoDhY00nn2uP2hsRxgYGi5mLQ5TimKav0a9Lrpd4deE+fcLXU8zFYRjlKPHZhpCvfEA6qnBxqQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.5 + '@babel/core': 7.20.7 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-module-imports': 7.18.6 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.20.5 - '@babel/types': 7.20.5 + '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.20.7 + '@babel/types': 7.20.7 dev: true - /@babel/runtime-corejs3/7.20.6: - resolution: {integrity: sha512-tqeujPiuEfcH067mx+7otTQWROVMKHXEaOQcAeNV5dDdbPWvPcFA8/W9LXw2NfjNmOetqLl03dfnG2WALPlsRQ==} + /@babel/runtime-corejs3/7.20.7: + resolution: {integrity: sha512-jr9lCZ4RbRQmCR28Q8U8Fu49zvFqLxTY9AMOUz+iyMohMoAgpEcVxY+wJNay99oXOpOcCTODkk70NDN2aaJEeg==} engines: {node: '>=6.9.0'} dependencies: - core-js-pure: 3.26.1 + core-js-pure: 3.27.1 regenerator-runtime: 0.13.11 dev: true - /@babel/runtime/7.20.6: - resolution: {integrity: sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==} + /@babel/runtime/7.20.7: + resolution: {integrity: sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.13.11 - /@babel/template/7.18.10: - resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} + /@babel/template/7.20.7: + resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/parser': 7.20.5 - '@babel/types': 7.20.5 + '@babel/parser': 7.20.7 + '@babel/types': 7.20.7 dev: true - /@babel/traverse/7.20.5: - resolution: {integrity: sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==} + /@babel/traverse/7.20.10: + resolution: {integrity: sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 - '@babel/generator': 7.20.5 + '@babel/generator': 7.20.7 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.19.0 '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.20.5 - '@babel/types': 7.20.5 + '@babel/parser': 7.20.7 + '@babel/types': 7.20.7 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: - supports-color dev: true - /@babel/types/7.20.5: - resolution: {integrity: sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==} + /@babel/types/7.20.7: + resolution: {integrity: sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-string-parser': 7.19.4 @@ -388,7 +389,7 @@ packages: dependencies: '@babel/helper-module-imports': 7.18.6 '@babel/plugin-syntax-jsx': 7.18.6 - '@babel/runtime': 7.20.6 + '@babel/runtime': 7.20.7 '@emotion/hash': 0.9.0 '@emotion/memoize': 0.8.0 '@emotion/serialize': 1.1.1 @@ -434,7 +435,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.20.6 + '@babel/runtime': 7.20.7 '@emotion/babel-plugin': 11.10.5 '@emotion/cache': 11.10.5 '@emotion/serialize': 1.1.1 @@ -472,7 +473,7 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.20.6 + '@babel/runtime': 7.20.7 '@emotion/babel-plugin': 11.10.5 '@emotion/is-prop-valid': 1.2.0 '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 @@ -598,8 +599,8 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true - /@mui/base/5.0.0-alpha.111_ib3m5ricvtkl2cll7qpr2f6lvq: - resolution: {integrity: sha512-2wfIPpl97S4dPzD0QOM3UIzQ/EuXCYQvHmXxTpfKxev/cfkzOe7Ik/McoYUBbtM1bSOqH3W276R/L2LF9cyXqQ==} + /@mui/base/5.0.0-alpha.112_ib3m5ricvtkl2cll7qpr2f6lvq: + resolution: {integrity: sha512-KPwb1iYPXsV/P8uu0SNQrj7v7YU6wdN4Eccc2lZQyRDW+f6PJYjHBuFUTYKc408B98Jvs1XbC/z5MN45a2DWrQ==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -609,10 +610,10 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.20.6 + '@babel/runtime': 7.20.7 '@emotion/is-prop-valid': 1.2.0 '@mui/types': 7.2.3_@types+react@18.0.26 - '@mui/utils': 5.11.1_react@18.2.0 + '@mui/utils': 5.11.2_react@18.2.0 '@popperjs/core': 2.11.6 '@types/react': 18.0.26 clsx: 1.2.1 @@ -622,12 +623,12 @@ packages: react-is: 18.2.0 dev: false - /@mui/core-downloads-tracker/5.11.1: - resolution: {integrity: sha512-QVqVNlZ2K+LqUDE5kFgYd0r4KekR/dv2cNYbAutQWbfOA8VPVUVrDz0ELrEcoe8TjM/CwnsmGvaDh/YSNl/ALA==} + /@mui/core-downloads-tracker/5.11.2: + resolution: {integrity: sha512-ztLQELdSSuJFXezng8g5eCzy8mogtzMM8JcfG3HIGgUJ2RlAiBXI2Qe0adKmrJlF4FMat8vTaTeoiRNBZH4t1Q==} dev: false - /@mui/material/5.11.1_lskpmcsdi7ipu6qpuapyu56ihm: - resolution: {integrity: sha512-yaZiXvcrl2vgUK+VO24780BWRgwdAMmAyuMVZnRTts1Yu0tWd6PjIYq2ZtaOlpj6/LbaSS+Q2kSfxYnDQ20CEQ==} + /@mui/material/5.11.2_lskpmcsdi7ipu6qpuapyu56ihm: + resolution: {integrity: sha512-PeraRDsghnDLzejorfe9ps1syxlB8UrGs+UKwg9GGlndv5Tghm+9nwuibrP2TCDC14mlryF+u2WlAOYaPPMwGA==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -643,14 +644,14 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.20.6 + '@babel/runtime': 7.20.7 '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 '@emotion/styled': 11.10.5_qvatmowesywn4ye42qoh247szu - '@mui/base': 5.0.0-alpha.111_ib3m5ricvtkl2cll7qpr2f6lvq - '@mui/core-downloads-tracker': 5.11.1 - '@mui/system': 5.11.1_ogriz7mfahdh34qnfautfro5yu + '@mui/base': 5.0.0-alpha.112_ib3m5ricvtkl2cll7qpr2f6lvq + '@mui/core-downloads-tracker': 5.11.2 + '@mui/system': 5.11.2_ogriz7mfahdh34qnfautfro5yu '@mui/types': 7.2.3_@types+react@18.0.26 - '@mui/utils': 5.11.1_react@18.2.0 + '@mui/utils': 5.11.2_react@18.2.0 '@types/react': 18.0.26 '@types/react-transition-group': 4.4.5 clsx: 1.2.1 @@ -662,8 +663,8 @@ packages: react-transition-group: 4.4.5_biqbaboplfbrettd7655fr4n2y dev: false - /@mui/private-theming/5.11.1_kzbn2opkn2327fwg5yzwzya5o4: - resolution: {integrity: sha512-nnHg7kA5RwFRhy0wiDYe59sLCVGORpPypL1JcEdhv0+N0Zbmc2E/y4z2zqMRZ62MAEscpro7cQbvv244ThA84A==} + /@mui/private-theming/5.11.2_kzbn2opkn2327fwg5yzwzya5o4: + resolution: {integrity: sha512-qZwMaqRFPwlYmqwVKblKBGKtIjJRAj3nsvX93pOmatsXyorW7N/0IPE/swPgz1VwChXhHO75DwBEx8tB+aRMNg==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -672,8 +673,8 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.20.6 - '@mui/utils': 5.11.1_react@18.2.0 + '@babel/runtime': 7.20.7 + '@mui/utils': 5.11.2_react@18.2.0 '@types/react': 18.0.26 prop-types: 15.8.1 react: 18.2.0 @@ -692,7 +693,7 @@ packages: '@emotion/styled': optional: true dependencies: - '@babel/runtime': 7.20.6 + '@babel/runtime': 7.20.7 '@emotion/cache': 11.10.5 '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 '@emotion/styled': 11.10.5_qvatmowesywn4ye42qoh247szu @@ -701,8 +702,8 @@ packages: react: 18.2.0 dev: false - /@mui/system/5.11.1_ogriz7mfahdh34qnfautfro5yu: - resolution: {integrity: sha512-BEA2S0hay8n8CcZftkeAVsi0nsb5ZjdnZRCahv5lX7QJYwDjO4ucJ6lnvxHe2v/9Te1LLjTO7ojxu/qM6CE5Cg==} + /@mui/system/5.11.2_ogriz7mfahdh34qnfautfro5yu: + resolution: {integrity: sha512-PPkYhrcP2MkhscX6SauIl0wPgra0w1LGPtll+hIKc2Z2JbGRSrUCFif93kxejB7I1cAoCay9jWW4mnNhsOqF/g==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -717,13 +718,13 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.20.6 + '@babel/runtime': 7.20.7 '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 '@emotion/styled': 11.10.5_qvatmowesywn4ye42qoh247szu - '@mui/private-theming': 5.11.1_kzbn2opkn2327fwg5yzwzya5o4 + '@mui/private-theming': 5.11.2_kzbn2opkn2327fwg5yzwzya5o4 '@mui/styled-engine': 5.11.0_dovxhg2tvkkxkdnqyoum6wzcxm '@mui/types': 7.2.3_@types+react@18.0.26 - '@mui/utils': 5.11.1_react@18.2.0 + '@mui/utils': 5.11.2_react@18.2.0 '@types/react': 18.0.26 clsx: 1.2.1 csstype: 3.1.1 @@ -742,13 +743,13 @@ packages: '@types/react': 18.0.26 dev: false - /@mui/utils/5.11.1_react@18.2.0: - resolution: {integrity: sha512-lMAPgIJoil8V9ZxsMbEflMsvZmWcHbRVMc4JDY9jPO9V4welpF43h/O267b1RqlcRnC5MEbVQV605GYkTZY29Q==} + /@mui/utils/5.11.2_react@18.2.0: + resolution: {integrity: sha512-AyizuHHlGdAtH5hOOXBW3kriuIwUIKUIgg0P7LzMvzf6jPhoQbENYqY6zJqfoZ7fAWMNNYT8mgN5EftNGzwE2w==} engines: {node: '>=12.0.0'} peerDependencies: react: ^17.0.0 || ^18.0.0 dependencies: - '@babel/runtime': 7.20.6 + '@babel/runtime': 7.20.7 '@types/prop-types': 15.7.5 '@types/react-is': 17.0.3 prop-types: 15.8.1 @@ -774,7 +775,7 @@ packages: engines: {node: '>= 8'} dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.14.0 + fastq: 1.15.0 dev: true /@popperjs/core/2.11.6: @@ -887,8 +888,8 @@ packages: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true - /@types/node/18.11.16: - resolution: {integrity: sha512-6T7P5bDkRhqRxrQtwj7vru+bWTpelgtcETAZEUSdq0YISKz8WKdoBukQLYQQ6DFHvU9JRsbFq0JH5C51X2ZdnA==} + /@types/node/18.11.18: + resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==} dev: true /@types/parse-json/4.0.0: @@ -903,8 +904,8 @@ packages: ts-toolbelt: 6.15.5 dev: true - /@types/react-dom/18.0.9: - resolution: {integrity: sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==} + /@types/react-dom/18.0.10: + resolution: {integrity: sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==} dependencies: '@types/react': 18.0.26 dev: true @@ -937,14 +938,14 @@ packages: peerDependencies: vite: ^3.0.0 dependencies: - '@babel/core': 7.20.5 - '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.20.5 - '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.20.5 - '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.20.5 - '@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.20.5 + '@babel/core': 7.20.7 + '@babel/plugin-transform-react-jsx': 7.20.7_@babel+core@7.20.7 + '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.20.7 + '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.20.7 + '@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.20.7 magic-string: 0.26.7 react-refresh: 0.14.0 - vite: 3.2.5_@types+node@18.11.16 + vite: 3.2.5_@types+node@18.11.18 transitivePeerDependencies: - supports-color dev: true @@ -997,8 +998,8 @@ packages: resolution: {integrity: sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==} engines: {node: '>=6.0'} dependencies: - '@babel/runtime': 7.20.6 - '@babel/runtime-corejs3': 7.20.6 + '@babel/runtime': 7.20.7 + '@babel/runtime-corejs3': 7.20.7 dev: true /array-includes/3.1.6: @@ -1034,7 +1035,7 @@ packages: postcss: ^8.1.0 dependencies: browserslist: 4.21.4 - caniuse-lite: 1.0.30001439 + caniuse-lite: 1.0.30001441 fraction.js: 4.2.0 normalize-range: 0.1.2 picocolors: 1.0.0 @@ -1055,7 +1056,7 @@ packages: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} dependencies: - '@babel/runtime': 7.20.6 + '@babel/runtime': 7.20.7 cosmiconfig: 7.1.0 resolve: 1.22.1 @@ -1087,7 +1088,7 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001439 + caniuse-lite: 1.0.30001441 electron-to-chromium: 1.4.284 node-releases: 2.0.8 update-browserslist-db: 1.0.10_browserslist@4.21.4 @@ -1109,8 +1110,8 @@ packages: engines: {node: '>= 6'} dev: true - /caniuse-lite/1.0.30001439: - resolution: {integrity: sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==} + /caniuse-lite/1.0.30001441: + resolution: {integrity: sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==} dev: true /chalk/2.4.2: @@ -1175,8 +1176,8 @@ packages: /convert-source-map/1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - /core-js-pure/3.26.1: - resolution: {integrity: sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==} + /core-js-pure/3.27.1: + resolution: {integrity: sha512-BS2NHgwwUppfeoqOXqi08mUqS5FiZpuRuJJpKsaME7kJz0xxuk0xkhDdfMIlP/zLa80krBqss1LtD7f889heAw==} requiresBuild: true dev: true @@ -1277,7 +1278,7 @@ packages: /dom-helpers/5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} dependencies: - '@babel/runtime': 7.20.6 + '@babel/runtime': 7.20.7 csstype: 3.1.1 dev: false @@ -1642,7 +1643,7 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 dependencies: - '@babel/runtime': 7.20.6 + '@babel/runtime': 7.20.7 aria-query: 4.2.2 array-includes: 3.1.6 ast-types-flow: 0.0.7 @@ -1699,8 +1700,8 @@ packages: micromatch: 4.0.5 dev: true - /fastq/1.14.0: - resolution: {integrity: sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==} + /fastq/1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: reusify: 1.0.4 dev: true @@ -1966,15 +1967,15 @@ packages: /json-parse-even-better-errors/2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - /json5/1.0.1: - resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} + /json5/1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true dependencies: minimist: 1.2.7 dev: true - /json5/2.2.2: - resolution: {integrity: sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==} + /json5/2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true dev: true @@ -2020,6 +2021,12 @@ packages: js-tokens: 4.0.0 dev: false + /lru-cache/5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + /magic-string/0.26.7: resolution: {integrity: sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==} engines: {node: '>=12'} @@ -2298,7 +2305,7 @@ packages: react: '>=16.6.0' react-dom: '>=16.6.0' dependencies: - '@babel/runtime': 7.20.6 + '@babel/runtime': 7.20.7 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 @@ -2506,7 +2513,7 @@ packages: resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} dependencies: '@types/json5': 0.0.29 - json5: 1.0.1 + json5: 1.0.2 minimist: 1.2.7 strip-bom: 3.0.0 dev: true @@ -2517,7 +2524,7 @@ packages: peerDependencies: tailwindcss: ^3.2.4 dependencies: - '@babel/template': 7.18.10 + '@babel/template': 7.20.7 babel-plugin-macros: 3.1.0 chalk: 4.1.2 lodash.get: 4.4.2 @@ -2556,7 +2563,7 @@ packages: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true - /vite/3.2.5_@types+node@18.11.16: + /vite/3.2.5_@types+node@18.11.18: resolution: {integrity: sha512-4mVEpXpSOgrssFZAOmGIr85wPHKvaDAcXqxVxVRZhljkJOMZi1ibLibzjLHzJvcok8BMguLc7g1W6W/GqZbLdQ==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -2581,7 +2588,7 @@ packages: terser: optional: true dependencies: - '@types/node': 18.11.16 + '@types/node': 18.11.18 esbuild: 0.15.18 postcss: 8.4.20 resolve: 1.22.1 @@ -2605,6 +2612,10 @@ packages: engines: {node: '>=0.4'} dev: true + /yallist/3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + /yaml/1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index fa48eb6..b5e2dbf 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -8,17 +8,11 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "adler32" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" - [[package]] name = "aho-corasick" -version = "0.7.19" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] @@ -40,9 +34,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.66" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" [[package]] name = "atk" @@ -96,6 +90,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + [[package]] name = "bitflags" version = "1.3.2" @@ -176,9 +176,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" [[package]] name = "cairo-rs" @@ -206,9 +206,9 @@ dependencies = [ [[package]] name = "cargo_toml" -version = "0.13.0" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa0e3586af56b3bfa51fca452bd56e8dbbbd5d8d81cbf0b7e4e35b695b537eb8" +checksum = "497049e9477329f8f6a559972ee42e117487d01d1e8c2cc9f836ea6fa23a9e1a" dependencies = [ "serde", "toml", @@ -216,9 +216,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.76" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" dependencies = [ "jobserver", ] @@ -398,14 +398,44 @@ dependencies = [ ] [[package]] -name = "crossbeam-utils" -version = "0.8.12" +name = "crossbeam-deque" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "crossbeam-utils", + "memoffset 0.7.1", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -505,16 +535,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "deflate" -version = "0.7.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" -dependencies = [ - "adler32", - "byteorder", -] - [[package]] name = "derive_more" version = "0.99.17" @@ -530,9 +550,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer", "crypto-common", @@ -576,6 +596,7 @@ dependencies = [ "either", "futures", "hex", + "image", "once_cell", "paris", "rumqttc", @@ -634,6 +655,21 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "exr" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eb5f255b5980bb0c8cf676b675d1a99be40f316881444f44e0462eaf5df5ded" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "smallvec", + "threadpool", +] + [[package]] name = "fastrand" version = "1.8.0" @@ -649,15 +685,15 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" dependencies = [ - "memoffset", + "memoffset 0.6.5", "rustc_version 0.3.3", ] [[package]] name = "filetime" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b9663d381d07ae25dc88dbdf27df458faa83a9b25336bcac83d5e452b5fc9d3" +checksum = "4e884668cd0c7480504233e951174ddc3b382f7c2666e3b7310b5c4e7b0c37f9" dependencies = [ "cfg-if 1.0.0", "libc", @@ -667,12 +703,12 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ "crc32fast", - "miniz_oxide 0.5.4", + "miniz_oxide", ] [[package]] @@ -900,15 +936,15 @@ dependencies = [ [[package]] name = "generator" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc184cace1cea8335047a471cc1da80f18acf8a76f3bab2028d499e328948ec7" +checksum = "d266041a359dfa931b370ef684cceb84b166beb14f7f0421f4a6a3d0c446d12e" dependencies = [ "cc", "libc", "log", "rustversion", - "windows 0.32.0", + "windows 0.39.0", ] [[package]] @@ -945,6 +981,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gif" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gio" version = "0.15.12" @@ -1105,6 +1151,15 @@ dependencies = [ "syn", ] +[[package]] +name = "half" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c467d36af040b7b2681f5fddd27427f6da8d3d072f575a265e181d2f8e8d157" +dependencies = [ + "crunchy", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1128,9 +1183,9 @@ checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" dependencies = [ "libc", ] @@ -1163,7 +1218,7 @@ checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", - "itoa 1.0.4", + "itoa 1.0.5", ] [[package]] @@ -1174,12 +1229,12 @@ checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" [[package]] name = "ico" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a4b3331534254a9b64095ae60d3dc2a8225a7a70229cd5888be127cdc1f6804" +checksum = "031530fe562d8c8d71c0635013d6d155bbfe8ba0aa4b4d2d24ce8af6b71047bd" dependencies = [ "byteorder", - "png 0.11.0", + "png", ] [[package]] @@ -1225,15 +1280,21 @@ dependencies = [ "bytemuck", "byteorder", "color_quant", + "exr", + "gif", + "jpeg-decoder", "num-rational", "num-traits", + "png", + "scoped_threadpool", + "tiff", ] [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", "hashbrown", @@ -1248,15 +1309,6 @@ dependencies = [ "cfb", ] -[[package]] -name = "inflate" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5f9f47468e9a76a6452271efadc88fe865a82be91fe75e6c0c57b87ccea59d4" -dependencies = [ - "adler32", -] - [[package]] name = "instant" version = "0.1.12" @@ -1274,9 +1326,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "javascriptcore-rs" @@ -1330,6 +1382,15 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" +dependencies = [ + "rayon", +] + [[package]] name = "js-sys" version = "0.3.60" @@ -1341,9 +1402,9 @@ dependencies = [ [[package]] name = "json-patch" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f995a3c8f2bc3dd52a18a583e90f9ec109c047fa1603a853e46bcda14d2e279d" +checksum = "eb3fa5a61630976fc4c353c70297f2e93f1930e3ccee574d59d618ccbd5154ce" dependencies = [ "serde", "serde_json", @@ -1369,10 +1430,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] -name = "libc" -version = "0.2.137" +name = "lebe" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + +[[package]] +name = "libc" +version = "0.2.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "libdbus-sys" @@ -1508,12 +1575,12 @@ dependencies = [ ] [[package]] -name = "miniz_oxide" -version = "0.5.4" +name = "memoffset" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ - "adler", + "autocfg", ] [[package]] @@ -1606,9 +1673,9 @@ checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] name = "notify-rust" -version = "4.5.10" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368e89ea58df747ce88be669ae44e79783c1d30bfd540ad0fc520b3f41f0b3b0" +checksum = "5cc2e370356160e41aba3fd0fbac26d86a89ddd2ac4300c03de999a77cfa2509" dependencies = [ "dbus", "mac-notification-sys", @@ -1635,17 +1702,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-iter" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-rational" version = "0.4.1" @@ -1668,9 +1724,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ "hermit-abi", "libc", @@ -1738,25 +1794,25 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "open" -version = "3.0.3" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4a3100141f1733ea40b53381b0ae3117330735ef22309a190ac57b9576ea716" +checksum = "2078c0039e6a54a0c42c28faa984e115fb4c2d5bf2208f77d1961002df8576f8" dependencies = [ "pathdiff", - "windows-sys 0.36.1", + "windows-sys 0.42.0", ] [[package]] name = "openssl" -version = "0.10.42" +version = "0.10.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" +checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -1786,9 +1842,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.77" +version = "0.9.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03b84c3b2d099b81f0953422b4d4ad58761589d0229b5506356afca05a3670a" +checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7" dependencies = [ "autocfg", "cc", @@ -1810,12 +1866,12 @@ dependencies = [ [[package]] name = "os_pipe" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dceb7e43f59c35ee1548045b2c72945a5a3bb6ce6d6f07cdc13dc8f6bc4930a" +checksum = "c6a252f1f8c11e84b3ab59d7a488e48e4478a93937e027076638c49536204639" dependencies = [ "libc", - "winapi 0.3.9", + "windows-sys 0.42.0", ] [[package]] @@ -1867,9 +1923,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" dependencies = [ "cfg-if 1.0.0", "libc", @@ -1880,9 +1936,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" +checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" [[package]] name = "pathdiff" @@ -1898,9 +1954,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.4.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a528564cc62c19a7acac4d81e01f39e53e25e17b934878f4c6d25cc2836e62f8" +checksum = "0f6e86fb9e7026527a0d46bc308b841d73170ef8f443e1807f6ef88526a816d4" dependencies = [ "thiserror", "ucd-trie", @@ -2056,18 +2112,6 @@ dependencies = [ "xml-rs", ] -[[package]] -name = "png" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925" -dependencies = [ - "bitflags", - "deflate", - "inflate", - "num-iter", -] - [[package]] name = "png" version = "0.17.7" @@ -2077,7 +2121,7 @@ dependencies = [ "bitflags", "crc32fast", "flate2", - "miniz_oxide 0.6.2", + "miniz_oxide", ] [[package]] @@ -2135,15 +2179,15 @@ dependencies = [ [[package]] name = "proc-macro-hack" -version = "0.5.19" +version = "0.5.20+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" dependencies = [ "unicode-ident", ] @@ -2159,9 +2203,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] @@ -2256,6 +2300,28 @@ dependencies = [ "cty", ] +[[package]] +name = "rayon" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -2384,7 +2450,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.14", + "semver 1.0.16", ] [[package]] @@ -2431,15 +2497,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" [[package]] name = "safemem" @@ -2472,6 +2538,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + [[package]] name = "scopeguard" version = "1.1.0" @@ -2554,9 +2626,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" dependencies = [ "serde", ] @@ -2572,18 +2644,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.147" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ "proc-macro2", "quote", @@ -2592,20 +2664,20 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.87" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" dependencies = [ - "itoa 1.0.4", + "itoa 1.0.5", "ryu", "serde", ] [[package]] name = "serde_repr" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca" +checksum = "9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e" dependencies = [ "proc-macro2", "quote", @@ -2619,7 +2691,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 1.0.4", + "itoa 1.0.5", "ryu", "serde", ] @@ -2861,9 +2933,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.103" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", @@ -2898,9 +2970,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.15.3" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42c460173627564bde252ca5ebf346ba5b37c5cee1a445782bacc8e9b8d38b5e" +checksum = "ac8e6399427c8494f9849b58694754d7cc741293348a6836b6c8d2c5aa82d8e6" dependencies = [ "bitflags", "cairo-rs", @@ -2931,12 +3003,12 @@ dependencies = [ "once_cell", "parking_lot", "paste", - "png 0.17.7", + "png", "raw-window-handle", "scopeguard", "serde", "unicode-segmentation", - "uuid 1.2.1", + "uuid 1.2.2", "windows 0.39.0", "windows-implement", "x11-dl", @@ -2955,9 +3027,9 @@ dependencies = [ [[package]] name = "tauri" -version = "1.2.0" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac135e45c2923bd91edbb95a0d656f8d025389697e34d6d79166952bfa79c61c" +checksum = "5b48820ee3bb6a5031a83b2b6e11f8630bdc5a2f68cb841ab8ebc7a15a916679" dependencies = [ "anyhow", "attohttpc", @@ -2984,7 +3056,7 @@ dependencies = [ "raw-window-handle", "regex", "rfd", - "semver 1.0.14", + "semver 1.0.16", "serde", "serde_json", "serde_repr", @@ -3000,7 +3072,7 @@ dependencies = [ "thiserror", "tokio", "url", - "uuid 1.2.1", + "uuid 1.2.2", "webkit2gtk", "webview2-com", "windows 0.39.0", @@ -3008,15 +3080,15 @@ dependencies = [ [[package]] name = "tauri-build" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef796f49abc98e6de0abe1b655120addc9d82363d8fc2304e71a4177c25e783c" +checksum = "8807c85d656b2b93927c19fe5a5f1f1f348f96c2de8b90763b3c2d561511f9b4" dependencies = [ "anyhow", "cargo_toml", "heck 0.4.0", "json-patch", - "semver 1.0.14", + "semver 1.0.16", "serde_json", "tauri-utils", "winres", @@ -3024,35 +3096,35 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afcb77cf7bfe3d8f886e73a7fa6157587d015c599671180b76595c1aef175ba8" +checksum = "14388d484b6b1b5dc0f6a7d6cc6433b3b230bec85eaa576adcdf3f9fafa49251" dependencies = [ "base64", "brotli", "ico", "json-patch", "plist", - "png 0.17.7", + "png", "proc-macro2", "quote", "regex", - "semver 1.0.14", + "semver 1.0.16", "serde", "serde_json", "sha2", "tauri-utils", "thiserror", "time", - "uuid 1.2.1", + "uuid 1.2.2", "walkdir", ] [[package]] name = "tauri-macros" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f24f481b0b2acfc288ac78755f00ebea53992c7365a165af64cb5ae00806edea" +checksum = "069319e5ecbe653a799b94b0690d9f9bf5d00f7b1d3989aa331c524d4e354075" dependencies = [ "heck 0.4.0", "proc-macro2", @@ -3064,9 +3136,9 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc5d54c476defa5436e70e0d0a06e3cb0f49b6f863895995d5e3769411769cf" +checksum = "c507d954d08ac8705d235bc70ec6975b9054fb95ff7823af72dbb04186596f3b" dependencies = [ "gtk", "http", @@ -3077,16 +3149,16 @@ dependencies = [ "serde_json", "tauri-utils", "thiserror", - "uuid 1.2.1", + "uuid 1.2.2", "webview2-com", "windows 0.39.0", ] [[package]] name = "tauri-runtime-wry" -version = "0.12.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78c55091701426c2519c7e9f1dc2dd33e533af4e75eae89cedc6995409351a2" +checksum = "36b1c5764a41a13176a4599b5b7bd0881bea7d94dfe45e1e755f789b98317e30" dependencies = [ "cocoa", "gtk", @@ -3095,7 +3167,7 @@ dependencies = [ "raw-window-handle", "tauri-runtime", "tauri-utils", - "uuid 1.2.1", + "uuid 1.2.2", "webkit2gtk", "webview2-com", "windows 0.39.0", @@ -3104,9 +3176,9 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d64c9a09ba1538b8e67ae8c78c10904f36ce38d364bf7f089ec807032a826b02" +checksum = "5abbc109a6eb45127956ffcc26ef0e875d160150ac16cfa45d26a6b2871686f1" dependencies = [ "brotli", "ctor", @@ -3120,7 +3192,7 @@ dependencies = [ "phf 0.10.1", "proc-macro2", "quote", - "semver 1.0.14", + "semver 1.0.16", "serde", "serde_json", "serde_with", @@ -3183,18 +3255,18 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", @@ -3210,13 +3282,33 @@ dependencies = [ "once_cell", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "tiff" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "time" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" dependencies = [ - "itoa 1.0.4", + "itoa 1.0.5", "serde", "time-core", "time-macros", @@ -3254,9 +3346,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.22.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" +checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" dependencies = [ "autocfg", "bytes", @@ -3269,14 +3361,14 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "winapi 0.3.9", + "windows-sys 0.42.0", ] [[package]] name = "tokio-macros" -version = "1.8.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" dependencies = [ "proc-macro2", "quote", @@ -3296,9 +3388,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" dependencies = [ "serde", ] @@ -3376,9 +3468,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-trie" @@ -3394,9 +3486,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "unicode-normalization" @@ -3445,9 +3537,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb41e78f93363bb2df8b0e86a2ca30eed7806ea16ea0c790d757cf93f79be83" +checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" dependencies = [ "getrandom 0.2.8", ] @@ -3686,6 +3778,12 @@ dependencies = [ "windows-metadata", ] +[[package]] +name = "weezl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" + [[package]] name = "winapi" version = "0.2.8" @@ -3723,19 +3821,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbedf6db9096bc2364adce0ae0aa636dcd89f3c3f2cd67947062aaf0ca2a10ec" -dependencies = [ - "windows_aarch64_msvc 0.32.0", - "windows_i686_gnu 0.32.0", - "windows_i686_msvc 0.32.0", - "windows_x86_64_gnu 0.32.0", - "windows_x86_64_msvc 0.32.0", -] - [[package]] name = "windows" version = "0.37.0" @@ -3829,12 +3914,6 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" -[[package]] -name = "windows_aarch64_msvc" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" - [[package]] name = "windows_aarch64_msvc" version = "0.36.1" @@ -3859,12 +3938,6 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" -[[package]] -name = "windows_i686_gnu" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" - [[package]] name = "windows_i686_gnu" version = "0.36.1" @@ -3889,12 +3962,6 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" -[[package]] -name = "windows_i686_msvc" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" - [[package]] name = "windows_i686_msvc" version = "0.36.1" @@ -3919,12 +3986,6 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" -[[package]] -name = "windows_x86_64_gnu" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" - [[package]] name = "windows_x86_64_gnu" version = "0.36.1" @@ -3955,12 +4016,6 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" -[[package]] -name = "windows_x86_64_msvc" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" - [[package]] name = "windows_x86_64_msvc" version = "0.36.1" @@ -3996,9 +4051,9 @@ dependencies = [ [[package]] name = "wry" -version = "0.22.0" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "923d297b203eae65b095af16c02978b7932be1968012b4da7138390edf34dea5" +checksum = "4c1ad8e2424f554cc5bdebe8aa374ef5b433feff817aebabca0389961fc7ef98" dependencies = [ "base64", "block", @@ -4034,9 +4089,9 @@ dependencies = [ [[package]] name = "x11" -version = "2.20.0" +version = "2.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7ae97874a928d821b061fce3d1fc52f08071dd53c89a6102bc06efcac3b2908" +checksum = "c2638d5b9c17ac40575fb54bb461a4b1d2a8d1b4ffcc4ff237d254ec59ddeb82" dependencies = [ "libc", "pkg-config", @@ -4044,9 +4099,9 @@ dependencies = [ [[package]] name = "x11-dl" -version = "2.20.0" +version = "2.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c83627bc137605acc00bb399c7b908ef460b621fc37c953db2b09f88c449ea6" +checksum = "b1536d6965a5d4e573c7ef73a2c15ebcd0b2de3347bdf526c34c297c00ac40f0" dependencies = [ "lazy_static", "libc", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 25ea562..ee9e59c 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -33,6 +33,7 @@ time = { version = "0.3.17", features = ["formatting"] } color_space = "0.5.3" futures = "0.3.25" either = "1.8.0" +image = "0.24.5" [features] # by default Tauri runs in production mode diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index e5f809b..c7ed0b1 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -46,7 +46,6 @@ async fn get_screenshot_by_config(config: DisplayConfig) -> Result { - info!("截图耗时 {} s", start.elapsed().as_seconds_f32()); Ok(screenshot_dto) } Err(error) => { diff --git a/src-tauri/src/picker/screenshot.rs b/src-tauri/src/picker/screenshot.rs index 4b1a4a9..0d336a5 100644 --- a/src-tauri/src/picker/screenshot.rs +++ b/src-tauri/src/picker/screenshot.rs @@ -1,13 +1,10 @@ +use image::ImageBuffer; +use image::{ImageOutputFormat, Rgb}; +use paris::error; +use serde::{Deserialize, Serialize}; use std::iter; -use color_space::{Hsv, Rgb}; -use either::Either; -use serde::{Deserialize, Serialize}; - -use super::{ - config::{DisplayConfig, LedStripConfig}, - led_color::LedColor, -}; +use super::{config::DisplayConfig, led_color::LedColor}; type Point = (usize, usize); type LedSamplePoints = Vec; @@ -233,24 +230,38 @@ impl Screenshot { pub async fn to_webp_base64(&self) -> String { let bitmap = &self.bitmap; - let mut bitflipped = - Vec::with_capacity(self.config.display_width * self.config.display_height * 3); let stride = bitmap.len() / self.config.display_height; - for y in 0..self.config.display_height { - for x in 0..self.config.display_width { - let i = stride * y + 4 * x; - bitflipped.extend_from_slice(&[bitmap[i + 2], bitmap[i + 1], bitmap[i]]); + let mut image_buffer = ImageBuffer::new( + self.config.display_width as u32 / 3, + self.config.display_height as u32 / 3, + ); + + for y in 0..self.config.display_height / 3 { + for x in 0..self.config.display_width / 3 { + let i = stride * y * 3 + 4 * x * 3; + image_buffer.put_pixel( + x as u32, + y as u32, + Rgb::([bitmap[i + 2], bitmap[i + 1], bitmap[i]]), + ); } } - let webp_memory = webp::Encoder::from_rgb( - bitflipped.as_slice(), - self.config.display_width as u32, - self.config.display_height as u32, - ) - .encode(100.0); - return base64::encode(&*webp_memory); + // let webp_memory = + // webp::Encoder::from_rgb(bitflipped.as_slice(), size_x, size_y).encode(50.0); + // return base64::encode(&*webp_memory); + + let mut cursor = std::io::Cursor::new(vec![]); + match image_buffer.write_to(&mut cursor, ImageOutputFormat::Tiff) { + Ok(_) => { + return base64::encode(cursor.into_inner()); + } + Err(err) => { + error!("can not encode image. {:?}", err); + return String::from(""); + } + } } pub async fn to_dto(&self) -> ScreenshotDto { diff --git a/src/configurator/components/display-with-led-strips.tsx b/src/configurator/components/display-with-led-strips.tsx index b3b2ab5..ed9f56e 100644 --- a/src/configurator/components/display-with-led-strips.tsx +++ b/src/configurator/components/display-with-led-strips.tsx @@ -31,7 +31,7 @@ export const DisplayWithLedStrips: FC = ({ ...htmlAttrs }) => { const screenshotUrl = useMemo( - () => `data:image/png;base64,${screenshot.encode_image}`, + () => `data:image/ico;base64,${screenshot.encode_image}`, [screenshot.encode_image], ); diff --git a/src/configurator/components/led-strip.tsx b/src/configurator/components/led-strip.tsx index be256cd..785d693 100644 --- a/src/configurator/components/led-strip.tsx +++ b/src/configurator/components/led-strip.tsx @@ -1,7 +1,7 @@ import { HTMLAttributes, useMemo } from 'react'; import { FC } from 'react'; import { LedStripConfig } from '../models/led-strip-config'; -import tw, { css, styled, theme } from 'twin.macro'; +import tw, { css, styled } from 'twin.macro'; import { splitEvery } from 'ramda'; export interface LedStripProps extends HTMLAttributes { From 5293ed52ffd8a3cbcdefabdaffc789f47225cbab Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Thu, 12 Jan 2023 13:44:54 +0800 Subject: [PATCH 07/19] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E5=AE=9E?= =?UTF-8?q?=E6=97=B6=E4=BF=9D=E5=AD=98=E9=85=8D=E7=BD=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/core/core.rs | 2 +- src-tauri/src/main.rs | 27 +++++++++++++----- src-tauri/src/picker/config/manger.rs | 31 +++++++++++--------- src-tauri/src/picker/manager.rs | 28 +++++++++++------- src-tauri/tauri.conf.json | 2 +- src/configurator/configurator.tsx | 41 ++++++++++++++++++++------- 6 files changed, 87 insertions(+), 44 deletions(-) diff --git a/src-tauri/src/core/core.rs b/src-tauri/src/core/core.rs index ef5c2d1..b33abcd 100644 --- a/src-tauri/src/core/core.rs +++ b/src-tauri/src/core/core.rs @@ -95,7 +95,7 @@ impl CoreManager { let mut futs = vec![]; if let AmbientLightMode::Follow = *lock { drop(lock); - let configs = Picker::global().display_configs.lock().await; + let configs = Picker::global().await.display_configs.lock().await; let (tx, mut rx) = mpsc::channel(10); diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index c7ed0b1..165aac2 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -18,7 +18,7 @@ use std::vec; #[tauri::command] async fn take_snapshot() -> Vec { - let manager = Picker::global(); + let manager = Picker::global().await; let start = time::Instant::now(); let base64_bitmap_list = match manager.list_displays().await { @@ -42,12 +42,10 @@ async fn get_screenshot_by_config(config: DisplayConfig) -> Result { - Ok(screenshot_dto) - } + Ok(screenshot_dto) => Ok(screenshot_dto), Err(error) => { error!("get_screenshot_by_config failed. {}", error); Err(format!("get_screenshot_by_config failed. {}", error)) @@ -56,11 +54,25 @@ async fn get_screenshot_by_config(config: DisplayConfig) -> Result picker::config::Configuration { - let configuration = picker::config::Manager::global().get_config(); +async fn get_picker_config() -> picker::config::Configuration { + let configuration = picker::config::Manager::global().get_config().await; info!("configuration: {:?}", configuration); configuration } +#[tauri::command] +async fn write_picker_config(config: picker::config::Configuration) -> Result<(), String> { + let manager = picker::config::Manager::global(); + let path = picker::config::Manager::get_config_file_path(); + info!("log save in {:?}", path.to_str()); + manager.set_config(&config).await; + match picker::config::Manager::write_config_to_disk(path, &config) { + Ok(_) => Ok(()), + Err(err) => { + error!("can not write picker config. {:?}", err); + Err(format!("can not write picker config. {:?}", err)) + } + } +} #[tauri::command] async fn play_mode(target_mode: AmbientLightMode) { @@ -78,6 +90,7 @@ async fn main() { play_mode, get_picker_config, get_screenshot_by_config, + write_picker_config, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/picker/config/manger.rs b/src-tauri/src/picker/config/manger.rs index d21b704..d8751da 100644 --- a/src-tauri/src/picker/config/manger.rs +++ b/src-tauri/src/picker/config/manger.rs @@ -2,12 +2,13 @@ use std::{ env::current_dir, fs::{self, File}, io::Read, - path::PathBuf, + path::PathBuf, sync::Arc, }; use once_cell::sync::OnceCell; +use paris::info; use serde::{Deserialize, Serialize}; -use tauri::api::path::config_dir; +use tauri::{api::path::config_dir, async_runtime::Mutex}; use super::DisplayConfig; @@ -26,9 +27,8 @@ impl Configuration { } } -#[derive(Serialize, Deserialize)] pub struct Manager { - config: Configuration, + config: Arc>, } impl Manager { @@ -43,7 +43,7 @@ impl Manager { } pub fn new(config: Configuration) -> Self { - Self { config } + Self { config: Arc::new(Mutex::new(config)) } } pub fn get_config_file_path() -> PathBuf { @@ -70,16 +70,21 @@ impl Manager { .map_err(|error| anyhow::anyhow!("can not parse config file contents. {}", error)) } - pub fn write_config_to_disk(&self, config_file_path: PathBuf) -> anyhow::Result<()> { - let contents = serde_json::to_string(&self.config) + pub fn write_config_to_disk(config_file_path: PathBuf, config: &Configuration) -> anyhow::Result<()> { + let contents = serde_json::to_string(config) .map_err(|error| anyhow::anyhow!("can not serialize config. {}", error))?; + info!("contents: {}", contents); fs::write(config_file_path, contents.as_bytes()) .map_err(|error| anyhow::anyhow!("can not write config file. {}", error))?; Ok(()) } - pub fn get_config(&self) -> Configuration { - self.config.clone() + pub async fn get_config(&self) -> Configuration { + self.config.lock().await.clone() + } + pub async fn set_config(&self, new_config: &Configuration) { + let mut config = self.config.lock().await; + *config = new_config.clone(); } } @@ -93,13 +98,13 @@ mod tests { use crate::picker::config::Configuration; - #[test] - fn write_config_to_disk_should_be_successful() { + #[tokio::test] + async fn write_config_to_disk_should_be_successful() { let temp = TestDir::temp().create("config_dir", test_dir::FileType::Dir); let config_file_path = temp.path("config_dir").join("picker.config.json"); let manager = crate::picker::config::manger::Manager::default(); - manager - .write_config_to_disk(config_file_path.clone()) + crate::picker::config::manger::Manager + ::write_config_to_disk(config_file_path.clone(), &Configuration::default()) .unwrap(); let contents = fs::read_to_string(config_file_path.clone()).unwrap(); diff --git a/src-tauri/src/picker/manager.rs b/src-tauri/src/picker/manager.rs index 0cfb114..75c9726 100644 --- a/src-tauri/src/picker/manager.rs +++ b/src-tauri/src/picker/manager.rs @@ -1,9 +1,11 @@ use futures::{stream::FuturesUnordered, StreamExt}; -use once_cell::sync::OnceCell; use paris::info; use scrap::Display; use std::sync::Arc; -use tokio::{sync::Mutex, task}; +use tokio::{ + sync::{Mutex, OnceCell}, + task, +}; use crate::picker::{config, screen::Screen}; @@ -20,16 +22,20 @@ pub struct Picker { } impl Picker { - pub fn global() -> &'static Picker { - static SCREEN_COLOR_PICKER: OnceCell = OnceCell::new(); + pub async fn global() -> &'static Picker { + static SCREEN_COLOR_PICKER: OnceCell = OnceCell::const_new(); - SCREEN_COLOR_PICKER.get_or_init(|| Picker { - screens: Arc::new(Mutex::new(vec![])), - screenshots: Arc::new(Mutex::new(vec![])), - display_configs: Arc::new(Mutex::new( - config::Manager::global().get_config().display_configs, - )), - }) + SCREEN_COLOR_PICKER + .get_or_init(|| async { + Picker { + screens: Arc::new(Mutex::new(vec![])), + screenshots: Arc::new(Mutex::new(vec![])), + display_configs: Arc::new(Mutex::new( + config::Manager::global().get_config().await.display_configs, + )), + } + }) + .await } pub async fn list_displays(&self) -> anyhow::Result> { diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index aaa7344..3e8cdea 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -28,7 +28,7 @@ "icons/icon.icns", "icons/icon.ico" ], - "identifier": "com.tauri.dev", + "identifier": "cc.ivanli.ambient", "longDescription": "", "macOS": { "entitlements": null, diff --git a/src/configurator/configurator.tsx b/src/configurator/configurator.tsx index ea51bd7..b6b361a 100644 --- a/src/configurator/configurator.tsx +++ b/src/configurator/configurator.tsx @@ -22,6 +22,11 @@ const getScreenshotByConfig = async (config: DisplayConfig) => { config, }); }; +const writePickerConfig = async (config: PickerConfiguration) => { + return await invoke('write_picker_config', { + config, + }); +}; export const Configurator: FC = () => { const { loading: pendingPickerConfig, result: savedPickerConfig } = useAsync( @@ -34,14 +39,25 @@ export const Configurator: FC = () => { const [screenshotOfDisplays, setScreenshotOfDisplays] = useState([]); - const { loading: pendingGetLedColorsByConfig, execute: onPickerChange } = + const { loading: pendingGetLedColorsByConfig, execute: onDisplayConfigChange } = useAsyncCallback(async (value: DisplayConfig) => { - console.log(value); + console.log('onDisplayConfigChange', value); const screenshot = await getScreenshotByConfig(value); setScreenshotOfDisplays((old) => { const index = old.findIndex((it) => it.config.id === screenshot.config.id); - console.log({ old, n: update(index, screenshot, old) }); - return update(index, screenshot, old); + const newValue = update(index, screenshot, old); + console.log({ old, n: newValue }); + savedPickerConfig && + writePickerConfig({ + ...savedPickerConfig, + display_configs: newValue.map((it) => it.config), + }).then(() => { + console.log('writing config is successful.', { + ...savedPickerConfig, + display_configs: newValue.map((it) => it.config), + }); + }); + return newValue; }); console.log('screenshot', screenshot); @@ -51,15 +67,18 @@ export const Configurator: FC = () => { useEffect(() => { const displayConfigs = savedPickerConfig?.display_configs; - if (displayConfigs) { + console.log('displayConfigs change', displayConfigs); + if (displayConfigs && defaultScreenshotOfDisplays) { setDisplayConfigs(displayConfigs); - } - }, [savedPickerConfig]); - useEffect(() => { - if (defaultScreenshotOfDisplays) { setScreenshotOfDisplays(defaultScreenshotOfDisplays); + (async () => { + for (const config of displayConfigs) { + await onDisplayConfigChange(config); + } + })().then(); } - }, [defaultScreenshotOfDisplays]); + }, [savedPickerConfig, onDisplayConfigChange, defaultScreenshotOfDisplays]); + useEffect(() => {}, [defaultScreenshotOfDisplays]); const displays = useMemo(() => { if (screenshotOfDisplays) { @@ -69,7 +88,7 @@ export const Configurator: FC = () => { key={index} config={screenshot.config} screenshot={screenshot} - onChange={(value) => onPickerChange(value)} + onChange={(value) => onDisplayConfigChange(value)} /> )); } From 56f65fed10ccee4d4a01611058a7ba45bb8754f7 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Sun, 15 Jan 2023 15:30:20 +0800 Subject: [PATCH 08/19] chore: remove console log. --- src/configurator/configurator.tsx | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/configurator/configurator.tsx b/src/configurator/configurator.tsx index b6b361a..8d61817 100644 --- a/src/configurator/configurator.tsx +++ b/src/configurator/configurator.tsx @@ -14,7 +14,6 @@ import { update } from 'ramda'; const getPickerConfig = () => invoke('get_picker_config'); const getScreenshotOfDisplays = () => invoke('take_snapshot').then((items) => { - console.log(items); return items; }); const getScreenshotByConfig = async (config: DisplayConfig) => { @@ -41,33 +40,23 @@ export const Configurator: FC = () => { const { loading: pendingGetLedColorsByConfig, execute: onDisplayConfigChange } = useAsyncCallback(async (value: DisplayConfig) => { - console.log('onDisplayConfigChange', value); const screenshot = await getScreenshotByConfig(value); setScreenshotOfDisplays((old) => { const index = old.findIndex((it) => it.config.id === screenshot.config.id); const newValue = update(index, screenshot, old); - console.log({ old, n: newValue }); savedPickerConfig && writePickerConfig({ ...savedPickerConfig, display_configs: newValue.map((it) => it.config), - }).then(() => { - console.log('writing config is successful.', { - ...savedPickerConfig, - display_configs: newValue.map((it) => it.config), - }); }); return newValue; }); - - console.log('screenshot', screenshot); }); const [displayConfigs, setDisplayConfigs] = useState([]); useEffect(() => { const displayConfigs = savedPickerConfig?.display_configs; - console.log('displayConfigs change', displayConfigs); if (displayConfigs && defaultScreenshotOfDisplays) { setDisplayConfigs(displayConfigs); setScreenshotOfDisplays(defaultScreenshotOfDisplays); @@ -82,7 +71,6 @@ export const Configurator: FC = () => { const displays = useMemo(() => { if (screenshotOfDisplays) { - console.log({ c: screenshotOfDisplays }); return screenshotOfDisplays.map((screenshot, index) => ( Date: Sun, 15 Jan 2023 18:38:25 +0800 Subject: [PATCH 09/19] =?UTF-8?q?feat:=20=E9=85=8D=E7=BD=AE=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E8=B0=83=E6=95=B4=E5=92=8C=E5=88=9D=E6=AD=A5=E7=81=AF?= =?UTF-8?q?=E6=9D=A1=E9=85=8D=E7=BD=AE=E7=95=8C=E9=9D=A2=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 14 +- pnpm-lock.yaml | 490 ++++++++++++------ src-tauri/src/picker/config/display_config.rs | 36 +- src-tauri/src/picker/screenshot.rs | 12 +- .../components/completed-led-strip.tsx | 93 ++++ .../components/display-with-led-strips.tsx | 49 +- src/configurator/components/led-strip.tsx | 12 +- src/configurator/components/styled-pixel.tsx | 10 + src/configurator/configurator.tsx | 13 +- src/configurator/models/display-config.ts | 16 +- src/constants/border.ts | 2 + 11 files changed, 533 insertions(+), 214 deletions(-) create mode 100644 src/configurator/components/completed-led-strip.tsx create mode 100644 src/configurator/components/styled-pixel.tsx create mode 100644 src/constants/border.ts diff --git a/package.json b/package.json index c276125..649a500 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,10 @@ "@fortawesome/free-regular-svg-icons": "^6.2.1", "@fortawesome/free-solid-svg-icons": "^6.2.1", "@fortawesome/react-fontawesome": "^0.2.0", - "@mui/material": "^5.11.2", + "@mui/material": "^5.11.4", "@tauri-apps/api": "^1.2.0", "clsx": "^1.2.1", + "debug": "^4.3.4", "ramda": "^0.28.0", "react": "^18.2.0", "react-async-hook": "^4.0.0", @@ -29,6 +30,7 @@ "@emotion/babel-plugin-jsx-pragmatic": "^0.2.0", "@emotion/serialize": "^1.1.1", "@tauri-apps/cli": "^1.2.2", + "@types/debug": "^4.1.7", "@types/node": "^18.11.18", "@types/ramda": "^0.28.20", "@types/react": "^18.0.26", @@ -36,13 +38,13 @@ "@vitejs/plugin-react": "^2.2.0", "autoprefixer": "^10.4.13", "babel-plugin-macros": "^3.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jsx-a11y": "^6.6.1", + "eslint-config-prettier": "^8.6.0", + "eslint-plugin-import": "^2.27.4", + "eslint-plugin-jsx-a11y": "^6.7.1", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-simple-import-sort": "^8.0.0", - "postcss": "^8.4.20", - "prettier": "^2.8.1", + "postcss": "^8.4.21", + "prettier": "^2.8.3", "tailwindcss": "^3.2.4", "twin.macro": "^3.1.0", "typescript": "^4.9.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1d13e74..2e381a2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,9 +10,10 @@ specifiers: '@fortawesome/free-regular-svg-icons': ^6.2.1 '@fortawesome/free-solid-svg-icons': ^6.2.1 '@fortawesome/react-fontawesome': ^0.2.0 - '@mui/material': ^5.11.2 + '@mui/material': ^5.11.4 '@tauri-apps/api': ^1.2.0 '@tauri-apps/cli': ^1.2.2 + '@types/debug': ^4.1.7 '@types/node': ^18.11.18 '@types/ramda': ^0.28.20 '@types/react': ^18.0.26 @@ -21,13 +22,14 @@ specifiers: autoprefixer: ^10.4.13 babel-plugin-macros: ^3.1.0 clsx: ^1.2.1 - eslint-config-prettier: ^8.5.0 - eslint-plugin-import: ^2.26.0 - eslint-plugin-jsx-a11y: ^6.6.1 + debug: ^4.3.4 + eslint-config-prettier: ^8.6.0 + eslint-plugin-import: ^2.27.4 + eslint-plugin-jsx-a11y: ^6.7.1 eslint-plugin-prettier: ^4.2.1 eslint-plugin-simple-import-sort: ^8.0.0 - postcss: ^8.4.20 - prettier: ^2.8.1 + postcss: ^8.4.21 + prettier: ^2.8.3 ramda: ^0.28.0 react: ^18.2.0 react-async-hook: ^4.0.0 @@ -44,9 +46,10 @@ dependencies: '@fortawesome/free-regular-svg-icons': 6.2.1 '@fortawesome/free-solid-svg-icons': 6.2.1 '@fortawesome/react-fontawesome': 0.2.0_z27bm67dtmuyyvss23ckjdrcuy - '@mui/material': 5.11.2_lskpmcsdi7ipu6qpuapyu56ihm + '@mui/material': 5.11.4_lskpmcsdi7ipu6qpuapyu56ihm '@tauri-apps/api': 1.2.0 clsx: 1.2.1 + debug: 4.3.4 ramda: 0.28.0 react: 18.2.0 react-async-hook: 4.0.0_react@18.2.0 @@ -57,21 +60,22 @@ devDependencies: '@emotion/babel-plugin-jsx-pragmatic': 0.2.0 '@emotion/serialize': 1.1.1 '@tauri-apps/cli': 1.2.2 + '@types/debug': 4.1.7 '@types/node': 18.11.18 '@types/ramda': 0.28.20 '@types/react': 18.0.26 '@types/react-dom': 18.0.10 '@vitejs/plugin-react': 2.2.0_vite@3.2.5 - autoprefixer: 10.4.13_postcss@8.4.20 + autoprefixer: 10.4.13_postcss@8.4.21 babel-plugin-macros: 3.1.0 - eslint-config-prettier: 8.5.0 - eslint-plugin-import: 2.26.0 - eslint-plugin-jsx-a11y: 6.6.1 - eslint-plugin-prettier: 4.2.1_oixrjny4ajrp742454blm2dh6q + eslint-config-prettier: 8.6.0 + eslint-plugin-import: 2.27.4 + eslint-plugin-jsx-a11y: 6.7.1 + eslint-plugin-prettier: 4.2.1_sf22gp4h4llr342kfjdanueldy eslint-plugin-simple-import-sort: 8.0.0 - postcss: 8.4.20 - prettier: 2.8.1 - tailwindcss: 3.2.4_postcss@8.4.20 + postcss: 8.4.21 + prettier: 2.8.3 + tailwindcss: 3.2.4_postcss@8.4.21 twin.macro: 3.1.0_tailwindcss@3.2.4 typescript: 4.9.4 vite: 3.2.5_@types+node@18.11.18 @@ -97,19 +101,19 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/core/7.20.7: - resolution: {integrity: sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==} + /@babel/core/7.20.12: + resolution: {integrity: sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.0 '@babel/code-frame': 7.18.6 '@babel/generator': 7.20.7 - '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.7 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.12 '@babel/helper-module-transforms': 7.20.11 '@babel/helpers': 7.20.7 '@babel/parser': 7.20.7 '@babel/template': 7.20.7 - '@babel/traverse': 7.20.10 + '@babel/traverse': 7.20.12 '@babel/types': 7.20.7 convert-source-map: 1.9.0 debug: 4.3.4 @@ -136,14 +140,14 @@ packages: '@babel/types': 7.20.7 dev: true - /@babel/helper-compilation-targets/7.20.7_@babel+core@7.20.7: + /@babel/helper-compilation-targets/7.20.7_@babel+core@7.20.12: resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: '@babel/compat-data': 7.20.10 - '@babel/core': 7.20.7 + '@babel/core': 7.20.12 '@babel/helper-validator-option': 7.18.6 browserslist: 4.21.4 lru-cache: 5.1.1 @@ -186,7 +190,7 @@ packages: '@babel/helper-split-export-declaration': 7.18.6 '@babel/helper-validator-identifier': 7.19.1 '@babel/template': 7.20.7 - '@babel/traverse': 7.20.10 + '@babel/traverse': 7.20.12 '@babel/types': 7.20.7 transitivePeerDependencies: - supports-color @@ -228,7 +232,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.20.7 - '@babel/traverse': 7.20.10 + '@babel/traverse': 7.20.12 '@babel/types': 7.20.7 transitivePeerDependencies: - supports-color @@ -258,43 +262,43 @@ packages: dependencies: '@babel/helper-plugin-utils': 7.20.2 - /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.20.7: + /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.20.12: resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.7 + '@babel/core': 7.20.12 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.20.7: + /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.20.12: resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.7 - '@babel/plugin-transform-react-jsx': 7.20.7_@babel+core@7.20.7 + '@babel/core': 7.20.12 + '@babel/plugin-transform-react-jsx': 7.20.7_@babel+core@7.20.12 dev: true - /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.20.7: + /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.20.12: resolution: {integrity: sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.7 + '@babel/core': 7.20.12 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-react-jsx-source/7.19.6_@babel+core@7.20.7: + /@babel/plugin-transform-react-jsx-source/7.19.6_@babel+core@7.20.12: resolution: {integrity: sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.7 + '@babel/core': 7.20.12 '@babel/helper-plugin-utils': 7.20.2 dev: true @@ -311,28 +315,20 @@ packages: '@babel/types': 7.20.7 dev: true - /@babel/plugin-transform-react-jsx/7.20.7_@babel+core@7.20.7: + /@babel/plugin-transform-react-jsx/7.20.7_@babel+core@7.20.12: resolution: {integrity: sha512-Tfq7qqD+tRj3EoDhY00nn2uP2hsRxgYGi5mLQ5TimKav0a9Lrpd4deE+fcLXU8zFYRjlKPHZhpCvfEA6qnBxqQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.20.7 + '@babel/core': 7.20.12 '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-module-imports': 7.18.6 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.20.7 + '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.20.12 '@babel/types': 7.20.7 dev: true - /@babel/runtime-corejs3/7.20.7: - resolution: {integrity: sha512-jr9lCZ4RbRQmCR28Q8U8Fu49zvFqLxTY9AMOUz+iyMohMoAgpEcVxY+wJNay99oXOpOcCTODkk70NDN2aaJEeg==} - engines: {node: '>=6.9.0'} - dependencies: - core-js-pure: 3.27.1 - regenerator-runtime: 0.13.11 - dev: true - /@babel/runtime/7.20.7: resolution: {integrity: sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==} engines: {node: '>=6.9.0'} @@ -348,8 +344,8 @@ packages: '@babel/types': 7.20.7 dev: true - /@babel/traverse/7.20.10: - resolution: {integrity: sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg==} + /@babel/traverse/7.20.12: + resolution: {integrity: sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.18.6 @@ -599,8 +595,8 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true - /@mui/base/5.0.0-alpha.112_ib3m5ricvtkl2cll7qpr2f6lvq: - resolution: {integrity: sha512-KPwb1iYPXsV/P8uu0SNQrj7v7YU6wdN4Eccc2lZQyRDW+f6PJYjHBuFUTYKc408B98Jvs1XbC/z5MN45a2DWrQ==} + /@mui/base/5.0.0-alpha.113_ib3m5ricvtkl2cll7qpr2f6lvq: + resolution: {integrity: sha512-XSjvyQWATM8uk+EJZvYna8D21kOXC42lwb3q4K70btuGieKlCIQLaHTTDV2OfD4+JfT4o3NJy3I4Td2co31RZA==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -623,12 +619,12 @@ packages: react-is: 18.2.0 dev: false - /@mui/core-downloads-tracker/5.11.2: - resolution: {integrity: sha512-ztLQELdSSuJFXezng8g5eCzy8mogtzMM8JcfG3HIGgUJ2RlAiBXI2Qe0adKmrJlF4FMat8vTaTeoiRNBZH4t1Q==} + /@mui/core-downloads-tracker/5.11.4: + resolution: {integrity: sha512-jWVwGM3vG4O0sXcW0VcIl+njCWbGCBF5vvjRpuKJajrz51AD7D6+fP1SkInZXVk5pRHf6Bnk/Yj9Of9gXxb/hA==} dev: false - /@mui/material/5.11.2_lskpmcsdi7ipu6qpuapyu56ihm: - resolution: {integrity: sha512-PeraRDsghnDLzejorfe9ps1syxlB8UrGs+UKwg9GGlndv5Tghm+9nwuibrP2TCDC14mlryF+u2WlAOYaPPMwGA==} + /@mui/material/5.11.4_lskpmcsdi7ipu6qpuapyu56ihm: + resolution: {integrity: sha512-ZL/czK9ynrQJ6uyDwQgK+j7m1iKA1XKPON+rEPupwAu/bJ1XJxD+H/H2bkMM8UpOkzaucx/WuMbJJGQ60l7gBg==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -647,9 +643,9 @@ packages: '@babel/runtime': 7.20.7 '@emotion/react': 11.10.5_kzbn2opkn2327fwg5yzwzya5o4 '@emotion/styled': 11.10.5_qvatmowesywn4ye42qoh247szu - '@mui/base': 5.0.0-alpha.112_ib3m5ricvtkl2cll7qpr2f6lvq - '@mui/core-downloads-tracker': 5.11.2 - '@mui/system': 5.11.2_ogriz7mfahdh34qnfautfro5yu + '@mui/base': 5.0.0-alpha.113_ib3m5ricvtkl2cll7qpr2f6lvq + '@mui/core-downloads-tracker': 5.11.4 + '@mui/system': 5.11.4_ogriz7mfahdh34qnfautfro5yu '@mui/types': 7.2.3_@types+react@18.0.26 '@mui/utils': 5.11.2_react@18.2.0 '@types/react': 18.0.26 @@ -702,8 +698,8 @@ packages: react: 18.2.0 dev: false - /@mui/system/5.11.2_ogriz7mfahdh34qnfautfro5yu: - resolution: {integrity: sha512-PPkYhrcP2MkhscX6SauIl0wPgra0w1LGPtll+hIKc2Z2JbGRSrUCFif93kxejB7I1cAoCay9jWW4mnNhsOqF/g==} + /@mui/system/5.11.4_ogriz7mfahdh34qnfautfro5yu: + resolution: {integrity: sha512-fE2Ts33V5zh7ouciwXgMm/a6sLvjIj9OMeojuHNYY7BStTxparC/Fp9CNUZNJwt76U6ZJC59aYScFSRQKbW08g==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -884,10 +880,20 @@ packages: '@tauri-apps/cli-win32-x64-msvc': 1.2.2 dev: true + /@types/debug/4.1.7: + resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} + dependencies: + '@types/ms': 0.7.31 + dev: true + /@types/json5/0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true + /@types/ms/0.7.31: + resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} + dev: true + /@types/node/18.11.18: resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==} dev: true @@ -938,11 +944,11 @@ packages: peerDependencies: vite: ^3.0.0 dependencies: - '@babel/core': 7.20.7 - '@babel/plugin-transform-react-jsx': 7.20.7_@babel+core@7.20.7 - '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.20.7 - '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.20.7 - '@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.20.7 + '@babel/core': 7.20.12 + '@babel/plugin-transform-react-jsx': 7.20.7_@babel+core@7.20.12 + '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.20.12 + '@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.20.12 magic-string: 0.26.7 react-refresh: 0.14.0 vite: 3.2.5_@types+node@18.11.18 @@ -994,12 +1000,10 @@ packages: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} dev: true - /aria-query/4.2.2: - resolution: {integrity: sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==} - engines: {node: '>=6.0'} + /aria-query/5.1.3: + resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} dependencies: - '@babel/runtime': 7.20.7 - '@babel/runtime-corejs3': 7.20.7 + deep-equal: 2.2.0 dev: true /array-includes/3.1.6: @@ -1008,7 +1012,7 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.5 + es-abstract: 1.21.1 get-intrinsic: 1.1.3 is-string: 1.0.7 dev: true @@ -1019,7 +1023,17 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.5 + es-abstract: 1.21.1 + es-shim-unscopables: 1.0.0 + dev: true + + /array.prototype.flatmap/1.3.1: + resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.21.1 es-shim-unscopables: 1.0.0 dev: true @@ -1027,7 +1041,7 @@ packages: resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==} dev: true - /autoprefixer/10.4.13_postcss@8.4.20: + /autoprefixer/10.4.13_postcss@8.4.21: resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} engines: {node: ^10 || ^12 || >=14} hasBin: true @@ -1035,21 +1049,28 @@ packages: postcss: ^8.1.0 dependencies: browserslist: 4.21.4 - caniuse-lite: 1.0.30001441 + caniuse-lite: 1.0.30001445 fraction.js: 4.2.0 normalize-range: 0.1.2 picocolors: 1.0.0 - postcss: 8.4.20 + postcss: 8.4.21 postcss-value-parser: 4.2.0 dev: true - /axe-core/4.6.1: - resolution: {integrity: sha512-lCZN5XRuOnpG4bpMq8v0khrWtUOn+i8lZSb6wHZH56ZfbIEv6XwJV84AAueh9/zi7qPVJ/E4yz6fmsiyOmXR4w==} + /available-typed-arrays/1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: true + + /axe-core/4.6.2: + resolution: {integrity: sha512-b1WlTV8+XKLj9gZy2DZXgQiyDp9xkkoe2a6U6UbYccScq2wgH/YwCeI2/Jq2mgo0HzQxqJOjWZBLeA/mqsk5Mg==} engines: {node: '>=4'} dev: true - /axobject-query/2.2.0: - resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==} + /axobject-query/3.1.1: + resolution: {integrity: sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==} + dependencies: + deep-equal: 2.2.0 dev: true /babel-plugin-macros/3.1.0: @@ -1088,7 +1109,7 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001441 + caniuse-lite: 1.0.30001445 electron-to-chromium: 1.4.284 node-releases: 2.0.8 update-browserslist-db: 1.0.10_browserslist@4.21.4 @@ -1110,8 +1131,8 @@ packages: engines: {node: '>= 6'} dev: true - /caniuse-lite/1.0.30001441: - resolution: {integrity: sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==} + /caniuse-lite/1.0.30001445: + resolution: {integrity: sha512-8sdQIdMztYmzfTMO6KfLny878Ln9c2M0fc7EH60IjlP4Dc4PiCy7K2Vl3ITmWgOyPgVQKa5x+UP/KqFsxj4mBg==} dev: true /chalk/2.4.2: @@ -1176,11 +1197,6 @@ packages: /convert-source-map/1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - /core-js-pure/3.27.1: - resolution: {integrity: sha512-BS2NHgwwUppfeoqOXqi08mUqS5FiZpuRuJJpKsaME7kJz0xxuk0xkhDdfMIlP/zLa80krBqss1LtD7f889heAw==} - requiresBuild: true - dev: true - /cosmiconfig/7.1.0: resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} engines: {node: '>=10'} @@ -1204,17 +1220,6 @@ packages: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} dev: true - /debug/2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - dev: true - /debug/3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -1236,6 +1241,27 @@ packages: optional: true dependencies: ms: 2.1.2 + + /deep-equal/2.2.0: + resolution: {integrity: sha512-RdpzE0Hv4lhowpIUKKMJfeH6C1pXdtT1/it80ubgWqwI3qpuxUBpC1S4hnHg+zjnuOoDkzUtUCEEkG+XG5l3Mw==} + dependencies: + call-bind: 1.0.2 + es-get-iterator: 1.1.3 + get-intrinsic: 1.1.3 + is-arguments: 1.1.1 + is-array-buffer: 3.0.1 + is-date-object: 1.0.5 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + isarray: 2.0.5 + object-is: 1.1.5 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.4.3 + side-channel: 1.0.4 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.1 + which-typed-array: 1.1.9 dev: true /define-properties/1.1.4: @@ -1295,35 +1321,66 @@ packages: dependencies: is-arrayish: 0.2.1 - /es-abstract/1.20.5: - resolution: {integrity: sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ==} + /es-abstract/1.21.1: + resolution: {integrity: sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==} engines: {node: '>= 0.4'} dependencies: + available-typed-arrays: 1.0.5 call-bind: 1.0.2 + es-set-tostringtag: 2.0.1 es-to-primitive: 1.2.1 function-bind: 1.1.1 function.prototype.name: 1.1.5 get-intrinsic: 1.1.3 get-symbol-description: 1.0.0 + globalthis: 1.0.3 gopd: 1.0.1 has: 1.0.3 has-property-descriptors: 1.0.0 + has-proto: 1.0.1 has-symbols: 1.0.3 internal-slot: 1.0.4 + is-array-buffer: 3.0.1 is-callable: 1.2.7 is-negative-zero: 2.0.2 is-regex: 1.1.4 is-shared-array-buffer: 1.0.2 is-string: 1.0.7 + is-typed-array: 1.1.10 is-weakref: 1.0.2 - object-inspect: 1.12.2 + object-inspect: 1.12.3 object-keys: 1.1.1 object.assign: 4.1.4 regexp.prototype.flags: 1.4.3 safe-regex-test: 1.0.0 string.prototype.trimend: 1.0.6 string.prototype.trimstart: 1.0.6 + typed-array-length: 1.0.4 unbox-primitive: 1.0.2 + which-typed-array: 1.1.9 + dev: true + + /es-get-iterator/1.1.3: + resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + has-symbols: 1.0.3 + is-arguments: 1.1.1 + is-map: 2.0.2 + is-set: 2.0.2 + is-string: 1.0.7 + isarray: 2.0.5 + stop-iteration-iterator: 1.0.0 + dev: true + + /es-set-tostringtag/2.0.1: + resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.1.3 + has: 1.0.3 + has-tostringtag: 1.0.0 dev: true /es-shim-unscopables/1.0.0: @@ -1565,23 +1622,24 @@ packages: engines: {node: '>=10'} dev: false - /eslint-config-prettier/8.5.0: - resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} + /eslint-config-prettier/8.6.0: + resolution: {integrity: sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==} hasBin: true peerDependencies: eslint: '>=7.0.0' dev: true - /eslint-import-resolver-node/0.3.6: - resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==} + /eslint-import-resolver-node/0.3.7: + resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==} dependencies: debug: 3.2.7 + is-core-module: 2.11.0 resolve: 1.22.1 transitivePeerDependencies: - supports-color dev: true - /eslint-module-utils/2.7.4_ulu2225r2ychl26a37c6o2rfje: + /eslint-module-utils/2.7.4_sgsp5urgqm477dupjnxj5zkyya: resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} engines: {node: '>=4'} peerDependencies: @@ -1603,13 +1661,13 @@ packages: optional: true dependencies: debug: 3.2.7 - eslint-import-resolver-node: 0.3.6 + eslint-import-resolver-node: 0.3.7 transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-import/2.26.0: - resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} + /eslint-plugin-import/2.27.4: + resolution: {integrity: sha512-Z1jVt1EGKia1X9CnBCkpAOhWy8FgQ7OmJ/IblEkT82yrFU/xJaxwujaTzLWqigewwynRQ9mmHfX9MtAfhxm0sA==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -1620,16 +1678,18 @@ packages: dependencies: array-includes: 3.1.6 array.prototype.flat: 1.3.1 - debug: 2.6.9 + array.prototype.flatmap: 1.3.1 + debug: 3.2.7 doctrine: 2.1.0 - eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.4_ulu2225r2ychl26a37c6o2rfje + eslint-import-resolver-node: 0.3.7 + eslint-module-utils: 2.7.4_sgsp5urgqm477dupjnxj5zkyya has: 1.0.3 is-core-module: 2.11.0 is-glob: 4.0.3 minimatch: 3.1.2 object.values: 1.1.6 resolve: 1.22.1 + semver: 6.3.0 tsconfig-paths: 3.14.1 transitivePeerDependencies: - eslint-import-resolver-typescript @@ -1637,28 +1697,31 @@ packages: - supports-color dev: true - /eslint-plugin-jsx-a11y/6.6.1: - resolution: {integrity: sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==} + /eslint-plugin-jsx-a11y/6.7.1: + resolution: {integrity: sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==} engines: {node: '>=4.0'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 dependencies: '@babel/runtime': 7.20.7 - aria-query: 4.2.2 + aria-query: 5.1.3 array-includes: 3.1.6 + array.prototype.flatmap: 1.3.1 ast-types-flow: 0.0.7 - axe-core: 4.6.1 - axobject-query: 2.2.0 + axe-core: 4.6.2 + axobject-query: 3.1.1 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 has: 1.0.3 jsx-ast-utils: 3.3.3 - language-tags: 1.0.7 + language-tags: 1.0.5 minimatch: 3.1.2 + object.entries: 1.1.6 + object.fromentries: 2.0.6 semver: 6.3.0 dev: true - /eslint-plugin-prettier/4.2.1_oixrjny4ajrp742454blm2dh6q: + /eslint-plugin-prettier/4.2.1_sf22gp4h4llr342kfjdanueldy: resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1669,8 +1732,8 @@ packages: eslint-config-prettier: optional: true dependencies: - eslint-config-prettier: 8.5.0 - prettier: 2.8.1 + eslint-config-prettier: 8.6.0 + prettier: 2.8.3 prettier-linter-helpers: 1.0.0 dev: true @@ -1717,6 +1780,12 @@ packages: resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} dev: false + /for-each/0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + /fraction.js/4.2.0: resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} dev: true @@ -1738,7 +1807,7 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.5 + es-abstract: 1.21.1 functions-have-names: 1.2.3 dev: true @@ -1786,6 +1855,13 @@ packages: engines: {node: '>=4'} dev: true + /globalthis/1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.1.4 + dev: true + /gopd/1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: @@ -1811,6 +1887,11 @@ packages: get-intrinsic: 1.1.3 dev: true + /has-proto/1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + dev: true + /has-symbols/1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} @@ -1851,6 +1932,22 @@ packages: side-channel: 1.0.4 dev: true + /is-arguments/1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-array-buffer/3.0.1: + resolution: {integrity: sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + is-typed-array: 1.1.10 + dev: true + /is-arrayish/0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -1904,6 +2001,10 @@ packages: is-extglob: 2.1.1 dev: true + /is-map/2.0.2: + resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} + dev: true + /is-negative-zero/2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} @@ -1929,6 +2030,10 @@ packages: has-tostringtag: 1.0.0 dev: true + /is-set/2.0.2: + resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} + dev: true + /is-shared-array-buffer/1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: @@ -1949,12 +2054,38 @@ packages: has-symbols: 1.0.3 dev: true + /is-typed-array/1.1.10: + resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + dev: true + + /is-weakmap/2.0.1: + resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} + dev: true + /is-weakref/1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: call-bind: 1.0.2 dev: true + /is-weakset/2.0.2: + resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + dev: true + + /isarray/2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + /js-tokens/4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1992,8 +2123,8 @@ packages: resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} dev: true - /language-tags/1.0.7: - resolution: {integrity: sha512-bSytju1/657hFjgUzPAPqszxH62ouE8nQFoFaVlIQfne4wO/wXC9A4+m8jYve7YBBvi59eq0SUpcshvG8h5Usw==} + /language-tags/1.0.5: + resolution: {integrity: sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==} dependencies: language-subtag-registry: 0.3.22 dev: true @@ -2057,13 +2188,8 @@ packages: resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} dev: true - /ms/2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - dev: true - /ms/2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true /ms/2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -2099,8 +2225,16 @@ packages: engines: {node: '>= 6'} dev: true - /object-inspect/1.12.2: - resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} + /object-inspect/1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + dev: true + + /object-is/1.1.5: + resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 dev: true /object-keys/1.1.1: @@ -2118,13 +2252,31 @@ packages: object-keys: 1.1.1 dev: true + /object.entries/1.1.6: + resolution: {integrity: sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.21.1 + dev: true + + /object.fromentries/2.0.6: + resolution: {integrity: sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.21.1 + dev: true + /object.values/1.1.6: resolution: {integrity: sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.5 + es-abstract: 1.21.1 dev: true /parent-module/1.0.1: @@ -2163,29 +2315,29 @@ packages: engines: {node: '>=0.10.0'} dev: true - /postcss-import/14.1.0_postcss@8.4.20: + /postcss-import/14.1.0_postcss@8.4.21: resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==} engines: {node: '>=10.0.0'} peerDependencies: postcss: ^8.0.0 dependencies: - postcss: 8.4.20 + postcss: 8.4.21 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.1 dev: true - /postcss-js/4.0.0_postcss@8.4.20: + /postcss-js/4.0.0_postcss@8.4.21: resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.3.3 dependencies: camelcase-css: 2.0.1 - postcss: 8.4.20 + postcss: 8.4.21 dev: true - /postcss-load-config/3.1.4_postcss@8.4.20: + /postcss-load-config/3.1.4_postcss@8.4.21: resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} engines: {node: '>= 10'} peerDependencies: @@ -2198,17 +2350,17 @@ packages: optional: true dependencies: lilconfig: 2.0.6 - postcss: 8.4.20 + postcss: 8.4.21 yaml: 1.10.2 dev: true - /postcss-nested/6.0.0_postcss@8.4.20: + /postcss-nested/6.0.0_postcss@8.4.21: resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.2.14 dependencies: - postcss: 8.4.20 + postcss: 8.4.21 postcss-selector-parser: 6.0.11 dev: true @@ -2224,8 +2376,8 @@ packages: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} dev: true - /postcss/8.4.20: - resolution: {integrity: sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==} + /postcss/8.4.21: + resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.4 @@ -2240,8 +2392,8 @@ packages: fast-diff: 1.2.0 dev: true - /prettier/2.8.1: - resolution: {integrity: sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==} + /prettier/2.8.3: + resolution: {integrity: sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==} engines: {node: '>=10.13.0'} hasBin: true dev: true @@ -2400,7 +2552,7 @@ packages: dependencies: call-bind: 1.0.2 get-intrinsic: 1.1.3 - object-inspect: 1.12.2 + object-inspect: 1.12.3 dev: true /source-map-js/1.0.2: @@ -2418,12 +2570,19 @@ packages: deprecated: Please use @jridgewell/sourcemap-codec instead dev: true + /stop-iteration-iterator/1.0.0: + resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} + engines: {node: '>= 0.4'} + dependencies: + internal-slot: 1.0.4 + dev: true + /string.prototype.trimend/1.0.6: resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.5 + es-abstract: 1.21.1 dev: true /string.prototype.trimstart/1.0.6: @@ -2431,7 +2590,7 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.1.4 - es-abstract: 1.20.5 + es-abstract: 1.21.1 dev: true /strip-bom/3.0.0: @@ -2460,7 +2619,7 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /tailwindcss/3.2.4_postcss@8.4.20: + /tailwindcss/3.2.4_postcss@8.4.21: resolution: {integrity: sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==} engines: {node: '>=12.13.0'} hasBin: true @@ -2481,11 +2640,11 @@ packages: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.0.0 - postcss: 8.4.20 - postcss-import: 14.1.0_postcss@8.4.20 - postcss-js: 4.0.0_postcss@8.4.20 - postcss-load-config: 3.1.4_postcss@8.4.20 - postcss-nested: 6.0.0_postcss@8.4.20 + postcss: 8.4.21 + postcss-import: 14.1.0_postcss@8.4.21 + postcss-js: 4.0.0_postcss@8.4.21 + postcss-load-config: 3.1.4_postcss@8.4.21 + postcss-nested: 6.0.0_postcss@8.4.21 postcss-selector-parser: 6.0.11 postcss-value-parser: 4.2.0 quick-lru: 5.1.1 @@ -2530,7 +2689,15 @@ packages: lodash.get: 4.4.2 lodash.merge: 4.6.2 postcss-selector-parser: 6.0.11 - tailwindcss: 3.2.4_postcss@8.4.20 + tailwindcss: 3.2.4_postcss@8.4.21 + dev: true + + /typed-array-length/1.0.4: + resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + dependencies: + call-bind: 1.0.2 + for-each: 0.3.3 + is-typed-array: 1.1.10 dev: true /typescript/4.9.4: @@ -2590,7 +2757,7 @@ packages: dependencies: '@types/node': 18.11.18 esbuild: 0.15.18 - postcss: 8.4.20 + postcss: 8.4.21 resolve: 1.22.1 rollup: 2.79.1 optionalDependencies: @@ -2607,6 +2774,27 @@ packages: is-symbol: 1.0.4 dev: true + /which-collection/1.0.1: + resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} + dependencies: + is-map: 2.0.2 + is-set: 2.0.2 + is-weakmap: 2.0.1 + is-weakset: 2.0.2 + dev: true + + /which-typed-array/1.1.9: + resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + is-typed-array: 1.1.10 + dev: true + /xtend/4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} diff --git a/src-tauri/src/picker/config/display_config.rs b/src-tauri/src/picker/config/display_config.rs index 1bb664e..e6dda63 100644 --- a/src-tauri/src/picker/config/display_config.rs +++ b/src-tauri/src/picker/config/display_config.rs @@ -1,5 +1,13 @@ use serde::{Deserialize, Serialize}; +#[derive(Clone, Copy, Serialize, Deserialize, Debug)] +pub struct LedStripConfigOfBorders { + pub top: Option, + pub bottom: Option, + pub left: Option, + pub right: Option, +} + #[derive(Clone, Copy, Serialize, Deserialize, Debug)] pub struct LedStripConfig { pub index: usize, @@ -13,23 +21,33 @@ pub struct DisplayConfig { pub index_of_display: usize, pub display_width: usize, pub display_height: usize, - pub top_led_strip: Option, - pub bottom_led_strip: Option, - pub left_led_strip: Option, - pub right_led_strip: Option, + pub led_strip_of_borders: LedStripConfigOfBorders, +} + +impl LedStripConfigOfBorders { + pub fn default() -> Self { + Self { + top: None, + bottom: None, + left: None, + right: None, + } + } } impl DisplayConfig { - pub fn default(id: usize, index_of_display: usize, display_width: usize, display_height: usize) -> Self { + pub fn default( + id: usize, + index_of_display: usize, + display_width: usize, + display_height: usize, + ) -> Self { Self { id, index_of_display, display_width, display_height, - top_led_strip: None, - bottom_led_strip: None, - left_led_strip: None, - right_led_strip: None, + led_strip_of_borders: LedStripConfigOfBorders::default(), } } } diff --git a/src-tauri/src/picker/screenshot.rs b/src-tauri/src/picker/screenshot.rs index 0d336a5..563c22f 100644 --- a/src-tauri/src/picker/screenshot.rs +++ b/src-tauri/src/picker/screenshot.rs @@ -34,7 +34,7 @@ impl Screenshot { } fn get_sample_points(config: DisplayConfig) -> ScreenSamplePoints { - let top = match config.top_led_strip { + let top = match config.led_strip_of_borders.top { Some(led_strip_config) => Self::get_one_edge_sample_points( config.display_height / 8, config.display_width, @@ -48,7 +48,7 @@ impl Screenshot { } }; - let bottom: Vec = match config.bottom_led_strip { + let bottom: Vec = match config.led_strip_of_borders.bottom { Some(led_strip_config) => { let points = Self::get_one_edge_sample_points( config.display_height / 9, @@ -73,7 +73,7 @@ impl Screenshot { } }; - let left: Vec = match config.left_led_strip { + let left: Vec = match config.led_strip_of_borders.left { Some(led_strip_config) => { let points = Self::get_one_edge_sample_points( config.display_width / 16, @@ -95,7 +95,7 @@ impl Screenshot { } }; - let right: Vec = match config.right_led_strip { + let right: Vec = match config.led_strip_of_borders.right { Some(led_strip_config) => { let points = Self::get_one_edge_sample_points( config.display_width / 16, @@ -217,13 +217,13 @@ impl Screenshot { pub fn get_top_of_led_start_at(&self) -> usize { self.config - .top_led_strip + .led_strip_of_borders.top .and_then(|c| Some(c.global_start_position)) .unwrap_or(0) } pub fn get_top_of_led_end_at(&self) -> usize { self.config - .top_led_strip + .led_strip_of_borders.top .and_then(|c| Some(c.global_end_position)) .unwrap_or(0) } diff --git a/src/configurator/components/completed-led-strip.tsx b/src/configurator/components/completed-led-strip.tsx new file mode 100644 index 0000000..28f52a0 --- /dev/null +++ b/src/configurator/components/completed-led-strip.tsx @@ -0,0 +1,93 @@ +import { isNil, splitEvery } from 'ramda'; +import { FC, useMemo } from 'react'; +import tw, { css, styled } from 'twin.macro'; +import { borders } from '../../constants/border'; +import { DisplayConfig } from '../models/display-config'; +import { LedStripConfig } from '../models/led-strip-config'; +import { ScreenshotDto } from '../models/screenshot.dto'; +import { LedStrip } from './led-strip'; +import { StyledPixel } from './styled-pixel'; + +interface CompletedLedStripProps { + screenshots: ScreenshotDto[]; + onDisplayConfigChange?: (value: DisplayConfig) => void; +} + +type BorderLedStrip = { + pixels: [number, number, number][]; + config: LedStripConfig | null; +}; + +const StyledContainer = styled.section( + ({ rows, columns }: { rows: number; columns: number }) => [ + tw`grid m-4 pb-2`, + css` + grid-template-columns: repeat(${columns}, 1fr); + grid-template-rows: auto repeat(${rows}, 1fr); + `, + ], +); +const StyledCompletedContainer = styled.section( + tw`dark:bg-transparent shadow-xl border-gray-500 border rounded-full flex flex-wrap justify-around items-center mb-2`, + css` + grid-column: 1 / -1; + `, +); + +export const CompletedLedStrip: FC = ({ + screenshots, + onDisplayConfigChange, +}) => { + const borderLedStrips: BorderLedStrip[] = useMemo(() => { + return screenshots.flatMap((ss) => + borders.map((b) => ({ + pixels: splitEvery(3, Array.from(ss.colors[b])) as [number, number, number][], + config: ss.config.led_strip_of_borders[b], + })), + ); + }, [screenshots]); + const ledCount = useMemo( + () => borderLedStrips.reduce((prev, curr) => prev + curr.pixels.length, 0), + [borderLedStrips], + ); + + const completedPixels = useMemo(() => { + const completed: [number, number, number][] = new Array(ledCount).fill([0, 0, 0]); + borderLedStrips.forEach(({ pixels, config }) => { + if (isNil(config)) { + return; + } + if (config.global_start_position <= config.global_end_position) { + pixels.forEach((color, i) => { + completed[config.global_start_position + i] = color; + }); + } else { + pixels.forEach((color, i) => { + completed[config.global_start_position - i] = color; + }); + } + }); + + return completed.map((color) => ); + }, [ledCount, borderLedStrips]); + + const strips = useMemo(() => { + return borderLedStrips.map(({ config, pixels }, index) => ( + + )); + }, [borderLedStrips]); + return ( + + {completedPixels} + {strips} + + ); +}; diff --git a/src/configurator/components/display-with-led-strips.tsx b/src/configurator/components/display-with-led-strips.tsx index ed9f56e..f9eef3c 100644 --- a/src/configurator/components/display-with-led-strips.tsx +++ b/src/configurator/components/display-with-led-strips.tsx @@ -1,11 +1,15 @@ import { HTMLAttributes, useCallback, useMemo } from 'react'; import { FC } from 'react'; -import { DisplayConfig } from '../models/display-config'; +import { DisplayConfig, LedStripConfigOfBorders } from '../models/display-config'; import { LedStrip } from './led-strip'; import tw, { css, styled, theme } from 'twin.macro'; import { ScreenshotDto } from '../models/screenshot.dto'; import { LedStripEditor } from './led-strip-editor'; import { LedStripConfig } from '../models/led-strip-config'; +import debug from 'debug'; +import { lensPath, lensProp, set, view } from 'ramda'; + +const logger = debug('app:display-with-led-strips'); export interface DisplayWithLedStripsProps extends Omit, 'onChange'> { @@ -36,61 +40,60 @@ export const DisplayWithLedStrips: FC = ({ ); const onLedStripConfigChange = useCallback( - ( - position: - | 'top_led_strip' - | 'left_led_strip' - | 'right_led_strip' - | 'bottom_led_strip', - value: LedStripConfig | null, - ) => { - const c = { ...config, [position]: value }; + (position: keyof LedStripConfigOfBorders, value: LedStripConfig | null) => { + const xLens = lensPath< + DisplayConfig, + 'led_strip_of_borders', + keyof LedStripConfigOfBorders + >(['led_strip_of_borders', position]); + const c = set(xLens, value, config); + logger('on change. prev: %o, curr: %o', view(xLens, config), value); onChange?.(c); }, [config], ); return ( - + onLedStripConfigChange('top_led_strip', value)} + onChange={(value) => onLedStripConfigChange('top', value)} /> onLedStripConfigChange('left_led_strip', value)} + onChange={(value) => onLedStripConfigChange('left', value)} /> onLedStripConfigChange('right_led_strip', value)} + onChange={(value) => onLedStripConfigChange('right', value)} /> onLedStripConfigChange('bottom_led_strip', value)} + onChange={(value) => onLedStripConfigChange('bottom', value)} /> ); diff --git a/src/configurator/components/led-strip.tsx b/src/configurator/components/led-strip.tsx index 785d693..d6d2fa1 100644 --- a/src/configurator/components/led-strip.tsx +++ b/src/configurator/components/led-strip.tsx @@ -3,6 +3,7 @@ import { FC } from 'react'; import { LedStripConfig } from '../models/led-strip-config'; import tw, { css, styled } from 'twin.macro'; import { splitEvery } from 'ramda'; +import { StyledPixel } from './styled-pixel'; export interface LedStripProps extends HTMLAttributes { config: LedStripConfig | null; @@ -10,19 +11,10 @@ export interface LedStripProps extends HTMLAttributes { } const StyledContainer = styled.section( - tw`dark:bg-transparent shadow-xl border-gray-500 border rounded-full flex flex-wrap justify-around items-center`, + tw`dark:bg-transparent shadow-xl border-gray-500 border rounded-full flex flex-wrap justify-around items-center -mx-px -mt-px`, css``, ); -const StyledPixel = styled.span( - ({ rgb: [r, g, b] }: { rgb: [number, number, number] }) => [ - tw`rounded-full h-3 w-3 bg-current block border border-gray-700`, - css` - color: rgb(${r}, ${g}, ${b}); - `, - ], -); - export const LedStrip: FC = ({ config, colors, ...htmlAttrs }) => { const pixels = useMemo(() => { const pixels = splitEvery(3, Array.from(colors)) as Array<[number, number, number]>; diff --git a/src/configurator/components/styled-pixel.tsx b/src/configurator/components/styled-pixel.tsx new file mode 100644 index 0000000..c742021 --- /dev/null +++ b/src/configurator/components/styled-pixel.tsx @@ -0,0 +1,10 @@ +import tw, { css, styled } from 'twin.macro'; + +export const StyledPixel = styled.span( + ({ rgb: [r, g, b] }: { rgb: [number, number, number] }) => [ + tw`rounded-full h-3 w-3 bg-current block border border-gray-700`, + css` + color: rgb(${r}, ${g}, ${b}); + `, + ], +); diff --git a/src/configurator/configurator.tsx b/src/configurator/configurator.tsx index 8d61817..ec5ebc2 100644 --- a/src/configurator/configurator.tsx +++ b/src/configurator/configurator.tsx @@ -1,6 +1,6 @@ import { invoke } from '@tauri-apps/api'; import { FC, Fragment, useCallback, useEffect, useMemo, useState } from 'react'; -import tw from 'twin.macro'; +import tw, { styled } from 'twin.macro'; import { useAsync, useAsyncCallback } from 'react-async-hook'; import { DisplayWithLedStrips } from './components/display-with-led-strips'; import { PickerConfiguration } from './models/picker-configuration'; @@ -10,6 +10,7 @@ import { Alert, Snackbar } from '@mui/material'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faSpinner } from '@fortawesome/free-solid-svg-icons'; import { update } from 'ramda'; +import { CompletedLedStrip } from './components/completed-led-strip'; const getPickerConfig = () => invoke('get_picker_config'); const getScreenshotOfDisplays = () => @@ -26,6 +27,9 @@ const writePickerConfig = async (config: PickerConfiguration) => { config, }); }; +const StyledConfiguratorContainer = styled.section(tw`flex flex-col items-stretch`); + +const StyledDisplayContainer = styled.section(tw`overflow-auto`); export const Configurator: FC = () => { const { loading: pendingPickerConfig, result: savedPickerConfig } = useAsync( @@ -91,13 +95,14 @@ export const Configurator: FC = () => { } return ( - -
{displays}
; + + + {displays}; } sx={{ width: '100%' }}> This is a success message! -
+ ); }; diff --git a/src/configurator/models/display-config.ts b/src/configurator/models/display-config.ts index ef2ad54..3ce2b1f 100644 --- a/src/configurator/models/display-config.ts +++ b/src/configurator/models/display-config.ts @@ -1,10 +1,16 @@ -import { LedStripConfig } from './led-strip-config'; +import { Borders } from '../../constants/border'; +import { LedStripConfig } from "./led-strip-config"; +export class LedStripConfigOfBorders implements Record { + constructor( + public top: LedStripConfig | null = null, + public bottom: LedStripConfig | null = null, + public left: LedStripConfig | null = null, + public right: LedStripConfig | null = null, + ) {} +} export class DisplayConfig { - top_led_strip: LedStripConfig | null = null; - bottom_led_strip: LedStripConfig | null = null; - left_led_strip: LedStripConfig | null = null; - right_led_strip: LedStripConfig | null = null; + led_strip_of_borders = new LedStripConfigOfBorders(); constructor( public id: number, diff --git a/src/constants/border.ts b/src/constants/border.ts new file mode 100644 index 0000000..62db3c0 --- /dev/null +++ b/src/constants/border.ts @@ -0,0 +1,2 @@ +export const borders = ['top', 'right', 'bottom', 'left'] as const; +export type Borders = typeof borders[number]; \ No newline at end of file From a12c503e812ed6e4eab191411819d13e4935c50e Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Sun, 15 Jan 2023 19:35:14 +0800 Subject: [PATCH 10/19] =?UTF-8?q?fix:=20=E5=81=9C=E6=AD=A2=E8=B7=9F?= =?UTF-8?q?=E9=9A=8F=E5=B1=8F=E5=B9=95=E6=97=B6=EF=BC=8C=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=E5=B4=A9=E6=BA=83=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/core/core.rs | 159 +++++++++++++++++-------------------- src-tauri/src/main.rs | 2 +- 2 files changed, 75 insertions(+), 86 deletions(-) diff --git a/src-tauri/src/core/core.rs b/src-tauri/src/core/core.rs index b33abcd..931a854 100644 --- a/src-tauri/src/core/core.rs +++ b/src-tauri/src/core/core.rs @@ -1,14 +1,12 @@ use futures::future::join_all; use once_cell::sync::OnceCell; -use paris::info; +use paris::{error, info}; use serde::{Deserialize, Serialize}; use std::{collections::HashMap, sync::Arc, time::Duration}; use tauri::async_runtime::RwLock; use tokio::{ - join, sync::mpsc, - task, time::{sleep, Instant}, }; use tracing::warn; @@ -21,7 +19,7 @@ use crate::{ rpc, }; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Clone, Copy)] pub enum AmbientLightMode { None, Follow, @@ -40,25 +38,25 @@ impl CoreManager { ambient_light_mode: Arc::new(RwLock::new(AmbientLightMode::None)), }); - tokio::spawn(async { - loop { - core.play_flowing_light().await; - match core.play_follow().await { - Ok(_) => {} - Err(error) => { - warn!("Can not following displays. {}", error); - sleep(Duration::from_millis(1000)).await; - } - }; - sleep(Duration::from_millis(10)).await; - } - }); core } pub async fn set_ambient_light(&self, target_mode: AmbientLightMode) { let mut mode = self.ambient_light_mode.write().await; *mode = target_mode; + + drop(mode); + + match target_mode { + AmbientLightMode::Flowing => self.play_flowing_light().await, + AmbientLightMode::None => {} + AmbientLightMode::Follow => match self.play_follow().await { + Ok(_) => {} + Err(error) => { + warn!("Can not following displays. {}", error); + } + }, + }; } pub async fn play_flowing_light(&self) { @@ -91,76 +89,67 @@ impl CoreManager { } pub async fn play_follow(&self) -> anyhow::Result<()> { - let lock = self.ambient_light_mode.read().await; let mut futs = vec![]; - if let AmbientLightMode::Follow = *lock { - drop(lock); - let configs = Picker::global().await.display_configs.lock().await; + let configs = Picker::global().await.display_configs.lock().await; + info!("piker display configs: {:?}", configs); - let (tx, mut rx) = mpsc::channel(10); + let (tx, mut rx) = mpsc::channel(10); - for config in configs.to_owned() { - let tx = tx.clone(); - let fut = tokio::spawn(async move { - match Self::follow_display_by_config(config, tx).await { - Ok(_) => {} - Err(error) => { - warn!("following failed. {}", error); - } - } - }); - futs.push(fut); - } - - let configs = configs.clone(); - - tokio::spawn(async move { - let mut global_colors = HashMap::new(); - while let Some(screenshot) = rx.recv().await { - let start_at = Instant::now(); - let colors = screenshot.get_top_colors(); - let start = screenshot - .get_top_of_led_start_at() - .min(screenshot.get_top_of_led_end_at()); - - let colors_len = colors.len(); - for (index, color) in colors.into_iter().enumerate() { - global_colors.insert(index + start, color); - } - - info!( - "led count: {}, spend: {:?}", - global_colors.len(), - start_at.elapsed() - ); - - if global_colors.len() == 60 { - let mut colors = vec![]; - for index in 0..global_colors.len() { - colors.push(*global_colors.get(&index).unwrap()); - } - global_colors = HashMap::new(); - match rpc::manager::Manager::global() - .publish_led_colors(&colors) - .await - { - Ok(_) => { - info!("publish successful",); - } - Err(error) => { - warn!("publish led colors failed. {}", error); - } - } + for config in configs.to_owned() { + let tx = tx.clone(); + let fut = tokio::spawn(async move { + match Self::follow_display_by_config(config, tx).await { + Ok(_) => {} + Err(error) => { + warn!("following failed. {}", error); } } }); - - join_all(futs).await; - } else { - drop(lock); - return Ok(()); + futs.push(fut); } + tokio::spawn(async move { + let mut global_colors = HashMap::new(); + while let Some(screenshot) = rx.recv().await { + let start_at = Instant::now(); + let colors = screenshot.get_top_colors(); + let start = screenshot + .get_top_of_led_start_at() + .min(screenshot.get_top_of_led_end_at()); + + for (index, color) in colors.into_iter().enumerate() { + global_colors.insert(index + start, color); + } + + info!( + "led count: {}, spend: {:?}", + global_colors.len(), + start_at.elapsed() + ); + + if global_colors.len() == 60 { + let mut colors = vec![]; + for index in 0..global_colors.len() { + colors.push(*global_colors.get(&index).unwrap()); + } + global_colors = HashMap::new(); + match rpc::manager::Manager::global() + .publish_led_colors(&colors) + .await + { + Ok(_) => { + info!("publish successful",); + } + Err(error) => { + warn!("publish led colors failed. {}", error); + } + } + } + } + }); + + join_all(futs).await; + Ok(()) } @@ -179,17 +168,17 @@ impl CoreManager { drop(lock); let screenshot = picker.take_screenshot()?; info!("Take Screenshot Spend: {:?}", start.elapsed()); - tx.send(screenshot).await; + match tx.send(screenshot).await { + Ok(_) => {} + Err(err) => { + error!("send screenshot to main thread was failed. {:?}", err); + } + }; } else { break; } tokio::time::sleep_until(next_tick).await; } - - // // Picker::global().take_screenshots_for_all().await?; - // // let colors = Picker::global().get_led_strip_colors().await?; - - // // let colors = colors.into_iter().rev().collect(); Ok(()) } } diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 165aac2..9b4ad86 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -78,7 +78,7 @@ async fn write_picker_config(config: picker::config::Configuration) -> Result<() async fn play_mode(target_mode: AmbientLightMode) { info!("target mode: {:?}", target_mode); - CoreManager::global().set_ambient_light(target_mode).await; + tokio::spawn(async move { CoreManager::global().set_ambient_light(target_mode).await }); } #[tokio::main] From a3e2b5a234101322b2a255f7664320808c031380 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Sun, 15 Jan 2023 20:47:21 +0800 Subject: [PATCH 11/19] =?UTF-8?q?chore:=20=E6=9B=B4=E5=A5=BD=E5=9C=B0?= =?UTF-8?q?=E6=8C=89=E5=B8=A7=E5=8F=91=E9=80=81=E7=81=AF=E6=9D=A1=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/Cargo.lock | 356 ++++++++++++++++++++++++++++++++ src-tauri/Cargo.toml | 1 + src-tauri/src/core/core.rs | 23 ++- src-tauri/src/picker/manager.rs | 8 +- 4 files changed, 383 insertions(+), 5 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index b5e2dbf..f1ca52b 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -38,6 +38,159 @@ version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" +[[package]] +name = "async-attributes" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "async-channel" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-executor" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b" +dependencies = [ + "async-lock", + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" +dependencies = [ + "async-channel", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "async-io" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c374dda1ed3e7d8f0d9ba58715f924862c63eae6849c92d3a18e7fbde9e2794" +dependencies = [ + "async-lock", + "autocfg", + "concurrent-queue", + "futures-lite", + "libc", + "log", + "parking", + "polling", + "slab", + "socket2", + "waker-fn", + "windows-sys 0.42.0", +] + +[[package]] +name = "async-lock" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685" +dependencies = [ + "event-listener", + "futures-lite", +] + +[[package]] +name = "async-process" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6381ead98388605d0d9ff86371043b5aa922a3905824244de40dc263a14fcba4" +dependencies = [ + "async-io", + "async-lock", + "autocfg", + "blocking", + "cfg-if 1.0.0", + "event-listener", + "futures-lite", + "libc", + "signal-hook", + "windows-sys 0.42.0", +] + +[[package]] +name = "async-std" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +dependencies = [ + "async-attributes", + "async-channel", + "async-global-executor", + "async-io", + "async-lock", + "async-process", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-stream" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22068c0c19514942eefcfd4daf8976ef1aad84e61539f95cd200c35202f80af5" +dependencies = [ + "async-stream-impl", + "futures-core", +] + +[[package]] +name = "async-stream-impl" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f9db3b38af870bf7e5cc649167533b493928e50744e2c30ae350230b414670" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-task" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" + [[package]] name = "atk" version = "0.15.1" @@ -62,6 +215,12 @@ dependencies = [ "system-deps 6.0.3", ] +[[package]] +name = "atomic-waker" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" + [[package]] name = "attohttpc" version = "0.22.0" @@ -117,6 +276,20 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blocking" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c67b173a56acffd6d2326fb7ab938ba0b00a71480e14902b2591c87bc5741e8" +dependencies = [ + "async-channel", + "async-lock", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", +] + [[package]] name = "bmp" version = "0.5.0" @@ -322,6 +495,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "concurrent-queue" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd7bef69dc86e3c610e4e7aed41035e2a7ed12e72dd7530f61327a6579a4390b" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -597,6 +779,7 @@ dependencies = [ "futures", "hex", "image", + "mdns", "once_cell", "paris", "rumqttc", @@ -613,6 +796,16 @@ dependencies = [ "webp", ] +[[package]] +name = "dns-parser" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4d33be9473d06f75f58220f71f7a9317aca647dc061dbd3c361b0bef505fbea" +dependencies = [ + "byteorder", + "quick-error", +] + [[package]] name = "dtoa" version = "0.4.8" @@ -655,6 +848,26 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "err-derive" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22deed3a8124cff5fa835713fa105621e43bbdc46690c3a6b68328a012d350d4" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "rustversion", + "syn", + "synstructure", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "exr" version = "1.5.2" @@ -812,6 +1025,21 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-macro" version = "0.3.25" @@ -1085,6 +1313,18 @@ dependencies = [ "regex", ] +[[package]] +name = "gloo-timers" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98c4a8d6391675c6b2ee1a6c8d06e8e2d03605c44cec1270675985a4c2a5500b" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "gobject-sys" version = "0.15.10" @@ -1423,6 +1663,15 @@ dependencies = [ "selectors", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -1485,6 +1734,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if 1.0.0", + "value-bag", ] [[package]] @@ -1559,6 +1809,22 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +[[package]] +name = "mdns" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c769962ac75a6ea437f0922b27834bcccd4c013d591383a16ae5731e3ef0f3f3" +dependencies = [ + "async-std", + "async-stream", + "dns-parser", + "err-derive", + "futures-core", + "futures-util", + "log", + "net2", +] + [[package]] name = "memchr" version = "2.5.0" @@ -1659,6 +1925,17 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "net2" +version = "0.2.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", +] + [[package]] name = "new_debug_unreachable" version = "1.0.4" @@ -1911,6 +2188,12 @@ version = "1.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eaf2319cd71dd9ff38c72bebde61b9ea657134abcf26ae4205f54f772a32810" +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + [[package]] name = "parking_lot" version = "0.12.1" @@ -2124,6 +2407,20 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "polling" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "libc", + "log", + "wepoll-ffi", + "windows-sys 0.42.0", +] + [[package]] name = "pollster" version = "0.2.5" @@ -2192,6 +2489,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quick-xml" version = "0.23.1" @@ -2780,6 +3083,16 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "signal-hook" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" +dependencies = [ + "libc", + "signal-hook-registry", +] + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -2942,6 +3255,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + [[package]] name = "system-deps" version = "5.0.0" @@ -3505,6 +3830,12 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + [[package]] name = "untrusted" version = "0.7.1" @@ -3550,6 +3881,16 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "value-bag" +version = "1.0.0-alpha.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" +dependencies = [ + "ctor", + "version_check", +] + [[package]] name = "vcpkg" version = "0.2.15" @@ -3574,6 +3915,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + [[package]] name = "walkdir" version = "2.3.2" @@ -3784,6 +4131,15 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" +[[package]] +name = "wepoll-ffi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" +dependencies = [ + "cc", +] + [[package]] name = "winapi" version = "0.2.8" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index ee9e59c..69a62c8 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -34,6 +34,7 @@ color_space = "0.5.3" futures = "0.3.25" either = "1.8.0" image = "0.24.5" +mdns = "3.0.0" [features] # by default Tauri runs in production mode diff --git a/src-tauri/src/core/core.rs b/src-tauri/src/core/core.rs index 931a854..9e25c2c 100644 --- a/src-tauri/src/core/core.rs +++ b/src-tauri/src/core/core.rs @@ -3,7 +3,7 @@ use once_cell::sync::OnceCell; use paris::{error, info}; use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, sync::Arc, time::Duration}; +use std::{collections::{HashMap, HashSet}, sync::Arc, time::Duration}; use tauri::async_runtime::RwLock; use tokio::{ sync::mpsc, @@ -108,6 +108,25 @@ impl CoreManager { futs.push(fut); } + let total_colors_count = configs + .iter() + .flat_map(|c| { + vec![ + c.led_strip_of_borders.top, + c.led_strip_of_borders.bottom, + c.led_strip_of_borders.left, + c.led_strip_of_borders.right, + ] + }) + .flat_map(|l| match l { + Some(l) => (l.global_start_position.min(l.global_end_position) + ..l.global_start_position.max(l.global_end_position)) + .collect(), + None => { + vec![] + } + }).collect::>() + .len(); tokio::spawn(async move { let mut global_colors = HashMap::new(); while let Some(screenshot) = rx.recv().await { @@ -127,7 +146,7 @@ impl CoreManager { start_at.elapsed() ); - if global_colors.len() == 60 { + if global_colors.len() >= total_colors_count { let mut colors = vec![]; for index in 0..global_colors.len() { colors.push(*global_colors.get(&index).unwrap()); diff --git a/src-tauri/src/picker/manager.rs b/src-tauri/src/picker/manager.rs index 75c9726..5ccd375 100644 --- a/src-tauri/src/picker/manager.rs +++ b/src-tauri/src/picker/manager.rs @@ -27,11 +27,13 @@ impl Picker { SCREEN_COLOR_PICKER .get_or_init(|| async { + let configs = config::Manager::global().get_config().await.display_configs; + info!("Global Picker use configs. {:?}", configs); Picker { screens: Arc::new(Mutex::new(vec![])), screenshots: Arc::new(Mutex::new(vec![])), display_configs: Arc::new(Mutex::new( - config::Manager::global().get_config().await.display_configs, + configs, )), } }) @@ -39,12 +41,12 @@ impl Picker { } pub async fn list_displays(&self) -> anyhow::Result> { - let mut configs = self.display_configs.lock().await; + let mut configs = vec![]; let displays = Display::all() .map_err(|error| anyhow::anyhow!("Can not get all of displays. {}", error))?; - configs.clear(); + // configs.clear(); let mut futs = FuturesUnordered::new(); for (index, display) in displays.iter().enumerate() { From 6802dbb7c05f0efd0351b43ecabc30dce0a88f11 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Mon, 16 Jan 2023 00:56:19 +0800 Subject: [PATCH 12/19] =?UTF-8?q?feat:=20=E5=9F=BA=E6=9C=AC=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=8B=96=E6=8B=BD=E9=85=8D=E7=BD=AE=E7=81=AF=E6=9D=A1?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 3 +- .../components/completed-led-strip.tsx | 267 ++++++++++++++++-- src/configurator/configurator.tsx | 16 +- src/configurator/contents/led-count.tsx | 25 ++ src/configurator/models/pixel-rgb.ts | 1 + 5 files changed, 286 insertions(+), 26 deletions(-) create mode 100644 src/configurator/contents/led-count.tsx create mode 100644 src/configurator/models/pixel-rgb.ts diff --git a/src/App.tsx b/src/App.tsx index e916cf8..d688bd5 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,12 +2,13 @@ import { useCallback, useEffect, useState } from 'react'; import tw from 'twin.macro'; import { invoke } from '@tauri-apps/api/tauri'; import './App.css'; -import clsx from 'clsx'; import { Configurator } from './configurator/configurator'; import { ButtonSwitch } from './commons/components/button'; type Mode = 'Flowing' | 'Follow' | null; +localStorage.setItem('debug', '*'); + function App() { const [screenshots, setScreenshots] = useState([]); const [ledStripColors, setLedStripColors] = useState([]); diff --git a/src/configurator/components/completed-led-strip.tsx b/src/configurator/components/completed-led-strip.tsx index 28f52a0..cc0f9a6 100644 --- a/src/configurator/components/completed-led-strip.tsx +++ b/src/configurator/components/completed-led-strip.tsx @@ -1,26 +1,43 @@ -import { isNil, splitEvery } from 'ramda'; -import { FC, useMemo } from 'react'; +import debug from 'debug'; +import { isNil, lensPath, set, splitEvery, update } from 'ramda'; +import { + createRef, + FC, + Fragment, + MouseEventHandler, + ReactEventHandler, + ReactNode, + RefObject, + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; import tw, { css, styled } from 'twin.macro'; -import { borders } from '../../constants/border'; -import { DisplayConfig } from '../models/display-config'; +import { Borders, borders } from '../../constants/border'; +import { useLedCount } from '../contents/led-count'; +import { DisplayConfig, LedStripConfigOfBorders } from '../models/display-config'; import { LedStripConfig } from '../models/led-strip-config'; +import { PixelRgb } from '../models/pixel-rgb'; import { ScreenshotDto } from '../models/screenshot.dto'; -import { LedStrip } from './led-strip'; import { StyledPixel } from './styled-pixel'; +const logger = debug('app:completed-led-strip'); + interface CompletedLedStripProps { screenshots: ScreenshotDto[]; onDisplayConfigChange?: (value: DisplayConfig) => void; } type BorderLedStrip = { - pixels: [number, number, number][]; + pixels: PixelRgb[]; config: LedStripConfig | null; }; const StyledContainer = styled.section( ({ rows, columns }: { rows: number; columns: number }) => [ - tw`grid m-4 pb-2`, + tw`grid m-4 pb-2 items-center justify-items-center select-none`, css` grid-template-columns: repeat(${columns}, 1fr); grid-template-rows: auto repeat(${rows}, 1fr); @@ -31,6 +48,7 @@ const StyledCompletedContainer = styled.section( tw`dark:bg-transparent shadow-xl border-gray-500 border rounded-full flex flex-wrap justify-around items-center mb-2`, css` grid-column: 1 / -1; + justify-self: stretch; `, ); @@ -41,7 +59,7 @@ export const CompletedLedStrip: FC = ({ const borderLedStrips: BorderLedStrip[] = useMemo(() => { return screenshots.flatMap((ss) => borders.map((b) => ({ - pixels: splitEvery(3, Array.from(ss.colors[b])) as [number, number, number][], + pixels: splitEvery(3, Array.from(ss.colors[b])) as PixelRgb[], config: ss.config.led_strip_of_borders[b], })), ); @@ -51,9 +69,18 @@ export const CompletedLedStrip: FC = ({ [borderLedStrips], ); + const { setLedCount } = useLedCount(); + // setLedCount for context + useEffect(() => { + setLedCount(ledCount); + }, [ledCount, setLedCount]); + + const [overrideBorderLedStrips, setOverrideBorderLedStrips] = + useState(); + const completedPixels = useMemo(() => { - const completed: [number, number, number][] = new Array(ledCount).fill([0, 0, 0]); - borderLedStrips.forEach(({ pixels, config }) => { + const completed: PixelRgb[] = new Array(ledCount).fill([0, 0, 0]); + (overrideBorderLedStrips ?? borderLedStrips).forEach(({ pixels, config }) => { if (isNil(config)) { return; } @@ -68,21 +95,45 @@ export const CompletedLedStrip: FC = ({ } }); - return completed.map((color) => ); - }, [ledCount, borderLedStrips]); + return completed.map((color, i) => ); + }, [ledCount, borderLedStrips, overrideBorderLedStrips]); const strips = useMemo(() => { - return borderLedStrips.map(({ config, pixels }, index) => ( - - )); + return (overrideBorderLedStrips ?? borderLedStrips).map(({ config, pixels }, index) => + config ? ( + { + setOverrideBorderLedStrips( + update(index, { config: c, pixels }, borderLedStrips), + ); + }} + onConfigFinish={(c) => { + const indexOfDisplay = Math.round(index / borders.length); + const xLens = lensPath([ + borders[index % borders.length], + ]); + const displayConfig: DisplayConfig = { + ...screenshots[indexOfDisplay].config, + led_strip_of_borders: set( + xLens, + c, + screenshots[indexOfDisplay].config.led_strip_of_borders, + ), + }; + logger('Change DisplayConfig. %o', displayConfig); + onDisplayConfigChange?.(displayConfig); + }} + /> + ) : ( +
+ ), + ); + }, [borderLedStrips, overrideBorderLedStrips]); + + useEffect(() => { + setOverrideBorderLedStrips(undefined); }, [borderLedStrips]); return ( @@ -91,3 +142,173 @@ export const CompletedLedStrip: FC = ({ ); }; + +interface DraggableStripProp { + config: LedStripConfig; + pixels: PixelRgb[]; + index: number; + onConfigChange?: (config: LedStripConfig) => void; + onConfigFinish?: (config: LedStripConfig) => void; +} + +const DraggableStrip: FC = ({ + config, + pixels, + index, + onConfigChange, + onConfigFinish, +}) => { + const ledItems = pixels.map((rgb, i) => ( + + )); + + const { ledCount } = useLedCount(); + + const startXRef = useRef(0); + const currentXRef = useRef(0); + const configRef = useRef(); + // const currentDiffRef = useRef(0); + const [currentDiff, setCurrentDiff] = useState(0); + const isDragRef = useRef(false); + const handleMouseMoveRef = useRef<(ev: MouseEvent) => void>(); + const [boxTranslateX, setBoxTranslateX] = useState(0); + + const [placeholders, placeholderRefs]: [ReactNode[], RefObject[]] = + useMemo( + () => + new Array(ledCount) + .fill(undefined) + .map((_, i) => { + const ref = createRef(); + const n = ( + + ); + return [n, ref] as [ReactNode, RefObject]; + }) + .reduce( + ([nList, refList], [n, ref]) => [ + [...nList, n], + [...refList, ref], + ], + [[], []] as [ReactNode[], RefObject[]], + ), + [ledCount], + ); + + const handleMouseDown: MouseEventHandler = useCallback( + (ev) => { + startXRef.current = ev.pageX; + ev.currentTarget.requestPointerLock(); + isDragRef.current = true; + + const placeholderPositions = placeholderRefs.map((it) => { + if (!it.current) { + return [0, 0]; + } + const viewportOffset = it.current.getBoundingClientRect(); + return [viewportOffset.left, viewportOffset.right] as [number, number]; + }); + + logger('placeholderPositions: %o', placeholderPositions); + + // set init position + const initPos = placeholderPositions.findIndex( + ([l, r]) => l <= ev.pageX && r >= ev.pageX, + ); + setCurrentDiff(initPos); + let prevMatch = 0; + + if (handleMouseMoveRef.current) { + document.body.removeEventListener('mousemove', handleMouseMoveRef.current); + } + handleMouseMoveRef.current = (ev) => { + if (!isDragRef.current) { + return; + } + currentXRef.current = ev.pageX; + setBoxTranslateX(currentXRef.current - startXRef.current); + const match = placeholderPositions.findIndex( + ([l, r]) => l <= currentXRef.current && r >= currentXRef.current, + ); + if (match === -1) { + return; + } + + if (match === prevMatch) { + return; + } + prevMatch = match; + + const diff = match - initPos; + const newValue: LedStripConfig = { + ...config, + global_start_position: config.global_start_position + diff, + global_end_position: config.global_end_position + diff, + }; + configRef.current = newValue; + logger('change config. new: $o', newValue); + onConfigChange?.(newValue); + }; + document.body.addEventListener('mousemove', handleMouseMoveRef.current); + }, + [placeholderRefs], + ); + + // move event. + useEffect(() => { + const handleMouseUp = (ev: MouseEvent) => { + startXRef.current = 0; + isDragRef.current = false; + if (configRef.current) { + onConfigFinish?.(configRef.current); + } + document.exitPointerLock(); + if (handleMouseMoveRef.current) { + document.body.removeEventListener('mousemove', handleMouseMoveRef.current); + } + }; + document.body.addEventListener('mouseup', handleMouseUp); + return () => { + document.body.removeEventListener('mouseup', handleMouseUp); + }; + }, []); + // reset translateX when config updated. + useEffect(() => { + startXRef.current = currentXRef.current; + setCurrentDiff(0); + }, [config]); + + return ( + + {placeholders} + {ledItems} +
+
+ ); +}; diff --git a/src/configurator/configurator.tsx b/src/configurator/configurator.tsx index ec5ebc2..882d274 100644 --- a/src/configurator/configurator.tsx +++ b/src/configurator/configurator.tsx @@ -11,6 +11,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faSpinner } from '@fortawesome/free-solid-svg-icons'; import { update } from 'ramda'; import { CompletedLedStrip } from './components/completed-led-strip'; +import { LedCountProvider } from './contents/led-count'; const getPickerConfig = () => invoke('get_picker_config'); const getScreenshotOfDisplays = () => @@ -31,7 +32,7 @@ const StyledConfiguratorContainer = styled.section(tw`flex flex-col items-stretc const StyledDisplayContainer = styled.section(tw`overflow-auto`); -export const Configurator: FC = () => { +const ConfiguratorInner: FC = () => { const { loading: pendingPickerConfig, result: savedPickerConfig } = useAsync( getPickerConfig, [], @@ -96,7 +97,10 @@ export const Configurator: FC = () => { return ( - + {displays}; } sx={{ width: '100%' }}> @@ -106,3 +110,11 @@ export const Configurator: FC = () => { ); }; + +export const Configurator = () => { + return ( + + + + ); +}; diff --git a/src/configurator/contents/led-count.tsx b/src/configurator/contents/led-count.tsx new file mode 100644 index 0000000..ec3ba4a --- /dev/null +++ b/src/configurator/contents/led-count.tsx @@ -0,0 +1,25 @@ +import { + createContext, + Dispatch, + FC, + ReactNode, + SetStateAction, + useContext, + useState, +} from 'react'; + +interface LedCountContext { + ledCount: number; + setLedCount: Dispatch>; +} + +const Context = createContext(undefined as any); + +export const LedCountProvider: FC<{ children: ReactNode }> = ({ children }) => { + const [ledCount, setLedCount] = useState(0); + return ( + {children} + ); +}; + +export const useLedCount = () => useContext(Context); diff --git a/src/configurator/models/pixel-rgb.ts b/src/configurator/models/pixel-rgb.ts new file mode 100644 index 0000000..2229ef0 --- /dev/null +++ b/src/configurator/models/pixel-rgb.ts @@ -0,0 +1 @@ +export type PixelRgb = [number, number, number]; \ No newline at end of file From cb5fb901f94ae67e45c84a4789d20d42a111a568 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Mon, 16 Jan 2023 19:57:04 +0800 Subject: [PATCH 13/19] =?UTF-8?q?fix:=20=E9=99=8D=E4=BD=8E=E6=88=AA?= =?UTF-8?q?=E5=9B=BE=E5=B4=A9=E6=BA=83=E6=A6=82=E7=8E=87=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/main.rs | 20 +++++++++++++------- src-tauri/src/picker/manager.rs | 12 ------------ src-tauri/src/picker/screenshot.rs | 8 +++++++- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 9b4ad86..b9dc33c 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -14,10 +14,16 @@ use paris::*; use picker::config::DisplayConfig; use picker::manager::Picker; use picker::screenshot::ScreenshotDto; -use std::vec; +use tauri::async_runtime::Mutex; +use once_cell::sync::OnceCell; + +static GET_SCREENSHOT_LOCK: OnceCell> = OnceCell::new(); #[tauri::command] async fn take_snapshot() -> Vec { + info!("Hi?"); + let _lock = GET_SCREENSHOT_LOCK.get_or_init(|| Mutex::new(false)).lock().await; + info!("Hi!"); let manager = Picker::global().await; let start = time::Instant::now(); @@ -38,17 +44,17 @@ async fn take_snapshot() -> Vec { #[tauri::command] async fn get_screenshot_by_config(config: DisplayConfig) -> Result { - info!("Hi"); - let manager = Picker::global(); - + info!("Hi?"); + // let _lock = GET_SCREENSHOT_LOCK.get_or_init(|| Mutex::new(false)).lock().await; + // info!("Hi!"); let start = time::Instant::now(); - let screenshot_dto = manager.await.get_screenshot_by_config(config).await; + let screenshot_dto = Picker::preview_display_by_config(config).await; info!("截图耗时 {} s", start.elapsed().as_seconds_f32()); match screenshot_dto { Ok(screenshot_dto) => Ok(screenshot_dto), Err(error) => { - error!("get_screenshot_by_config failed. {}", error); - Err(format!("get_screenshot_by_config failed. {}", error)) + error!("preview_display_by_config failed. {}", error); + Err(format!("preview_display_by_config failed. {}", error)) } } } diff --git a/src-tauri/src/picker/manager.rs b/src-tauri/src/picker/manager.rs index 5ccd375..6680edd 100644 --- a/src-tauri/src/picker/manager.rs +++ b/src-tauri/src/picker/manager.rs @@ -84,16 +84,4 @@ impl Picker { anyhow::Ok(screenshot.to_dto().await) } - - pub async fn get_screenshot_by_config( - &self, - config: DisplayConfig, - ) -> anyhow::Result { - let start = time::Instant::now(); - let mut picker = DisplayPicker::from_config(config)?; - let screenshot = picker.take_screenshot()?; - info!("Take Screenshot Spend: {}", start.elapsed()); - - anyhow::Ok(screenshot.to_dto().await) - } } diff --git a/src-tauri/src/picker/screenshot.rs b/src-tauri/src/picker/screenshot.rs index 563c22f..116619d 100644 --- a/src-tauri/src/picker/screenshot.rs +++ b/src-tauri/src/picker/screenshot.rs @@ -1,8 +1,9 @@ use image::ImageBuffer; use image::{ImageOutputFormat, Rgb}; -use paris::error; +use paris::{error, info}; use serde::{Deserialize, Serialize}; use std::iter; +use std::time::SystemTime; use super::{config::DisplayConfig, led_color::LedColor}; @@ -265,9 +266,14 @@ impl Screenshot { } pub async fn to_dto(&self) -> ScreenshotDto { + let rk = SystemTime::now(); + info!("[{:?} {:p}] to_dto", rk.elapsed(), &self); let encode_image = self.to_webp_base64().await; + info!("[{:?} {:p}] image", rk.elapsed(), &self); let config = self.config.clone(); + info!("[{:?} {:p}] cloned", rk.elapsed(), &self); let colors = self.get_colors(); + info!("[{:?} {:p}] colors", rk.elapsed(), &self); ScreenshotDto { encode_image, config, From 458cc85db27c83694cd8988ef7ae428aa68de566 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Mon, 16 Jan 2023 21:02:53 +0800 Subject: [PATCH 14/19] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E7=81=AF=E6=9D=A1=E4=BD=8D=E7=BD=AE=E6=97=B6=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E9=94=99=E4=B9=B1=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/completed-led-strip.tsx | 193 +---------------- .../components/draggable-strip.tsx | 196 ++++++++++++++++++ .../components/led-strip-editor.tsx | 5 +- src/configurator/configurator.tsx | 5 +- 4 files changed, 210 insertions(+), 189 deletions(-) create mode 100644 src/configurator/components/draggable-strip.tsx diff --git a/src/configurator/components/completed-led-strip.tsx b/src/configurator/components/completed-led-strip.tsx index cc0f9a6..8c5fd23 100644 --- a/src/configurator/components/completed-led-strip.tsx +++ b/src/configurator/components/completed-led-strip.tsx @@ -1,19 +1,6 @@ import debug from 'debug'; import { isNil, lensPath, set, splitEvery, update } from 'ramda'; -import { - createRef, - FC, - Fragment, - MouseEventHandler, - ReactEventHandler, - ReactNode, - RefObject, - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from 'react'; +import { FC, useEffect, useMemo, useState } from 'react'; import tw, { css, styled } from 'twin.macro'; import { Borders, borders } from '../../constants/border'; import { useLedCount } from '../contents/led-count'; @@ -21,9 +8,10 @@ import { DisplayConfig, LedStripConfigOfBorders } from '../models/display-config import { LedStripConfig } from '../models/led-strip-config'; import { PixelRgb } from '../models/pixel-rgb'; import { ScreenshotDto } from '../models/screenshot.dto'; +import { DraggableStrip } from './draggable-strip'; import { StyledPixel } from './styled-pixel'; -const logger = debug('app:completed-led-strip'); +export const logger = debug('app:completed-led-strip'); interface CompletedLedStripProps { screenshots: ScreenshotDto[]; @@ -99,7 +87,7 @@ export const CompletedLedStrip: FC = ({ }, [ledCount, borderLedStrips, overrideBorderLedStrips]); const strips = useMemo(() => { - return (overrideBorderLedStrips ?? borderLedStrips).map(({ config, pixels }, index) => + return borderLedStrips.map(({ config, pixels }, index) => config ? ( = ({ ); }} onConfigFinish={(c) => { - const indexOfDisplay = Math.round(index / borders.length); + const indexOfDisplay = Math.floor(index / borders.length); const xLens = lensPath([ borders[index % borders.length], ]); @@ -122,7 +110,6 @@ export const CompletedLedStrip: FC = ({ screenshots[indexOfDisplay].config.led_strip_of_borders, ), }; - logger('Change DisplayConfig. %o', displayConfig); onDisplayConfigChange?.(displayConfig); }} /> @@ -130,7 +117,7 @@ export const CompletedLedStrip: FC = ({
), ); - }, [borderLedStrips, overrideBorderLedStrips]); + }, [borderLedStrips, screenshots]); useEffect(() => { setOverrideBorderLedStrips(undefined); @@ -143,172 +130,4 @@ export const CompletedLedStrip: FC = ({ ); }; -interface DraggableStripProp { - config: LedStripConfig; - pixels: PixelRgb[]; - index: number; - onConfigChange?: (config: LedStripConfig) => void; - onConfigFinish?: (config: LedStripConfig) => void; -} -const DraggableStrip: FC = ({ - config, - pixels, - index, - onConfigChange, - onConfigFinish, -}) => { - const ledItems = pixels.map((rgb, i) => ( - - )); - - const { ledCount } = useLedCount(); - - const startXRef = useRef(0); - const currentXRef = useRef(0); - const configRef = useRef(); - // const currentDiffRef = useRef(0); - const [currentDiff, setCurrentDiff] = useState(0); - const isDragRef = useRef(false); - const handleMouseMoveRef = useRef<(ev: MouseEvent) => void>(); - const [boxTranslateX, setBoxTranslateX] = useState(0); - - const [placeholders, placeholderRefs]: [ReactNode[], RefObject[]] = - useMemo( - () => - new Array(ledCount) - .fill(undefined) - .map((_, i) => { - const ref = createRef(); - const n = ( - - ); - return [n, ref] as [ReactNode, RefObject]; - }) - .reduce( - ([nList, refList], [n, ref]) => [ - [...nList, n], - [...refList, ref], - ], - [[], []] as [ReactNode[], RefObject[]], - ), - [ledCount], - ); - - const handleMouseDown: MouseEventHandler = useCallback( - (ev) => { - startXRef.current = ev.pageX; - ev.currentTarget.requestPointerLock(); - isDragRef.current = true; - - const placeholderPositions = placeholderRefs.map((it) => { - if (!it.current) { - return [0, 0]; - } - const viewportOffset = it.current.getBoundingClientRect(); - return [viewportOffset.left, viewportOffset.right] as [number, number]; - }); - - logger('placeholderPositions: %o', placeholderPositions); - - // set init position - const initPos = placeholderPositions.findIndex( - ([l, r]) => l <= ev.pageX && r >= ev.pageX, - ); - setCurrentDiff(initPos); - let prevMatch = 0; - - if (handleMouseMoveRef.current) { - document.body.removeEventListener('mousemove', handleMouseMoveRef.current); - } - handleMouseMoveRef.current = (ev) => { - if (!isDragRef.current) { - return; - } - currentXRef.current = ev.pageX; - setBoxTranslateX(currentXRef.current - startXRef.current); - const match = placeholderPositions.findIndex( - ([l, r]) => l <= currentXRef.current && r >= currentXRef.current, - ); - if (match === -1) { - return; - } - - if (match === prevMatch) { - return; - } - prevMatch = match; - - const diff = match - initPos; - const newValue: LedStripConfig = { - ...config, - global_start_position: config.global_start_position + diff, - global_end_position: config.global_end_position + diff, - }; - configRef.current = newValue; - logger('change config. new: $o', newValue); - onConfigChange?.(newValue); - }; - document.body.addEventListener('mousemove', handleMouseMoveRef.current); - }, - [placeholderRefs], - ); - - // move event. - useEffect(() => { - const handleMouseUp = (ev: MouseEvent) => { - startXRef.current = 0; - isDragRef.current = false; - if (configRef.current) { - onConfigFinish?.(configRef.current); - } - document.exitPointerLock(); - if (handleMouseMoveRef.current) { - document.body.removeEventListener('mousemove', handleMouseMoveRef.current); - } - }; - document.body.addEventListener('mouseup', handleMouseUp); - return () => { - document.body.removeEventListener('mouseup', handleMouseUp); - }; - }, []); - // reset translateX when config updated. - useEffect(() => { - startXRef.current = currentXRef.current; - setCurrentDiff(0); - }, [config]); - - return ( - - {placeholders} - {ledItems} -
-
- ); -}; diff --git a/src/configurator/components/draggable-strip.tsx b/src/configurator/components/draggable-strip.tsx new file mode 100644 index 0000000..b815372 --- /dev/null +++ b/src/configurator/components/draggable-strip.tsx @@ -0,0 +1,196 @@ +import { + createRef, + FC, + Fragment, + MouseEventHandler, + ReactNode, + RefObject, + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; +import { css } from 'twin.macro'; +import { useLedCount } from '../contents/led-count'; +import { LedStripConfig } from '../models/led-strip-config'; +import { PixelRgb } from '../models/pixel-rgb'; +import { StyledPixel } from './styled-pixel'; +import { logger } from './completed-led-strip'; + +interface DraggableStripProp { + config: LedStripConfig; + pixels: PixelRgb[]; + index: number; + onConfigChange?: (config: LedStripConfig) => void; + onConfigFinish?: (config: LedStripConfig) => void; +} +export const DraggableStrip: FC = ({ + config, + pixels, + index, + onConfigChange, + onConfigFinish, +}) => { + const { ledCount } = useLedCount(); + + const startXRef = useRef(0); + const currentXRef = useRef(0); + const configRef = useRef(); + const [availableConfig, setAvailableConfig] = useState(config); + // const currentDiffRef = useRef(0); + const isDragRef = useRef(false); + const handleMouseMoveRef = useRef<(ev: MouseEvent) => void>(); + const [boxTranslateX, setBoxTranslateX] = useState(0); + + const ledItems = useMemo( + () => + pixels.map((rgb, i) => ( + + )), + [pixels, availableConfig], + ); + + const [placeholders, placeholderRefs]: [ReactNode[], RefObject[]] = + useMemo( + () => + new Array(ledCount) + .fill(undefined) + .map((_, i) => { + const ref = createRef(); + const n = ( + + ); + return [n, ref] as [ReactNode, RefObject]; + }) + .reduce( + ([nList, refList], [n, ref]) => [ + [...nList, n], + [...refList, ref], + ], + [[], []] as [ReactNode[], RefObject[]], + ), + [ledCount], + ); + + // start and moving + const handleMouseDown: MouseEventHandler = useCallback( + (ev) => { + startXRef.current = ev.pageX; + ev.currentTarget.requestPointerLock(); + isDragRef.current = true; + logger('handleMouseDown, config: %o', config); + + const placeholderPositions = placeholderRefs.map((it) => { + if (!it.current) { + return [0, 0]; + } + const viewportOffset = it.current.getBoundingClientRect(); + return [viewportOffset.left, viewportOffset.right] as [number, number]; + }); + + logger('placeholderPositions: %o', placeholderPositions); + + // set init position + const initPos = placeholderPositions.findIndex( + ([l, r]) => l <= ev.pageX && r >= ev.pageX, + ); + let prevMatch = 0; + + if (handleMouseMoveRef.current) { + document.body.removeEventListener('mousemove', handleMouseMoveRef.current); + } + handleMouseMoveRef.current = (ev) => { + if (!isDragRef.current) { + return; + } + currentXRef.current = ev.pageX; + setBoxTranslateX(currentXRef.current - startXRef.current); + const match = placeholderPositions.findIndex( + ([l, r]) => l <= currentXRef.current && r >= currentXRef.current, + ); + if (match === -1) { + return; + } + + if (match === prevMatch) { + return; + } + prevMatch = match; + + const diff = match - initPos; + const newValue: LedStripConfig = { + ...config, + global_start_position: config.global_start_position + diff, + global_end_position: config.global_end_position + diff, + }; + configRef.current = newValue; + setAvailableConfig(newValue); + logger('change config. old: %o, new: %o', config, newValue); + onConfigChange?.(newValue); + }; + document.body.addEventListener('mousemove', handleMouseMoveRef.current); + }, + [placeholderRefs, availableConfig, setAvailableConfig, config], + ); + + // move event. + useEffect(() => { + const handleMouseUp = (ev: MouseEvent) => { + if (configRef.current && isDragRef.current) { + onConfigFinish?.(configRef.current); + } + startXRef.current = 0; + isDragRef.current = false; + document.exitPointerLock(); + if (handleMouseMoveRef.current) { + document.body.removeEventListener('mousemove', handleMouseMoveRef.current); + } + }; + document.body.addEventListener('mouseup', handleMouseUp); + return () => { + document.body.removeEventListener('mouseup', handleMouseUp); + }; + }, [onConfigFinish]); + // reset translateX when config updated. + useEffect(() => { + startXRef.current = currentXRef.current; + setAvailableConfig(config); + setBoxTranslateX(0); + logger('useEffect, config: %o', config); + }, [config]); + + return ( + + {placeholders} + {ledItems} +
+
+ ); +}; diff --git a/src/configurator/components/led-strip-editor.tsx b/src/configurator/components/led-strip-editor.tsx index f88ce86..2a88d06 100644 --- a/src/configurator/components/led-strip-editor.tsx +++ b/src/configurator/components/led-strip-editor.tsx @@ -1,7 +1,7 @@ import { HTMLAttributes, useCallback } from 'react'; import { FC } from 'react'; import { LedStripConfig } from '../models/led-strip-config'; -import tw, { css, styled, theme } from 'twin.macro'; +import tw, { styled } from 'twin.macro'; import { faLeftRight, faMinus, faPlus } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -52,6 +52,9 @@ export const LedStripEditor: FC = ({ + {`s: ${config?.global_start_position ?? 'x'}, e: ${ + config?.global_end_position ?? 'x' + }`} ); }; diff --git a/src/configurator/configurator.tsx b/src/configurator/configurator.tsx index 882d274..7f20802 100644 --- a/src/configurator/configurator.tsx +++ b/src/configurator/configurator.tsx @@ -1,5 +1,5 @@ import { invoke } from '@tauri-apps/api'; -import { FC, Fragment, useCallback, useEffect, useMemo, useState } from 'react'; +import { FC, useEffect, useMemo, useState } from 'react'; import tw, { styled } from 'twin.macro'; import { useAsync, useAsyncCallback } from 'react-async-hook'; import { DisplayWithLedStrips } from './components/display-with-led-strips'; @@ -12,6 +12,9 @@ import { faSpinner } from '@fortawesome/free-solid-svg-icons'; import { update } from 'ramda'; import { CompletedLedStrip } from './components/completed-led-strip'; import { LedCountProvider } from './contents/led-count'; +import debug from 'debug'; + +const logger = debug('app:configurator'); const getPickerConfig = () => invoke('get_picker_config'); const getScreenshotOfDisplays = () => From af03b22d05dc44ac41c93039ae14ec761c6fc0f7 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Mon, 16 Jan 2023 21:35:22 +0800 Subject: [PATCH 15/19] =?UTF-8?q?feat:=20=E7=81=AF=E6=9D=A1=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/core/core.rs | 22 +++++++++---- src-tauri/src/picker/config/manger.rs | 27 ++++++++++++---- .../components/draggable-strip.tsx | 30 ++++++++--------- .../components/led-strip-editor.tsx | 32 +++++++++++++++++-- 4 files changed, 80 insertions(+), 31 deletions(-) diff --git a/src-tauri/src/core/core.rs b/src-tauri/src/core/core.rs index 9e25c2c..4bbcd88 100644 --- a/src-tauri/src/core/core.rs +++ b/src-tauri/src/core/core.rs @@ -3,7 +3,11 @@ use once_cell::sync::OnceCell; use paris::{error, info}; use serde::{Deserialize, Serialize}; -use std::{collections::{HashMap, HashSet}, sync::Arc, time::Duration}; +use std::{ + collections::{HashMap, HashSet}, + sync::Arc, + time::Duration, +}; use tauri::async_runtime::RwLock; use tokio::{ sync::mpsc, @@ -13,7 +17,7 @@ use tracing::warn; use crate::{ picker::{ - config::DisplayConfig, display_picker::DisplayPicker, led_color::LedColor, manager::Picker, + self, config::DisplayConfig, display_picker::DisplayPicker, led_color::LedColor, screenshot::Screenshot, }, rpc, @@ -90,12 +94,16 @@ impl CoreManager { pub async fn play_follow(&self) -> anyhow::Result<()> { let mut futs = vec![]; - let configs = Picker::global().await.display_configs.lock().await; + let configs = picker::config::Manager::global().reload_config().await; + let configs = match configs { + Ok(c) => c.display_configs, + Err(err) => anyhow::bail!("can not get display configs. {:?}", err), + }; info!("piker display configs: {:?}", configs); let (tx, mut rx) = mpsc::channel(10); - for config in configs.to_owned() { + for config in configs.clone() { let tx = tx.clone(); let fut = tokio::spawn(async move { match Self::follow_display_by_config(config, tx).await { @@ -108,8 +116,7 @@ impl CoreManager { futs.push(fut); } - let total_colors_count = configs - .iter() + let total_colors_count = configs.iter() .flat_map(|c| { vec![ c.led_strip_of_borders.top, @@ -125,7 +132,8 @@ impl CoreManager { None => { vec![] } - }).collect::>() + }) + .collect::>() .len(); tokio::spawn(async move { let mut global_colors = HashMap::new(); diff --git a/src-tauri/src/picker/config/manger.rs b/src-tauri/src/picker/config/manger.rs index d8751da..4d9d8f0 100644 --- a/src-tauri/src/picker/config/manger.rs +++ b/src-tauri/src/picker/config/manger.rs @@ -2,7 +2,8 @@ use std::{ env::current_dir, fs::{self, File}, io::Read, - path::PathBuf, sync::Arc, + path::PathBuf, + sync::Arc, }; use once_cell::sync::OnceCell; @@ -43,7 +44,9 @@ impl Manager { } pub fn new(config: Configuration) -> Self { - Self { config: Arc::new(Mutex::new(config)) } + Self { + config: Arc::new(Mutex::new(config)), + } } pub fn get_config_file_path() -> PathBuf { @@ -70,7 +73,10 @@ impl Manager { .map_err(|error| anyhow::anyhow!("can not parse config file contents. {}", error)) } - pub fn write_config_to_disk(config_file_path: PathBuf, config: &Configuration) -> anyhow::Result<()> { + pub fn write_config_to_disk( + config_file_path: PathBuf, + config: &Configuration, + ) -> anyhow::Result<()> { let contents = serde_json::to_string(config) .map_err(|error| anyhow::anyhow!("can not serialize config. {}", error))?; info!("contents: {}", contents); @@ -86,6 +92,13 @@ impl Manager { let mut config = self.config.lock().await; *config = new_config.clone(); } + pub async fn reload_config(&self) -> anyhow::Result { + let mut config = self.config.lock().await; + let new_config = Self::read_config_from_disk(Self::get_config_file_path()) + .map_err(|err| anyhow::anyhow!("can not reload config. {:?}", err))?; + *config = new_config.clone(); + return anyhow::Ok(new_config); + } } #[cfg(test)] @@ -103,9 +116,11 @@ mod tests { let temp = TestDir::temp().create("config_dir", test_dir::FileType::Dir); let config_file_path = temp.path("config_dir").join("picker.config.json"); let manager = crate::picker::config::manger::Manager::default(); - crate::picker::config::manger::Manager - ::write_config_to_disk(config_file_path.clone(), &Configuration::default()) - .unwrap(); + crate::picker::config::manger::Manager::write_config_to_disk( + config_file_path.clone(), + &Configuration::default(), + ) + .unwrap(); let contents = fs::read_to_string(config_file_path.clone()).unwrap(); let _config: Configuration = serde_json::from_str(contents.as_str()).unwrap(); diff --git a/src/configurator/components/draggable-strip.tsx b/src/configurator/components/draggable-strip.tsx index b815372..5bb5a8a 100644 --- a/src/configurator/components/draggable-strip.tsx +++ b/src/configurator/components/draggable-strip.tsx @@ -43,21 +43,21 @@ export const DraggableStrip: FC = ({ const handleMouseMoveRef = useRef<(ev: MouseEvent) => void>(); const [boxTranslateX, setBoxTranslateX] = useState(0); - const ledItems = useMemo( - () => - pixels.map((rgb, i) => ( - - )), - [pixels, availableConfig], - ); + const ledItems = useMemo(() => { + const step = config.global_start_position - config.global_end_position < 0 ? 1 : -1; + return pixels.map((rgb, i) => ( + + )); + }, [pixels, availableConfig]); const [placeholders, placeholderRefs]: [ReactNode[], RefObject[]] = useMemo( diff --git a/src/configurator/components/led-strip-editor.tsx b/src/configurator/components/led-strip-editor.tsx index 2a88d06..b30e4e9 100644 --- a/src/configurator/components/led-strip-editor.tsx +++ b/src/configurator/components/led-strip-editor.tsx @@ -28,7 +28,14 @@ export const LedStripEditor: FC = ({ }) => { const addLed = useCallback(() => { if (config) { - onChange?.({ ...config, global_end_position: config.global_end_position + 1 }); + if (config.global_start_position <= config.global_end_position) { + onChange?.({ ...config, global_end_position: config.global_end_position + 1 }); + } else { + onChange?.({ + ...config, + global_start_position: config.global_start_position + 1, + }); + } } else { onChange?.(new LedStripConfig(0, 0, 1)); } @@ -36,10 +43,29 @@ export const LedStripEditor: FC = ({ const removeLed = useCallback(() => { if (!config) { onChange?.(null); + } else if (Math.abs(config.global_start_position - config.global_end_position) <= 1) { + onChange?.(null); } else { - onChange?.({ ...config, global_end_position: config.global_end_position - 1 }); + if (config.global_start_position <= config.global_end_position) { + onChange?.({ ...config, global_end_position: config.global_end_position - 1 }); + } else { + onChange?.({ + ...config, + global_start_position: config.global_start_position - 1, + }); + } } }, [config, onChange]); + const reverse = useCallback(() => { + if (!config) { + return; + } + onChange?.({ + ...config, + global_start_position: config.global_end_position, + global_end_position: config.global_start_position, + }); + }, [config, onChange]); return ( @@ -49,7 +75,7 @@ export const LedStripEditor: FC = ({ - + {`s: ${config?.global_start_position ?? 'x'}, e: ${ From 1882b8ccdc2500549372d866f9cce20359518db2 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Mon, 16 Jan 2023 23:39:33 +0800 Subject: [PATCH 16/19] =?UTF-8?q?feat:=20=E4=BD=BF=E7=94=A8=E5=B7=A6?= =?UTF-8?q?=E5=BC=80=E5=8F=B3=E9=97=AD=E5=8C=BA=E9=97=B4=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E6=AF=8F=E8=BE=B9=E7=9A=84=20LEDs=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/picker/screenshot.rs | 30 ++++++------------- src-tauri/src/rpc/manager.rs | 14 +++++++++ .../components/draggable-strip.tsx | 7 +++-- .../components/led-strip-editor.tsx | 2 +- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src-tauri/src/picker/screenshot.rs b/src-tauri/src/picker/screenshot.rs index 116619d..554b9ea 100644 --- a/src-tauri/src/picker/screenshot.rs +++ b/src-tauri/src/picker/screenshot.rs @@ -41,7 +41,7 @@ impl Screenshot { config.display_width, led_strip_config .global_start_position - .abs_diff(led_strip_config.global_end_position), + .abs_diff(led_strip_config.global_end_position) + 1, 5, ), None => { @@ -56,7 +56,7 @@ impl Screenshot { config.display_width, led_strip_config .global_start_position - .abs_diff(led_strip_config.global_end_position), + .abs_diff(led_strip_config.global_end_position) + 1, 5, ); points @@ -81,7 +81,7 @@ impl Screenshot { config.display_height, led_strip_config .global_start_position - .abs_diff(led_strip_config.global_end_position), + .abs_diff(led_strip_config.global_end_position) + 1, 5, ); points @@ -103,7 +103,7 @@ impl Screenshot { config.display_height, led_strip_config .global_start_position - .abs_diff(led_strip_config.global_end_position), + .abs_diff(led_strip_config.global_end_position) + 1, 5, ); points @@ -212,23 +212,6 @@ impl Screenshot { colors } - pub fn get_top_colors(&self) -> Vec { - self.get_one_edge_colors(&self.sample_points.top) - } - - pub fn get_top_of_led_start_at(&self) -> usize { - self.config - .led_strip_of_borders.top - .and_then(|c| Some(c.global_start_position)) - .unwrap_or(0) - } - pub fn get_top_of_led_end_at(&self) -> usize { - self.config - .led_strip_of_borders.top - .and_then(|c| Some(c.global_end_position)) - .unwrap_or(0) - } - pub async fn to_webp_base64(&self) -> String { let bitmap = &self.bitmap; let stride = bitmap.len() / self.config.display_height; @@ -280,6 +263,11 @@ impl Screenshot { colors, } } + + + pub fn get_config(&self) -> DisplayConfig { + self.config + } } #[derive(Clone, Serialize, Deserialize, Debug)] diff --git a/src-tauri/src/rpc/manager.rs b/src-tauri/src/rpc/manager.rs index 6166ae7..d37c224 100644 --- a/src-tauri/src/rpc/manager.rs +++ b/src-tauri/src/rpc/manager.rs @@ -38,4 +38,18 @@ impl Manager { .await .map_err(|error| anyhow::anyhow!("mqtt publish failed. {}", error)) } + + pub async fn publish_led_sub_pixels(&self, payload: Vec) -> anyhow::Result<()> { + + self.mqtt + .client + .publish( + "display-ambient-light/desktop/colors", + rumqttc::QoS::AtLeastOnce, + false, + payload, + ) + .await + .map_err(|error| anyhow::anyhow!("mqtt publish failed. {}", error)) + } } diff --git a/src/configurator/components/draggable-strip.tsx b/src/configurator/components/draggable-strip.tsx index 5bb5a8a..871910a 100644 --- a/src/configurator/components/draggable-strip.tsx +++ b/src/configurator/components/draggable-strip.tsx @@ -183,8 +183,11 @@ export const DraggableStrip: FC = ({
= ({ }); } } else { - onChange?.(new LedStripConfig(0, 0, 1)); + onChange?.(new LedStripConfig(0, 0, 0)); } }, [config, onChange]); const removeLed = useCallback(() => { From a55db2553bb3f2e68efd1971ef32721d7b8d3a0a Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Mon, 16 Jan 2023 23:39:59 +0800 Subject: [PATCH 17/19] =?UTF-8?q?fix:=20=E8=BE=93=E5=87=BA=E4=BF=A1?= =?UTF-8?q?=E5=8F=B7=E7=9A=84=20led=20=E9=A1=BA=E5=BA=8F=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/core/core.rs | 50 ++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/src-tauri/src/core/core.rs b/src-tauri/src/core/core.rs index 4bbcd88..a4deee6 100644 --- a/src-tauri/src/core/core.rs +++ b/src-tauri/src/core/core.rs @@ -116,7 +116,8 @@ impl CoreManager { futs.push(fut); } - let total_colors_count = configs.iter() + let total_colors_count = configs + .iter() .flat_map(|c| { vec![ c.led_strip_of_borders.top, @@ -136,36 +137,53 @@ impl CoreManager { .collect::>() .len(); tokio::spawn(async move { - let mut global_colors = HashMap::new(); + let mut global_sub_pixels = HashMap::new(); while let Some(screenshot) = rx.recv().await { let start_at = Instant::now(); - let colors = screenshot.get_top_colors(); - let start = screenshot - .get_top_of_led_start_at() - .min(screenshot.get_top_of_led_end_at()); - - for (index, color) in colors.into_iter().enumerate() { - global_colors.insert(index + start, color); + let colors = screenshot.get_colors(); + let config = screenshot.get_config(); + for (colors, config) in vec![ + (colors.top, config.led_strip_of_borders.top), + (colors.right, config.led_strip_of_borders.right), + (colors.bottom, config.led_strip_of_borders.bottom), + (colors.left, config.led_strip_of_borders.left), + ] { + match config { + Some(config) => { + let (sign, start) = if config.global_start_position <= config.global_end_position + { + (1, config.global_start_position as isize * 3) + } else { + (-1, (config.global_start_position as isize + 1) * 3 - 1) + }; + for (index, color) in colors.into_iter().enumerate() { + global_sub_pixels + .insert((sign * index as isize + start) as usize, color); + } + } + None => {} + } } info!( "led count: {}, spend: {:?}", - global_colors.len(), + global_sub_pixels.len(), start_at.elapsed() ); - if global_colors.len() >= total_colors_count { + if global_sub_pixels.len() >= total_colors_count * 3 { let mut colors = vec![]; - for index in 0..global_colors.len() { - colors.push(*global_colors.get(&index).unwrap()); + for index in 0..global_sub_pixels.len() { + colors.push(*global_sub_pixels.get(&index).unwrap()); } - global_colors = HashMap::new(); + // info!("{:?}", colors); + global_sub_pixels = HashMap::new(); match rpc::manager::Manager::global() - .publish_led_colors(&colors) + .publish_led_sub_pixels(colors) .await { Ok(_) => { - info!("publish successful",); + // info!("publish successful",); } Err(error) => { warn!("publish led colors failed. {}", error); From d3dfdb4d821448b4d9767cdc0489612df95ec970 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Tue, 17 Jan 2023 00:41:03 +0800 Subject: [PATCH 18/19] =?UTF-8?q?fix:=20=E5=BD=93=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=8F=8D=E5=90=91=E6=97=B6=EF=BC=8C=E9=A2=9C=E8=89=B2=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/core/core.rs | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src-tauri/src/core/core.rs b/src-tauri/src/core/core.rs index a4deee6..4f91560 100644 --- a/src-tauri/src/core/core.rs +++ b/src-tauri/src/core/core.rs @@ -150,26 +150,34 @@ impl CoreManager { ] { match config { Some(config) => { - let (sign, start) = if config.global_start_position <= config.global_end_position - { - (1, config.global_start_position as isize * 3) - } else { - (-1, (config.global_start_position as isize + 1) * 3 - 1) - }; + let (sign, start) = + if config.global_start_position <= config.global_end_position { + (1, config.global_start_position as isize * 3) + } else { + (-1, (config.global_start_position as isize + 1) * 3 - 1) + }; for (index, color) in colors.into_iter().enumerate() { - global_sub_pixels - .insert((sign * index as isize + start) as usize, color); + let pixel_index = index / 3; + let sub_pixel_index = index % 3; + let offset = if sign < 0 { + 2 - sub_pixel_index + } else { + sub_pixel_index + }; + let global_sub_pixel_index = + (sign * (pixel_index as isize * 3 + offset as isize) + start ) as usize; + global_sub_pixels.insert(global_sub_pixel_index, color); } } None => {} } } - info!( - "led count: {}, spend: {:?}", - global_sub_pixels.len(), - start_at.elapsed() - ); + // info!( + // "led count: {}, spend: {:?}", + // global_sub_pixels.len(), + // start_at.elapsed() + // ); if global_sub_pixels.len() >= total_colors_count * 3 { let mut colors = vec![]; From af671a4e63278106daa53abb913affbc38afe846 Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Thu, 19 Jan 2023 23:54:03 +0800 Subject: [PATCH 19/19] =?UTF-8?q?style:=20=E5=A4=96=E8=A7=82=E6=94=B9?= =?UTF-8?q?=E8=BF=9B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/core/core.rs | 8 ++++---- src/configurator/components/draggable-strip.tsx | 2 +- src/configurator/components/led-strip-editor.tsx | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src-tauri/src/core/core.rs b/src-tauri/src/core/core.rs index 4f91560..028bde3 100644 --- a/src-tauri/src/core/core.rs +++ b/src-tauri/src/core/core.rs @@ -1,6 +1,6 @@ use futures::future::join_all; use once_cell::sync::OnceCell; -use paris::{error, info}; +use paris::{error, info, warn}; use serde::{Deserialize, Serialize}; use std::{ @@ -13,7 +13,6 @@ use tokio::{ sync::mpsc, time::{sleep, Instant}, }; -use tracing::warn; use crate::{ picker::{ @@ -165,7 +164,8 @@ impl CoreManager { sub_pixel_index }; let global_sub_pixel_index = - (sign * (pixel_index as isize * 3 + offset as isize) + start ) as usize; + (sign * (pixel_index as isize * 3 + offset as isize) + start) + as usize; global_sub_pixels.insert(global_sub_pixel_index, color); } } @@ -220,7 +220,7 @@ impl CoreManager { if let AmbientLightMode::Follow = *lock { drop(lock); let screenshot = picker.take_screenshot()?; - info!("Take Screenshot Spend: {:?}", start.elapsed()); + // info!("Take Screenshot Spend: {:?}", start.elapsed()); match tx.send(screenshot).await { Ok(_) => {} Err(err) => { diff --git a/src/configurator/components/draggable-strip.tsx b/src/configurator/components/draggable-strip.tsx index 871910a..b193228 100644 --- a/src/configurator/components/draggable-strip.tsx +++ b/src/configurator/components/draggable-strip.tsx @@ -70,7 +70,7 @@ export const DraggableStrip: FC = ({ = ({