├── .gitignore ├── cli ├── .gitignore ├── Cargo.toml ├── src │ ├── utils.rs │ └── main.rs └── Cargo.lock ├── src ├── lib.rs ├── http_client.rs ├── common.rs ├── signal.rs ├── downloader.rs └── uploader.rs ├── .github └── assets │ └── discord-us-cli.gif ├── .idea ├── vcs.xml ├── .gitignore ├── discord.xml ├── modules.xml ├── dataSources.xml └── discord-us.iml ├── Cargo.toml ├── README.md └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | trash -------------------------------------------------------------------------------- /cli/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod uploader; 2 | pub mod downloader; 3 | mod http_client; 4 | pub mod common; 5 | pub mod signal; -------------------------------------------------------------------------------- /.github/assets/discord-us-cli.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UwUDev/discord-us/HEAD/.github/assets/discord-us-cli.gif -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/discord.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /cli/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cli" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | discord-us = { path = ".." } 10 | clap = { version = "4.4.2", features = ["derive"] } 11 | indicatif = "0.17.6" 12 | bytesize = "1.3.0" 13 | rand = "0.8.5" -------------------------------------------------------------------------------- /.idea/dataSources.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | sqlite.xerial 6 | true 7 | org.sqlite.JDBC 8 | jdbc:sqlite:$PROJECT_DIR$/files.db 9 | $ProjectFileDir$ 10 | 11 | 12 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "discord-us" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | # rusqlite = { version = "0.29.0", features = ["bundled"] } 10 | sha256 = "1.4.0" 11 | reqwest = { version = "0.11.20", features = ["blocking", "json", "brotli", "gzip"] } 12 | aes = "0.7" 13 | block-modes = "0.8" 14 | pbkdf2 = "0.9" 15 | hmac = "0.11.0" 16 | sha2 = "0.9.5" 17 | # uuid = { version = "1.4.1", features = ["v4"] } 18 | serde_json = "1.0.105" 19 | # md5 = "0.7" 20 | threadpool = "1.8.1" 21 | rand = "0.8.5" 22 | serde = { version = "1.0.188", features = ["derive"] } 23 | hex-buffer-serde = "0.4.0" 24 | sorted-vec = "0.8.2" 25 | dyn-clone = "1.0.13" 26 | dyn-clonable = "0.9.0" -------------------------------------------------------------------------------- /.idea/discord-us.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/http_client.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | use reqwest::blocking::{Client, RequestBuilder}; 3 | 4 | pub fn prepare_discord_request (request: RequestBuilder, token: String) -> RequestBuilder { 5 | request.header("Authorization", token.clone()) 6 | .header("Content-Type", "application/json") 7 | .header("X-Super-Properties", "eyJvcyI6IkFuZHJvaWQiLCJicm93c2VyIjoiRGlzY29yZCBBbmRyb2lkIiwiZGV2aWNlIjoiYmx1ZWpheSIsInN5c3RlbV9sb2NhbGUiOiJmci1GUiIsImNsaWVudF92ZXJzaW9uIjoiMTkyLjEzIC0gcm4iLCJyZWxlYXNlX2NoYW5uZWwiOiJnb29nbGVSZWxlYXNlIiwiZGV2aWNlX3ZlbmRvcl9pZCI6IjhkZGU4M2IzLTUzOGEtNDJkMi04MzExLTM1YmFlY2M2YmJiOCIsImJyb3dzZXJfdXNlcl9hZ2VudCI6IiIsImJyb3dzZXJfdmVyc2lvbiI6IiIsIm9zX3ZlcnNpb24iOiIzMyIsImNsaWVudF9idWlsZF9udW1iZXIiOjE5MjAxMzAwMTEzNzczLCJjbGllbnRfZXZlbnRfc291cmNlIjpudWxsLCJkZXNpZ25faWQiOjB9") 8 | .header("Accept-Language", "fr-FR") 9 | .header("X-Discord-Locale", "fr") 10 | .header("X-Discord-Timezone", "Europe/Paris") 11 | .header("X-Debug-Options", "bugReporterEnabled") 12 | .header("User-Agent", "Discord-Android/192013;RNA") 13 | .header("Host", "discord.com") 14 | .header("Connection", "Keep-Alive") 15 | .header("Accept-Encoding", "gzip") 16 | } 17 | 18 | pub fn create_client () -> Client{ 19 | Client::builder() 20 | .timeout(Duration::from_secs(60 * 60)) 21 | .brotli(true) 22 | .gzip(true) 23 | .build() 24 | .unwrap() 25 | } -------------------------------------------------------------------------------- /cli/src/utils.rs: -------------------------------------------------------------------------------- 1 | use rand::{distributions::Alphanumeric, Rng}; 2 | use discord_us::signal::{ProgressionRange}; 3 | 4 | pub fn create_random_password(length: usize) -> String { 5 | rand::thread_rng() 6 | .sample_iter(&Alphanumeric) 7 | .take(length) 8 | .map(char::from) 9 | .collect() 10 | } 11 | 12 | pub fn to_progress_bar( 13 | ranges: Vec>, 14 | total: u64, 15 | size: usize, 16 | character_loaded: char, 17 | character_unloaded: char 18 | ) -> String { 19 | let mut result = String::with_capacity(size); 20 | 21 | let part_range = total / size as u64; 22 | let mut range_cursor = 0usize; 23 | let mut c = 0u64; 24 | let step = part_range / 2; 25 | 26 | while c < total { 27 | if let Some(range) = ranges.get(range_cursor) { 28 | if c + step >= range.range_start && (c + step).min(total) <= range.range_end { 29 | result.push(character_loaded); 30 | } else { 31 | result.push(character_unloaded); 32 | if c >= range.range_end { 33 | range_cursor += 1; 34 | } 35 | } 36 | } else { 37 | result.push(character_unloaded); 38 | } 39 | 40 | c += part_range; 41 | }; 42 | 43 | result 44 | } 45 | 46 | // Do test 47 | #[cfg(test)] 48 | mod tests { 49 | use crate::utils::to_progress_bar; 50 | use discord_us::signal::{ProgressionRange}; 51 | 52 | #[test] 53 | fn test_progress_bar() { 54 | let ranges = vec![ 55 | ProgressionRange::of(241, 401), 56 | 57 | ProgressionRange::of(608, 754), 58 | ]; 59 | 60 | let result = to_progress_bar(ranges, 1000, 100, '#', '-'); 61 | 62 | println!("{}", result); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Project killed by Discord 2 | 3 | This project was made to abuse discord's storage system (aka Google cloud) with a highly secured system. 4 | 5 | Thanks to [theking90000](https://github.com/theking90000) for making this project a 100 times better :) 6 | 7 | This project was meant to be a torrent like system and was working tbh really well, after uploading thousands of gigabytes of data, discord decided to add extra "security" and this is why your discord files links has an expiration timestamp on it :c 8 | 9 | _Maybe a Terrabyte idk but now it's a dead project_ 10 | 11 | **You should take a look at "improvemets" branch** 12 | 13 |


14 | 15 | # Discord Unlimited Storage 16 | 17 | ## What is this? 18 | 19 | This is a simple rust app that allows you to upload files to discord without any file size limit. 20 | The uploaded files are saved in a format called 'Waterfall' (torrent synonym) keeping all information needed to 21 | download the file from Discord's server. 22 | 23 | It uses Aes256Cbc encryption to encrypt your files, so you don't have to worry about your files being analysed by 24 | discord and tencent + it avoids discord to remove non ToS compliant files. 25 | 26 | ## Demonstration 27 | 28 | ![Demonstration](./.github/assets/discord-us-cli.gif) 29 | 30 | ## How to use it? 31 | 32 | For the moment, there is 2 ways of using it: via the command line or via the lib. 33 | 34 | ### Command line 35 | 36 | To use the command line, you need to build the executable. 37 | ```shell 38 | cd cli && cargo build --release 39 | ``` 40 | 41 | The executable will be in `cli/target/release`. 42 | 43 | Then you can use it like this: 44 | ```shell 45 | cli.exe upload --token $TOKEN --channel_id $CHANNEL_ID --input file.txt --waterfall file.waterfall 46 | 47 | cli.exe download --waterfall file.waterfall --output file.txt 48 | ``` 49 | -------------------------------------------------------------------------------- /src/common.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::io::{Write}; 3 | use serde::{Deserialize, Serialize}; 4 | use hex_buffer_serde::{Hex as _, HexForm}; 5 | 6 | pub trait FileWritable { 7 | fn write_to_file(&self, file_path: String); 8 | } 9 | 10 | pub trait FileReadable { 11 | fn from_file(file_path: String) -> Self; 12 | } 13 | 14 | #[derive(Serialize, Deserialize, Clone, Debug)] 15 | pub struct Waterfall { 16 | pub filename: String, 17 | pub password: String, 18 | pub size: u64, 19 | 20 | pub containers: Vec, 21 | } 22 | 23 | impl FileWritable for Waterfall { 24 | fn write_to_file(&self, file_path: String) { 25 | let mut file = File::create(file_path).unwrap(); 26 | file.write_all(serde_json::to_string_pretty(&self).unwrap().as_bytes()).unwrap(); 27 | } 28 | } 29 | 30 | impl FileReadable for Waterfall { 31 | fn from_file(file_path: String) -> Self { 32 | let mut file = File::open(file_path).unwrap(); 33 | 34 | serde_json::from_reader(&mut file).unwrap() 35 | } 36 | } 37 | 38 | #[derive(Serialize, Deserialize, Clone, Debug)] 39 | pub struct Container { 40 | pub storage_url: String, 41 | pub chunk_size: u64, 42 | pub chunk_count: u64, 43 | 44 | #[serde(with = "HexForm")] 45 | pub salt: [u8; 16], 46 | 47 | pub bytes_range: [u64; 2], 48 | } 49 | 50 | pub enum Subscription { 51 | Free, 52 | Basic, 53 | Classic, 54 | // yeah you can still buy it 55 | Boost, 56 | } 57 | 58 | impl Subscription { 59 | pub fn get_max_chunk_upload_size(&self) -> usize { 60 | match *self { 61 | Self::Free => 25 * 1024 * 1024, 62 | Self::Basic => 50 * 1024 * 1024, 63 | Self::Classic => 100 * 1024 * 1024, 64 | Self::Boost => 500 * 1024 * 1024, 65 | } 66 | } 67 | } 68 | 69 | #[derive(Serialize, Deserialize, Clone)] 70 | pub struct ResumableFileUpload { 71 | pub(crate) file_path: String, 72 | pub(crate) file_size: u64, 73 | 74 | pub(crate) container_size: u32, 75 | pub(crate) remaining_indexes: Vec, 76 | pub(crate) containers: Vec, 77 | 78 | #[serde(with = "HexForm")] 79 | pub(crate) file_hash: [u8; 32], 80 | 81 | pub(crate) thread_count: usize, 82 | } 83 | 84 | impl FileWritable for ResumableFileUpload { 85 | fn write_to_file(&self, file_path: String) { 86 | let mut file = File::create(file_path).unwrap(); 87 | file.write_all(serde_json::to_string_pretty(&self).unwrap().as_bytes()).unwrap(); 88 | } 89 | } 90 | 91 | impl FileReadable for ResumableFileUpload { 92 | fn from_file(file_path: String) -> Self { 93 | let mut file = File::open(file_path).unwrap(); 94 | 95 | serde_json::from_reader(&mut file).unwrap() 96 | } 97 | } -------------------------------------------------------------------------------- /cli/src/main.rs: -------------------------------------------------------------------------------- 1 | mod utils; 2 | 3 | use std::thread::sleep; 4 | use std::io::{stdout, Write}; 5 | use std::sync::{Arc, Mutex}; 6 | use std::thread; 7 | use clap::{Parser, Subcommand}; 8 | // use clap::builder::Str; 9 | 10 | use discord_us::common::{Waterfall, FileReadable, Subscription, FileWritable}; 11 | use discord_us::downloader::{FileDownloader, Downloader, WaterfallDownloader, ByteRangeDownloader}; 12 | use discord_us::signal::{PartProgression, Signal}; 13 | 14 | use std::time::Instant; 15 | 16 | use bytesize::ByteSize; 17 | use discord_us::uploader::{FileUploadArguments, FileUploader, Uploader, WaterfallExporter}; 18 | use crate::utils::to_progress_bar; 19 | 20 | #[derive(Parser, Debug)] 21 | #[command(name = "discord-us", version = "0.1.0", about = "Discord Unlimited Storage")] 22 | struct Cli { 23 | #[command(subcommand)] 24 | command: Commands, 25 | } 26 | 27 | #[derive(Subcommand, Debug)] 28 | enum Commands { 29 | Download { 30 | #[arg(short, long)] 31 | password: Option, 32 | 33 | #[arg(short, long)] 34 | waterfall: String, 35 | 36 | #[arg(short, long)] 37 | output: String, 38 | }, 39 | 40 | Upload { 41 | #[arg(short, long)] 42 | password: Option, 43 | 44 | #[arg(short, long)] 45 | waterfall: String, 46 | 47 | #[arg(short, long)] 48 | input: String, 49 | 50 | #[arg(short, long, default_value_t = Subscription::Free.get_max_chunk_upload_size())] 51 | container_size: usize, 52 | 53 | #[arg(short, long)] 54 | token: String, 55 | 56 | #[arg(long)] 57 | channel_id: u64, 58 | }, 59 | } 60 | 61 | fn main() { 62 | let args = Cli::parse(); 63 | 64 | match args.command { 65 | Commands::Download { password, waterfall, output } => { 66 | let mut signal: PartProgression = PartProgression::new(); 67 | 68 | let waterfall = Waterfall::from_file(waterfall); 69 | 70 | println!("Downloading file {} ({}) into {}", waterfall.filename, ByteSize(waterfall.size).to_string_as(true), output); 71 | 72 | let mut file_downloader = FileDownloader::from_waterfall(waterfall.clone()); 73 | let now = Instant::now(); 74 | 75 | if let Some(password) = password { 76 | file_downloader.set_password(password); 77 | } 78 | 79 | file_downloader.with_signal(&signal); 80 | 81 | let f = Arc::new(Mutex::new(file_downloader.clone())); 82 | 83 | let handle = thread::spawn(move || { 84 | f.lock().unwrap().download_file(output); 85 | }); 86 | 87 | 88 | while signal.get_total() != file_downloader.get_size() { 89 | sleep(std::time::Duration::from_millis(50)); 90 | 91 | signal.retrim_ranges(); 92 | 93 | let progress = signal.get_total(); 94 | let data = signal.get_data(); 95 | 96 | let elapsed = now.elapsed().as_secs_f64(); 97 | 98 | let bar = to_progress_bar(data, file_downloader.get_size(), 50, '#', '-'); 99 | 100 | print!("\rProgress: {} {}/{} ({}/s) ({:.2}%)", 101 | bar, 102 | ByteSize(progress).to_string_as(true), 103 | ByteSize(file_downloader.get_size()).to_string_as(true), 104 | ByteSize((progress as f64 / elapsed) as u64).to_string_as(true), 105 | (progress as f64 / file_downloader.get_size() as f64) * 100.0); 106 | 107 | stdout().flush().unwrap(); 108 | } 109 | handle.join().unwrap(); 110 | 111 | println!("\nDownloaded succeed {:?}", now.elapsed()); 112 | } 113 | Commands::Upload { input, password, waterfall, container_size, channel_id, token } => { 114 | let mut signal: PartProgression = PartProgression::new(); 115 | 116 | let mut file_uploader = FileUploader::new(input, container_size as u32); 117 | let now = Instant::now(); 118 | 119 | let pass = match password.clone() { 120 | None => utils::create_random_password(16), 121 | Some(pass) => pass 122 | }; 123 | 124 | let mut upload_args = FileUploadArguments::new(pass.clone(), token.clone(), channel_id); 125 | 126 | upload_args.with_signal(&signal); 127 | 128 | let total_upload_size = file_uploader.upload(upload_args); 129 | 130 | let start = Instant::now(); 131 | 132 | println!("\n"); 133 | 134 | loop { 135 | sleep(std::time::Duration::from_millis(50)); 136 | 137 | signal.retrim_ranges(); 138 | 139 | let progress = signal.get_total(); 140 | let data = signal.get_data(); 141 | 142 | let elapsed = start.elapsed().as_secs_f64(); 143 | 144 | let bar = to_progress_bar(data, total_upload_size, 50, '#', '-'); 145 | 146 | print!("\rProgress: {} {}/{} ({}/s) ({:.2}%)", 147 | bar, 148 | ByteSize(progress).to_string_as(true), 149 | ByteSize(total_upload_size).to_string_as(true), 150 | ByteSize((progress as f64 / elapsed) as u64).to_string_as(true), 151 | (progress as f64 / total_upload_size as f64) * 100.0); 152 | 153 | stdout().flush().unwrap(); 154 | 155 | if progress == total_upload_size { 156 | println!("\nFinalizing upload..."); 157 | sleep(std::time::Duration::from_millis(5000)); 158 | break; 159 | } 160 | } 161 | 162 | let waterfall_struct = if password.is_some() { 163 | file_uploader.export_waterfall() 164 | } else { 165 | file_uploader.export_waterfall_with_password(pass.clone()) 166 | }; 167 | 168 | 169 | println!("Exporting waterfall"); 170 | 171 | waterfall_struct.write_to_file(waterfall.clone()); 172 | 173 | println!("Uploaded succeed {:?}", now.elapsed()); 174 | } 175 | }; 176 | } -------------------------------------------------------------------------------- /src/signal.rs: -------------------------------------------------------------------------------- 1 | use core::cmp::{Ord, PartialOrd, PartialEq}; 2 | use std::cmp::Ordering; 3 | use std::fmt::Debug; 4 | use std::ops::{Add, AddAssign, Sub}; 5 | use std::sync::atomic::AtomicU64; 6 | use std::sync::{Arc, Mutex}; 7 | 8 | use sorted_vec::SortedVec; 9 | use dyn_clone::{DynClone, clone_trait_object}; 10 | 11 | pub trait ReportSignal: DynClone 12 | where D: Sized { 13 | fn report_data(&mut self, t: D); 14 | } 15 | 16 | clone_trait_object!( ReportSignal where D: Sized + 'static); 17 | 18 | pub trait Signal 19 | where 20 | D: Sized { 21 | fn get_data(&self) -> D; 22 | } 23 | 24 | // Linear progression 25 | // Only meant for 1 updater 26 | // multiple readers 27 | #[derive(Clone, Debug)] 28 | pub struct LinearProgression { 29 | progression: Arc, 30 | } 31 | 32 | impl LinearProgression { 33 | pub fn new() -> Self { 34 | Self { 35 | progression: Arc::new(AtomicU64::new(0)), 36 | } 37 | } 38 | } 39 | 40 | impl ReportSignal for LinearProgression { 41 | fn report_data(&mut self, t: u64) { 42 | let atomic = &self.progression; 43 | 44 | atomic.fetch_add(t, std::sync::atomic::Ordering::SeqCst); 45 | } 46 | } 47 | 48 | impl Signal for LinearProgression { 49 | fn get_data(&self) -> u64 { 50 | let atomic = &self.progression; 51 | 52 | atomic.load(std::sync::atomic::Ordering::SeqCst) 53 | } 54 | } 55 | 56 | pub trait Integer: Add + AddAssign + Sub + Ord + PartialOrd + PartialEq + Clone + Copy + Debug + Zero {} 57 | 58 | pub trait Zero { 59 | fn zero() -> Self; 60 | } 61 | 62 | //impl Integer for T where T: Add + AddAssign + Ord + PartialOrd + PartialEq + Clone + Debug + 'static {} 63 | 64 | impl Integer for u64 {} 65 | 66 | impl Zero for u64 { 67 | fn zero() -> Self { 68 | 0 69 | } 70 | } 71 | 72 | 73 | #[derive(Clone, Debug)] 74 | pub struct ProgressionRange 75 | where 76 | T: Integer { 77 | pub range_start: T, 78 | pub range_end: T, 79 | } 80 | 81 | impl PartialEq for ProgressionRange { 82 | fn eq(&self, other: &Self) -> bool { 83 | self.range_start == other.range_start && self.range_end == other.range_end 84 | } 85 | } 86 | 87 | impl PartialOrd for ProgressionRange { 88 | fn partial_cmp(&self, other: &Self) -> Option { 89 | if self.range_start < other.range_start { 90 | Some(Ordering::Less) 91 | } else if self.range_start > other.range_start { 92 | Some(Ordering::Greater) 93 | } else if self.range_end < other.range_end { 94 | Some(Ordering::Less) 95 | } else if self.range_end > other.range_end { 96 | Some(Ordering::Greater) 97 | } else { 98 | Some(Ordering::Equal) 99 | } 100 | } 101 | } 102 | 103 | impl Eq for ProgressionRange {} 104 | 105 | impl Ord for ProgressionRange { 106 | fn cmp(&self, other: &Self) -> Ordering { 107 | if self.range_start < other.range_start { 108 | Ordering::Less 109 | } else if self.range_start > other.range_start { 110 | Ordering::Greater 111 | } else if self.range_end < other.range_end { 112 | Ordering::Less 113 | } else if self.range_end > other.range_end { 114 | Ordering::Greater 115 | } else { 116 | Ordering::Equal 117 | } 118 | } 119 | } 120 | 121 | #[derive(Clone, Debug)] 122 | pub struct PartProgression 123 | where T: Integer { 124 | progression: Arc>>>, 125 | } 126 | 127 | impl ProgressionRange { 128 | pub fn of(range_start: T, range_end: T) -> Self { 129 | Self { 130 | range_start, 131 | range_end, 132 | } 133 | } 134 | } 135 | 136 | impl PartProgression { 137 | pub fn new() -> Self { 138 | Self { 139 | progression: Arc::new(Mutex::new(SortedVec::new())), 140 | } 141 | } 142 | 143 | pub fn retrim_ranges(&mut self) { 144 | // not optimal but i can't use retain_mut on SortedVec 145 | // because it does not implement DerefMut. 146 | // the solution is to clone into a Vec and then replace the 147 | // current SortedVec with the new Vec 148 | 149 | let mut ranges = self.progression.lock().unwrap(); 150 | 151 | let vec = ranges.to_vec(); 152 | 153 | let mut prev_i = 0; 154 | 155 | let mut new_vec: Vec> = Vec::new(); 156 | 157 | for i in 0..vec.len() { 158 | let current = vec.get(i).unwrap().clone(); 159 | 160 | if prev_i != i { 161 | let prev = new_vec.get_mut(prev_i).unwrap(); 162 | 163 | if current.range_start <= prev.range_end { 164 | //println!("Merged {:?}->{:?} + {:?}->{:?} = {:?}->{:?}", prev.range_start, prev.range_end, current.range_start, current.range_end, prev.range_start, current.range_end); 165 | prev.range_end = current.range_end; 166 | continue; 167 | } 168 | } 169 | 170 | prev_i = new_vec.len(); 171 | new_vec.push(current); 172 | } 173 | 174 | //println!("Did retrim on size {}", new_vec.len()); 175 | 176 | *ranges = SortedVec::from(new_vec); 177 | } 178 | 179 | pub fn get_total(&self) -> T { 180 | let mut total: T = T::zero(); 181 | for range in self.get_data().iter() { 182 | total += range.range_end - range.range_start; 183 | } 184 | total 185 | } 186 | } 187 | 188 | impl ReportSignal> for PartProgression { 189 | fn report_data(&mut self, t: ProgressionRange) { 190 | self.progression.lock().unwrap().push(t); 191 | } 192 | } 193 | 194 | impl Signal>> for PartProgression { 195 | fn get_data(&self) -> Vec> { 196 | self.progression.lock().unwrap().to_vec() 197 | } 198 | } 199 | 200 | #[derive(Clone)] 201 | pub struct LinearPartSignal 202 | where T: Integer + 'static { 203 | signal: Box>>, 204 | cursor: T, 205 | } 206 | 207 | impl ReportSignal for LinearPartSignal { 208 | fn report_data(&mut self, t: T) { 209 | self.signal.report_data(ProgressionRange::of(self.cursor, self.cursor + t)); 210 | 211 | self.cursor += t; 212 | } 213 | } 214 | 215 | impl LinearPartSignal { 216 | pub fn new(signal: Box>>, cursor: T) -> Self { 217 | Self { signal, cursor } 218 | } 219 | } 220 | 221 | // impl ReportSignal for EmptySignal { 222 | // fn report_data(&mut self, t: U) {} 223 | // } 224 | 225 | // Test 226 | #[cfg(test)] 227 | mod tests { 228 | use crate::signal::{PartProgression, Signal, ProgressionRange, ReportSignal, LinearPartSignal}; 229 | 230 | #[test] 231 | fn test_ranges() { 232 | let mut signal = PartProgression::new(); 233 | 234 | signal.report_data(ProgressionRange::of(0, 10)); 235 | signal.report_data(ProgressionRange::of(10, 20)); 236 | 237 | signal.report_data(ProgressionRange::of(100, 110)); 238 | 239 | signal.report_data(ProgressionRange::of(20, 30)); 240 | signal.report_data(ProgressionRange::of(30, 40)); 241 | 242 | signal.report_data(ProgressionRange::of(110, 120)); 243 | 244 | signal.report_data(ProgressionRange::of(40, 50)); 245 | signal.report_data(ProgressionRange::of(50, 60)); 246 | 247 | signal.report_data(ProgressionRange::of(120, 130)); 248 | 249 | signal.retrim_ranges(); 250 | println!("{:?}", signal.get_data()); 251 | 252 | // let mut s = LinearPartSignal::new(Box::new(signal.clone()), 71 as u64); 253 | // 254 | // s.report_data(10); 255 | // s.report_data(40); 256 | // 257 | // 258 | // println!("{:?}", signal.get_data()); 259 | } 260 | } 261 | 262 | // Callback signal 263 | #[derive(Clone)] 264 | pub struct CallbackSignal { 265 | pub callback: CB, 266 | } 267 | 268 | 269 | impl CallbackSignal { 270 | fn trigger_callback

(self: &'_ mut Self, param: P) 271 | where 272 | CB : Fn(P) -> (), 273 | { 274 | (self.callback)(param); 275 | } 276 | } 277 | 278 | impl ReportSignal<()> for CallbackSignal 279 | where 280 | CB: Fn(()) -> () + Clone + 'static, 281 | { 282 | fn report_data(&mut self, t: ()) { 283 | self.trigger_callback(t); 284 | } 285 | } -------------------------------------------------------------------------------- /src/downloader.rs: -------------------------------------------------------------------------------- 1 | use std::cmp::{min}; 2 | use std::fs::File; 3 | use std::io::{Read, Write}; 4 | use aes::Aes256; 5 | use block_modes::block_padding::Pkcs7; 6 | use block_modes::{BlockMode, Cbc}; 7 | use hmac::Hmac; 8 | use pbkdf2::pbkdf2; 9 | use reqwest::blocking::{Response}; 10 | use reqwest::{StatusCode}; 11 | use sha2::{Digest, Sha256}; 12 | use crate::common::{Container, Waterfall}; 13 | use crate::http_client::create_client; 14 | use crate::signal::{ReportSignal, ProgressionRange, LinearPartSignal, PartProgression}; 15 | 16 | type Aes256Cbc = Cbc; 17 | 18 | const METADATA_SIZE: usize = 64; 19 | 20 | pub trait Downloader { 21 | fn download_file(&self, file_path: String); 22 | } 23 | 24 | pub trait WaterfallDownloader { 25 | fn from_waterfall(waterfall: Waterfall) -> Self; 26 | } 27 | 28 | pub trait ByteRangeDownloader { 29 | fn get_size(&self) -> u64; 30 | 31 | //fn get_range(&self, start: u64, end: u64) -> ByteRangeStreamDownloader; 32 | } 33 | 34 | 35 | #[derive(Clone)] 36 | pub struct DownloadProgressionSignal { 37 | signal: Option>>>, 38 | } 39 | 40 | impl DownloadProgressionSignal { 41 | pub fn new() -> Self { 42 | Self { 43 | signal: None, 44 | } 45 | } 46 | 47 | fn get_report_signal(&self, cursor: u64) -> Option>> { 48 | match &self.signal { 49 | Some(signal) => Some(Box::new(LinearPartSignal::new( 50 | signal.clone(), 51 | cursor, 52 | ))), 53 | None => None 54 | } 55 | } 56 | } 57 | 58 | #[derive(Clone)] 59 | pub struct FileDownloader { 60 | waterfall: Waterfall, 61 | password: String, 62 | 63 | signal: DownloadProgressionSignal, 64 | } 65 | 66 | unsafe impl Send for FileDownloader { 67 | } 68 | 69 | impl WaterfallDownloader for FileDownloader { 70 | fn from_waterfall(waterfall: Waterfall) -> Self { 71 | let waterfall = waterfall.clone(); 72 | let password = waterfall.password.clone(); 73 | 74 | FileDownloader { 75 | waterfall, 76 | password, 77 | 78 | signal: DownloadProgressionSignal::new(), 79 | } 80 | } 81 | } 82 | 83 | impl FileDownloader { 84 | pub fn set_password(&mut self, password: String) -> &mut FileDownloader { 85 | self.password = password.clone(); 86 | 87 | self 88 | } 89 | 90 | pub fn with_signal(&mut self, signal: &PartProgression) { 91 | self.signal.signal = Some(Box::new(signal.clone())); 92 | } 93 | 94 | pub fn get_container_downloader(&self, container: Container) -> ContainerDownloader { 95 | ContainerDownloader::new(container.clone(), self.waterfall.size, self.password.clone()) 96 | } 97 | 98 | pub fn get_range(&self, start: u64, end: u64) -> ByteRangeStreamDownloader { 99 | let downloader = ByteRangeStreamDownloader::new([start, end], self.clone()); 100 | 101 | downloader 102 | } 103 | } 104 | 105 | #[derive(Clone)] 106 | pub struct ContainerDownloader { 107 | container: Container, 108 | key: [u8; 32], 109 | file_size: u64, 110 | } 111 | 112 | impl ContainerDownloader { 113 | fn hash_key(encryption_password: String, salt: [u8; 16]) -> [u8; 32] { 114 | let mut key = [0u8; 32]; 115 | pbkdf2::>(encryption_password.as_bytes(), &salt, 10000, &mut key); 116 | key 117 | } 118 | 119 | pub fn new(container: Container, file_size: u64, encryption_password: String) -> Self { 120 | let key = Self::hash_key(encryption_password, container.salt); 121 | 122 | ContainerDownloader { 123 | container, 124 | key, 125 | file_size, 126 | } 127 | } 128 | 129 | pub fn get_byte_stream(&self, chunk_offset: u64, count: usize) -> Result { 130 | ByteStream::new(self.container.clone(), self.key.clone(), self.file_size, chunk_offset, count) 131 | } 132 | 133 | pub fn get_chunks(&self, chunk_offset: u64, count: usize) -> Result>, &str> { 134 | let mut chunks: Vec> = Vec::with_capacity(count); 135 | 136 | let mut downloader = self.get_byte_stream(chunk_offset, count).unwrap(); 137 | 138 | for _i in 0..count { 139 | let mut chunk: Vec = vec![0; self.container.chunk_size as usize - METADATA_SIZE]; 140 | 141 | downloader.read(&mut chunk).expect("TODO: panic message"); 142 | 143 | chunks.push(chunk); 144 | } 145 | 146 | Ok(chunks.clone()) 147 | } 148 | } 149 | 150 | pub struct ByteStream { 151 | container: Container, 152 | key: [u8; 32], 153 | file_size: u64, 154 | 155 | chunk_offset: u64, 156 | count: usize, 157 | 158 | current_chunk: u64, 159 | buffer: Vec, 160 | buffer_cursor: usize, 161 | 162 | response: Response, 163 | } 164 | 165 | impl ByteStream { 166 | pub fn new(container: Container, key: [u8; 32], file_size: u64, chunk_offset: u64, count: usize) -> Result { 167 | let range_start = chunk_offset * container.chunk_size; 168 | let range_stop = range_start + (count as u64 * container.chunk_size); 169 | 170 | let response = create_client().get(container.storage_url.clone()) 171 | .header("User-Agent", "Mozilla/5.0") 172 | .header("Range", format!("bytes={}-{}", range_start, range_stop)) 173 | .send() 174 | .unwrap(); 175 | 176 | if response.status() != StatusCode::from_u16(206).unwrap() { 177 | return Err("Invalid response status"); 178 | } 179 | 180 | let chunk_size = container.chunk_size; 181 | 182 | Ok(Self { container, key, file_size, chunk_offset, count, current_chunk: 0, buffer: vec![0; chunk_size as usize], buffer_cursor: chunk_size as usize, response }) 183 | } 184 | 185 | fn download_chunk(&mut self) -> Result<(), &str> { 186 | let mut buffer = vec![0; self.container.chunk_size as usize]; 187 | 188 | let mut read = 0; 189 | 190 | while read < buffer.len() { 191 | let r = self.response.read(&mut buffer[read..]).expect("TODO: panic message"); 192 | read += r; 193 | } 194 | 195 | // println!("Download: Read {} bytes (chunk {})", read, self.current_chunk + self.chunk_offset); 196 | 197 | let chunk_start = self.container.bytes_range[0] + (self.current_chunk + self.chunk_offset) * (self.container.chunk_size - METADATA_SIZE as u64); 198 | 199 | let chunk_stop = min(self.file_size, chunk_start + self.container.chunk_size - (METADATA_SIZE as u64)); 200 | 201 | return match self.decrypt_and_verify_chunk(&mut buffer, (chunk_stop - chunk_start) as usize) { 202 | Ok(data) => { 203 | self.buffer = data; 204 | Ok(()) 205 | } 206 | Err(err) => { 207 | eprintln!("Error: {}", err); 208 | Err("Cannot decrypt chunk") 209 | } 210 | }; 211 | } 212 | 213 | fn decrypt_and_verify_chunk(&self, chunk: &mut Vec, content_size: usize) -> Result, &str> { 214 | //println!("Decrypting and verifying chunk of size {} (real {})", content_size, chunk.len()); 215 | 216 | let chunk_size = self.container.chunk_size as usize; 217 | 218 | if chunk.len() != chunk_size { 219 | return Err("Chunk size mismatch"); 220 | } 221 | 222 | let salt = chunk[(chunk_size - 48)..(chunk_size - 32)].to_vec(); 223 | let hash = chunk[(chunk_size - 32)..].to_vec(); 224 | 225 | //println!("Read salt: {:X?}", salt); 226 | //println!("Read hash: {:X?}", hash); 227 | 228 | let cipher = Aes256Cbc::new_from_slices( 229 | &self.key.clone(), 230 | &salt.clone(), 231 | ).unwrap(); 232 | 233 | if let Err(err) = cipher.decrypt(&mut chunk[0..(chunk_size - 48)]) { 234 | eprintln!("Error: {err}"); 235 | return Err("Cannot decrypt chunk"); 236 | } 237 | 238 | // compute hash 239 | let data = chunk[0..content_size].to_vec(); 240 | 241 | let mut hasher = Sha256::new(); 242 | hasher.update(&chunk[0..((self.container.chunk_size as usize) - (METADATA_SIZE))]); 243 | let data_hash = hasher.finalize(); 244 | 245 | if hash != data_hash.to_vec() { 246 | return Err("Hash mismatch"); 247 | } 248 | 249 | Ok(data.to_vec()) 250 | } 251 | } 252 | 253 | impl Read for ByteStream { 254 | fn read(&mut self, buf: &mut [u8]) -> std::io::Result { 255 | //println!("Read : size({:?}) | residual buffer_cursor {:?}", buf.len(), self.buffer_cursor); 256 | 257 | let mut read = 0; 258 | 259 | while read < buf.len() { 260 | // println!("Read loop {:?} over {:?}", self.buffer_cursor, self.buffer.len()); 261 | 262 | if self.buffer_cursor < self.buffer.len() { 263 | let remain = min(buf.len() - read, self.buffer.len() - self.buffer_cursor); 264 | buf[read..(read + remain)].clone_from_slice(&self.buffer[self.buffer_cursor..(self.buffer_cursor + remain)]); 265 | read += remain; 266 | self.buffer_cursor += remain; 267 | } 268 | 269 | if self.buffer_cursor >= self.buffer.len() { 270 | // println!("Count: {:?} | Current chunk: {:?}", self.count, self.current_chunk); 271 | 272 | if self.current_chunk >= self.count as u64 { 273 | return Ok(read); 274 | } else { 275 | self.download_chunk().expect("TODO: panic message"); 276 | self.current_chunk += 1; 277 | self.buffer_cursor = 0; 278 | } 279 | } 280 | } 281 | 282 | Ok(read) 283 | } 284 | } 285 | 286 | impl Downloader for FileDownloader { 287 | fn download_file(&self, file_path: String) { 288 | let mut f = File::create(file_path).unwrap(); 289 | 290 | let signal = &mut self.signal.get_report_signal(0); 291 | 292 | let mut containers = self.waterfall.clone().containers.clone(); 293 | containers.sort_by(|a,b| a.bytes_range[0].cmp(&b.bytes_range[0])); 294 | 295 | for ctn in containers.iter() { 296 | let container = self.get_container_downloader(ctn.clone()); 297 | let mut stream = container.get_byte_stream(0, ctn.chunk_count as usize).unwrap(); 298 | 299 | let mut buf = [0u8; 65536 - 64]; 300 | let mut to_write = (ctn.bytes_range[1] - ctn.bytes_range[0]) as usize; 301 | 302 | //println!("to_write: {}", to_write); 303 | 304 | while to_write > 0 { 305 | let read = stream.read(&mut buf).unwrap(); 306 | 307 | let c = to_write.min(read); 308 | f.write_all(&mut buf[..c]).expect("TODO: panic message"); 309 | // println!("to_write: {}", to_write); 310 | 311 | if let Some(s) = signal { 312 | s.report_data(c as u64); 313 | } 314 | 315 | to_write -= c; 316 | } 317 | } 318 | } 319 | } 320 | 321 | impl ByteRangeDownloader for FileDownloader { 322 | fn get_size(&self) -> u64 { 323 | self.waterfall.size 324 | } 325 | } 326 | 327 | pub struct ByteRangeStreamDownloader { 328 | range: [u64; 2], 329 | file_downloader: FileDownloader, 330 | position: u64, 331 | current_container: Option, 332 | buffer: Vec, 333 | buffer_cursor: Option, 334 | 335 | current_bytestream: Option, 336 | sorted_containers: Vec, 337 | } 338 | 339 | impl ByteRangeStreamDownloader { 340 | pub fn new(range: [u64; 2], file_downloader: FileDownloader) -> Self { 341 | let mut sorted_containers = file_downloader.waterfall.containers.clone(); 342 | sorted_containers.sort_by(|a, b| a.bytes_range[0].cmp(&b.bytes_range[0])); 343 | 344 | ByteRangeStreamDownloader { 345 | range, 346 | file_downloader, 347 | 348 | position: range[0], 349 | current_container: None, 350 | buffer: Vec::new(), 351 | buffer_cursor: None, 352 | current_bytestream: None, 353 | 354 | sorted_containers, 355 | } 356 | } 357 | 358 | fn find_container(&self, start: u64) -> Option { 359 | for container in self.sorted_containers.clone() { 360 | if start >= container.bytes_range[0] && start < container.bytes_range[1] { 361 | return Some(container); 362 | } 363 | } 364 | None 365 | } 366 | 367 | fn get_remaining(&self) -> u64 { 368 | self.range[1] - self.position 369 | } 370 | 371 | fn read_all_into_buff(&mut self) -> usize { 372 | return match self.current_bytestream { 373 | Some(ref mut stream) => { 374 | let mut read = 0; 375 | 376 | while read < self.buffer.len() { 377 | let r = stream.read(&mut self.buffer[read..]).expect("TODO: panic message"); 378 | read += r; 379 | } 380 | 381 | read 382 | } 383 | None => 0 384 | }; 385 | } 386 | 387 | fn is_container_out_of_bound(&self) -> bool { 388 | return match self.current_container { 389 | Some(ref container) => { 390 | self.position >= container.bytes_range[1] 391 | } 392 | None => true 393 | }; 394 | } 395 | 396 | fn is_position_out_of_bound(&self) -> bool { 397 | return self.position >= self.range[1]; 398 | } 399 | 400 | fn update_container(&mut self) { 401 | self.current_container = self.find_container(self.position); 402 | //println!("Update container: {:?}", self.current_container); 403 | } 404 | 405 | fn start_container_download(&mut self) { 406 | if let Some(ref container) = self.current_container { 407 | let start = self.position - container.bytes_range[0]; 408 | let chunk_size = self.get_chunk_real_size() as u64; 409 | // make start a multiple of chunk_size 410 | let chunk_start = start / chunk_size; 411 | let chunk_end = min(container.chunk_count, ((min(self.range[1], container.bytes_range[1]) - container.bytes_range[0]) / chunk_size) + 1); 412 | 413 | let container_downloader = self.file_downloader.get_container_downloader(container.clone()); 414 | 415 | //println!("Starting container downloader start: {} || start : {} | end : {}", start, chunk_start, chunk_end); 416 | 417 | self.current_bytestream = container_downloader.get_byte_stream(chunk_start, (chunk_end - chunk_start) as usize).ok(); 418 | } 419 | } 420 | 421 | fn get_buffer_cursor(&self) -> usize { 422 | return match self.buffer_cursor { 423 | Some(cursor) => cursor, 424 | None => 0 425 | }; 426 | } 427 | 428 | fn set_buffer_cursor(&mut self, cursor: usize) { 429 | self.buffer_cursor = Some(cursor); 430 | } 431 | 432 | fn get_chunk_real_size(&self) -> usize { 433 | return match self.current_container { 434 | Some(ref container) => container.chunk_size as usize - METADATA_SIZE, 435 | None => 0 436 | }; 437 | } 438 | 439 | fn get_current_chunk_size(&self, offset: usize) -> usize { 440 | let real_size = self.get_chunk_real_size(); 441 | let remaining = self.get_remaining() as usize; 442 | 443 | return min(real_size, remaining + offset); 444 | } 445 | 446 | fn get_skip_offset(&self) -> usize { 447 | match self.current_container { 448 | Some(ref container) => { 449 | let chunk_size = self.get_chunk_real_size() as u64; 450 | 451 | // we are in the first chunk 452 | if self.position == self.range[0] { 453 | let start = self.position - container.bytes_range[0]; 454 | 455 | let chunk_start = start / chunk_size; 456 | 457 | 458 | return (self.position - (chunk_start * chunk_size)) as usize; 459 | } 460 | } 461 | None => {} 462 | } 463 | 464 | return 0; 465 | } 466 | } 467 | 468 | impl Read for ByteRangeStreamDownloader { 469 | fn read(&mut self, buf: &mut [u8]) -> std::io::Result { 470 | let mut read = 0; 471 | 472 | while read < buf.len() { 473 | let buffer_cursor = self.get_buffer_cursor(); 474 | //println!("Read loop {} over {} (position {})", buffer_cursor, self.buffer.len(), self.position); 475 | 476 | if buffer_cursor < self.buffer.len() { 477 | let remain = min(buf.len() - read, self.buffer.len() - buffer_cursor); 478 | buf[read..(read + remain)].clone_from_slice(&self.buffer[buffer_cursor..(buffer_cursor + remain)]); 479 | read += remain; 480 | self.position += remain as u64; 481 | self.set_buffer_cursor(buffer_cursor + remain); 482 | } 483 | 484 | if self.is_position_out_of_bound() { 485 | break; 486 | } 487 | 488 | if self.is_container_out_of_bound() { 489 | //println!("Container out of bound"); 490 | self.update_container(); 491 | self.start_container_download(); 492 | } 493 | 494 | if buffer_cursor >= self.buffer.len() { 495 | // load next chunk (shrink) into memory 496 | let offset = self.get_skip_offset(); 497 | let size = self.get_current_chunk_size(offset); 498 | 499 | // if current buffer is not big enough, resize it 500 | if size != self.buffer.len() { 501 | self.buffer = vec![0; size]; 502 | } 503 | 504 | self.read_all_into_buff(); 505 | 506 | 507 | //println!("Current size: {}, offset : {}", size, offset); 508 | 509 | self.buffer = self.buffer[offset..].to_vec(); 510 | self.buffer_cursor = Some(0); 511 | } 512 | } 513 | 514 | Ok(read) 515 | } 516 | } -------------------------------------------------------------------------------- /src/uploader.rs: -------------------------------------------------------------------------------- 1 | use std::cmp::{min}; 2 | use std::collections::VecDeque; 3 | use std::marker::Send; 4 | use std::fs::{File, metadata}; 5 | use std::io::{Read, Seek, SeekFrom}; 6 | use std::sync::{Arc, Mutex}; 7 | use aes::{Aes256}; 8 | use block_modes::block_padding::Pkcs7; 9 | use block_modes::{BlockMode, Cbc}; 10 | use hmac::Hmac; 11 | use pbkdf2::pbkdf2; 12 | use reqwest::blocking::{Body, Client}; 13 | use serde_json::json; 14 | use sha2::{Digest, Sha256}; 15 | use threadpool::ThreadPool; 16 | use rand::{RngCore, thread_rng}; 17 | use crate::common::{Container, Waterfall, FileReadable, FileWritable, ResumableFileUpload}; 18 | use crate::http_client::{create_client, prepare_discord_request}; 19 | use crate::signal::{LinearPartSignal, PartProgression, ProgressionRange, ReportSignal}; 20 | 21 | type Aes256Cbc = Cbc; 22 | 23 | pub trait Uploader 24 | where T: Sized + Clone 25 | { 26 | fn upload(&mut self, data: T) -> R; 27 | } 28 | 29 | pub trait WaterfallExporter { 30 | fn export_waterfall(&self) -> Waterfall; 31 | fn export_waterfall_with_password(&self, password: String) -> Waterfall; 32 | } 33 | 34 | pub trait ResumableUploader 35 | where T: FileWritable + FileReadable + Clone { 36 | fn export_resume_session(&self) -> T; 37 | 38 | fn from_resume_session(resume_session: T) -> std::io::Result 39 | where Self: Sized; 40 | } 41 | 42 | const CHUNK_SIZE: u32 = 1 << 16; 43 | 44 | const METADATA_SIZE: usize = 64; 45 | 46 | pub struct FileUploader { 47 | file_path: String, 48 | file_size: u64, 49 | 50 | container_size: u32, 51 | 52 | remaining_container_indexes: Arc>>, 53 | current_downloading_indexes: Arc>>, 54 | containers: Arc>>, 55 | 56 | pool: Arc, 57 | } 58 | 59 | impl FileUploader { 60 | pub fn new(file_path: String, container_size: u32) -> FileUploader { 61 | FileUploader::new_with_threads_count(file_path, container_size, 2) 62 | } 63 | 64 | pub fn new_with_threads_count(file_path: String, container_size: u32, threads_count: u32) -> FileUploader { 65 | let file_size = Self::file_size(file_path.clone()); 66 | 67 | let container_count = Self::container_count(file_size, container_size as u64); 68 | let mut deque: VecDeque = VecDeque::with_capacity(container_count); 69 | 70 | for i in 0..container_count { 71 | deque.push_back(i as u32 + 1); 72 | } 73 | 74 | FileUploader { 75 | file_size, 76 | file_path: file_path.clone(), 77 | container_size, 78 | remaining_container_indexes: Arc::new(Mutex::new(deque)), 79 | containers: Arc::new(Mutex::new(Vec::new())), 80 | current_downloading_indexes: Arc::new(Mutex::new(Vec::new())), 81 | pool: Arc::new(ThreadPool::new(threads_count as usize)), 82 | } 83 | } 84 | 85 | fn file_size(file_path: String) -> u64 { 86 | let meta = metadata(file_path).unwrap(); 87 | 88 | meta.len() 89 | } 90 | 91 | fn container_count(file_size: u64, container_size: u64) -> usize { 92 | let chunk_count = (file_size / (CHUNK_SIZE as u64 - METADATA_SIZE as u64)) + 1; 93 | 94 | let chunks_per_container = container_size / (CHUNK_SIZE as u64); 95 | 96 | (chunk_count as f64 / chunks_per_container as f64).ceil() as usize 97 | } 98 | 99 | fn file_hash(file_path: String) -> [u8; 32] { 100 | let mut hasher = Sha256::new(); 101 | // hash file 102 | let mut file = File::open(file_path).unwrap(); 103 | let mut buffer = [0u8; 1024 * 1024]; 104 | loop { 105 | let bytes_read = file.read(&mut buffer).unwrap(); 106 | if bytes_read == 0 { 107 | break; 108 | } 109 | hasher.update(&buffer[0..bytes_read]); 110 | } 111 | hasher.finalize().into() 112 | } 113 | 114 | fn compute_chunk_count(&self) -> usize { 115 | let real_size = CHUNK_SIZE as usize - METADATA_SIZE; 116 | 117 | let chunks_per_container = (self.container_size as usize) / (CHUNK_SIZE as usize); 118 | 119 | let container = Self::container_count(self.file_size, self.container_size as u64); 120 | 121 | // the first N-1 containers are always full: 122 | let mut chunk_count = (container - 1) * chunks_per_container; 123 | 124 | // for the last container, we need to compute the remaining bytes. 125 | let used_bytes = chunk_count * (real_size); 126 | 127 | let remaining = self.file_size as usize - used_bytes; 128 | 129 | // we ask ourself how much containers can fit in remaing space 130 | chunk_count += (remaining / real_size) + 1; 131 | 132 | chunk_count 133 | } 134 | } 135 | 136 | impl Clone for FileUploader { 137 | fn clone(&self) -> Self { 138 | FileUploader { 139 | file_path: self.file_path.clone(), 140 | file_size: self.file_size, 141 | container_size: self.container_size, 142 | remaining_container_indexes: Arc::clone(&self.remaining_container_indexes), 143 | containers: Arc::clone(&self.containers), 144 | current_downloading_indexes: Arc::clone(&self.current_downloading_indexes), 145 | pool: Arc::clone(&self.pool), 146 | } 147 | } 148 | } 149 | 150 | #[derive(Clone)] 151 | pub struct FileUploadArguments { 152 | encryption_password: String, 153 | token: String, 154 | channel_id: u64, 155 | 156 | signal: Option>>>, 157 | join: bool, 158 | } 159 | 160 | // impl Clone for Box>> { 161 | // fn clone(&self) -> Self { 162 | // 163 | // } 164 | // } 165 | 166 | impl FileUploadArguments { 167 | pub fn new(encryption_password: String, token: String, channel_id: u64) -> FileUploadArguments { 168 | FileUploadArguments { 169 | encryption_password, 170 | token, 171 | channel_id, 172 | signal: None, 173 | join: true, 174 | } 175 | } 176 | 177 | pub fn with_signal(&mut self, signal: &PartProgression) -> &Self { 178 | self.signal = Some(Box::new(signal.clone())); 179 | 180 | self.join = false; 181 | 182 | self 183 | } 184 | } 185 | 186 | impl Uploader for FileUploader { 187 | /// Upload the file using the arguments 188 | /// Returning the number of bytes uploaded 189 | /// (Or being uploaded if a signal is passed) 190 | fn upload(&mut self, arguments: FileUploadArguments) -> u64 { 191 | for _ in 0..self.pool.max_count() { 192 | // create file uploader 193 | let mut uploader = FileThreadedUploader::new( 194 | self.remaining_container_indexes.clone(), 195 | self.file_path.clone(), 196 | self.container_size, 197 | arguments.clone(), 198 | self.file_size, 199 | self.containers.clone(), 200 | self.current_downloading_indexes.clone(), 201 | ); 202 | 203 | self.pool.execute(move || { 204 | uploader.start_uploading(); 205 | }); 206 | } 207 | 208 | if arguments.join { 209 | self.pool.join(); 210 | } 211 | 212 | self.compute_chunk_count() as u64 * CHUNK_SIZE as u64 213 | } 214 | } 215 | 216 | impl WaterfallExporter for FileUploader { 217 | fn export_waterfall(&self) -> Waterfall { 218 | self.export_waterfall_with_password(String::new()) 219 | } 220 | 221 | 222 | fn export_waterfall_with_password(&self, password: String) -> Waterfall { 223 | let containers = self.containers.lock().unwrap().clone(); 224 | 225 | Waterfall { 226 | containers, 227 | size: self.file_size, 228 | filename: self.file_path.clone(), 229 | password: password.clone(), 230 | } 231 | } 232 | } 233 | 234 | impl ResumableUploader for FileUploader { 235 | fn export_resume_session(&self) -> ResumableFileUpload { 236 | // Collect remaining indexes 237 | let remaining_container_indexes = self.remaining_container_indexes.lock().unwrap().clone(); 238 | 239 | // Collect containers 240 | let containers = self.containers.lock().unwrap().clone(); 241 | 242 | // collect working indexes 243 | let working_indexes = self.current_downloading_indexes.lock().unwrap().clone(); 244 | 245 | // construct file hash 246 | let file_hash = Self::file_hash(self.file_path.clone()); 247 | 248 | // push all remaining indexes 249 | let mut remaining_indexes = Vec::with_capacity(remaining_container_indexes.len() + working_indexes.len()); 250 | 251 | for index in remaining_container_indexes { 252 | remaining_indexes.push(index); 253 | } 254 | 255 | for index in working_indexes { 256 | remaining_indexes.push(index); 257 | } 258 | 259 | ResumableFileUpload { 260 | file_path: self.file_path.clone(), 261 | file_size: self.file_size, 262 | container_size: self.container_size, 263 | remaining_indexes, 264 | containers, 265 | file_hash, 266 | thread_count: self.pool.max_count(), 267 | } 268 | } 269 | 270 | fn from_resume_session(resume_session: ResumableFileUpload) -> std::io::Result 271 | where Self: Sized { 272 | let file_size = Self::file_size(resume_session.file_path.clone()); 273 | 274 | if file_size != resume_session.file_size { 275 | return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "File size mismatch")); 276 | } 277 | 278 | let file_hash = Self::file_hash(resume_session.file_path.clone()); 279 | 280 | if file_hash != resume_session.file_hash { 281 | return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "File hash mismatch")); 282 | } 283 | 284 | let file_uploader = FileUploader { 285 | file_path: resume_session.file_path.clone(), 286 | file_size, 287 | container_size: resume_session.container_size, 288 | remaining_container_indexes: Arc::new(Mutex::new(VecDeque::from(resume_session.remaining_indexes.clone()))), 289 | current_downloading_indexes: Arc::new(Mutex::new(Vec::new())), 290 | containers: Arc::new(Mutex::new(resume_session.containers.clone())), 291 | pool: Arc::new(ThreadPool::new(resume_session.thread_count)), 292 | }; 293 | 294 | Ok(file_uploader) 295 | } 296 | } 297 | 298 | struct FileThreadedUploader { 299 | current_container_index: Arc>>, 300 | 301 | file_path: String, 302 | file_size: u64, 303 | container_size: u32, 304 | 305 | arguments: FileUploadArguments, 306 | 307 | client: Client, 308 | 309 | containers: Arc>>, 310 | current_downloading_indexes: Arc>>, 311 | } 312 | 313 | unsafe impl Send for FileThreadedUploader {} 314 | 315 | impl FileThreadedUploader { 316 | fn new(current_container_index: Arc>>, 317 | file_path: String, 318 | container_size: u32, 319 | arguments: FileUploadArguments, 320 | file_size: u64, 321 | containers: Arc>>, 322 | current_downloading_indexes: Arc>>, 323 | ) -> FileThreadedUploader { 324 | FileThreadedUploader { 325 | container_size, 326 | file_path, 327 | current_container_index, 328 | arguments, 329 | file_size, 330 | client: create_client(), 331 | containers, 332 | current_downloading_indexes, 333 | } 334 | } 335 | 336 | fn start_uploading(&mut self) { 337 | while let Some(container_index) = self.get_processing_container_index() { 338 | self.set_current_downloading_index(container_index); 339 | 340 | //println!("Uploading Container {:?}", container_index); 341 | 342 | let container = self.upload(container_index); 343 | 344 | self.add_container(container); 345 | 346 | self.remove_current_downloading_index(container_index); 347 | } 348 | 349 | return; 350 | } 351 | 352 | fn upload(&mut self, container_index: u32) -> Container { 353 | let filename = "data.enc".to_string(); 354 | 355 | let mut salt = [0u8; 16]; 356 | 357 | //println!("Doing upload of index {:?}", container_index); 358 | 359 | thread_rng().fill_bytes(&mut salt); 360 | 361 | let mut key = [0u8; 32]; 362 | pbkdf2::>(self.arguments.encryption_password.as_bytes(), &salt, 10000, &mut key); 363 | 364 | 365 | //println!("Computing cursor chunks_per_container: {:?}", self.chunks_per_container()); 366 | 367 | //let cursor = (((container_index - 1) * self.container_size) as i64) - ((METADATA_SIZE as i64) * (max(0, (container_index as i64) - 2)) * (self.chunks_per_container() as i64)); 368 | let cursor = (container_index as i64 - 1) * self.chunks_per_container() as i64 * (CHUNK_SIZE as i64 - METADATA_SIZE as i64); 369 | 370 | //println!("cursor: {:?}", cursor); 371 | 372 | let remaining_real_size = self.file_size - cursor as u64; 373 | let remaining_extra_padding = ((remaining_real_size / (CHUNK_SIZE as u64 - METADATA_SIZE as u64)) + 1) * METADATA_SIZE as u64; 374 | 375 | //println!("Remaining real size: {:?} (extra padding {:?}", remaining_real_size, remaining_extra_padding); 376 | 377 | let mut remaining_size = min(self.container_size as u64, remaining_real_size + remaining_extra_padding); 378 | 379 | if remaining_size % (CHUNK_SIZE as u64) > 0 { 380 | remaining_size += (CHUNK_SIZE as u64) - remaining_size % (CHUNK_SIZE as u64); 381 | } 382 | 383 | //println!("Remaining size: {:?}", remaining_size); 384 | 385 | //println!("Requesting attachment"); 386 | let (upload_url, upload_filename) = self.request_attachment(filename.clone(), remaining_size); 387 | 388 | //println!("Got upload url: {:?}", upload_url); 389 | 390 | let report_signal = 391 | if let Some(signal) = self.arguments.signal.clone() { 392 | let cursor_with_metadata = ((container_index as u64) - 1) * self.chunks_per_container() as u64 * (CHUNK_SIZE as u64); 393 | Some(Box::new(LinearPartSignal::new(signal.clone(), cursor_with_metadata)) as Box>) 394 | } else { 395 | None 396 | }; 397 | 398 | let file_uploader = CustomBody::new( 399 | key, 400 | remaining_size as i64, 401 | self.file_path.clone(), 402 | cursor, 403 | report_signal, 404 | ); 405 | 406 | let body = Body::sized(file_uploader, remaining_size); 407 | 408 | 409 | self.client.put(upload_url) 410 | .header("accept-encoding", "gzip") 411 | .header("connection", "Keep-Alive") 412 | .header("content-length", remaining_size) 413 | .header("content-type", "application/x-x509-ca-cert") 414 | .header("host", "discord-attachments-uploads-prd.storage.googleapis.com") 415 | .header("user-agent", "Discord-Android/192013;RNA") 416 | .body(body).send().unwrap(); 417 | 418 | let storage_url = self.post_message(filename.clone(), upload_filename); 419 | 420 | //println!("Computing byte range end (cursor: {:?}, remaining_size: {:?}, file_size {:?}, metadata size: {:?})", cursor, remaining_size, self.file_size, (remaining_size / CHUNK_SIZE as u64) * METADATA_SIZE as u64); 421 | let byte_range_end = min(self.file_size, cursor as u64 + remaining_size - ((remaining_size / CHUNK_SIZE as u64) * METADATA_SIZE as u64)); 422 | 423 | return Container { 424 | storage_url, 425 | chunk_count: remaining_size / CHUNK_SIZE as u64, 426 | chunk_size: CHUNK_SIZE as u64, 427 | salt, 428 | bytes_range: [ 429 | cursor as u64, 430 | byte_range_end 431 | ], 432 | }; 433 | } 434 | 435 | fn get_processing_container_index(&mut self) -> Option { 436 | let mut deque = self.current_container_index.lock().unwrap(); 437 | 438 | //println!("Trying to find work! (remaining indexes : {:?}", deque); 439 | 440 | deque.pop_front() 441 | } 442 | 443 | fn set_current_downloading_index(&mut self, index: u32) { 444 | let mut deque = self.current_downloading_indexes.lock().unwrap(); 445 | 446 | deque.push(index); 447 | } 448 | 449 | fn remove_current_downloading_index(&mut self, index: u32) { 450 | let mut deque = self.current_downloading_indexes.lock().unwrap(); 451 | 452 | deque.retain(|&x| x != index); 453 | } 454 | 455 | fn add_container(&mut self, container: Container) { 456 | let mut deque = self.containers.lock().unwrap(); 457 | 458 | deque.push(container); 459 | } 460 | 461 | fn chunks_per_container(&self) -> u32 { 462 | self.container_size / CHUNK_SIZE 463 | } 464 | 465 | fn request_attachment(&self, filename: String, size: u64) -> (String, String) { 466 | //println!("Requesting attachment of size {:?}", size); 467 | 468 | let url = format!("https://discord.com/api/v9/channels/{}/attachments", self.arguments.channel_id); 469 | 470 | let payload = json!( 471 | { 472 | "files": [ 473 | { 474 | "filename": filename, 475 | "file_size": size, 476 | "id": "8" 477 | } 478 | ] 479 | } 480 | ); 481 | 482 | 483 | let mut request = self.client.post(url); 484 | 485 | request = prepare_discord_request(request, self.arguments.token.clone()); 486 | 487 | let resp = request.json(&payload).send().unwrap().json::().unwrap(); 488 | 489 | let upload_url = resp["attachments"][0]["upload_url"].as_str().unwrap(); 490 | let upload_filename = resp["attachments"][0]["upload_filename"].as_str().unwrap(); 491 | 492 | return (upload_url.to_string(), upload_filename.to_string()); 493 | } 494 | 495 | fn post_message(&self, filename: String, upload_filename: String) -> String { 496 | // println!("Sending message with filename {:?} and upload_filename {:?}", filename, upload_filename); 497 | 498 | let url = format!("https://discord.com/api/v9/channels/{}/messages", self.arguments.channel_id); 499 | 500 | let payload = json!( 501 | { 502 | "content": "", 503 | "channel_id": self.arguments.channel_id, 504 | "type": 0, 505 | "attachments": [ 506 | { 507 | "id": "0", 508 | "filename": filename, 509 | "uploaded_filename": upload_filename 510 | } 511 | ] 512 | } 513 | ); 514 | 515 | let req = self.client.post(url); 516 | 517 | let resp = prepare_discord_request(req, self.arguments.token.clone()).json(&payload) 518 | .send().unwrap().json::().unwrap(); 519 | 520 | let file_url = resp["attachments"][0]["url"].as_str().unwrap(); 521 | 522 | //println!("Message has file url: {:?}", file_url); 523 | 524 | file_url.to_string() 525 | } 526 | } 527 | 528 | 529 | struct CustomBody { 530 | key: [u8; 32], 531 | 532 | remaining_size: i64, 533 | file: File, 534 | buffer_cursor: usize, 535 | buffer: Vec, 536 | 537 | signal: Option>>, 538 | } 539 | 540 | unsafe impl Send for CustomBody {} 541 | 542 | impl CustomBody { 543 | fn do_one_chunk(&mut self) { 544 | // println!("Reading chunk (remaining to process: {:?})", self.remaining_size); 545 | 546 | let mut salt = [0u8; 16]; 547 | thread_rng().fill_bytes(&mut salt); 548 | 549 | let content_size = min(self.remaining_size as usize, (CHUNK_SIZE as usize) - METADATA_SIZE); 550 | 551 | // println!("Buffer size: {:?}, Content size {:?}", self.buffer.len(), content_size); 552 | 553 | self.file.read(&mut self.buffer[0..content_size]).unwrap(); 554 | 555 | // println!("Read {:?} bytes from file", bytes_read); 556 | 557 | // compute hash 558 | let mut hasher = Sha256::new(); 559 | hasher.update(&self.buffer[0..content_size]); 560 | let hash = hasher.finalize(); 561 | 562 | //println!("Chunk hash: {:?}", hash); 563 | 564 | // encrypt data 565 | let cipher = Aes256Cbc::new_from_slices( 566 | &self.key.clone(), 567 | &salt.clone(), 568 | ).unwrap(); 569 | 570 | // println!("Encryption key: {:?}", self.key.clone()); 571 | // println!("Encryption salt: {:?}", salt.clone()); 572 | 573 | // println!("Encrypting chunk from 0 to {:?}", content_size + 16); 574 | 575 | cipher.encrypt(&mut self.buffer[0..(content_size + 16)], content_size) 576 | .expect("encryption failure!"); 577 | 578 | // println!("Setting salt at {:?} -> {:?}", (CHUNK_SIZE as usize) - 48, ((CHUNK_SIZE as usize) - 32)); 579 | 580 | // add at end the iv 581 | self.buffer[(CHUNK_SIZE as usize) - 48..((CHUNK_SIZE as usize) - 32)].clone_from_slice(&salt.clone()); 582 | 583 | self.buffer[(CHUNK_SIZE as usize) - 32..].clone_from_slice(&hash.clone()); 584 | 585 | self.remaining_size -= CHUNK_SIZE as i64; 586 | } 587 | 588 | pub fn new(key: [u8; 32], remaining_size: i64, file_path: String, cursor: i64, signal: Option>>) -> CustomBody { 589 | let mut file = File::open(file_path.clone()).unwrap(); 590 | //println!("Seeking to {:?}", cursor); 591 | 592 | file.seek(SeekFrom::Current(cursor)).unwrap(); 593 | 594 | CustomBody { key, remaining_size, file, buffer: vec![0; CHUNK_SIZE as usize], buffer_cursor: CHUNK_SIZE as usize, signal } 595 | } 596 | } 597 | 598 | impl Read for CustomBody { 599 | fn read(&mut self, buf: &mut [u8]) -> std::io::Result { 600 | let mut read = 0; 601 | 602 | //println!("Doing read of {:?}", buf.len()); 603 | 604 | while read < buf.len() { 605 | // println!("Read loop: buffer_cursor {:?} (read {:?})", self.buffer_cursor, read); 606 | 607 | if self.buffer_cursor < CHUNK_SIZE as usize { 608 | let remain = min(buf.len() - read, CHUNK_SIZE as usize - self.buffer_cursor); 609 | buf[read..(read + remain)].clone_from_slice(&self.buffer[self.buffer_cursor..(self.buffer_cursor + remain)]); 610 | // println!("Read loop: pushing {:?} buf", remain); 611 | read += remain; 612 | self.buffer_cursor += remain; 613 | } 614 | 615 | if self.buffer_cursor >= CHUNK_SIZE as usize { 616 | if self.remaining_size <= 0 { 617 | //println!("End ! with read = {:?}", read); 618 | break; 619 | } else { 620 | //println!("Read loop: doing_one_chunk"); 621 | self.do_one_chunk(); 622 | self.buffer_cursor = 0; 623 | } 624 | } 625 | } 626 | 627 | // report read; 628 | 629 | if let Some(signal) = self.signal.as_mut() { 630 | signal.report_data(read as u64); 631 | } 632 | 633 | Ok(read) 634 | } 635 | } 636 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.21.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "aes" 22 | version = "0.7.5" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" 25 | dependencies = [ 26 | "cfg-if", 27 | "cipher", 28 | "cpufeatures", 29 | "opaque-debug", 30 | ] 31 | 32 | [[package]] 33 | name = "alloc-no-stdlib" 34 | version = "2.0.4" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" 37 | 38 | [[package]] 39 | name = "alloc-stdlib" 40 | version = "0.2.2" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" 43 | dependencies = [ 44 | "alloc-no-stdlib", 45 | ] 46 | 47 | [[package]] 48 | name = "async-compression" 49 | version = "0.4.2" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "d495b6dc0184693324491a5ac05f559acc97bf937ab31d7a1c33dd0016be6d2b" 52 | dependencies = [ 53 | "brotli", 54 | "flate2", 55 | "futures-core", 56 | "memchr", 57 | "pin-project-lite", 58 | "tokio", 59 | ] 60 | 61 | [[package]] 62 | name = "async-trait" 63 | version = "0.1.73" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" 66 | dependencies = [ 67 | "proc-macro2", 68 | "quote", 69 | "syn 2.0.29", 70 | ] 71 | 72 | [[package]] 73 | name = "autocfg" 74 | version = "1.1.0" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 77 | 78 | [[package]] 79 | name = "backtrace" 80 | version = "0.3.69" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" 83 | dependencies = [ 84 | "addr2line", 85 | "cc", 86 | "cfg-if", 87 | "libc", 88 | "miniz_oxide", 89 | "object", 90 | "rustc-demangle", 91 | ] 92 | 93 | [[package]] 94 | name = "base64" 95 | version = "0.21.3" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" 98 | 99 | [[package]] 100 | name = "base64ct" 101 | version = "1.0.1" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" 104 | 105 | [[package]] 106 | name = "bitflags" 107 | version = "1.3.2" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 110 | 111 | [[package]] 112 | name = "bitflags" 113 | version = "2.4.0" 114 | source = "registry+https://github.com/rust-lang/crates.io-index" 115 | checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" 116 | 117 | [[package]] 118 | name = "block-buffer" 119 | version = "0.9.0" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 122 | dependencies = [ 123 | "generic-array", 124 | ] 125 | 126 | [[package]] 127 | name = "block-buffer" 128 | version = "0.10.4" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 131 | dependencies = [ 132 | "generic-array", 133 | ] 134 | 135 | [[package]] 136 | name = "block-modes" 137 | version = "0.8.1" 138 | source = "registry+https://github.com/rust-lang/crates.io-index" 139 | checksum = "2cb03d1bed155d89dce0f845b7899b18a9a163e148fd004e1c28421a783e2d8e" 140 | dependencies = [ 141 | "block-padding", 142 | "cipher", 143 | ] 144 | 145 | [[package]] 146 | name = "block-padding" 147 | version = "0.2.1" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" 150 | 151 | [[package]] 152 | name = "brotli" 153 | version = "3.3.4" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" 156 | dependencies = [ 157 | "alloc-no-stdlib", 158 | "alloc-stdlib", 159 | "brotli-decompressor", 160 | ] 161 | 162 | [[package]] 163 | name = "brotli-decompressor" 164 | version = "2.3.4" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" 167 | dependencies = [ 168 | "alloc-no-stdlib", 169 | "alloc-stdlib", 170 | ] 171 | 172 | [[package]] 173 | name = "bumpalo" 174 | version = "3.13.0" 175 | source = "registry+https://github.com/rust-lang/crates.io-index" 176 | checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" 177 | 178 | [[package]] 179 | name = "bytes" 180 | version = "1.4.0" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" 183 | 184 | [[package]] 185 | name = "cc" 186 | version = "1.0.83" 187 | source = "registry+https://github.com/rust-lang/crates.io-index" 188 | checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" 189 | dependencies = [ 190 | "libc", 191 | ] 192 | 193 | [[package]] 194 | name = "cfg-if" 195 | version = "1.0.0" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 198 | 199 | [[package]] 200 | name = "cipher" 201 | version = "0.3.0" 202 | source = "registry+https://github.com/rust-lang/crates.io-index" 203 | checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" 204 | dependencies = [ 205 | "generic-array", 206 | ] 207 | 208 | [[package]] 209 | name = "core-foundation" 210 | version = "0.9.3" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 213 | dependencies = [ 214 | "core-foundation-sys", 215 | "libc", 216 | ] 217 | 218 | [[package]] 219 | name = "core-foundation-sys" 220 | version = "0.8.4" 221 | source = "registry+https://github.com/rust-lang/crates.io-index" 222 | checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" 223 | 224 | [[package]] 225 | name = "cpufeatures" 226 | version = "0.2.9" 227 | source = "registry+https://github.com/rust-lang/crates.io-index" 228 | checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" 229 | dependencies = [ 230 | "libc", 231 | ] 232 | 233 | [[package]] 234 | name = "crc32fast" 235 | version = "1.3.2" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 238 | dependencies = [ 239 | "cfg-if", 240 | ] 241 | 242 | [[package]] 243 | name = "crypto-common" 244 | version = "0.1.6" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 247 | dependencies = [ 248 | "generic-array", 249 | "typenum", 250 | ] 251 | 252 | [[package]] 253 | name = "crypto-mac" 254 | version = "0.11.1" 255 | source = "registry+https://github.com/rust-lang/crates.io-index" 256 | checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" 257 | dependencies = [ 258 | "generic-array", 259 | "subtle", 260 | ] 261 | 262 | [[package]] 263 | name = "digest" 264 | version = "0.9.0" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 267 | dependencies = [ 268 | "generic-array", 269 | ] 270 | 271 | [[package]] 272 | name = "digest" 273 | version = "0.10.7" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 276 | dependencies = [ 277 | "block-buffer 0.10.4", 278 | "crypto-common", 279 | ] 280 | 281 | [[package]] 282 | name = "discord-us" 283 | version = "0.1.0" 284 | dependencies = [ 285 | "aes", 286 | "block-modes", 287 | "dyn-clonable", 288 | "dyn-clone", 289 | "hex-buffer-serde", 290 | "hmac", 291 | "pbkdf2", 292 | "rand", 293 | "reqwest", 294 | "serde", 295 | "serde_json", 296 | "sha2 0.9.9", 297 | "sha256", 298 | "sorted-vec", 299 | "threadpool", 300 | ] 301 | 302 | [[package]] 303 | name = "dyn-clonable" 304 | version = "0.9.0" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" 307 | dependencies = [ 308 | "dyn-clonable-impl", 309 | "dyn-clone", 310 | ] 311 | 312 | [[package]] 313 | name = "dyn-clonable-impl" 314 | version = "0.9.0" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" 317 | dependencies = [ 318 | "proc-macro2", 319 | "quote", 320 | "syn 1.0.109", 321 | ] 322 | 323 | [[package]] 324 | name = "dyn-clone" 325 | version = "1.0.13" 326 | source = "registry+https://github.com/rust-lang/crates.io-index" 327 | checksum = "bbfc4744c1b8f2a09adc0e55242f60b1af195d88596bd8700be74418c056c555" 328 | 329 | [[package]] 330 | name = "encoding_rs" 331 | version = "0.8.33" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" 334 | dependencies = [ 335 | "cfg-if", 336 | ] 337 | 338 | [[package]] 339 | name = "errno" 340 | version = "0.3.3" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" 343 | dependencies = [ 344 | "errno-dragonfly", 345 | "libc", 346 | "windows-sys", 347 | ] 348 | 349 | [[package]] 350 | name = "errno-dragonfly" 351 | version = "0.1.2" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" 354 | dependencies = [ 355 | "cc", 356 | "libc", 357 | ] 358 | 359 | [[package]] 360 | name = "fastrand" 361 | version = "2.0.0" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" 364 | 365 | [[package]] 366 | name = "flate2" 367 | version = "1.0.27" 368 | source = "registry+https://github.com/rust-lang/crates.io-index" 369 | checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" 370 | dependencies = [ 371 | "crc32fast", 372 | "miniz_oxide", 373 | ] 374 | 375 | [[package]] 376 | name = "fnv" 377 | version = "1.0.7" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 380 | 381 | [[package]] 382 | name = "foreign-types" 383 | version = "0.3.2" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 386 | dependencies = [ 387 | "foreign-types-shared", 388 | ] 389 | 390 | [[package]] 391 | name = "foreign-types-shared" 392 | version = "0.1.1" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 395 | 396 | [[package]] 397 | name = "form_urlencoded" 398 | version = "1.2.0" 399 | source = "registry+https://github.com/rust-lang/crates.io-index" 400 | checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" 401 | dependencies = [ 402 | "percent-encoding", 403 | ] 404 | 405 | [[package]] 406 | name = "futures-channel" 407 | version = "0.3.28" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" 410 | dependencies = [ 411 | "futures-core", 412 | ] 413 | 414 | [[package]] 415 | name = "futures-core" 416 | version = "0.3.28" 417 | source = "registry+https://github.com/rust-lang/crates.io-index" 418 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" 419 | 420 | [[package]] 421 | name = "futures-io" 422 | version = "0.3.28" 423 | source = "registry+https://github.com/rust-lang/crates.io-index" 424 | checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" 425 | 426 | [[package]] 427 | name = "futures-sink" 428 | version = "0.3.28" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" 431 | 432 | [[package]] 433 | name = "futures-task" 434 | version = "0.3.28" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" 437 | 438 | [[package]] 439 | name = "futures-util" 440 | version = "0.3.28" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" 443 | dependencies = [ 444 | "futures-core", 445 | "futures-io", 446 | "futures-task", 447 | "memchr", 448 | "pin-project-lite", 449 | "pin-utils", 450 | "slab", 451 | ] 452 | 453 | [[package]] 454 | name = "generic-array" 455 | version = "0.14.7" 456 | source = "registry+https://github.com/rust-lang/crates.io-index" 457 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 458 | dependencies = [ 459 | "typenum", 460 | "version_check", 461 | ] 462 | 463 | [[package]] 464 | name = "getrandom" 465 | version = "0.2.10" 466 | source = "registry+https://github.com/rust-lang/crates.io-index" 467 | checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" 468 | dependencies = [ 469 | "cfg-if", 470 | "libc", 471 | "wasi", 472 | ] 473 | 474 | [[package]] 475 | name = "gimli" 476 | version = "0.28.0" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" 479 | 480 | [[package]] 481 | name = "h2" 482 | version = "0.3.21" 483 | source = "registry+https://github.com/rust-lang/crates.io-index" 484 | checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" 485 | dependencies = [ 486 | "bytes", 487 | "fnv", 488 | "futures-core", 489 | "futures-sink", 490 | "futures-util", 491 | "http", 492 | "indexmap", 493 | "slab", 494 | "tokio", 495 | "tokio-util", 496 | "tracing", 497 | ] 498 | 499 | [[package]] 500 | name = "hashbrown" 501 | version = "0.12.3" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 504 | 505 | [[package]] 506 | name = "hermit-abi" 507 | version = "0.3.2" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" 510 | 511 | [[package]] 512 | name = "hex" 513 | version = "0.4.3" 514 | source = "registry+https://github.com/rust-lang/crates.io-index" 515 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 516 | 517 | [[package]] 518 | name = "hex-buffer-serde" 519 | version = "0.4.0" 520 | source = "registry+https://github.com/rust-lang/crates.io-index" 521 | checksum = "c7e84645a601cf4a58f40673d51c111d1b5f847b711559c076ebcb779606a6d0" 522 | dependencies = [ 523 | "hex", 524 | "serde", 525 | ] 526 | 527 | [[package]] 528 | name = "hmac" 529 | version = "0.11.0" 530 | source = "registry+https://github.com/rust-lang/crates.io-index" 531 | checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" 532 | dependencies = [ 533 | "crypto-mac", 534 | "digest 0.9.0", 535 | ] 536 | 537 | [[package]] 538 | name = "http" 539 | version = "0.2.9" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" 542 | dependencies = [ 543 | "bytes", 544 | "fnv", 545 | "itoa", 546 | ] 547 | 548 | [[package]] 549 | name = "http-body" 550 | version = "0.4.5" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 553 | dependencies = [ 554 | "bytes", 555 | "http", 556 | "pin-project-lite", 557 | ] 558 | 559 | [[package]] 560 | name = "httparse" 561 | version = "1.8.0" 562 | source = "registry+https://github.com/rust-lang/crates.io-index" 563 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 564 | 565 | [[package]] 566 | name = "httpdate" 567 | version = "1.0.3" 568 | source = "registry+https://github.com/rust-lang/crates.io-index" 569 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 570 | 571 | [[package]] 572 | name = "hyper" 573 | version = "0.14.27" 574 | source = "registry+https://github.com/rust-lang/crates.io-index" 575 | checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" 576 | dependencies = [ 577 | "bytes", 578 | "futures-channel", 579 | "futures-core", 580 | "futures-util", 581 | "h2", 582 | "http", 583 | "http-body", 584 | "httparse", 585 | "httpdate", 586 | "itoa", 587 | "pin-project-lite", 588 | "socket2 0.4.9", 589 | "tokio", 590 | "tower-service", 591 | "tracing", 592 | "want", 593 | ] 594 | 595 | [[package]] 596 | name = "hyper-tls" 597 | version = "0.5.0" 598 | source = "registry+https://github.com/rust-lang/crates.io-index" 599 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 600 | dependencies = [ 601 | "bytes", 602 | "hyper", 603 | "native-tls", 604 | "tokio", 605 | "tokio-native-tls", 606 | ] 607 | 608 | [[package]] 609 | name = "idna" 610 | version = "0.4.0" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" 613 | dependencies = [ 614 | "unicode-bidi", 615 | "unicode-normalization", 616 | ] 617 | 618 | [[package]] 619 | name = "indexmap" 620 | version = "1.9.3" 621 | source = "registry+https://github.com/rust-lang/crates.io-index" 622 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 623 | dependencies = [ 624 | "autocfg", 625 | "hashbrown", 626 | ] 627 | 628 | [[package]] 629 | name = "ipnet" 630 | version = "2.8.0" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" 633 | 634 | [[package]] 635 | name = "itoa" 636 | version = "1.0.9" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" 639 | 640 | [[package]] 641 | name = "js-sys" 642 | version = "0.3.64" 643 | source = "registry+https://github.com/rust-lang/crates.io-index" 644 | checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" 645 | dependencies = [ 646 | "wasm-bindgen", 647 | ] 648 | 649 | [[package]] 650 | name = "lazy_static" 651 | version = "1.4.0" 652 | source = "registry+https://github.com/rust-lang/crates.io-index" 653 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 654 | 655 | [[package]] 656 | name = "libc" 657 | version = "0.2.147" 658 | source = "registry+https://github.com/rust-lang/crates.io-index" 659 | checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" 660 | 661 | [[package]] 662 | name = "linux-raw-sys" 663 | version = "0.4.5" 664 | source = "registry+https://github.com/rust-lang/crates.io-index" 665 | checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" 666 | 667 | [[package]] 668 | name = "log" 669 | version = "0.4.20" 670 | source = "registry+https://github.com/rust-lang/crates.io-index" 671 | checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" 672 | 673 | [[package]] 674 | name = "memchr" 675 | version = "2.6.2" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | checksum = "5486aed0026218e61b8a01d5fbd5a0a134649abb71a0e53b7bc088529dced86e" 678 | 679 | [[package]] 680 | name = "mime" 681 | version = "0.3.17" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 684 | 685 | [[package]] 686 | name = "miniz_oxide" 687 | version = "0.7.1" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 690 | dependencies = [ 691 | "adler", 692 | ] 693 | 694 | [[package]] 695 | name = "mio" 696 | version = "0.8.8" 697 | source = "registry+https://github.com/rust-lang/crates.io-index" 698 | checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" 699 | dependencies = [ 700 | "libc", 701 | "wasi", 702 | "windows-sys", 703 | ] 704 | 705 | [[package]] 706 | name = "native-tls" 707 | version = "0.2.11" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" 710 | dependencies = [ 711 | "lazy_static", 712 | "libc", 713 | "log", 714 | "openssl", 715 | "openssl-probe", 716 | "openssl-sys", 717 | "schannel", 718 | "security-framework", 719 | "security-framework-sys", 720 | "tempfile", 721 | ] 722 | 723 | [[package]] 724 | name = "num_cpus" 725 | version = "1.16.0" 726 | source = "registry+https://github.com/rust-lang/crates.io-index" 727 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 728 | dependencies = [ 729 | "hermit-abi", 730 | "libc", 731 | ] 732 | 733 | [[package]] 734 | name = "object" 735 | version = "0.32.0" 736 | source = "registry+https://github.com/rust-lang/crates.io-index" 737 | checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" 738 | dependencies = [ 739 | "memchr", 740 | ] 741 | 742 | [[package]] 743 | name = "once_cell" 744 | version = "1.18.0" 745 | source = "registry+https://github.com/rust-lang/crates.io-index" 746 | checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" 747 | 748 | [[package]] 749 | name = "opaque-debug" 750 | version = "0.3.0" 751 | source = "registry+https://github.com/rust-lang/crates.io-index" 752 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 753 | 754 | [[package]] 755 | name = "openssl" 756 | version = "0.10.57" 757 | source = "registry+https://github.com/rust-lang/crates.io-index" 758 | checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" 759 | dependencies = [ 760 | "bitflags 2.4.0", 761 | "cfg-if", 762 | "foreign-types", 763 | "libc", 764 | "once_cell", 765 | "openssl-macros", 766 | "openssl-sys", 767 | ] 768 | 769 | [[package]] 770 | name = "openssl-macros" 771 | version = "0.1.1" 772 | source = "registry+https://github.com/rust-lang/crates.io-index" 773 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 774 | dependencies = [ 775 | "proc-macro2", 776 | "quote", 777 | "syn 2.0.29", 778 | ] 779 | 780 | [[package]] 781 | name = "openssl-probe" 782 | version = "0.1.5" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 785 | 786 | [[package]] 787 | name = "openssl-sys" 788 | version = "0.9.92" 789 | source = "registry+https://github.com/rust-lang/crates.io-index" 790 | checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b" 791 | dependencies = [ 792 | "cc", 793 | "libc", 794 | "pkg-config", 795 | "vcpkg", 796 | ] 797 | 798 | [[package]] 799 | name = "password-hash" 800 | version = "0.3.2" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8" 803 | dependencies = [ 804 | "base64ct", 805 | "rand_core", 806 | "subtle", 807 | ] 808 | 809 | [[package]] 810 | name = "pbkdf2" 811 | version = "0.9.0" 812 | source = "registry+https://github.com/rust-lang/crates.io-index" 813 | checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" 814 | dependencies = [ 815 | "crypto-mac", 816 | "hmac", 817 | "password-hash", 818 | "sha2 0.9.9", 819 | ] 820 | 821 | [[package]] 822 | name = "percent-encoding" 823 | version = "2.3.0" 824 | source = "registry+https://github.com/rust-lang/crates.io-index" 825 | checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" 826 | 827 | [[package]] 828 | name = "pin-project-lite" 829 | version = "0.2.13" 830 | source = "registry+https://github.com/rust-lang/crates.io-index" 831 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 832 | 833 | [[package]] 834 | name = "pin-utils" 835 | version = "0.1.0" 836 | source = "registry+https://github.com/rust-lang/crates.io-index" 837 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 838 | 839 | [[package]] 840 | name = "pkg-config" 841 | version = "0.3.27" 842 | source = "registry+https://github.com/rust-lang/crates.io-index" 843 | checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" 844 | 845 | [[package]] 846 | name = "ppv-lite86" 847 | version = "0.2.17" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 850 | 851 | [[package]] 852 | name = "proc-macro2" 853 | version = "1.0.66" 854 | source = "registry+https://github.com/rust-lang/crates.io-index" 855 | checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" 856 | dependencies = [ 857 | "unicode-ident", 858 | ] 859 | 860 | [[package]] 861 | name = "quote" 862 | version = "1.0.33" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 865 | dependencies = [ 866 | "proc-macro2", 867 | ] 868 | 869 | [[package]] 870 | name = "rand" 871 | version = "0.8.5" 872 | source = "registry+https://github.com/rust-lang/crates.io-index" 873 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 874 | dependencies = [ 875 | "libc", 876 | "rand_chacha", 877 | "rand_core", 878 | ] 879 | 880 | [[package]] 881 | name = "rand_chacha" 882 | version = "0.3.1" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 885 | dependencies = [ 886 | "ppv-lite86", 887 | "rand_core", 888 | ] 889 | 890 | [[package]] 891 | name = "rand_core" 892 | version = "0.6.4" 893 | source = "registry+https://github.com/rust-lang/crates.io-index" 894 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 895 | dependencies = [ 896 | "getrandom", 897 | ] 898 | 899 | [[package]] 900 | name = "redox_syscall" 901 | version = "0.3.5" 902 | source = "registry+https://github.com/rust-lang/crates.io-index" 903 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" 904 | dependencies = [ 905 | "bitflags 1.3.2", 906 | ] 907 | 908 | [[package]] 909 | name = "reqwest" 910 | version = "0.11.20" 911 | source = "registry+https://github.com/rust-lang/crates.io-index" 912 | checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" 913 | dependencies = [ 914 | "async-compression", 915 | "base64", 916 | "bytes", 917 | "encoding_rs", 918 | "futures-core", 919 | "futures-util", 920 | "h2", 921 | "http", 922 | "http-body", 923 | "hyper", 924 | "hyper-tls", 925 | "ipnet", 926 | "js-sys", 927 | "log", 928 | "mime", 929 | "native-tls", 930 | "once_cell", 931 | "percent-encoding", 932 | "pin-project-lite", 933 | "serde", 934 | "serde_json", 935 | "serde_urlencoded", 936 | "tokio", 937 | "tokio-native-tls", 938 | "tokio-util", 939 | "tower-service", 940 | "url", 941 | "wasm-bindgen", 942 | "wasm-bindgen-futures", 943 | "web-sys", 944 | "winreg", 945 | ] 946 | 947 | [[package]] 948 | name = "rustc-demangle" 949 | version = "0.1.23" 950 | source = "registry+https://github.com/rust-lang/crates.io-index" 951 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 952 | 953 | [[package]] 954 | name = "rustix" 955 | version = "0.38.10" 956 | source = "registry+https://github.com/rust-lang/crates.io-index" 957 | checksum = "ed6248e1caa625eb708e266e06159f135e8c26f2bb7ceb72dc4b2766d0340964" 958 | dependencies = [ 959 | "bitflags 2.4.0", 960 | "errno", 961 | "libc", 962 | "linux-raw-sys", 963 | "windows-sys", 964 | ] 965 | 966 | [[package]] 967 | name = "ryu" 968 | version = "1.0.15" 969 | source = "registry+https://github.com/rust-lang/crates.io-index" 970 | checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" 971 | 972 | [[package]] 973 | name = "schannel" 974 | version = "0.1.22" 975 | source = "registry+https://github.com/rust-lang/crates.io-index" 976 | checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" 977 | dependencies = [ 978 | "windows-sys", 979 | ] 980 | 981 | [[package]] 982 | name = "security-framework" 983 | version = "2.9.2" 984 | source = "registry+https://github.com/rust-lang/crates.io-index" 985 | checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" 986 | dependencies = [ 987 | "bitflags 1.3.2", 988 | "core-foundation", 989 | "core-foundation-sys", 990 | "libc", 991 | "security-framework-sys", 992 | ] 993 | 994 | [[package]] 995 | name = "security-framework-sys" 996 | version = "2.9.1" 997 | source = "registry+https://github.com/rust-lang/crates.io-index" 998 | checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" 999 | dependencies = [ 1000 | "core-foundation-sys", 1001 | "libc", 1002 | ] 1003 | 1004 | [[package]] 1005 | name = "serde" 1006 | version = "1.0.188" 1007 | source = "registry+https://github.com/rust-lang/crates.io-index" 1008 | checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" 1009 | dependencies = [ 1010 | "serde_derive", 1011 | ] 1012 | 1013 | [[package]] 1014 | name = "serde_derive" 1015 | version = "1.0.188" 1016 | source = "registry+https://github.com/rust-lang/crates.io-index" 1017 | checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" 1018 | dependencies = [ 1019 | "proc-macro2", 1020 | "quote", 1021 | "syn 2.0.29", 1022 | ] 1023 | 1024 | [[package]] 1025 | name = "serde_json" 1026 | version = "1.0.105" 1027 | source = "registry+https://github.com/rust-lang/crates.io-index" 1028 | checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" 1029 | dependencies = [ 1030 | "itoa", 1031 | "ryu", 1032 | "serde", 1033 | ] 1034 | 1035 | [[package]] 1036 | name = "serde_urlencoded" 1037 | version = "0.7.1" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1040 | dependencies = [ 1041 | "form_urlencoded", 1042 | "itoa", 1043 | "ryu", 1044 | "serde", 1045 | ] 1046 | 1047 | [[package]] 1048 | name = "sha2" 1049 | version = "0.9.9" 1050 | source = "registry+https://github.com/rust-lang/crates.io-index" 1051 | checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" 1052 | dependencies = [ 1053 | "block-buffer 0.9.0", 1054 | "cfg-if", 1055 | "cpufeatures", 1056 | "digest 0.9.0", 1057 | "opaque-debug", 1058 | ] 1059 | 1060 | [[package]] 1061 | name = "sha2" 1062 | version = "0.10.7" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" 1065 | dependencies = [ 1066 | "cfg-if", 1067 | "cpufeatures", 1068 | "digest 0.10.7", 1069 | ] 1070 | 1071 | [[package]] 1072 | name = "sha256" 1073 | version = "1.4.0" 1074 | source = "registry+https://github.com/rust-lang/crates.io-index" 1075 | checksum = "7895c8ae88588ccead14ff438b939b0c569cd619116f14b4d13fdff7b8333386" 1076 | dependencies = [ 1077 | "async-trait", 1078 | "bytes", 1079 | "hex", 1080 | "sha2 0.10.7", 1081 | "tokio", 1082 | ] 1083 | 1084 | [[package]] 1085 | name = "slab" 1086 | version = "0.4.9" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1089 | dependencies = [ 1090 | "autocfg", 1091 | ] 1092 | 1093 | [[package]] 1094 | name = "socket2" 1095 | version = "0.4.9" 1096 | source = "registry+https://github.com/rust-lang/crates.io-index" 1097 | checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" 1098 | dependencies = [ 1099 | "libc", 1100 | "winapi", 1101 | ] 1102 | 1103 | [[package]] 1104 | name = "socket2" 1105 | version = "0.5.3" 1106 | source = "registry+https://github.com/rust-lang/crates.io-index" 1107 | checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" 1108 | dependencies = [ 1109 | "libc", 1110 | "windows-sys", 1111 | ] 1112 | 1113 | [[package]] 1114 | name = "sorted-vec" 1115 | version = "0.8.2" 1116 | source = "registry+https://github.com/rust-lang/crates.io-index" 1117 | checksum = "f0047b8207660638866f228b4b4147e98cc8efb190a70cd63d5cb899a4a539a8" 1118 | 1119 | [[package]] 1120 | name = "subtle" 1121 | version = "2.4.1" 1122 | source = "registry+https://github.com/rust-lang/crates.io-index" 1123 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 1124 | 1125 | [[package]] 1126 | name = "syn" 1127 | version = "1.0.109" 1128 | source = "registry+https://github.com/rust-lang/crates.io-index" 1129 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1130 | dependencies = [ 1131 | "proc-macro2", 1132 | "quote", 1133 | "unicode-ident", 1134 | ] 1135 | 1136 | [[package]] 1137 | name = "syn" 1138 | version = "2.0.29" 1139 | source = "registry+https://github.com/rust-lang/crates.io-index" 1140 | checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" 1141 | dependencies = [ 1142 | "proc-macro2", 1143 | "quote", 1144 | "unicode-ident", 1145 | ] 1146 | 1147 | [[package]] 1148 | name = "tempfile" 1149 | version = "3.8.0" 1150 | source = "registry+https://github.com/rust-lang/crates.io-index" 1151 | checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" 1152 | dependencies = [ 1153 | "cfg-if", 1154 | "fastrand", 1155 | "redox_syscall", 1156 | "rustix", 1157 | "windows-sys", 1158 | ] 1159 | 1160 | [[package]] 1161 | name = "threadpool" 1162 | version = "1.8.1" 1163 | source = "registry+https://github.com/rust-lang/crates.io-index" 1164 | checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" 1165 | dependencies = [ 1166 | "num_cpus", 1167 | ] 1168 | 1169 | [[package]] 1170 | name = "tinyvec" 1171 | version = "1.6.0" 1172 | source = "registry+https://github.com/rust-lang/crates.io-index" 1173 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 1174 | dependencies = [ 1175 | "tinyvec_macros", 1176 | ] 1177 | 1178 | [[package]] 1179 | name = "tinyvec_macros" 1180 | version = "0.1.1" 1181 | source = "registry+https://github.com/rust-lang/crates.io-index" 1182 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 1183 | 1184 | [[package]] 1185 | name = "tokio" 1186 | version = "1.32.0" 1187 | source = "registry+https://github.com/rust-lang/crates.io-index" 1188 | checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" 1189 | dependencies = [ 1190 | "backtrace", 1191 | "bytes", 1192 | "libc", 1193 | "mio", 1194 | "num_cpus", 1195 | "pin-project-lite", 1196 | "socket2 0.5.3", 1197 | "windows-sys", 1198 | ] 1199 | 1200 | [[package]] 1201 | name = "tokio-native-tls" 1202 | version = "0.3.1" 1203 | source = "registry+https://github.com/rust-lang/crates.io-index" 1204 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 1205 | dependencies = [ 1206 | "native-tls", 1207 | "tokio", 1208 | ] 1209 | 1210 | [[package]] 1211 | name = "tokio-util" 1212 | version = "0.7.8" 1213 | source = "registry+https://github.com/rust-lang/crates.io-index" 1214 | checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" 1215 | dependencies = [ 1216 | "bytes", 1217 | "futures-core", 1218 | "futures-sink", 1219 | "pin-project-lite", 1220 | "tokio", 1221 | "tracing", 1222 | ] 1223 | 1224 | [[package]] 1225 | name = "tower-service" 1226 | version = "0.3.2" 1227 | source = "registry+https://github.com/rust-lang/crates.io-index" 1228 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1229 | 1230 | [[package]] 1231 | name = "tracing" 1232 | version = "0.1.37" 1233 | source = "registry+https://github.com/rust-lang/crates.io-index" 1234 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 1235 | dependencies = [ 1236 | "cfg-if", 1237 | "pin-project-lite", 1238 | "tracing-core", 1239 | ] 1240 | 1241 | [[package]] 1242 | name = "tracing-core" 1243 | version = "0.1.31" 1244 | source = "registry+https://github.com/rust-lang/crates.io-index" 1245 | checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" 1246 | dependencies = [ 1247 | "once_cell", 1248 | ] 1249 | 1250 | [[package]] 1251 | name = "try-lock" 1252 | version = "0.2.4" 1253 | source = "registry+https://github.com/rust-lang/crates.io-index" 1254 | checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" 1255 | 1256 | [[package]] 1257 | name = "typenum" 1258 | version = "1.16.0" 1259 | source = "registry+https://github.com/rust-lang/crates.io-index" 1260 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" 1261 | 1262 | [[package]] 1263 | name = "unicode-bidi" 1264 | version = "0.3.13" 1265 | source = "registry+https://github.com/rust-lang/crates.io-index" 1266 | checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" 1267 | 1268 | [[package]] 1269 | name = "unicode-ident" 1270 | version = "1.0.11" 1271 | source = "registry+https://github.com/rust-lang/crates.io-index" 1272 | checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" 1273 | 1274 | [[package]] 1275 | name = "unicode-normalization" 1276 | version = "0.1.22" 1277 | source = "registry+https://github.com/rust-lang/crates.io-index" 1278 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 1279 | dependencies = [ 1280 | "tinyvec", 1281 | ] 1282 | 1283 | [[package]] 1284 | name = "url" 1285 | version = "2.4.1" 1286 | source = "registry+https://github.com/rust-lang/crates.io-index" 1287 | checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" 1288 | dependencies = [ 1289 | "form_urlencoded", 1290 | "idna", 1291 | "percent-encoding", 1292 | ] 1293 | 1294 | [[package]] 1295 | name = "vcpkg" 1296 | version = "0.2.15" 1297 | source = "registry+https://github.com/rust-lang/crates.io-index" 1298 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1299 | 1300 | [[package]] 1301 | name = "version_check" 1302 | version = "0.9.4" 1303 | source = "registry+https://github.com/rust-lang/crates.io-index" 1304 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1305 | 1306 | [[package]] 1307 | name = "want" 1308 | version = "0.3.1" 1309 | source = "registry+https://github.com/rust-lang/crates.io-index" 1310 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1311 | dependencies = [ 1312 | "try-lock", 1313 | ] 1314 | 1315 | [[package]] 1316 | name = "wasi" 1317 | version = "0.11.0+wasi-snapshot-preview1" 1318 | source = "registry+https://github.com/rust-lang/crates.io-index" 1319 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1320 | 1321 | [[package]] 1322 | name = "wasm-bindgen" 1323 | version = "0.2.87" 1324 | source = "registry+https://github.com/rust-lang/crates.io-index" 1325 | checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" 1326 | dependencies = [ 1327 | "cfg-if", 1328 | "wasm-bindgen-macro", 1329 | ] 1330 | 1331 | [[package]] 1332 | name = "wasm-bindgen-backend" 1333 | version = "0.2.87" 1334 | source = "registry+https://github.com/rust-lang/crates.io-index" 1335 | checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" 1336 | dependencies = [ 1337 | "bumpalo", 1338 | "log", 1339 | "once_cell", 1340 | "proc-macro2", 1341 | "quote", 1342 | "syn 2.0.29", 1343 | "wasm-bindgen-shared", 1344 | ] 1345 | 1346 | [[package]] 1347 | name = "wasm-bindgen-futures" 1348 | version = "0.4.37" 1349 | source = "registry+https://github.com/rust-lang/crates.io-index" 1350 | checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" 1351 | dependencies = [ 1352 | "cfg-if", 1353 | "js-sys", 1354 | "wasm-bindgen", 1355 | "web-sys", 1356 | ] 1357 | 1358 | [[package]] 1359 | name = "wasm-bindgen-macro" 1360 | version = "0.2.87" 1361 | source = "registry+https://github.com/rust-lang/crates.io-index" 1362 | checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" 1363 | dependencies = [ 1364 | "quote", 1365 | "wasm-bindgen-macro-support", 1366 | ] 1367 | 1368 | [[package]] 1369 | name = "wasm-bindgen-macro-support" 1370 | version = "0.2.87" 1371 | source = "registry+https://github.com/rust-lang/crates.io-index" 1372 | checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" 1373 | dependencies = [ 1374 | "proc-macro2", 1375 | "quote", 1376 | "syn 2.0.29", 1377 | "wasm-bindgen-backend", 1378 | "wasm-bindgen-shared", 1379 | ] 1380 | 1381 | [[package]] 1382 | name = "wasm-bindgen-shared" 1383 | version = "0.2.87" 1384 | source = "registry+https://github.com/rust-lang/crates.io-index" 1385 | checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" 1386 | 1387 | [[package]] 1388 | name = "web-sys" 1389 | version = "0.3.64" 1390 | source = "registry+https://github.com/rust-lang/crates.io-index" 1391 | checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" 1392 | dependencies = [ 1393 | "js-sys", 1394 | "wasm-bindgen", 1395 | ] 1396 | 1397 | [[package]] 1398 | name = "winapi" 1399 | version = "0.3.9" 1400 | source = "registry+https://github.com/rust-lang/crates.io-index" 1401 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1402 | dependencies = [ 1403 | "winapi-i686-pc-windows-gnu", 1404 | "winapi-x86_64-pc-windows-gnu", 1405 | ] 1406 | 1407 | [[package]] 1408 | name = "winapi-i686-pc-windows-gnu" 1409 | version = "0.4.0" 1410 | source = "registry+https://github.com/rust-lang/crates.io-index" 1411 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1412 | 1413 | [[package]] 1414 | name = "winapi-x86_64-pc-windows-gnu" 1415 | version = "0.4.0" 1416 | source = "registry+https://github.com/rust-lang/crates.io-index" 1417 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1418 | 1419 | [[package]] 1420 | name = "windows-sys" 1421 | version = "0.48.0" 1422 | source = "registry+https://github.com/rust-lang/crates.io-index" 1423 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1424 | dependencies = [ 1425 | "windows-targets", 1426 | ] 1427 | 1428 | [[package]] 1429 | name = "windows-targets" 1430 | version = "0.48.5" 1431 | source = "registry+https://github.com/rust-lang/crates.io-index" 1432 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 1433 | dependencies = [ 1434 | "windows_aarch64_gnullvm", 1435 | "windows_aarch64_msvc", 1436 | "windows_i686_gnu", 1437 | "windows_i686_msvc", 1438 | "windows_x86_64_gnu", 1439 | "windows_x86_64_gnullvm", 1440 | "windows_x86_64_msvc", 1441 | ] 1442 | 1443 | [[package]] 1444 | name = "windows_aarch64_gnullvm" 1445 | version = "0.48.5" 1446 | source = "registry+https://github.com/rust-lang/crates.io-index" 1447 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 1448 | 1449 | [[package]] 1450 | name = "windows_aarch64_msvc" 1451 | version = "0.48.5" 1452 | source = "registry+https://github.com/rust-lang/crates.io-index" 1453 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 1454 | 1455 | [[package]] 1456 | name = "windows_i686_gnu" 1457 | version = "0.48.5" 1458 | source = "registry+https://github.com/rust-lang/crates.io-index" 1459 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 1460 | 1461 | [[package]] 1462 | name = "windows_i686_msvc" 1463 | version = "0.48.5" 1464 | source = "registry+https://github.com/rust-lang/crates.io-index" 1465 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 1466 | 1467 | [[package]] 1468 | name = "windows_x86_64_gnu" 1469 | version = "0.48.5" 1470 | source = "registry+https://github.com/rust-lang/crates.io-index" 1471 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 1472 | 1473 | [[package]] 1474 | name = "windows_x86_64_gnullvm" 1475 | version = "0.48.5" 1476 | source = "registry+https://github.com/rust-lang/crates.io-index" 1477 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 1478 | 1479 | [[package]] 1480 | name = "windows_x86_64_msvc" 1481 | version = "0.48.5" 1482 | source = "registry+https://github.com/rust-lang/crates.io-index" 1483 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 1484 | 1485 | [[package]] 1486 | name = "winreg" 1487 | version = "0.50.0" 1488 | source = "registry+https://github.com/rust-lang/crates.io-index" 1489 | checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" 1490 | dependencies = [ 1491 | "cfg-if", 1492 | "windows-sys", 1493 | ] 1494 | -------------------------------------------------------------------------------- /cli/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.21.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "aes" 22 | version = "0.7.5" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" 25 | dependencies = [ 26 | "cfg-if", 27 | "cipher", 28 | "cpufeatures", 29 | "opaque-debug", 30 | ] 31 | 32 | [[package]] 33 | name = "alloc-no-stdlib" 34 | version = "2.0.4" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" 37 | 38 | [[package]] 39 | name = "alloc-stdlib" 40 | version = "0.2.2" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" 43 | dependencies = [ 44 | "alloc-no-stdlib", 45 | ] 46 | 47 | [[package]] 48 | name = "anstream" 49 | version = "0.5.0" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" 52 | dependencies = [ 53 | "anstyle", 54 | "anstyle-parse", 55 | "anstyle-query", 56 | "anstyle-wincon", 57 | "colorchoice", 58 | "utf8parse", 59 | ] 60 | 61 | [[package]] 62 | name = "anstyle" 63 | version = "1.0.2" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" 66 | 67 | [[package]] 68 | name = "anstyle-parse" 69 | version = "0.2.1" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" 72 | dependencies = [ 73 | "utf8parse", 74 | ] 75 | 76 | [[package]] 77 | name = "anstyle-query" 78 | version = "1.0.0" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" 81 | dependencies = [ 82 | "windows-sys 0.48.0", 83 | ] 84 | 85 | [[package]] 86 | name = "anstyle-wincon" 87 | version = "2.1.0" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" 90 | dependencies = [ 91 | "anstyle", 92 | "windows-sys 0.48.0", 93 | ] 94 | 95 | [[package]] 96 | name = "async-compression" 97 | version = "0.4.2" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "d495b6dc0184693324491a5ac05f559acc97bf937ab31d7a1c33dd0016be6d2b" 100 | dependencies = [ 101 | "brotli", 102 | "flate2", 103 | "futures-core", 104 | "memchr", 105 | "pin-project-lite", 106 | "tokio", 107 | ] 108 | 109 | [[package]] 110 | name = "async-trait" 111 | version = "0.1.73" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" 114 | dependencies = [ 115 | "proc-macro2", 116 | "quote", 117 | "syn 2.0.30", 118 | ] 119 | 120 | [[package]] 121 | name = "autocfg" 122 | version = "1.1.0" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 125 | 126 | [[package]] 127 | name = "backtrace" 128 | version = "0.3.69" 129 | source = "registry+https://github.com/rust-lang/crates.io-index" 130 | checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" 131 | dependencies = [ 132 | "addr2line", 133 | "cc", 134 | "cfg-if", 135 | "libc", 136 | "miniz_oxide", 137 | "object", 138 | "rustc-demangle", 139 | ] 140 | 141 | [[package]] 142 | name = "base64" 143 | version = "0.21.3" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" 146 | 147 | [[package]] 148 | name = "base64ct" 149 | version = "1.0.1" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" 152 | 153 | [[package]] 154 | name = "bitflags" 155 | version = "1.3.2" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 158 | 159 | [[package]] 160 | name = "bitflags" 161 | version = "2.4.0" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" 164 | 165 | [[package]] 166 | name = "block-buffer" 167 | version = "0.9.0" 168 | source = "registry+https://github.com/rust-lang/crates.io-index" 169 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 170 | dependencies = [ 171 | "generic-array", 172 | ] 173 | 174 | [[package]] 175 | name = "block-buffer" 176 | version = "0.10.4" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 179 | dependencies = [ 180 | "generic-array", 181 | ] 182 | 183 | [[package]] 184 | name = "block-modes" 185 | version = "0.8.1" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "2cb03d1bed155d89dce0f845b7899b18a9a163e148fd004e1c28421a783e2d8e" 188 | dependencies = [ 189 | "block-padding", 190 | "cipher", 191 | ] 192 | 193 | [[package]] 194 | name = "block-padding" 195 | version = "0.2.1" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" 198 | 199 | [[package]] 200 | name = "brotli" 201 | version = "3.3.4" 202 | source = "registry+https://github.com/rust-lang/crates.io-index" 203 | checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" 204 | dependencies = [ 205 | "alloc-no-stdlib", 206 | "alloc-stdlib", 207 | "brotli-decompressor", 208 | ] 209 | 210 | [[package]] 211 | name = "brotli-decompressor" 212 | version = "2.3.4" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" 215 | dependencies = [ 216 | "alloc-no-stdlib", 217 | "alloc-stdlib", 218 | ] 219 | 220 | [[package]] 221 | name = "bumpalo" 222 | version = "3.13.0" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" 225 | 226 | [[package]] 227 | name = "bytes" 228 | version = "1.4.0" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" 231 | 232 | [[package]] 233 | name = "bytesize" 234 | version = "1.3.0" 235 | source = "registry+https://github.com/rust-lang/crates.io-index" 236 | checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" 237 | 238 | [[package]] 239 | name = "cc" 240 | version = "1.0.83" 241 | source = "registry+https://github.com/rust-lang/crates.io-index" 242 | checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" 243 | dependencies = [ 244 | "libc", 245 | ] 246 | 247 | [[package]] 248 | name = "cfg-if" 249 | version = "1.0.0" 250 | source = "registry+https://github.com/rust-lang/crates.io-index" 251 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 252 | 253 | [[package]] 254 | name = "cipher" 255 | version = "0.3.0" 256 | source = "registry+https://github.com/rust-lang/crates.io-index" 257 | checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" 258 | dependencies = [ 259 | "generic-array", 260 | ] 261 | 262 | [[package]] 263 | name = "clap" 264 | version = "4.4.2" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | checksum = "6a13b88d2c62ff462f88e4a121f17a82c1af05693a2f192b5c38d14de73c19f6" 267 | dependencies = [ 268 | "clap_builder", 269 | "clap_derive", 270 | ] 271 | 272 | [[package]] 273 | name = "clap_builder" 274 | version = "4.4.2" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" 277 | dependencies = [ 278 | "anstream", 279 | "anstyle", 280 | "clap_lex", 281 | "strsim", 282 | ] 283 | 284 | [[package]] 285 | name = "clap_derive" 286 | version = "4.4.2" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" 289 | dependencies = [ 290 | "heck", 291 | "proc-macro2", 292 | "quote", 293 | "syn 2.0.30", 294 | ] 295 | 296 | [[package]] 297 | name = "clap_lex" 298 | version = "0.5.1" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" 301 | 302 | [[package]] 303 | name = "cli" 304 | version = "0.1.0" 305 | dependencies = [ 306 | "bytesize", 307 | "clap", 308 | "discord-us", 309 | "indicatif", 310 | "rand", 311 | ] 312 | 313 | [[package]] 314 | name = "colorchoice" 315 | version = "1.0.0" 316 | source = "registry+https://github.com/rust-lang/crates.io-index" 317 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 318 | 319 | [[package]] 320 | name = "console" 321 | version = "0.15.7" 322 | source = "registry+https://github.com/rust-lang/crates.io-index" 323 | checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" 324 | dependencies = [ 325 | "encode_unicode", 326 | "lazy_static", 327 | "libc", 328 | "unicode-width", 329 | "windows-sys 0.45.0", 330 | ] 331 | 332 | [[package]] 333 | name = "core-foundation" 334 | version = "0.9.3" 335 | source = "registry+https://github.com/rust-lang/crates.io-index" 336 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 337 | dependencies = [ 338 | "core-foundation-sys", 339 | "libc", 340 | ] 341 | 342 | [[package]] 343 | name = "core-foundation-sys" 344 | version = "0.8.4" 345 | source = "registry+https://github.com/rust-lang/crates.io-index" 346 | checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" 347 | 348 | [[package]] 349 | name = "cpufeatures" 350 | version = "0.2.9" 351 | source = "registry+https://github.com/rust-lang/crates.io-index" 352 | checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" 353 | dependencies = [ 354 | "libc", 355 | ] 356 | 357 | [[package]] 358 | name = "crc32fast" 359 | version = "1.3.2" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 362 | dependencies = [ 363 | "cfg-if", 364 | ] 365 | 366 | [[package]] 367 | name = "crypto-common" 368 | version = "0.1.6" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 371 | dependencies = [ 372 | "generic-array", 373 | "typenum", 374 | ] 375 | 376 | [[package]] 377 | name = "crypto-mac" 378 | version = "0.11.1" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" 381 | dependencies = [ 382 | "generic-array", 383 | "subtle", 384 | ] 385 | 386 | [[package]] 387 | name = "digest" 388 | version = "0.9.0" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 391 | dependencies = [ 392 | "generic-array", 393 | ] 394 | 395 | [[package]] 396 | name = "digest" 397 | version = "0.10.7" 398 | source = "registry+https://github.com/rust-lang/crates.io-index" 399 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 400 | dependencies = [ 401 | "block-buffer 0.10.4", 402 | "crypto-common", 403 | ] 404 | 405 | [[package]] 406 | name = "discord-us" 407 | version = "0.1.0" 408 | dependencies = [ 409 | "aes", 410 | "block-modes", 411 | "dyn-clonable", 412 | "dyn-clone", 413 | "hex-buffer-serde", 414 | "hmac", 415 | "pbkdf2", 416 | "rand", 417 | "reqwest", 418 | "serde", 419 | "serde_json", 420 | "sha2 0.9.9", 421 | "sha256", 422 | "sorted-vec", 423 | "threadpool", 424 | ] 425 | 426 | [[package]] 427 | name = "dyn-clonable" 428 | version = "0.9.0" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" 431 | dependencies = [ 432 | "dyn-clonable-impl", 433 | "dyn-clone", 434 | ] 435 | 436 | [[package]] 437 | name = "dyn-clonable-impl" 438 | version = "0.9.0" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" 441 | dependencies = [ 442 | "proc-macro2", 443 | "quote", 444 | "syn 1.0.109", 445 | ] 446 | 447 | [[package]] 448 | name = "dyn-clone" 449 | version = "1.0.13" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "bbfc4744c1b8f2a09adc0e55242f60b1af195d88596bd8700be74418c056c555" 452 | 453 | [[package]] 454 | name = "encode_unicode" 455 | version = "0.3.6" 456 | source = "registry+https://github.com/rust-lang/crates.io-index" 457 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" 458 | 459 | [[package]] 460 | name = "encoding_rs" 461 | version = "0.8.33" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" 464 | dependencies = [ 465 | "cfg-if", 466 | ] 467 | 468 | [[package]] 469 | name = "errno" 470 | version = "0.3.3" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" 473 | dependencies = [ 474 | "errno-dragonfly", 475 | "libc", 476 | "windows-sys 0.48.0", 477 | ] 478 | 479 | [[package]] 480 | name = "errno-dragonfly" 481 | version = "0.1.2" 482 | source = "registry+https://github.com/rust-lang/crates.io-index" 483 | checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" 484 | dependencies = [ 485 | "cc", 486 | "libc", 487 | ] 488 | 489 | [[package]] 490 | name = "fastrand" 491 | version = "2.0.0" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" 494 | 495 | [[package]] 496 | name = "flate2" 497 | version = "1.0.27" 498 | source = "registry+https://github.com/rust-lang/crates.io-index" 499 | checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" 500 | dependencies = [ 501 | "crc32fast", 502 | "miniz_oxide", 503 | ] 504 | 505 | [[package]] 506 | name = "fnv" 507 | version = "1.0.7" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 510 | 511 | [[package]] 512 | name = "foreign-types" 513 | version = "0.3.2" 514 | source = "registry+https://github.com/rust-lang/crates.io-index" 515 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 516 | dependencies = [ 517 | "foreign-types-shared", 518 | ] 519 | 520 | [[package]] 521 | name = "foreign-types-shared" 522 | version = "0.1.1" 523 | source = "registry+https://github.com/rust-lang/crates.io-index" 524 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 525 | 526 | [[package]] 527 | name = "form_urlencoded" 528 | version = "1.2.0" 529 | source = "registry+https://github.com/rust-lang/crates.io-index" 530 | checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" 531 | dependencies = [ 532 | "percent-encoding", 533 | ] 534 | 535 | [[package]] 536 | name = "futures-channel" 537 | version = "0.3.28" 538 | source = "registry+https://github.com/rust-lang/crates.io-index" 539 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" 540 | dependencies = [ 541 | "futures-core", 542 | ] 543 | 544 | [[package]] 545 | name = "futures-core" 546 | version = "0.3.28" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" 549 | 550 | [[package]] 551 | name = "futures-io" 552 | version = "0.3.28" 553 | source = "registry+https://github.com/rust-lang/crates.io-index" 554 | checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" 555 | 556 | [[package]] 557 | name = "futures-sink" 558 | version = "0.3.28" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" 561 | 562 | [[package]] 563 | name = "futures-task" 564 | version = "0.3.28" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" 567 | 568 | [[package]] 569 | name = "futures-util" 570 | version = "0.3.28" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" 573 | dependencies = [ 574 | "futures-core", 575 | "futures-io", 576 | "futures-task", 577 | "memchr", 578 | "pin-project-lite", 579 | "pin-utils", 580 | "slab", 581 | ] 582 | 583 | [[package]] 584 | name = "generic-array" 585 | version = "0.14.7" 586 | source = "registry+https://github.com/rust-lang/crates.io-index" 587 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 588 | dependencies = [ 589 | "typenum", 590 | "version_check", 591 | ] 592 | 593 | [[package]] 594 | name = "getrandom" 595 | version = "0.2.10" 596 | source = "registry+https://github.com/rust-lang/crates.io-index" 597 | checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" 598 | dependencies = [ 599 | "cfg-if", 600 | "libc", 601 | "wasi", 602 | ] 603 | 604 | [[package]] 605 | name = "gimli" 606 | version = "0.28.0" 607 | source = "registry+https://github.com/rust-lang/crates.io-index" 608 | checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" 609 | 610 | [[package]] 611 | name = "h2" 612 | version = "0.3.21" 613 | source = "registry+https://github.com/rust-lang/crates.io-index" 614 | checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" 615 | dependencies = [ 616 | "bytes", 617 | "fnv", 618 | "futures-core", 619 | "futures-sink", 620 | "futures-util", 621 | "http", 622 | "indexmap", 623 | "slab", 624 | "tokio", 625 | "tokio-util", 626 | "tracing", 627 | ] 628 | 629 | [[package]] 630 | name = "hashbrown" 631 | version = "0.12.3" 632 | source = "registry+https://github.com/rust-lang/crates.io-index" 633 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 634 | 635 | [[package]] 636 | name = "heck" 637 | version = "0.4.1" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 640 | 641 | [[package]] 642 | name = "hermit-abi" 643 | version = "0.3.2" 644 | source = "registry+https://github.com/rust-lang/crates.io-index" 645 | checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" 646 | 647 | [[package]] 648 | name = "hex" 649 | version = "0.4.3" 650 | source = "registry+https://github.com/rust-lang/crates.io-index" 651 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 652 | 653 | [[package]] 654 | name = "hex-buffer-serde" 655 | version = "0.4.0" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | checksum = "c7e84645a601cf4a58f40673d51c111d1b5f847b711559c076ebcb779606a6d0" 658 | dependencies = [ 659 | "hex", 660 | "serde", 661 | ] 662 | 663 | [[package]] 664 | name = "hmac" 665 | version = "0.11.0" 666 | source = "registry+https://github.com/rust-lang/crates.io-index" 667 | checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" 668 | dependencies = [ 669 | "crypto-mac", 670 | "digest 0.9.0", 671 | ] 672 | 673 | [[package]] 674 | name = "http" 675 | version = "0.2.9" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" 678 | dependencies = [ 679 | "bytes", 680 | "fnv", 681 | "itoa", 682 | ] 683 | 684 | [[package]] 685 | name = "http-body" 686 | version = "0.4.5" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 689 | dependencies = [ 690 | "bytes", 691 | "http", 692 | "pin-project-lite", 693 | ] 694 | 695 | [[package]] 696 | name = "httparse" 697 | version = "1.8.0" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 700 | 701 | [[package]] 702 | name = "httpdate" 703 | version = "1.0.3" 704 | source = "registry+https://github.com/rust-lang/crates.io-index" 705 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 706 | 707 | [[package]] 708 | name = "hyper" 709 | version = "0.14.27" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" 712 | dependencies = [ 713 | "bytes", 714 | "futures-channel", 715 | "futures-core", 716 | "futures-util", 717 | "h2", 718 | "http", 719 | "http-body", 720 | "httparse", 721 | "httpdate", 722 | "itoa", 723 | "pin-project-lite", 724 | "socket2 0.4.9", 725 | "tokio", 726 | "tower-service", 727 | "tracing", 728 | "want", 729 | ] 730 | 731 | [[package]] 732 | name = "hyper-tls" 733 | version = "0.5.0" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 736 | dependencies = [ 737 | "bytes", 738 | "hyper", 739 | "native-tls", 740 | "tokio", 741 | "tokio-native-tls", 742 | ] 743 | 744 | [[package]] 745 | name = "idna" 746 | version = "0.4.0" 747 | source = "registry+https://github.com/rust-lang/crates.io-index" 748 | checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" 749 | dependencies = [ 750 | "unicode-bidi", 751 | "unicode-normalization", 752 | ] 753 | 754 | [[package]] 755 | name = "indexmap" 756 | version = "1.9.3" 757 | source = "registry+https://github.com/rust-lang/crates.io-index" 758 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 759 | dependencies = [ 760 | "autocfg", 761 | "hashbrown", 762 | ] 763 | 764 | [[package]] 765 | name = "indicatif" 766 | version = "0.17.6" 767 | source = "registry+https://github.com/rust-lang/crates.io-index" 768 | checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730" 769 | dependencies = [ 770 | "console", 771 | "instant", 772 | "number_prefix", 773 | "portable-atomic", 774 | "unicode-width", 775 | ] 776 | 777 | [[package]] 778 | name = "instant" 779 | version = "0.1.12" 780 | source = "registry+https://github.com/rust-lang/crates.io-index" 781 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 782 | dependencies = [ 783 | "cfg-if", 784 | ] 785 | 786 | [[package]] 787 | name = "ipnet" 788 | version = "2.8.0" 789 | source = "registry+https://github.com/rust-lang/crates.io-index" 790 | checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" 791 | 792 | [[package]] 793 | name = "itoa" 794 | version = "1.0.9" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" 797 | 798 | [[package]] 799 | name = "js-sys" 800 | version = "0.3.64" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" 803 | dependencies = [ 804 | "wasm-bindgen", 805 | ] 806 | 807 | [[package]] 808 | name = "lazy_static" 809 | version = "1.4.0" 810 | source = "registry+https://github.com/rust-lang/crates.io-index" 811 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 812 | 813 | [[package]] 814 | name = "libc" 815 | version = "0.2.147" 816 | source = "registry+https://github.com/rust-lang/crates.io-index" 817 | checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" 818 | 819 | [[package]] 820 | name = "linux-raw-sys" 821 | version = "0.4.5" 822 | source = "registry+https://github.com/rust-lang/crates.io-index" 823 | checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" 824 | 825 | [[package]] 826 | name = "log" 827 | version = "0.4.20" 828 | source = "registry+https://github.com/rust-lang/crates.io-index" 829 | checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" 830 | 831 | [[package]] 832 | name = "memchr" 833 | version = "2.6.3" 834 | source = "registry+https://github.com/rust-lang/crates.io-index" 835 | checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" 836 | 837 | [[package]] 838 | name = "mime" 839 | version = "0.3.17" 840 | source = "registry+https://github.com/rust-lang/crates.io-index" 841 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 842 | 843 | [[package]] 844 | name = "miniz_oxide" 845 | version = "0.7.1" 846 | source = "registry+https://github.com/rust-lang/crates.io-index" 847 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 848 | dependencies = [ 849 | "adler", 850 | ] 851 | 852 | [[package]] 853 | name = "mio" 854 | version = "0.8.8" 855 | source = "registry+https://github.com/rust-lang/crates.io-index" 856 | checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" 857 | dependencies = [ 858 | "libc", 859 | "wasi", 860 | "windows-sys 0.48.0", 861 | ] 862 | 863 | [[package]] 864 | name = "native-tls" 865 | version = "0.2.11" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" 868 | dependencies = [ 869 | "lazy_static", 870 | "libc", 871 | "log", 872 | "openssl", 873 | "openssl-probe", 874 | "openssl-sys", 875 | "schannel", 876 | "security-framework", 877 | "security-framework-sys", 878 | "tempfile", 879 | ] 880 | 881 | [[package]] 882 | name = "num_cpus" 883 | version = "1.16.0" 884 | source = "registry+https://github.com/rust-lang/crates.io-index" 885 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 886 | dependencies = [ 887 | "hermit-abi", 888 | "libc", 889 | ] 890 | 891 | [[package]] 892 | name = "number_prefix" 893 | version = "0.4.0" 894 | source = "registry+https://github.com/rust-lang/crates.io-index" 895 | checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" 896 | 897 | [[package]] 898 | name = "object" 899 | version = "0.32.1" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" 902 | dependencies = [ 903 | "memchr", 904 | ] 905 | 906 | [[package]] 907 | name = "once_cell" 908 | version = "1.18.0" 909 | source = "registry+https://github.com/rust-lang/crates.io-index" 910 | checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" 911 | 912 | [[package]] 913 | name = "opaque-debug" 914 | version = "0.3.0" 915 | source = "registry+https://github.com/rust-lang/crates.io-index" 916 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 917 | 918 | [[package]] 919 | name = "openssl" 920 | version = "0.10.57" 921 | source = "registry+https://github.com/rust-lang/crates.io-index" 922 | checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" 923 | dependencies = [ 924 | "bitflags 2.4.0", 925 | "cfg-if", 926 | "foreign-types", 927 | "libc", 928 | "once_cell", 929 | "openssl-macros", 930 | "openssl-sys", 931 | ] 932 | 933 | [[package]] 934 | name = "openssl-macros" 935 | version = "0.1.1" 936 | source = "registry+https://github.com/rust-lang/crates.io-index" 937 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 938 | dependencies = [ 939 | "proc-macro2", 940 | "quote", 941 | "syn 2.0.30", 942 | ] 943 | 944 | [[package]] 945 | name = "openssl-probe" 946 | version = "0.1.5" 947 | source = "registry+https://github.com/rust-lang/crates.io-index" 948 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 949 | 950 | [[package]] 951 | name = "openssl-sys" 952 | version = "0.9.92" 953 | source = "registry+https://github.com/rust-lang/crates.io-index" 954 | checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b" 955 | dependencies = [ 956 | "cc", 957 | "libc", 958 | "pkg-config", 959 | "vcpkg", 960 | ] 961 | 962 | [[package]] 963 | name = "password-hash" 964 | version = "0.3.2" 965 | source = "registry+https://github.com/rust-lang/crates.io-index" 966 | checksum = "1d791538a6dcc1e7cb7fe6f6b58aca40e7f79403c45b2bc274008b5e647af1d8" 967 | dependencies = [ 968 | "base64ct", 969 | "rand_core", 970 | "subtle", 971 | ] 972 | 973 | [[package]] 974 | name = "pbkdf2" 975 | version = "0.9.0" 976 | source = "registry+https://github.com/rust-lang/crates.io-index" 977 | checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" 978 | dependencies = [ 979 | "crypto-mac", 980 | "hmac", 981 | "password-hash", 982 | "sha2 0.9.9", 983 | ] 984 | 985 | [[package]] 986 | name = "percent-encoding" 987 | version = "2.3.0" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" 990 | 991 | [[package]] 992 | name = "pin-project-lite" 993 | version = "0.2.13" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 996 | 997 | [[package]] 998 | name = "pin-utils" 999 | version = "0.1.0" 1000 | source = "registry+https://github.com/rust-lang/crates.io-index" 1001 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1002 | 1003 | [[package]] 1004 | name = "pkg-config" 1005 | version = "0.3.27" 1006 | source = "registry+https://github.com/rust-lang/crates.io-index" 1007 | checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" 1008 | 1009 | [[package]] 1010 | name = "portable-atomic" 1011 | version = "1.4.3" 1012 | source = "registry+https://github.com/rust-lang/crates.io-index" 1013 | checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b" 1014 | 1015 | [[package]] 1016 | name = "ppv-lite86" 1017 | version = "0.2.17" 1018 | source = "registry+https://github.com/rust-lang/crates.io-index" 1019 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1020 | 1021 | [[package]] 1022 | name = "proc-macro2" 1023 | version = "1.0.66" 1024 | source = "registry+https://github.com/rust-lang/crates.io-index" 1025 | checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" 1026 | dependencies = [ 1027 | "unicode-ident", 1028 | ] 1029 | 1030 | [[package]] 1031 | name = "quote" 1032 | version = "1.0.33" 1033 | source = "registry+https://github.com/rust-lang/crates.io-index" 1034 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 1035 | dependencies = [ 1036 | "proc-macro2", 1037 | ] 1038 | 1039 | [[package]] 1040 | name = "rand" 1041 | version = "0.8.5" 1042 | source = "registry+https://github.com/rust-lang/crates.io-index" 1043 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1044 | dependencies = [ 1045 | "libc", 1046 | "rand_chacha", 1047 | "rand_core", 1048 | ] 1049 | 1050 | [[package]] 1051 | name = "rand_chacha" 1052 | version = "0.3.1" 1053 | source = "registry+https://github.com/rust-lang/crates.io-index" 1054 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1055 | dependencies = [ 1056 | "ppv-lite86", 1057 | "rand_core", 1058 | ] 1059 | 1060 | [[package]] 1061 | name = "rand_core" 1062 | version = "0.6.4" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1065 | dependencies = [ 1066 | "getrandom", 1067 | ] 1068 | 1069 | [[package]] 1070 | name = "redox_syscall" 1071 | version = "0.3.5" 1072 | source = "registry+https://github.com/rust-lang/crates.io-index" 1073 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" 1074 | dependencies = [ 1075 | "bitflags 1.3.2", 1076 | ] 1077 | 1078 | [[package]] 1079 | name = "reqwest" 1080 | version = "0.11.20" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" 1083 | dependencies = [ 1084 | "async-compression", 1085 | "base64", 1086 | "bytes", 1087 | "encoding_rs", 1088 | "futures-core", 1089 | "futures-util", 1090 | "h2", 1091 | "http", 1092 | "http-body", 1093 | "hyper", 1094 | "hyper-tls", 1095 | "ipnet", 1096 | "js-sys", 1097 | "log", 1098 | "mime", 1099 | "native-tls", 1100 | "once_cell", 1101 | "percent-encoding", 1102 | "pin-project-lite", 1103 | "serde", 1104 | "serde_json", 1105 | "serde_urlencoded", 1106 | "tokio", 1107 | "tokio-native-tls", 1108 | "tokio-util", 1109 | "tower-service", 1110 | "url", 1111 | "wasm-bindgen", 1112 | "wasm-bindgen-futures", 1113 | "web-sys", 1114 | "winreg", 1115 | ] 1116 | 1117 | [[package]] 1118 | name = "rustc-demangle" 1119 | version = "0.1.23" 1120 | source = "registry+https://github.com/rust-lang/crates.io-index" 1121 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 1122 | 1123 | [[package]] 1124 | name = "rustix" 1125 | version = "0.38.11" 1126 | source = "registry+https://github.com/rust-lang/crates.io-index" 1127 | checksum = "c0c3dde1fc030af041adc40e79c0e7fbcf431dd24870053d187d7c66e4b87453" 1128 | dependencies = [ 1129 | "bitflags 2.4.0", 1130 | "errno", 1131 | "libc", 1132 | "linux-raw-sys", 1133 | "windows-sys 0.48.0", 1134 | ] 1135 | 1136 | [[package]] 1137 | name = "ryu" 1138 | version = "1.0.15" 1139 | source = "registry+https://github.com/rust-lang/crates.io-index" 1140 | checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" 1141 | 1142 | [[package]] 1143 | name = "schannel" 1144 | version = "0.1.22" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" 1147 | dependencies = [ 1148 | "windows-sys 0.48.0", 1149 | ] 1150 | 1151 | [[package]] 1152 | name = "security-framework" 1153 | version = "2.9.2" 1154 | source = "registry+https://github.com/rust-lang/crates.io-index" 1155 | checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" 1156 | dependencies = [ 1157 | "bitflags 1.3.2", 1158 | "core-foundation", 1159 | "core-foundation-sys", 1160 | "libc", 1161 | "security-framework-sys", 1162 | ] 1163 | 1164 | [[package]] 1165 | name = "security-framework-sys" 1166 | version = "2.9.1" 1167 | source = "registry+https://github.com/rust-lang/crates.io-index" 1168 | checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" 1169 | dependencies = [ 1170 | "core-foundation-sys", 1171 | "libc", 1172 | ] 1173 | 1174 | [[package]] 1175 | name = "serde" 1176 | version = "1.0.188" 1177 | source = "registry+https://github.com/rust-lang/crates.io-index" 1178 | checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" 1179 | dependencies = [ 1180 | "serde_derive", 1181 | ] 1182 | 1183 | [[package]] 1184 | name = "serde_derive" 1185 | version = "1.0.188" 1186 | source = "registry+https://github.com/rust-lang/crates.io-index" 1187 | checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" 1188 | dependencies = [ 1189 | "proc-macro2", 1190 | "quote", 1191 | "syn 2.0.30", 1192 | ] 1193 | 1194 | [[package]] 1195 | name = "serde_json" 1196 | version = "1.0.105" 1197 | source = "registry+https://github.com/rust-lang/crates.io-index" 1198 | checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" 1199 | dependencies = [ 1200 | "itoa", 1201 | "ryu", 1202 | "serde", 1203 | ] 1204 | 1205 | [[package]] 1206 | name = "serde_urlencoded" 1207 | version = "0.7.1" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1210 | dependencies = [ 1211 | "form_urlencoded", 1212 | "itoa", 1213 | "ryu", 1214 | "serde", 1215 | ] 1216 | 1217 | [[package]] 1218 | name = "sha2" 1219 | version = "0.9.9" 1220 | source = "registry+https://github.com/rust-lang/crates.io-index" 1221 | checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" 1222 | dependencies = [ 1223 | "block-buffer 0.9.0", 1224 | "cfg-if", 1225 | "cpufeatures", 1226 | "digest 0.9.0", 1227 | "opaque-debug", 1228 | ] 1229 | 1230 | [[package]] 1231 | name = "sha2" 1232 | version = "0.10.7" 1233 | source = "registry+https://github.com/rust-lang/crates.io-index" 1234 | checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" 1235 | dependencies = [ 1236 | "cfg-if", 1237 | "cpufeatures", 1238 | "digest 0.10.7", 1239 | ] 1240 | 1241 | [[package]] 1242 | name = "sha256" 1243 | version = "1.4.0" 1244 | source = "registry+https://github.com/rust-lang/crates.io-index" 1245 | checksum = "7895c8ae88588ccead14ff438b939b0c569cd619116f14b4d13fdff7b8333386" 1246 | dependencies = [ 1247 | "async-trait", 1248 | "bytes", 1249 | "hex", 1250 | "sha2 0.10.7", 1251 | "tokio", 1252 | ] 1253 | 1254 | [[package]] 1255 | name = "slab" 1256 | version = "0.4.9" 1257 | source = "registry+https://github.com/rust-lang/crates.io-index" 1258 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1259 | dependencies = [ 1260 | "autocfg", 1261 | ] 1262 | 1263 | [[package]] 1264 | name = "socket2" 1265 | version = "0.4.9" 1266 | source = "registry+https://github.com/rust-lang/crates.io-index" 1267 | checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" 1268 | dependencies = [ 1269 | "libc", 1270 | "winapi", 1271 | ] 1272 | 1273 | [[package]] 1274 | name = "socket2" 1275 | version = "0.5.3" 1276 | source = "registry+https://github.com/rust-lang/crates.io-index" 1277 | checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" 1278 | dependencies = [ 1279 | "libc", 1280 | "windows-sys 0.48.0", 1281 | ] 1282 | 1283 | [[package]] 1284 | name = "sorted-vec" 1285 | version = "0.8.2" 1286 | source = "registry+https://github.com/rust-lang/crates.io-index" 1287 | checksum = "f0047b8207660638866f228b4b4147e98cc8efb190a70cd63d5cb899a4a539a8" 1288 | 1289 | [[package]] 1290 | name = "strsim" 1291 | version = "0.10.0" 1292 | source = "registry+https://github.com/rust-lang/crates.io-index" 1293 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 1294 | 1295 | [[package]] 1296 | name = "subtle" 1297 | version = "2.4.1" 1298 | source = "registry+https://github.com/rust-lang/crates.io-index" 1299 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 1300 | 1301 | [[package]] 1302 | name = "syn" 1303 | version = "1.0.109" 1304 | source = "registry+https://github.com/rust-lang/crates.io-index" 1305 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1306 | dependencies = [ 1307 | "proc-macro2", 1308 | "quote", 1309 | "unicode-ident", 1310 | ] 1311 | 1312 | [[package]] 1313 | name = "syn" 1314 | version = "2.0.30" 1315 | source = "registry+https://github.com/rust-lang/crates.io-index" 1316 | checksum = "0ddc1f908d32ec46858c2d3b3daa00cc35bf4b6841ce4355c7bb3eedf2283a68" 1317 | dependencies = [ 1318 | "proc-macro2", 1319 | "quote", 1320 | "unicode-ident", 1321 | ] 1322 | 1323 | [[package]] 1324 | name = "tempfile" 1325 | version = "3.8.0" 1326 | source = "registry+https://github.com/rust-lang/crates.io-index" 1327 | checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" 1328 | dependencies = [ 1329 | "cfg-if", 1330 | "fastrand", 1331 | "redox_syscall", 1332 | "rustix", 1333 | "windows-sys 0.48.0", 1334 | ] 1335 | 1336 | [[package]] 1337 | name = "threadpool" 1338 | version = "1.8.1" 1339 | source = "registry+https://github.com/rust-lang/crates.io-index" 1340 | checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" 1341 | dependencies = [ 1342 | "num_cpus", 1343 | ] 1344 | 1345 | [[package]] 1346 | name = "tinyvec" 1347 | version = "1.6.0" 1348 | source = "registry+https://github.com/rust-lang/crates.io-index" 1349 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 1350 | dependencies = [ 1351 | "tinyvec_macros", 1352 | ] 1353 | 1354 | [[package]] 1355 | name = "tinyvec_macros" 1356 | version = "0.1.1" 1357 | source = "registry+https://github.com/rust-lang/crates.io-index" 1358 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 1359 | 1360 | [[package]] 1361 | name = "tokio" 1362 | version = "1.32.0" 1363 | source = "registry+https://github.com/rust-lang/crates.io-index" 1364 | checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" 1365 | dependencies = [ 1366 | "backtrace", 1367 | "bytes", 1368 | "libc", 1369 | "mio", 1370 | "num_cpus", 1371 | "pin-project-lite", 1372 | "socket2 0.5.3", 1373 | "windows-sys 0.48.0", 1374 | ] 1375 | 1376 | [[package]] 1377 | name = "tokio-native-tls" 1378 | version = "0.3.1" 1379 | source = "registry+https://github.com/rust-lang/crates.io-index" 1380 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 1381 | dependencies = [ 1382 | "native-tls", 1383 | "tokio", 1384 | ] 1385 | 1386 | [[package]] 1387 | name = "tokio-util" 1388 | version = "0.7.8" 1389 | source = "registry+https://github.com/rust-lang/crates.io-index" 1390 | checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" 1391 | dependencies = [ 1392 | "bytes", 1393 | "futures-core", 1394 | "futures-sink", 1395 | "pin-project-lite", 1396 | "tokio", 1397 | "tracing", 1398 | ] 1399 | 1400 | [[package]] 1401 | name = "tower-service" 1402 | version = "0.3.2" 1403 | source = "registry+https://github.com/rust-lang/crates.io-index" 1404 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1405 | 1406 | [[package]] 1407 | name = "tracing" 1408 | version = "0.1.37" 1409 | source = "registry+https://github.com/rust-lang/crates.io-index" 1410 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 1411 | dependencies = [ 1412 | "cfg-if", 1413 | "pin-project-lite", 1414 | "tracing-core", 1415 | ] 1416 | 1417 | [[package]] 1418 | name = "tracing-core" 1419 | version = "0.1.31" 1420 | source = "registry+https://github.com/rust-lang/crates.io-index" 1421 | checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" 1422 | dependencies = [ 1423 | "once_cell", 1424 | ] 1425 | 1426 | [[package]] 1427 | name = "try-lock" 1428 | version = "0.2.4" 1429 | source = "registry+https://github.com/rust-lang/crates.io-index" 1430 | checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" 1431 | 1432 | [[package]] 1433 | name = "typenum" 1434 | version = "1.16.0" 1435 | source = "registry+https://github.com/rust-lang/crates.io-index" 1436 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" 1437 | 1438 | [[package]] 1439 | name = "unicode-bidi" 1440 | version = "0.3.13" 1441 | source = "registry+https://github.com/rust-lang/crates.io-index" 1442 | checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" 1443 | 1444 | [[package]] 1445 | name = "unicode-ident" 1446 | version = "1.0.11" 1447 | source = "registry+https://github.com/rust-lang/crates.io-index" 1448 | checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" 1449 | 1450 | [[package]] 1451 | name = "unicode-normalization" 1452 | version = "0.1.22" 1453 | source = "registry+https://github.com/rust-lang/crates.io-index" 1454 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 1455 | dependencies = [ 1456 | "tinyvec", 1457 | ] 1458 | 1459 | [[package]] 1460 | name = "unicode-width" 1461 | version = "0.1.10" 1462 | source = "registry+https://github.com/rust-lang/crates.io-index" 1463 | checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" 1464 | 1465 | [[package]] 1466 | name = "url" 1467 | version = "2.4.1" 1468 | source = "registry+https://github.com/rust-lang/crates.io-index" 1469 | checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" 1470 | dependencies = [ 1471 | "form_urlencoded", 1472 | "idna", 1473 | "percent-encoding", 1474 | ] 1475 | 1476 | [[package]] 1477 | name = "utf8parse" 1478 | version = "0.2.1" 1479 | source = "registry+https://github.com/rust-lang/crates.io-index" 1480 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" 1481 | 1482 | [[package]] 1483 | name = "vcpkg" 1484 | version = "0.2.15" 1485 | source = "registry+https://github.com/rust-lang/crates.io-index" 1486 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1487 | 1488 | [[package]] 1489 | name = "version_check" 1490 | version = "0.9.4" 1491 | source = "registry+https://github.com/rust-lang/crates.io-index" 1492 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1493 | 1494 | [[package]] 1495 | name = "want" 1496 | version = "0.3.1" 1497 | source = "registry+https://github.com/rust-lang/crates.io-index" 1498 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1499 | dependencies = [ 1500 | "try-lock", 1501 | ] 1502 | 1503 | [[package]] 1504 | name = "wasi" 1505 | version = "0.11.0+wasi-snapshot-preview1" 1506 | source = "registry+https://github.com/rust-lang/crates.io-index" 1507 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1508 | 1509 | [[package]] 1510 | name = "wasm-bindgen" 1511 | version = "0.2.87" 1512 | source = "registry+https://github.com/rust-lang/crates.io-index" 1513 | checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" 1514 | dependencies = [ 1515 | "cfg-if", 1516 | "wasm-bindgen-macro", 1517 | ] 1518 | 1519 | [[package]] 1520 | name = "wasm-bindgen-backend" 1521 | version = "0.2.87" 1522 | source = "registry+https://github.com/rust-lang/crates.io-index" 1523 | checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" 1524 | dependencies = [ 1525 | "bumpalo", 1526 | "log", 1527 | "once_cell", 1528 | "proc-macro2", 1529 | "quote", 1530 | "syn 2.0.30", 1531 | "wasm-bindgen-shared", 1532 | ] 1533 | 1534 | [[package]] 1535 | name = "wasm-bindgen-futures" 1536 | version = "0.4.37" 1537 | source = "registry+https://github.com/rust-lang/crates.io-index" 1538 | checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" 1539 | dependencies = [ 1540 | "cfg-if", 1541 | "js-sys", 1542 | "wasm-bindgen", 1543 | "web-sys", 1544 | ] 1545 | 1546 | [[package]] 1547 | name = "wasm-bindgen-macro" 1548 | version = "0.2.87" 1549 | source = "registry+https://github.com/rust-lang/crates.io-index" 1550 | checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" 1551 | dependencies = [ 1552 | "quote", 1553 | "wasm-bindgen-macro-support", 1554 | ] 1555 | 1556 | [[package]] 1557 | name = "wasm-bindgen-macro-support" 1558 | version = "0.2.87" 1559 | source = "registry+https://github.com/rust-lang/crates.io-index" 1560 | checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" 1561 | dependencies = [ 1562 | "proc-macro2", 1563 | "quote", 1564 | "syn 2.0.30", 1565 | "wasm-bindgen-backend", 1566 | "wasm-bindgen-shared", 1567 | ] 1568 | 1569 | [[package]] 1570 | name = "wasm-bindgen-shared" 1571 | version = "0.2.87" 1572 | source = "registry+https://github.com/rust-lang/crates.io-index" 1573 | checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" 1574 | 1575 | [[package]] 1576 | name = "web-sys" 1577 | version = "0.3.64" 1578 | source = "registry+https://github.com/rust-lang/crates.io-index" 1579 | checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" 1580 | dependencies = [ 1581 | "js-sys", 1582 | "wasm-bindgen", 1583 | ] 1584 | 1585 | [[package]] 1586 | name = "winapi" 1587 | version = "0.3.9" 1588 | source = "registry+https://github.com/rust-lang/crates.io-index" 1589 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1590 | dependencies = [ 1591 | "winapi-i686-pc-windows-gnu", 1592 | "winapi-x86_64-pc-windows-gnu", 1593 | ] 1594 | 1595 | [[package]] 1596 | name = "winapi-i686-pc-windows-gnu" 1597 | version = "0.4.0" 1598 | source = "registry+https://github.com/rust-lang/crates.io-index" 1599 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1600 | 1601 | [[package]] 1602 | name = "winapi-x86_64-pc-windows-gnu" 1603 | version = "0.4.0" 1604 | source = "registry+https://github.com/rust-lang/crates.io-index" 1605 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1606 | 1607 | [[package]] 1608 | name = "windows-sys" 1609 | version = "0.45.0" 1610 | source = "registry+https://github.com/rust-lang/crates.io-index" 1611 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 1612 | dependencies = [ 1613 | "windows-targets 0.42.2", 1614 | ] 1615 | 1616 | [[package]] 1617 | name = "windows-sys" 1618 | version = "0.48.0" 1619 | source = "registry+https://github.com/rust-lang/crates.io-index" 1620 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1621 | dependencies = [ 1622 | "windows-targets 0.48.5", 1623 | ] 1624 | 1625 | [[package]] 1626 | name = "windows-targets" 1627 | version = "0.42.2" 1628 | source = "registry+https://github.com/rust-lang/crates.io-index" 1629 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 1630 | dependencies = [ 1631 | "windows_aarch64_gnullvm 0.42.2", 1632 | "windows_aarch64_msvc 0.42.2", 1633 | "windows_i686_gnu 0.42.2", 1634 | "windows_i686_msvc 0.42.2", 1635 | "windows_x86_64_gnu 0.42.2", 1636 | "windows_x86_64_gnullvm 0.42.2", 1637 | "windows_x86_64_msvc 0.42.2", 1638 | ] 1639 | 1640 | [[package]] 1641 | name = "windows-targets" 1642 | version = "0.48.5" 1643 | source = "registry+https://github.com/rust-lang/crates.io-index" 1644 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 1645 | dependencies = [ 1646 | "windows_aarch64_gnullvm 0.48.5", 1647 | "windows_aarch64_msvc 0.48.5", 1648 | "windows_i686_gnu 0.48.5", 1649 | "windows_i686_msvc 0.48.5", 1650 | "windows_x86_64_gnu 0.48.5", 1651 | "windows_x86_64_gnullvm 0.48.5", 1652 | "windows_x86_64_msvc 0.48.5", 1653 | ] 1654 | 1655 | [[package]] 1656 | name = "windows_aarch64_gnullvm" 1657 | version = "0.42.2" 1658 | source = "registry+https://github.com/rust-lang/crates.io-index" 1659 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 1660 | 1661 | [[package]] 1662 | name = "windows_aarch64_gnullvm" 1663 | version = "0.48.5" 1664 | source = "registry+https://github.com/rust-lang/crates.io-index" 1665 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 1666 | 1667 | [[package]] 1668 | name = "windows_aarch64_msvc" 1669 | version = "0.42.2" 1670 | source = "registry+https://github.com/rust-lang/crates.io-index" 1671 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 1672 | 1673 | [[package]] 1674 | name = "windows_aarch64_msvc" 1675 | version = "0.48.5" 1676 | source = "registry+https://github.com/rust-lang/crates.io-index" 1677 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 1678 | 1679 | [[package]] 1680 | name = "windows_i686_gnu" 1681 | version = "0.42.2" 1682 | source = "registry+https://github.com/rust-lang/crates.io-index" 1683 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 1684 | 1685 | [[package]] 1686 | name = "windows_i686_gnu" 1687 | version = "0.48.5" 1688 | source = "registry+https://github.com/rust-lang/crates.io-index" 1689 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 1690 | 1691 | [[package]] 1692 | name = "windows_i686_msvc" 1693 | version = "0.42.2" 1694 | source = "registry+https://github.com/rust-lang/crates.io-index" 1695 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 1696 | 1697 | [[package]] 1698 | name = "windows_i686_msvc" 1699 | version = "0.48.5" 1700 | source = "registry+https://github.com/rust-lang/crates.io-index" 1701 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 1702 | 1703 | [[package]] 1704 | name = "windows_x86_64_gnu" 1705 | version = "0.42.2" 1706 | source = "registry+https://github.com/rust-lang/crates.io-index" 1707 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 1708 | 1709 | [[package]] 1710 | name = "windows_x86_64_gnu" 1711 | version = "0.48.5" 1712 | source = "registry+https://github.com/rust-lang/crates.io-index" 1713 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 1714 | 1715 | [[package]] 1716 | name = "windows_x86_64_gnullvm" 1717 | version = "0.42.2" 1718 | source = "registry+https://github.com/rust-lang/crates.io-index" 1719 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 1720 | 1721 | [[package]] 1722 | name = "windows_x86_64_gnullvm" 1723 | version = "0.48.5" 1724 | source = "registry+https://github.com/rust-lang/crates.io-index" 1725 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 1726 | 1727 | [[package]] 1728 | name = "windows_x86_64_msvc" 1729 | version = "0.42.2" 1730 | source = "registry+https://github.com/rust-lang/crates.io-index" 1731 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 1732 | 1733 | [[package]] 1734 | name = "windows_x86_64_msvc" 1735 | version = "0.48.5" 1736 | source = "registry+https://github.com/rust-lang/crates.io-index" 1737 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 1738 | 1739 | [[package]] 1740 | name = "winreg" 1741 | version = "0.50.0" 1742 | source = "registry+https://github.com/rust-lang/crates.io-index" 1743 | checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" 1744 | dependencies = [ 1745 | "cfg-if", 1746 | "windows-sys 0.48.0", 1747 | ] 1748 | --------------------------------------------------------------------------------