diff --git a/extensions/warp-ipfs/examples/identity-interface.rs b/extensions/warp-ipfs/examples/identity-interface.rs index 94d563061..b8c3b5533 100644 --- a/extensions/warp-ipfs/examples/identity-interface.rs +++ b/extensions/warp-ipfs/examples/identity-interface.rs @@ -674,7 +674,7 @@ async fn main() -> anyhow::Result<()> { } }; - if let Err(e) = account.update_identity(IdentityUpdate::Picture(picture.to_string())).await { + if let Err(e) = account.update_identity(IdentityUpdate::Picture(picture.as_bytes().to_vec())).await { writeln!(stdout, "Error updating picture: {e}")?; continue; } @@ -690,7 +690,7 @@ async fn main() -> anyhow::Result<()> { } }; - if let Err(e) = account.update_identity(IdentityUpdate::Banner(banner.to_string())).await { + if let Err(e) = account.update_identity(IdentityUpdate::Banner(banner.as_bytes().to_vec())).await { writeln!(stdout, "Error updating banner: {e}")?; continue; } @@ -765,8 +765,8 @@ async fn main() -> anyhow::Result<()> { created.to_string(), modified.to_string(), identity.status_message().unwrap_or_default(), - (!profile_banner.is_empty()).to_string(), - (!profile_picture.is_empty()).to_string(), + (!profile_banner.data().is_empty()).to_string(), + (!profile_picture.data().is_empty()).to_string(), platform.to_string(), format!("{status:?}"), ]); diff --git a/extensions/warp-ipfs/src/config.rs b/extensions/warp-ipfs/src/config.rs index 834d798e3..9128b4f55 100644 --- a/extensions/warp-ipfs/src/config.rs +++ b/extensions/warp-ipfs/src/config.rs @@ -6,7 +6,7 @@ use std::{ str::FromStr, time::Duration, }; -use warp::multipass::identity::Identity; +use warp::{multipass::identity::Identity, constellation::file::FileType}; #[derive(Default, Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] @@ -250,7 +250,7 @@ pub enum UpdateEvents { } pub type DefaultPfpFn = - std::sync::Arc Result, std::io::Error> + Send + Sync + 'static>; + std::sync::Arc Result<(Vec, FileType), std::io::Error> + Send + Sync + 'static>; #[derive(Clone, Serialize, Deserialize)] pub struct StoreSetting { diff --git a/extensions/warp-ipfs/src/lib.rs b/extensions/warp-ipfs/src/lib.rs index 06181af60..de1ff2057 100644 --- a/extensions/warp-ipfs/src/lib.rs +++ b/extensions/warp-ipfs/src/lib.rs @@ -60,7 +60,7 @@ use ipfs::{DhtMode, Ipfs, Keypair, PeerId, Protocol, UninitializedIpfs}; use warp::crypto::{KeyMaterial, DID}; use warp::error::Error; use warp::multipass::identity::{ - Identifier, Identity, IdentityProfile, IdentityUpdate, Relationship, + Identifier, Identity, IdentityImage, IdentityProfile, IdentityUpdate, Relationship, }; use warp::multipass::{ identity, Friends, FriendsEvent, IdentityImportOption, IdentityInformation, ImportLocation, @@ -689,15 +689,31 @@ impl MultiPass for WarpIpfs { trace!("image size = {}", len); - let cid = store - .store_photo( - futures::stream::iter(Ok::<_, std::io::Error>(Ok(serde_json::to_vec( - &data, - )?))) - .boxed(), - Some(2 * 1024 * 1024), - ) - .await?; + let (data, format) = tokio::task::spawn_blocking(move || { + let cursor = std::io::Cursor::new(data); + + let image = image::io::Reader::new(cursor).with_guessed_format()?; + + let format = image + .format() + .and_then(|format| ExtensionType::try_from(format).ok()) + .unwrap_or(ExtensionType::Other); + + let inner = image.into_inner(); + + let data = inner.into_inner(); + Ok::<_, Error>((data, format)) + }) + .await + .map_err(anyhow::Error::from)??; + + let cid = store::document::image_dag::store_photo( + &self.ipfs()?, + futures::stream::iter(Ok::<_, std::io::Error>(Ok(data))).boxed(), + format.into(), + Some(2 * 1024 * 1024), + ) + .await?; debug!("Image cid: {cid}"); @@ -724,7 +740,7 @@ impl MultiPass for WarpIpfs { ))); } - let file = tokio::fs::File::open(path).await?; + let file = tokio::fs::File::open(&path).await?; let metadata = file.metadata().await?; @@ -739,6 +755,12 @@ impl MultiPass for WarpIpfs { }); } + let extension = path + .extension() + .and_then(OsStr::to_str) + .map(ExtensionType::from) + .unwrap_or(ExtensionType::Other); + trace!("image size = {}", len); let stream = async_stream::stream! { @@ -760,9 +782,13 @@ impl MultiPass for WarpIpfs { } }; - let cid = store - .store_photo(stream.boxed(), Some(2 * 1024 * 1024)) - .await?; + let cid = store::document::image_dag::store_photo( + &self.ipfs()?, + stream.boxed(), + extension.into(), + Some(2 * 1024 * 1024), + ) + .await?; debug!("Image cid: {cid}"); @@ -802,15 +828,31 @@ impl MultiPass for WarpIpfs { trace!("image size = {}", len); - let cid = store - .store_photo( - futures::stream::iter(Ok::<_, std::io::Error>(Ok(serde_json::to_vec( - &data, - )?))) - .boxed(), - Some(2 * 1024 * 1024), - ) - .await?; + let (data, format) = tokio::task::spawn_blocking(move || { + let cursor = std::io::Cursor::new(data); + + let image = image::io::Reader::new(cursor).with_guessed_format()?; + + let format = image + .format() + .and_then(|format| ExtensionType::try_from(format).ok()) + .unwrap_or(ExtensionType::Other); + + let inner = image.into_inner(); + + let data = inner.into_inner(); + Ok::<_, Error>((data, format)) + }) + .await + .map_err(anyhow::Error::from)??; + + let cid = store::document::image_dag::store_photo( + &self.ipfs()?, + futures::stream::iter(Ok::<_, std::io::Error>(Ok(data))).boxed(), + format.into(), + Some(2 * 1024 * 1024), + ) + .await?; debug!("Image cid: {cid}"); @@ -837,7 +879,7 @@ impl MultiPass for WarpIpfs { ))); } - let file = tokio::fs::File::open(path).await?; + let file = tokio::fs::File::open(&path).await?; let metadata = file.metadata().await?; @@ -852,6 +894,12 @@ impl MultiPass for WarpIpfs { }); } + let extension = path + .extension() + .and_then(OsStr::to_str) + .map(ExtensionType::from) + .unwrap_or(ExtensionType::Other); + trace!("image size = {}", len); let stream = async_stream::stream! { @@ -873,9 +921,13 @@ impl MultiPass for WarpIpfs { } }; - let cid = store - .store_photo(stream.boxed(), Some(2 * 1024 * 1024)) - .await?; + let cid = store::document::image_dag::store_photo( + &self.ipfs()?, + stream.boxed(), + extension.into(), + Some(2 * 1024 * 1024), + ) + .await?; debug!("Image cid: {cid}"); @@ -1147,12 +1199,12 @@ impl FriendsEvent for WarpIpfs { #[async_trait::async_trait] impl IdentityInformation for WarpIpfs { - async fn identity_picture(&self, did: &DID) -> Result { + async fn identity_picture(&self, did: &DID) -> Result { let store = self.identity_store(true).await?; store.identity_picture(did).await } - async fn identity_banner(&self, did: &DID) -> Result { + async fn identity_banner(&self, did: &DID) -> Result { let store = self.identity_store(true).await?; store.identity_banner(did).await } diff --git a/extensions/warp-ipfs/src/store/document.rs b/extensions/warp-ipfs/src/store/document.rs index d884d1462..3e48d5829 100644 --- a/extensions/warp-ipfs/src/store/document.rs +++ b/extensions/warp-ipfs/src/store/document.rs @@ -1,6 +1,7 @@ pub mod cache; pub mod conversation; pub mod identity; +pub mod image_dag; pub mod root; pub mod utils; diff --git a/extensions/warp-ipfs/src/store/document/identity.rs b/extensions/warp-ipfs/src/store/document/identity.rs index b2d397483..0e74d1d08 100644 --- a/extensions/warp-ipfs/src/store/document/identity.rs +++ b/extensions/warp-ipfs/src/store/document/identity.rs @@ -1,7 +1,7 @@ use chrono::{DateTime, Utc}; use futures::{StreamExt, TryStreamExt}; use libipld::Cid; -use rust_ipfs::{Ipfs, IpfsPath}; +use rust_ipfs::{Ipfs, IpfsPath, PeerId}; use serde::{Deserialize, Serialize}; use std::{hash::Hash, time::Duration}; use warp::{ @@ -196,6 +196,7 @@ pub async fn unixfs_fetch( ipfs: &Ipfs, cid: Cid, timeout: Option, + peers: &[PeerId], local: bool, limit: Option, ) -> Result, Error> { @@ -203,7 +204,7 @@ pub async fn unixfs_fetch( let mut stream = ipfs .unixfs() - .cat(IpfsPath::from(cid), None, &[], local, timeout) + .cat(IpfsPath::from(cid), None, peers, local, timeout) .await .map_err(anyhow::Error::from)? .boxed(); diff --git a/extensions/warp-ipfs/src/store/document/image_dag.rs b/extensions/warp-ipfs/src/store/document/image_dag.rs new file mode 100644 index 000000000..87dc7868a --- /dev/null +++ b/extensions/warp-ipfs/src/store/document/image_dag.rs @@ -0,0 +1,135 @@ +use futures::{stream::BoxStream, StreamExt}; +use libipld::{serde::to_ipld, Cid}; +use rust_ipfs::{Ipfs, PeerId}; +use serde::{Deserialize, Serialize}; +use std::task::Poll; +use tracing::log; +use warp::{constellation::file::FileType, error::Error, multipass::identity::IdentityImage}; + +use super::{ + identity::unixfs_fetch, + utils::{GetDag, GetLocalDag}, +}; + +#[derive(Deserialize, Serialize, Debug, Clone)] +pub struct ImageDag { + pub link: Cid, + pub size: u64, + pub mime: FileType, +} + +#[tracing::instrument(skip(ipfs, stream))] +pub async fn store_photo( + ipfs: &Ipfs, + stream: BoxStream<'static, std::io::Result>>, + file_type: FileType, + limit: Option, +) -> Result { + let mut stream = ipfs.add_unixfs(stream).await?; + + let mut size = 0; + + let cid = futures::future::poll_fn(|cx| loop { + match stream.poll_next_unpin(cx) { + Poll::Ready(Some(rust_ipfs::unixfs::UnixfsStatus::ProgressStatus { + written, .. + })) => { + if let Some(limit) = limit { + if written > limit { + return Poll::Ready(Err(Error::InvalidLength { + context: "photo".into(), + current: written, + minimum: Some(1), + maximum: Some(limit), + })); + } + } + log::trace!("{written} bytes written"); + } + Poll::Ready(Some(rust_ipfs::unixfs::UnixfsStatus::CompletedStatus { + path, + written, + .. + })) => { + size = written; + log::debug!("Image is written with {written} bytes - stored at {path}"); + return Poll::Ready(path.root().cid().copied().ok_or(Error::Other)); + } + Poll::Ready(Some(rust_ipfs::unixfs::UnixfsStatus::FailedStatus { + written, + error, + .. + })) => { + let err = match error { + Some(e) => { + log::error!( + "Error uploading picture with {written} bytes written with error: {e}" + ); + e.into() + } + None => { + log::error!("Error uploading picture with {written} bytes written"); + Error::OtherWithContext("Error uploading photo".into()) + } + }; + + return Poll::Ready(Err(err)); + } + Poll::Ready(None) => return Poll::Ready(Err(Error::ReceiverChannelUnavailable)), + Poll::Pending => return Poll::Pending, + } + }) + .await?; + + let dag = ImageDag { + link: cid, + size: size as _, + mime: file_type, + }; + + let cid = ipfs + .put_dag(to_ipld(dag).map_err(anyhow::Error::from)?) + .await?; + + if !ipfs.is_pinned(&cid).await? { + ipfs.insert_pin(&cid, true).await?; + } + + Ok(cid) +} + +#[tracing::instrument(skip(ipfs))] +pub async fn get_image( + ipfs: &Ipfs, + cid: Cid, + peers: &[PeerId], + local: bool, + limit: Option, +) -> Result { + let dag: ImageDag = match local { + true => cid.get_local_dag(ipfs).await?, + false => cid.get_dag(ipfs, None).await?, + }; + + match limit { + Some(size) if dag.size > size as _ => { + return Err(Error::InvalidLength { + context: "image".into(), + current: dag.size as _, + minimum: None, + maximum: limit, + }); + } + Some(_) => {} + None => {} + } + + let image = unixfs_fetch(ipfs, dag.link, None, peers, local, limit).await?; + + let mut id_img = IdentityImage::default(); + + id_img.set_data(image); + id_img.set_image_type(dag.mime); + + Ok(id_img) +} diff --git a/extensions/warp-ipfs/src/store/identity.rs b/extensions/warp-ipfs/src/store/identity.rs index 832dd35df..7bd904877 100644 --- a/extensions/warp-ipfs/src/store/identity.rs +++ b/extensions/warp-ipfs/src/store/identity.rs @@ -8,7 +8,7 @@ use crate::{ }; use chrono::Utc; -use futures::{channel::oneshot, stream::BoxStream, StreamExt, TryStreamExt}; +use futures::{channel::oneshot, StreamExt}; use ipfs::{Ipfs, IpfsPath, Keypair}; use libipld::Cid; use rust_ipfs as ipfs; @@ -16,7 +16,6 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::{ collections::{HashMap, HashSet}, path::PathBuf, - task::Poll, time::{Duration, Instant}, }; @@ -26,7 +25,11 @@ use tracing::{ warn, }; -use warp::{crypto::zeroize::Zeroizing, multipass::identity::Platform}; +use warp::{ + constellation::file::FileType, + crypto::zeroize::Zeroizing, + multipass::identity::{IdentityImage, Platform}, +}; use warp::{ crypto::{did_key::Generate, DIDKey, Ed25519KeyPair, Fingerprint, DID}, error::Error, @@ -41,11 +44,8 @@ use warp::{ use super::{ connected_to_peer, did_keypair, document::{ - cache::IdentityCache, - identity::{unixfs_fetch, IdentityDocument}, - root::RootDocumentMap, - utils::GetLocalDag, - ExtractedRootDocument, RootDocument, ToCid, + cache::IdentityCache, identity::IdentityDocument, image_dag::get_image, + root::RootDocumentMap, utils::GetLocalDag, ExtractedRootDocument, RootDocument, ToCid, }, ecdh_decrypt, ecdh_encrypt, libp2p_pub_to_did, phonebook::PhoneBook, @@ -206,7 +206,11 @@ pub enum ResponseOption { /// Identity request Identity { identity: IdentityDocument }, /// Pictures - Image { cid: Cid, data: Vec }, + Image { + cid: Cid, + ty: FileType, + data: Vec, + }, } impl std::fmt::Debug for ResponseOption { @@ -788,10 +792,21 @@ impl IdentityStore { return Ok(()); } - let data = unixfs_fetch(&self.ipfs, cid, None, true, Some(2 * 1024 * 1024)).await?; + let image = super::document::image_dag::get_image( + &self.ipfs, + cid, + &[], + true, + Some(2 * 1024 * 1024), + ) + .await?; let event = IdentityEvent::Receive { - option: ResponseOption::Image { cid, data }, + option: ResponseOption::Image { + cid, + ty: image.image_type().clone(), + data: image.data().to_vec(), + }, }; let payload_bytes = serde_json::to_vec(&event)?; @@ -834,10 +849,21 @@ impl IdentityStore { return Ok(()); } - let data = unixfs_fetch(&self.ipfs, cid, None, true, Some(2 * 1024 * 1024)).await?; + let image = super::document::image_dag::get_image( + &self.ipfs, + cid, + &[], + true, + Some(2 * 1024 * 1024), + ) + .await?; let event = IdentityEvent::Receive { - option: ResponseOption::Image { cid, data }, + option: ResponseOption::Image { + cid, + ty: image.image_type().clone(), + data: image.data().to_vec(), + }, }; let payload_bytes = serde_json::to_vec(&event)?; @@ -970,20 +996,20 @@ impl IdentityStore { let did = in_did.clone(); async move { let peer_id = vec![did.to_peer_id()?]; - - let mut stream = ipfs - .unixfs() - .cat( - identity_profile_picture, - None, - &peer_id, - false, - None, - ) - .await? - .boxed(); - - while let Some(_d) = stream.try_next().await? {} + let _ = super::document::image_dag::get_image( + &ipfs, + identity_profile_picture, + &peer_id, + false, + Some(2 * 1024 * 1024), + ) + .await + .map_err(|e| { + log::error!("Error fetching image from {did}: {e}"); + e + })?; + + log::trace!("Image pointed to {identity_profile_picture} for {did} downloaded"); if emit { store.emit_event( @@ -1027,19 +1053,20 @@ impl IdentityStore { async move { let peer_id = vec![did.to_peer_id()?]; - let mut stream = ipfs - .unixfs() - .cat( - identity_profile_banner, - None, - &peer_id, - false, - None, - ) - .await? - .boxed(); - - while let Some(_d) = stream.try_next().await? {} + let _ = super::document::image_dag::get_image( + &ipfs, + identity_profile_banner, + &peer_id, + false, + Some(2 * 1024 * 1024), + ) + .await + .map_err(|e| { + log::error!("Error fetching image from {did}: {e}"); + e + })?; + + log::trace!("Image pointed to {identity_profile_banner} for {did} downloaded"); if emit { store.emit_event( @@ -1111,13 +1138,23 @@ impl IdentityStore { let did = in_did.clone(); let store = self.clone(); async move { - let mut stream = ipfs - .unixfs() - .cat(picture, None, &[], false, None) - .await? - .boxed(); + let peer_id = vec![did.to_peer_id()?]; + let _ = super::document::image_dag::get_image( + &ipfs, + picture, + &peer_id, + false, + Some(2 * 1024 * 1024), + ) + .await + .map_err(|e| { + log::error!( + "Error fetching image from {did}: {e}" + ); + e + })?; - while let Some(_d) = stream.try_next().await? {} + log::trace!("Image pointed to {picture} for {did} downloaded"); store.emit_event( MultiPassEventKind::IdentityUpdate { did }, @@ -1134,13 +1171,23 @@ impl IdentityStore { let did = in_did.clone(); async move { - let mut stream = ipfs - .unixfs() - .cat(banner, None, &[], false, None) - .await? - .boxed(); + let peer_id = vec![did.to_peer_id()?]; + let _ = super::document::image_dag::get_image( + &ipfs, + banner, + &peer_id, + false, + Some(2 * 1024 * 1024), + ) + .await + .map_err(|e| { + log::error!( + "Error fetching image from {did}: {e}" + ); + e + })?; - while let Some(_d) = stream.try_next().await? {} + log::trace!("Image pointed to {banner} for {did} downloaded"); store.emit_event( MultiPassEventKind::IdentityUpdate { did }, @@ -1158,21 +1205,21 @@ impl IdentityStore { } //Used when receiving an image (eg banner, pfp) from a peer IdentityEvent::Receive { - option: ResponseOption::Image { cid, data }, + option: ResponseOption::Image { cid, ty, data }, } => { let cache = self.identity_cache.get(&in_did).await?; if cache.profile_picture == Some(cid) || cache.profile_banner == Some(cid) { tokio::spawn({ - let mut store = self.clone(); + let store = self.clone(); async move { - let added_cid = store - .store_photo( - futures::stream::iter(Ok::<_, std::io::Error>(Ok(data))) - .boxed(), - Some(2 * 1024 * 1024), - ) - .await?; + let added_cid = super::document::image_dag::store_photo( + &store.ipfs, + futures::stream::iter(Ok::<_, std::io::Error>(Ok(data))).boxed(), + ty, + Some(2 * 1024 * 1024), + ) + .await?; debug_assert_eq!(added_cid, cid); store.emit_event(MultiPassEventKind::IdentityUpdate { @@ -1586,74 +1633,8 @@ impl IdentityStore { Ok(identity) } - #[tracing::instrument(skip(self, stream))] - pub async fn store_photo( - &mut self, - stream: BoxStream<'static, std::io::Result>>, - limit: Option, - ) -> Result { - let ipfs = self.ipfs.clone(); - - let mut stream = ipfs.add_unixfs(stream).await?; - - let cid = futures::future::poll_fn(|cx| loop { - match stream.poll_next_unpin(cx) { - Poll::Ready(Some(ipfs::unixfs::UnixfsStatus::ProgressStatus { - written, .. - })) => { - if let Some(limit) = limit { - if written > limit { - return Poll::Ready(Err(Error::InvalidLength { - context: "photo".into(), - current: written, - minimum: Some(1), - maximum: Some(limit), - })); - } - } - log::trace!("{written} bytes written"); - } - Poll::Ready(Some(ipfs::unixfs::UnixfsStatus::CompletedStatus { - path, - written, - .. - })) => { - log::debug!("Image is written with {written} bytes - stored at {path}"); - return Poll::Ready(path.root().cid().copied().ok_or(Error::Other)); - } - Poll::Ready(Some(ipfs::unixfs::UnixfsStatus::FailedStatus { - written, - error, - .. - })) => { - let err = match error { - Some(e) => { - log::error!("Error uploading picture with {written} bytes written with error: {e}"); - e.into() - }, - None => { - log::error!("Error uploading picture with {written} bytes written"); - Error::OtherWithContext("Error uploading photo".into()) - } - }; - - return Poll::Ready(Err(err)); - } - Poll::Ready(None) => return Poll::Ready(Err(Error::ReceiverChannelUnavailable)), - Poll::Pending => return Poll::Pending, - } - }) - .await?; - - if !ipfs.is_pinned(&cid).await? { - ipfs.insert_pin(&cid, true).await?; - } - - Ok(cid) - } - #[tracing::instrument(skip(self))] - pub async fn identity_picture(&self, did: &DID) -> Result { + pub async fn identity_picture(&self, did: &DID) -> Result { if self.config.store_setting.disable_images { return Err(Error::InvalidIdentityPicture); } @@ -1664,31 +1645,31 @@ impl IdentityStore { }; if let Some(cid) = document.profile_picture { - let data = match unixfs_fetch(&self.ipfs, cid, None, true, Some(2 * 1024 * 1024)).await - { + let data = match get_image(&self.ipfs, cid, &[], true, Some(2 * 1024 * 1024)).await { Ok(data) => data, Err(_) => { return Err(Error::InvalidIdentityPicture); } }; - let picture: String = serde_json::from_slice(&data)?; - if !picture.is_empty() { - return Ok(picture); - } + return Ok(data); } if let Some(cb) = self.config.store_setting.default_profile_picture.as_deref() { let identity = document.resolve()?; - let picture = cb(&identity)?; - return Ok(String::from_utf8_lossy(&picture).to_string()); + let (picture, ty) = cb(&identity)?; + let mut image = IdentityImage::default(); + image.set_data(picture); + image.set_image_type(ty); + + return Ok(image); } Err(Error::InvalidIdentityPicture) } #[tracing::instrument(skip(self))] - pub async fn identity_banner(&self, did: &DID) -> Result { + pub async fn identity_banner(&self, did: &DID) -> Result { if self.config.store_setting.disable_images { return Err(Error::InvalidIdentityBanner); } @@ -1699,24 +1680,14 @@ impl IdentityStore { }; if let Some(cid) = document.profile_banner { - let data = match unixfs_fetch(&self.ipfs, cid, None, true, Some(2 * 1024 * 1024)).await - { + let data = match get_image(&self.ipfs, cid, &[], true, Some(2 * 1024 * 1024)).await { Ok(data) => data, Err(_) => { return Err(Error::InvalidIdentityPicture); } }; - let picture: String = serde_json::from_slice(&data)?; - if !picture.is_empty() { - return Ok(picture); - } - } - - if let Some(cb) = self.config.store_setting.default_profile_picture.as_deref() { - let identity = document.resolve()?; - let picture = cb(&identity)?; - return Ok(String::from_utf8_lossy(&picture).to_string()); + return Ok(data); } Err(Error::InvalidIdentityBanner) diff --git a/extensions/warp-ipfs/tests/accounts.rs b/extensions/warp-ipfs/tests/accounts.rs index b3291593b..2ba7ce6d1 100644 --- a/extensions/warp-ipfs/tests/accounts.rs +++ b/extensions/warp-ipfs/tests/accounts.rs @@ -1,9 +1,11 @@ pub mod common; + #[cfg(test)] mod test { use std::time::Duration; - use crate::common::{create_account, create_accounts}; + use crate::common::{self, create_account, create_accounts}; + use warp::constellation::file::FileType; use warp::multipass::identity::{IdentityStatus, IdentityUpdate, Platform}; use warp::tesseract::Tesseract; use warp_ipfs::WarpIpfsBuilder; @@ -269,6 +271,28 @@ mod test { Ok(()) } + #[tokio::test] + async fn identity_real_profile_picture() -> anyhow::Result<()> { + let (mut account, did, _) = create_account( + Some("JohnDoe"), + None, + Some("test::identity_real_profile_picture".into()), + ) + .await?; + + account + .update_identity(IdentityUpdate::Picture(common::PROFILE_IMAGE.into())) + .await?; + + let image = account.identity_picture(&did).await?; + + assert_eq!(image.data(), common::PROFILE_IMAGE); + assert!(image + .image_type() + .eq(&FileType::Mime("image/png".parse().unwrap()))); + Ok(()) + } + #[tokio::test] async fn identity_profile_picture() -> anyhow::Result<()> { let (mut account, did, _) = create_account( @@ -284,7 +308,10 @@ mod test { let image = account.identity_picture(&did).await?; - assert_eq!(image, "picture"); + assert_eq!(image.data(), b"picture"); + assert!(image + .image_type() + .eq(&FileType::Mime("application/octet-stream".parse().unwrap()))); Ok(()) } @@ -303,7 +330,10 @@ mod test { let image = account.identity_banner(&did).await?; - assert_eq!(image, "banner"); + assert_eq!(image.data(), b"banner"); + assert!(image + .image_type() + .eq(&FileType::Mime("application/octet-stream".parse().unwrap()))); Ok(()) } diff --git a/extensions/warp-ipfs/tests/common.rs b/extensions/warp-ipfs/tests/common.rs index 576bebaa2..83bf7e3a0 100644 --- a/extensions/warp-ipfs/tests/common.rs +++ b/extensions/warp-ipfs/tests/common.rs @@ -151,3 +151,399 @@ pub async fn create_accounts_and_chat( Ok(accounts) } + +#[allow(dead_code)] +pub const PROFILE_IMAGE: &[u8] = &[ + 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 1, 144, 0, 0, 1, 144, 8, 2, + 0, 0, 0, 15, 221, 161, 155, 0, 0, 31, 134, 73, 68, 65, 84, 120, 156, 236, 221, 121, 92, 85, + 229, 222, 247, 241, 13, 169, 56, 161, 166, 38, 56, 130, 3, 155, 28, 203, 9, 21, 68, 9, 65, 156, + 192, 130, 84, 202, 121, 54, 43, 211, 202, 236, 212, 221, 105, 56, 231, 120, 58, 169, 153, 122, + 167, 37, 150, 165, 146, 226, 44, 206, 160, 136, 32, 162, 136, 67, 230, 0, 136, 136, 3, 155, + 156, 167, 99, 74, 138, 60, 175, 39, 239, 167, 167, 187, 163, 76, 94, 107, 93, 235, 90, 251, + 243, 254, 235, 188, 122, 229, 247, 250, 189, 56, 246, 229, 90, 123, 175, 117, 173, 50, 181, + 106, 53, 176, 0, 128, 10, 28, 101, 15, 0, 0, 197, 69, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, + 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, + 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, + 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, + 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, + 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, + 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, + 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, + 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, + 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, + 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, + 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, + 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, + 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, + 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, + 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, + 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 81, 70, 246, 0, 230, 84, 177, 98, + 197, 103, 158, 105, 89, 163, 70, 141, 251, 247, 243, 79, 157, 58, 125, 252, 120, 154, 236, 137, + 0, 51, 160, 176, 132, 169, 85, 235, 169, 33, 67, 6, 250, 248, 116, 242, 246, 238, 248, 208, + 127, 33, 50, 114, 217, 238, 221, 123, 86, 174, 92, 163, 251, 104, 128, 73, 56, 212, 170, 213, + 64, 246, 12, 106, 115, 113, 169, 53, 98, 196, 208, 94, 189, 122, 88, 173, 77, 138, 249, 71, 82, + 82, 82, 191, 253, 246, 251, 205, 155, 99, 238, 220, 185, 163, 241, 116, 128, 169, 80, 88, 143, + 101, 252, 248, 177, 31, 126, 248, 94, 233, 254, 236, 185, 115, 57, 175, 191, 254, 230, 238, + 221, 123, 68, 15, 5, 152, 214, 19, 149, 42, 85, 149, 61, 131, 146, 122, 246, 236, 254, 237, + 183, 95, 133, 133, 61, 95, 234, 132, 42, 85, 170, 132, 135, 247, 107, 217, 178, 197, 177, 99, + 199, 47, 95, 190, 34, 116, 58, 192, 156, 216, 97, 149, 198, 95, 254, 50, 121, 226, 196, 215, 4, + 6, 118, 233, 18, 152, 158, 158, 33, 48, 16, 48, 37, 118, 88, 37, 54, 107, 214, 244, 81, 163, + 134, 139, 205, 12, 9, 233, 243, 235, 175, 119, 15, 28, 56, 40, 54, 22, 48, 25, 10, 171, 100, + 86, 175, 94, 214, 171, 87, 144, 240, 216, 138, 21, 43, 248, 251, 251, 253, 252, 243, 249, 195, + 135, 143, 8, 15, 7, 76, 131, 27, 71, 75, 96, 194, 132, 87, 125, 124, 58, 105, 151, 255, 222, + 123, 239, 120, 122, 90, 181, 203, 7, 84, 199, 103, 88, 197, 229, 237, 221, 113, 205, 154, 40, + 29, 22, 242, 245, 13, 200, 200, 56, 161, 195, 66, 128, 114, 184, 36, 44, 150, 186, 117, 235, + 196, 198, 110, 112, 116, 212, 99, 67, 90, 185, 114, 165, 205, 155, 183, 234, 176, 16, 160, 28, + 46, 9, 139, 101, 242, 228, 73, 101, 202, 232, 244, 84, 64, 255, 254, 97, 143, 186, 87, 30, 176, + 115, 92, 18, 22, 205, 205, 173, 193, 174, 93, 219, 203, 149, 43, 167, 219, 138, 103, 207, 158, + 235, 220, 217, 255, 206, 157, 60, 221, 86, 4, 148, 192, 14, 171, 104, 147, 39, 79, 210, 179, + 173, 44, 22, 75, 253, 250, 245, 122, 246, 20, 255, 93, 36, 160, 58, 10, 171, 8, 238, 238, 110, + 253, 250, 133, 234, 191, 110, 72, 72, 31, 253, 23, 5, 12, 142, 194, 42, 66, 151, 46, 157, 165, + 172, 171, 197, 221, 94, 128, 234, 40, 172, 34, 248, 251, 251, 201, 90, 58, 52, 180, 175, 172, + 165, 1, 99, 162, 176, 138, 208, 189, 123, 55, 89, 75, 107, 122, 147, 42, 160, 34, 190, 37, 44, + 194, 249, 243, 167, 101, 45, 93, 80, 80, 224, 234, 234, 46, 107, 117, 192, 128, 216, 97, 21, + 198, 197, 229, 41, 137, 171, 59, 56, 56, 72, 92, 29, 48, 32, 10, 171, 48, 47, 188, 80, 250, + 227, 174, 132, 224, 209, 66, 224, 143, 40, 172, 194, 84, 174, 92, 73, 238, 0, 13, 27, 186, 201, + 29, 0, 48, 20, 10, 203, 208, 244, 121, 122, 17, 80, 5, 255, 61, 20, 230, 254, 253, 251, 114, 7, + 184, 112, 225, 162, 220, 1, 0, 67, 161, 176, 10, 19, 23, 183, 83, 238, 0, 71, 142, 28, 147, 59, + 0, 96, 40, 20, 86, 97, 14, 29, 250, 81, 238, 0, 188, 7, 12, 248, 35, 10, 203, 184, 120, 3, 24, + 240, 39, 20, 86, 17, 182, 111, 223, 33, 107, 233, 164, 164, 100, 89, 75, 3, 198, 68, 97, 21, + 225, 224, 193, 195, 178, 150, 254, 254, 251, 37, 178, 150, 6, 140, 137, 194, 42, 66, 66, 194, + 46, 41, 235, 238, 216, 145, 112, 241, 226, 37, 41, 75, 3, 134, 69, 97, 21, 97, 239, 222, 148, + 99, 199, 210, 244, 95, 247, 224, 193, 67, 250, 47, 10, 24, 28, 133, 85, 180, 41, 83, 222, 215, + 127, 209, 111, 191, 253, 94, 255, 69, 1, 131, 211, 233, 197, 10, 74, 75, 73, 73, 77, 73, 73, + 245, 242, 106, 167, 219, 138, 127, 253, 235, 223, 204, 116, 61, 232, 230, 214, 160, 85, 171, + 150, 15, 254, 119, 189, 122, 117, 90, 180, 104, 94, 248, 145, 211, 119, 239, 222, 205, 200, 56, + 113, 230, 204, 217, 187, 119, 239, 89, 44, 150, 204, 204, 147, 105, 105, 233, 5, 5, 5, 122, + 205, 11, 227, 226, 120, 153, 98, 105, 213, 170, 69, 108, 236, 70, 125, 214, 58, 122, 244, 152, + 191, 127, 79, 125, 214, 210, 66, 205, 154, 53, 134, 13, 27, 92, 174, 92, 185, 145, 35, 135, 86, + 174, 92, 89, 96, 242, 237, 219, 183, 23, 47, 254, 225, 250, 245, 27, 235, 214, 109, 56, 113, + 34, 83, 96, 50, 84, 65, 97, 21, 215, 228, 201, 147, 222, 126, 123, 162, 14, 11, 245, 233, 19, + 186, 111, 223, 126, 29, 22, 18, 197, 106, 245, 104, 214, 236, 233, 160, 160, 128, 154, 53, 107, + 234, 121, 162, 244, 158, 61, 41, 54, 91, 238, 214, 173, 177, 57, 57, 54, 181, 126, 98, 40, 53, + 10, 171, 4, 34, 35, 23, 6, 4, 248, 107, 186, 196, 184, 113, 175, 175, 89, 19, 173, 233, 18, + 162, 132, 133, 61, 223, 176, 161, 251, 132, 9, 227, 157, 156, 156, 100, 207, 242, 127, 45, 93, + 186, 60, 59, 251, 244, 236, 217, 115, 165, 63, 1, 10, 237, 80, 88, 37, 80, 187, 118, 237, 168, + 168, 69, 218, 157, 81, 21, 25, 185, 236, 205, 55, 167, 104, 20, 46, 68, 131, 6, 245, 253, 252, + 186, 116, 235, 246, 92, 143, 30, 129, 178, 103, 121, 164, 157, 59, 19, 119, 239, 222, 147, 148, + 148, 204, 182, 203, 124, 40, 172, 18, 75, 72, 136, 213, 162, 179, 146, 146, 146, 67, 67, 195, + 133, 199, 138, 18, 16, 224, 63, 97, 194, 248, 14, 29, 218, 203, 30, 164, 4, 210, 210, 210, 87, + 174, 92, 51, 103, 206, 60, 217, 131, 64, 24, 10, 171, 196, 92, 93, 93, 22, 44, 152, 215, 190, + 125, 91, 129, 153, 31, 124, 240, 241, 252, 249, 223, 10, 12, 20, 165, 87, 175, 160, 46, 93, + 124, 135, 15, 31, 44, 123, 144, 199, 18, 29, 189, 49, 46, 46, 126, 233, 210, 229, 178, 7, 193, + 227, 162, 176, 74, 73, 212, 103, 240, 119, 239, 222, 237, 223, 127, 144, 1, 159, 115, 238, 209, + 163, 251, 71, 31, 189, 223, 176, 161, 169, 222, 130, 241, 206, 59, 239, 243, 192, 147, 210, 40, + 172, 210, 107, 213, 170, 229, 251, 239, 191, 227, 231, 215, 165, 116, 127, 60, 47, 239, 215, + 57, 115, 230, 70, 70, 46, 179, 217, 114, 69, 143, 86, 122, 117, 235, 214, 121, 249, 229, 1, + 125, 251, 6, 123, 120, 52, 150, 61, 139, 38, 46, 94, 188, 180, 102, 205, 186, 21, 43, 86, 31, + 62, 124, 68, 246, 44, 40, 49, 10, 235, 113, 181, 111, 223, 118, 218, 180, 169, 77, 155, 62, 93, + 162, 63, 181, 98, 197, 234, 105, 211, 102, 158, 62, 125, 70, 179, 185, 74, 227, 253, 247, 167, + 76, 152, 48, 94, 246, 20, 58, 217, 176, 97, 211, 152, 49, 175, 229, 231, 231, 203, 30, 4, 37, + 64, 97, 137, 209, 177, 163, 87, 183, 110, 207, 185, 187, 187, 117, 234, 228, 245, 212, 83, 15, + 127, 57, 88, 70, 70, 102, 90, 90, 122, 98, 98, 82, 66, 194, 174, 236, 108, 105, 175, 59, 252, + 79, 181, 107, 215, 30, 56, 112, 192, 192, 129, 225, 117, 234, 212, 150, 61, 139, 222, 190, 250, + 42, 34, 50, 50, 42, 35, 227, 132, 236, 65, 80, 44, 20, 150, 38, 158, 125, 182, 213, 239, 119, + 108, 221, 186, 117, 107, 213, 170, 181, 134, 61, 157, 125, 236, 216, 81, 31, 125, 244, 190, + 157, 191, 237, 98, 209, 162, 200, 201, 147, 223, 147, 61, 5, 138, 70, 97, 217, 175, 46, 93, 58, + 127, 248, 225, 123, 45, 90, 52, 151, 61, 136, 33, 100, 101, 157, 250, 230, 155, 239, 23, 44, + 88, 40, 123, 16, 20, 134, 194, 178, 83, 91, 182, 172, 107, 221, 250, 89, 217, 83, 24, 142, 205, + 150, 59, 96, 192, 96, 174, 16, 13, 235, 137, 74, 149, 170, 202, 158, 1, 186, 26, 53, 106, 248, + 138, 21, 145, 110, 110, 252, 162, 122, 8, 103, 103, 231, 161, 67, 7, 58, 56, 56, 164, 167, 103, + 220, 190, 125, 91, 246, 56, 248, 51, 10, 203, 142, 88, 173, 30, 17, 17, 115, 31, 28, 165, 32, + 123, 22, 227, 114, 116, 116, 244, 241, 233, 20, 16, 224, 159, 158, 126, 226, 236, 217, 115, + 178, 199, 193, 255, 66, 97, 217, 139, 137, 19, 95, 155, 58, 245, 147, 102, 205, 74, 118, 251, + 133, 221, 170, 89, 179, 70, 120, 120, 191, 114, 229, 202, 38, 38, 238, 150, 61, 11, 254, 63, + 62, 195, 178, 11, 115, 230, 124, 222, 191, 127, 152, 236, 41, 148, 116, 252, 120, 218, 152, 49, + 175, 102, 100, 112, 252, 150, 33, 176, 195, 50, 185, 192, 64, 255, 197, 139, 191, 241, 245, + 245, 145, 61, 136, 170, 158, 122, 170, 102, 143, 30, 221, 239, 221, 187, 123, 240, 160, 228, + 183, 234, 130, 194, 50, 57, 111, 239, 142, 203, 151, 47, 169, 94, 189, 186, 236, 65, 212, 230, + 236, 236, 220, 173, 219, 115, 188, 218, 214, 8, 40, 44, 211, 154, 62, 253, 211, 169, 83, 63, + 150, 61, 133, 121, 248, 248, 116, 122, 230, 153, 86, 123, 246, 164, 252, 251, 223, 255, 150, + 61, 139, 253, 226, 51, 44, 19, 42, 83, 166, 204, 242, 229, 75, 124, 124, 58, 201, 30, 196, 132, + 50, 51, 179, 124, 124, 158, 147, 61, 133, 253, 178, 235, 7, 50, 76, 201, 106, 245, 136, 141, + 221, 64, 91, 105, 164, 73, 147, 70, 169, 169, 73, 90, 159, 148, 141, 71, 97, 135, 101, 42, 86, + 171, 71, 98, 226, 54, 217, 83, 216, 133, 23, 94, 24, 192, 71, 90, 250, 99, 135, 101, 30, 86, + 171, 71, 84, 212, 98, 217, 83, 216, 139, 53, 107, 162, 130, 131, 123, 203, 158, 194, 238, 240, + 161, 187, 73, 180, 104, 209, 44, 62, 62, 198, 217, 217, 89, 246, 32, 118, 36, 36, 164, 247, + 157, 59, 121, 41, 41, 169, 178, 7, 177, 35, 92, 18, 154, 65, 155, 54, 207, 126, 247, 93, 132, + 139, 75, 45, 217, 131, 20, 230, 230, 205, 155, 201, 201, 123, 239, 220, 201, 179, 88, 44, 151, + 47, 95, 206, 200, 56, 113, 233, 210, 149, 63, 189, 207, 185, 90, 181, 170, 141, 26, 185, 215, + 173, 91, 199, 193, 193, 177, 92, 185, 178, 29, 58, 120, 61, 249, 100, 53, 121, 35, 23, 203, + 232, 209, 175, 70, 71, 111, 144, 61, 133, 189, 224, 85, 245, 202, 243, 244, 180, 110, 222, 188, + 78, 246, 20, 15, 113, 235, 214, 173, 175, 191, 254, 38, 63, 63, 63, 38, 102, 219, 227, 156, 71, + 92, 179, 102, 141, 33, 67, 6, 58, 58, 58, 6, 7, 247, 122, 250, 105, 79, 161, 51, 10, 16, 17, + 241, 165, 197, 82, 16, 29, 173, 211, 139, 193, 237, 28, 59, 44, 181, 61, 248, 220, 202, 56, 39, + 133, 238, 218, 181, 251, 240, 225, 35, 7, 14, 28, 74, 74, 74, 190, 114, 229, 138, 22, 75, 244, + 232, 17, 232, 225, 209, 196, 215, 215, 167, 107, 87, 95, 45, 242, 75, 103, 252, 248, 137, 171, + 86, 173, 145, 61, 133, 249, 81, 88, 10, 51, 206, 119, 130, 57, 57, 182, 31, 126, 136, 138, 136, + 88, 120, 253, 250, 117, 61, 215, 237, 223, 63, 108, 226, 196, 215, 27, 55, 110, 168, 231, 162, + 143, 194, 247, 134, 58, 160, 176, 84, 229, 230, 214, 96, 237, 218, 229, 114, 247, 86, 105, 105, + 25, 43, 86, 172, 138, 141, 141, 75, 79, 207, 144, 56, 134, 139, 75, 45, 127, 127, 191, 151, 95, + 30, 224, 229, 213, 78, 226, 24, 191, 157, 53, 54, 126, 253, 122, 174, 13, 53, 68, 97, 41, 201, + 209, 209, 49, 57, 57, 222, 221, 221, 77, 214, 0, 123, 247, 238, 155, 54, 109, 102, 98, 98, 146, + 172, 1, 30, 170, 121, 243, 166, 83, 166, 188, 29, 20, 20, 32, 107, 128, 83, 167, 178, 59, 118, + 236, 42, 107, 117, 123, 64, 97, 41, 41, 34, 98, 110, 72, 136, 132, 155, 128, 238, 221, 187, 23, + 25, 185, 108, 229, 202, 53, 70, 254, 46, 223, 106, 245, 8, 11, 123, 126, 248, 240, 193, 85, + 171, 74, 184, 101, 39, 61, 61, 99, 192, 128, 33, 185, 185, 6, 122, 215, 164, 153, 80, 88, 234, + 249, 228, 147, 15, 198, 142, 29, 165, 255, 186, 73, 73, 201, 147, 39, 191, 119, 242, 100, 150, + 254, 75, 151, 206, 140, 25, 159, 14, 26, 244, 146, 254, 235, 254, 248, 227, 79, 221, 187, 247, + 209, 127, 93, 123, 192, 141, 163, 138, 9, 14, 238, 253, 201, 39, 31, 232, 188, 232, 250, 245, + 155, 254, 242, 151, 15, 166, 79, 255, 226, 234, 213, 171, 58, 47, 253, 56, 98, 98, 182, 69, 71, + 111, 116, 112, 176, 180, 110, 253, 140, 158, 235, 186, 186, 186, 112, 22, 141, 70, 216, 97, + 169, 196, 193, 193, 225, 231, 159, 179, 117, 94, 52, 44, 236, 165, 93, 187, 212, 62, 38, 184, + 121, 243, 102, 243, 230, 205, 242, 244, 180, 234, 185, 232, 196, 137, 239, 44, 93, 26, 165, + 231, 138, 246, 128, 29, 150, 50, 170, 85, 171, 22, 19, 179, 190, 102, 205, 26, 186, 173, 248, + 221, 119, 139, 7, 13, 26, 145, 150, 150, 174, 219, 138, 26, 185, 120, 241, 98, 100, 100, 84, + 126, 126, 126, 171, 86, 45, 157, 156, 116, 122, 1, 71, 171, 86, 45, 226, 226, 226, 53, 186, 25, + 205, 110, 177, 195, 82, 198, 199, 31, 127, 48, 110, 156, 78, 31, 93, 101, 103, 159, 158, 56, + 113, 114, 114, 242, 94, 125, 150, 211, 141, 187, 187, 219, 204, 153, 159, 121, 123, 119, 212, + 103, 185, 125, 251, 246, 247, 233, 19, 170, 207, 90, 118, 130, 29, 150, 26, 2, 3, 187, 233, + 118, 124, 232, 218, 181, 209, 227, 198, 189, 113, 252, 120, 154, 62, 203, 233, 233, 218, 181, + 235, 81, 81, 43, 43, 86, 172, 160, 207, 29, 91, 117, 235, 214, 41, 40, 40, 48, 95, 239, 75, + 196, 14, 75, 1, 245, 235, 215, 75, 77, 213, 233, 142, 167, 201, 147, 223, 91, 180, 40, 82, 159, + 181, 36, 242, 246, 238, 184, 104, 209, 2, 125, 14, 183, 224, 14, 120, 129, 56, 15, 75, 1, 83, + 166, 188, 165, 195, 42, 54, 91, 174, 175, 111, 128, 61, 180, 213, 131, 175, 240, 186, 118, 13, + 210, 231, 6, 253, 207, 63, 255, 87, 197, 138, 21, 117, 88, 200, 30, 80, 88, 70, 231, 237, 221, + 177, 95, 63, 205, 63, 7, 185, 121, 243, 230, 128, 1, 131, 51, 50, 78, 104, 189, 144, 113, 228, + 228, 228, 116, 233, 18, 120, 232, 208, 97, 173, 23, 106, 216, 208, 125, 252, 248, 49, 90, 175, + 98, 39, 248, 12, 203, 208, 92, 93, 93, 182, 111, 223, 226, 232, 232, 160, 233, 42, 209, 209, + 27, 3, 3, 123, 95, 190, 108, 143, 223, 103, 45, 89, 178, 244, 193, 27, 113, 52, 93, 165, 77, + 155, 103, 55, 109, 218, 106, 159, 63, 97, 177, 40, 44, 67, 27, 55, 110, 116, 231, 206, 222, + 154, 46, 145, 148, 148, 60, 104, 208, 112, 77, 151, 48, 184, 7, 31, 48, 105, 218, 89, 101, 203, + 150, 109, 215, 174, 205, 226, 197, 63, 104, 183, 132, 157, 160, 176, 140, 203, 106, 245, 152, + 62, 253, 159, 229, 203, 151, 215, 110, 137, 181, 107, 215, 15, 30, 60, 66, 187, 124, 85, 232, + 208, 89, 46, 46, 181, 174, 94, 189, 118, 240, 224, 33, 237, 150, 176, 7, 20, 150, 113, 45, 90, + 244, 77, 163, 70, 26, 158, 244, 148, 148, 148, 76, 91, 253, 78, 135, 206, 170, 87, 175, 238, + 194, 133, 188, 37, 228, 177, 80, 88, 6, 21, 28, 220, 107, 220, 184, 209, 218, 229, 71, 71, 111, + 180, 243, 43, 193, 255, 164, 117, 103, 213, 172, 89, 163, 76, 153, 50, 170, 63, 231, 36, 23, + 133, 101, 80, 115, 230, 204, 112, 117, 117, 213, 40, 60, 37, 37, 245, 165, 151, 134, 106, 20, + 174, 52, 173, 59, 171, 83, 167, 14, 209, 209, 27, 249, 244, 189, 212, 184, 173, 193, 136, 122, + 246, 236, 254, 236, 179, 90, 29, 48, 144, 149, 117, 138, 182, 42, 196, 244, 233, 95, 108, 219, + 182, 67, 187, 252, 129, 3, 195, 181, 11, 55, 61, 238, 116, 55, 162, 243, 231, 79, 107, 23, 238, + 227, 227, 159, 153, 121, 82, 187, 124, 115, 72, 72, 136, 213, 238, 116, 7, 23, 23, 105, 71, + 197, 170, 142, 29, 150, 225, 104, 122, 56, 95, 223, 190, 253, 104, 171, 226, 120, 233, 165, 97, + 55, 110, 220, 212, 40, 252, 235, 175, 231, 104, 148, 108, 122, 20, 150, 225, 188, 248, 226, 11, + 26, 37, 79, 155, 54, 115, 207, 158, 20, 141, 194, 77, 38, 39, 39, 103, 232, 80, 173, 126, 115, + 60, 255, 124, 136, 213, 234, 161, 81, 184, 185, 241, 161, 187, 177, 116, 238, 236, 61, 97, 194, + 120, 45, 146, 147, 146, 146, 223, 120, 227, 109, 45, 146, 205, 234, 236, 217, 115, 21, 42, 104, + 117, 174, 67, 94, 94, 94, 124, 124, 130, 22, 201, 230, 198, 103, 88, 198, 178, 109, 219, 198, + 150, 45, 91, 8, 143, 205, 203, 251, 181, 65, 3, 126, 165, 151, 70, 66, 194, 54, 79, 79, 241, + 63, 186, 219, 183, 111, 187, 187, 63, 45, 60, 214, 244, 184, 36, 52, 144, 142, 29, 59, 104, + 209, 86, 191, 29, 215, 203, 222, 170, 148, 6, 15, 30, 97, 179, 137, 127, 5, 78, 133, 10, 21, + 66, 66, 120, 81, 69, 137, 81, 88, 6, 50, 98, 196, 16, 45, 98, 147, 146, 146, 87, 175, 94, 167, + 69, 178, 61, 56, 125, 250, 76, 100, 228, 50, 45, 146, 103, 207, 158, 174, 69, 172, 185, 81, 88, + 6, 18, 24, 232, 47, 60, 211, 102, 203, 29, 54, 140, 179, 77, 30, 203, 183, 223, 46, 210, 226, + 228, 172, 10, 21, 42, 104, 125, 74, 132, 249, 80, 88, 70, 49, 114, 228, 48, 45, 142, 121, 91, + 178, 100, 217, 141, 27, 55, 132, 199, 218, 149, 43, 87, 174, 188, 242, 202, 27, 90, 36, 15, 27, + 54, 88, 139, 88, 19, 163, 176, 140, 98, 248, 112, 241, 215, 131, 233, 233, 25, 223, 124, 243, + 157, 240, 88, 59, 116, 244, 232, 177, 136, 136, 133, 194, 99, 253, 252, 124, 29, 28, 180, 61, + 236, 204, 100, 40, 44, 67, 232, 218, 213, 215, 195, 163, 177, 240, 216, 41, 83, 254, 235, 218, + 181, 107, 194, 99, 237, 147, 22, 135, 71, 87, 169, 82, 229, 205, 55, 39, 8, 143, 53, 49, 10, + 203, 16, 186, 118, 245, 21, 158, 153, 152, 152, 196, 251, 90, 4, 202, 200, 56, 177, 118, 237, + 122, 225, 177, 190, 190, 62, 194, 51, 77, 140, 194, 50, 132, 30, 61, 2, 133, 103, 126, 255, + 253, 18, 225, 153, 118, 110, 236, 216, 215, 174, 93, 187, 46, 54, 179, 83, 167, 14, 238, 238, + 220, 11, 89, 92, 20, 150, 124, 158, 158, 214, 198, 141, 27, 137, 205, 76, 79, 207, 88, 191, + 126, 147, 216, 76, 60, 120, 27, 182, 240, 76, 63, 191, 174, 194, 51, 205, 138, 194, 146, 47, + 56, 184, 151, 240, 204, 119, 223, 253, 64, 120, 38, 44, 22, 203, 178, 101, 43, 132, 103, 114, + 115, 67, 241, 81, 88, 242, 133, 135, 247, 19, 27, 152, 154, 122, 128, 55, 119, 106, 228, 212, + 169, 236, 45, 91, 98, 197, 102, 6, 5, 5, 136, 13, 52, 49, 10, 75, 178, 122, 245, 234, 214, 175, + 95, 79, 108, 102, 100, 100, 148, 216, 64, 252, 209, 63, 254, 241, 169, 216, 64, 39, 39, 167, + 62, 125, 122, 138, 205, 52, 43, 10, 75, 50, 45, 46, 7, 54, 110, 220, 44, 60, 19, 191, 203, 200, + 200, 220, 187, 119, 159, 216, 76, 158, 43, 44, 38, 10, 75, 178, 128, 0, 193, 143, 227, 108, + 219, 22, 119, 253, 186, 224, 111, 178, 240, 39, 75, 151, 46, 23, 27, 216, 183, 47, 133, 85, 44, + 20, 150, 100, 205, 154, 9, 62, 99, 228, 159, 255, 228, 145, 90, 205, 197, 199, 39, 10, 207, + 116, 119, 231, 220, 228, 162, 81, 88, 146, 53, 105, 34, 242, 6, 247, 204, 204, 172, 35, 71, + 142, 10, 12, 196, 67, 229, 230, 230, 174, 89, 19, 45, 54, 83, 163, 147, 133, 76, 134, 194, 146, + 105, 208, 160, 151, 196, 6, 110, 219, 22, 39, 54, 16, 143, 18, 19, 179, 77, 108, 96, 235, 214, + 90, 189, 39, 201, 76, 40, 44, 153, 132, 191, 216, 57, 53, 245, 128, 216, 64, 60, 138, 240, 35, + 198, 132, 127, 89, 108, 74, 20, 150, 76, 163, 70, 13, 19, 27, 184, 101, 203, 86, 177, 129, 40, + 68, 92, 92, 188, 192, 180, 231, 158, 227, 126, 247, 162, 81, 88, 50, 57, 57, 57, 9, 76, 91, + 178, 100, 217, 221, 187, 247, 4, 6, 162, 112, 98, 159, 45, 119, 118, 174, 44, 48, 205, 172, 40, + 44, 105, 132, 191, 218, 192, 102, 179, 137, 13, 68, 225, 142, 31, 79, 23, 27, 56, 100, 200, 64, + 177, 129, 230, 67, 97, 73, 99, 181, 10, 126, 177, 240, 220, 185, 243, 197, 6, 162, 112, 177, + 177, 219, 197, 6, 214, 170, 245, 148, 216, 64, 243, 161, 176, 164, 169, 82, 197, 89, 96, 218, + 173, 91, 191, 220, 190, 125, 91, 96, 32, 138, 227, 232, 209, 99, 2, 211, 58, 119, 246, 22, 152, + 102, 74, 20, 150, 52, 98, 255, 118, 198, 197, 237, 16, 152, 134, 98, 218, 180, 73, 228, 183, + 28, 157, 58, 117, 16, 152, 102, 74, 20, 150, 52, 101, 202, 148, 17, 152, 118, 243, 230, 191, 5, + 166, 161, 152, 14, 30, 60, 36, 54, 144, 35, 222, 11, 71, 97, 73, 83, 169, 82, 37, 129, 105, 90, + 60, 44, 130, 34, 109, 223, 46, 242, 206, 6, 139, 197, 210, 188, 121, 51, 177, 129, 38, 67, 97, + 73, 227, 227, 211, 81, 96, 90, 126, 126, 190, 192, 52, 200, 210, 176, 161, 187, 236, 17, 12, + 141, 194, 146, 166, 124, 249, 242, 2, 211, 142, 28, 57, 34, 48, 13, 197, 119, 241, 226, 69, + 217, 35, 216, 17, 10, 203, 36, 178, 179, 207, 200, 30, 193, 78, 165, 164, 236, 151, 61, 130, + 29, 161, 176, 228, 40, 87, 174, 156, 236, 17, 32, 6, 23, 227, 122, 162, 176, 228, 232, 216, + 209, 75, 96, 218, 213, 171, 188, 45, 85, 154, 123, 247, 68, 62, 14, 85, 173, 90, 85, 129, 105, + 230, 67, 97, 201, 209, 162, 133, 200, 47, 131, 120, 230, 89, 162, 156, 156, 28, 129, 105, 86, + 107, 19, 129, 105, 230, 67, 97, 201, 81, 177, 98, 69, 129, 105, 54, 219, 207, 2, 211, 80, 34, + 233, 233, 153, 2, 211, 158, 122, 138, 167, 115, 10, 67, 97, 153, 193, 253, 251, 247, 101, 143, + 96, 191, 238, 220, 185, 35, 48, 237, 137, 39, 158, 16, 152, 102, 62, 20, 22, 0, 101, 80, 88, 0, + 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 96, 32, 5, 5, 5, 178, 71, 48, 52, 10, 203, 12, + 28, 29, 249, 255, 81, 154, 138, 21, 43, 8, 76, 187, 123, 247, 87, 129, 105, 230, 195, 95, 116, + 57, 114, 115, 115, 5, 166, 53, 109, 234, 41, 48, 13, 37, 34, 246, 64, 152, 147, 39, 79, 9, 76, + 51, 31, 10, 75, 142, 253, 251, 69, 30, 252, 22, 20, 20, 40, 48, 13, 37, 82, 187, 182, 171, 192, + 180, 51, 103, 206, 10, 76, 51, 31, 10, 75, 142, 180, 52, 145, 47, 92, 225, 110, 67, 211, 200, + 203, 227, 146, 176, 48, 20, 22, 240, 88, 248, 0, 81, 79, 252, 172, 77, 162, 89, 179, 166, 178, + 71, 176, 83, 222, 222, 34, 79, 142, 69, 225, 40, 44, 105, 108, 54, 145, 159, 187, 55, 110, 220, + 72, 96, 26, 138, 175, 122, 245, 39, 5, 166, 21, 20, 240, 88, 104, 97, 40, 44, 105, 196, 190, + 112, 165, 114, 101, 145, 175, 180, 64, 49, 9, 191, 30, 220, 183, 143, 243, 75, 11, 67, 97, 73, + 147, 159, 47, 242, 119, 169, 159, 95, 23, 129, 105, 40, 166, 23, 95, 124, 65, 108, 224, 249, + 243, 23, 196, 6, 154, 12, 133, 37, 205, 207, 63, 139, 60, 196, 202, 217, 89, 228, 123, 164, 81, + 76, 238, 238, 110, 2, 211, 120, 119, 119, 145, 40, 44, 105, 196, 190, 188, 192, 223, 191, 171, + 192, 52, 20, 211, 224, 193, 47, 11, 76, 91, 182, 108, 165, 192, 52, 83, 162, 176, 164, 17, 123, + 22, 184, 131, 131, 67, 203, 150, 205, 5, 6, 162, 72, 206, 206, 149, 107, 213, 18, 121, 64, 232, + 165, 75, 151, 4, 166, 153, 18, 133, 37, 77, 124, 252, 78, 177, 129, 220, 239, 174, 51, 63, 63, + 193, 187, 218, 61, 123, 82, 196, 6, 154, 15, 133, 37, 205, 237, 219, 34, 143, 214, 229, 134, + 32, 253, 181, 110, 221, 74, 108, 224, 174, 93, 187, 197, 6, 154, 15, 133, 37, 83, 118, 246, + 105, 129, 105, 62, 62, 157, 184, 235, 90, 79, 158, 158, 86, 129, 105, 153, 153, 39, 5, 166, + 153, 21, 127, 191, 101, 90, 177, 98, 181, 216, 192, 94, 189, 130, 196, 6, 226, 81, 156, 156, + 156, 2, 2, 252, 5, 6, 30, 59, 150, 38, 48, 205, 172, 40, 44, 153, 226, 227, 19, 196, 6, 6, 7, + 247, 22, 27, 136, 71, 121, 253, 245, 87, 196, 6, 238, 221, 187, 79, 108, 160, 41, 81, 88, 50, + 165, 166, 30, 16, 27, 216, 190, 125, 27, 177, 129, 120, 20, 177, 239, 238, 182, 88, 44, 231, + 206, 137, 124, 33, 171, 89, 81, 88, 146, 109, 220, 184, 69, 96, 90, 221, 186, 117, 187, 119, + 239, 38, 48, 16, 15, 213, 168, 81, 67, 95, 95, 31, 177, 153, 91, 182, 196, 136, 13, 52, 37, 10, + 75, 178, 147, 39, 179, 196, 6, 190, 250, 234, 56, 177, 129, 248, 79, 61, 122, 116, 23, 27, 120, + 233, 210, 101, 177, 129, 102, 69, 97, 73, 118, 248, 240, 17, 177, 129, 29, 59, 122, 213, 173, + 91, 71, 108, 38, 254, 164, 127, 255, 48, 177, 129, 11, 23, 46, 18, 27, 104, 86, 20, 150, 100, + 49, 49, 219, 132, 103, 134, 132, 244, 17, 158, 137, 223, 181, 107, 215, 70, 248, 33, 250, 235, + 214, 109, 16, 27, 104, 86, 20, 150, 100, 121, 121, 121, 27, 54, 108, 22, 155, 41, 252, 247, 63, + 254, 232, 191, 254, 235, 93, 177, 129, 54, 91, 238, 137, 19, 153, 98, 51, 205, 138, 194, 146, + 79, 248, 253, 205, 205, 154, 61, 29, 28, 220, 75, 108, 38, 30, 104, 214, 172, 105, 167, 78, 29, + 196, 102, 198, 198, 110, 23, 27, 104, 98, 20, 150, 124, 90, 124, 126, 241, 229, 151, 95, 8, + 207, 132, 197, 98, 25, 56, 112, 128, 240, 204, 196, 68, 158, 200, 41, 46, 10, 203, 16, 118, + 238, 76, 20, 27, 232, 228, 228, 20, 22, 246, 188, 216, 76, 212, 171, 87, 55, 52, 84, 252, 79, + 53, 46, 46, 94, 120, 166, 89, 81, 88, 134, 32, 252, 25, 29, 139, 197, 50, 108, 216, 96, 225, + 153, 118, 110, 218, 180, 169, 98, 79, 112, 183, 88, 44, 95, 124, 241, 223, 183, 110, 221, 18, + 155, 105, 98, 20, 150, 33, 236, 222, 189, 87, 120, 166, 151, 87, 59, 14, 156, 17, 168, 109, + 219, 54, 254, 254, 126, 194, 99, 121, 34, 167, 68, 40, 44, 67, 200, 201, 201, 89, 182, 108, + 133, 240, 216, 69, 139, 22, 84, 170, 196, 203, 41, 196, 24, 59, 118, 164, 240, 204, 19, 39, 50, + 185, 30, 44, 17, 10, 203, 40, 190, 250, 106, 129, 22, 177, 111, 190, 57, 65, 139, 88, 123, 211, + 174, 93, 219, 190, 125, 197, 223, 221, 182, 121, 51, 143, 227, 148, 140, 67, 173, 90, 13, 100, + 207, 128, 255, 145, 144, 16, 43, 246, 136, 165, 7, 234, 213, 107, 124, 247, 174, 200, 227, 152, + 237, 141, 179, 179, 115, 102, 166, 224, 7, 18, 30, 240, 245, 13, 200, 200, 56, 161, 69, 178, + 89, 177, 195, 50, 144, 53, 107, 162, 181, 136, 221, 186, 149, 187, 168, 31, 203, 219, 111, 79, + 212, 34, 118, 251, 246, 29, 180, 85, 73, 61, 81, 169, 82, 85, 217, 51, 224, 127, 156, 63, 127, + 97, 212, 168, 225, 194, 99, 31, 188, 40, 97, 247, 238, 61, 194, 147, 237, 129, 151, 87, 187, + 207, 63, 255, 151, 22, 201, 99, 198, 188, 122, 225, 194, 69, 45, 146, 77, 140, 29, 150, 129, + 156, 58, 149, 189, 122, 245, 58, 45, 146, 199, 142, 29, 201, 187, 236, 75, 161, 118, 237, 218, + 26, 181, 213, 143, 63, 30, 254, 233, 167, 163, 90, 36, 155, 27, 133, 101, 44, 175, 188, 162, + 201, 103, 228, 85, 170, 84, 153, 61, 123, 134, 22, 201, 230, 54, 126, 252, 104, 15, 143, 38, + 90, 36, 255, 240, 195, 114, 45, 98, 77, 143, 194, 50, 156, 37, 75, 150, 106, 17, 219, 174, 93, + 155, 57, 115, 102, 106, 145, 108, 86, 97, 97, 207, 143, 25, 35, 254, 86, 6, 139, 197, 114, 225, + 194, 197, 165, 75, 41, 172, 210, 160, 176, 12, 103, 213, 42, 77, 174, 10, 127, 59, 197, 33, + 180, 107, 87, 95, 141, 194, 77, 198, 106, 245, 152, 59, 119, 150, 70, 225, 127, 255, 251, 167, + 121, 121, 121, 26, 133, 155, 27, 133, 101, 56, 187, 119, 39, 139, 61, 55, 249, 143, 150, 47, + 95, 210, 189, 123, 128, 70, 225, 166, 209, 164, 73, 227, 168, 168, 197, 26, 133, 31, 56, 112, + 40, 42, 138, 87, 210, 151, 18, 133, 101, 68, 35, 71, 106, 120, 204, 241, 212, 169, 31, 243, + 250, 194, 194, 125, 246, 217, 63, 234, 212, 169, 173, 81, 248, 250, 245, 27, 53, 74, 182, 7, + 252, 197, 53, 162, 130, 130, 130, 175, 190, 138, 208, 40, 188, 126, 253, 122, 241, 241, 91, + 107, 215, 214, 234, 63, 72, 213, 69, 68, 204, 245, 241, 233, 164, 81, 120, 122, 122, 134, 70, + 159, 81, 218, 9, 238, 116, 55, 40, 171, 213, 35, 49, 81, 252, 233, 201, 191, 75, 79, 207, 232, + 210, 133, 71, 163, 255, 108, 245, 234, 101, 218, 181, 149, 197, 98, 121, 225, 133, 1, 220, 16, + 247, 56, 216, 97, 25, 84, 70, 198, 137, 89, 179, 190, 212, 46, 223, 211, 211, 154, 144, 16, 91, + 187, 182, 171, 118, 75, 40, 231, 179, 207, 166, 106, 218, 86, 155, 55, 199, 208, 86, 143, 137, + 29, 150, 161, 105, 244, 116, 225, 239, 216, 103, 253, 78, 235, 189, 149, 197, 98, 233, 214, + 173, 215, 145, 35, 220, 44, 250, 88, 216, 97, 25, 218, 135, 31, 254, 93, 211, 252, 255, 183, + 207, 178, 247, 207, 179, 34, 34, 190, 212, 186, 173, 34, 35, 151, 209, 86, 143, 143, 29, 150, + 209, 233, 240, 155, 223, 158, 247, 89, 101, 203, 150, 141, 138, 90, 204, 79, 88, 21, 236, 176, + 140, 110, 196, 136, 113, 54, 91, 174, 166, 75, 120, 122, 90, 247, 237, 219, 21, 24, 104, 119, + 239, 184, 111, 208, 160, 254, 242, 229, 75, 180, 110, 43, 29, 118, 202, 246, 131, 211, 26, 140, + 238, 206, 157, 59, 247, 238, 221, 235, 214, 237, 57, 77, 87, 169, 90, 181, 106, 104, 104, 223, + 221, 187, 247, 156, 61, 123, 78, 211, 133, 140, 195, 106, 245, 72, 78, 142, 175, 95, 191, 158, + 214, 11, 37, 37, 37, 255, 235, 95, 60, 200, 41, 6, 133, 165, 128, 131, 7, 15, 53, 109, 250, + 180, 213, 234, 161, 245, 66, 225, 225, 253, 26, 52, 168, 111, 15, 199, 96, 78, 154, 244, 250, + 252, 249, 255, 173, 195, 13, 180, 167, 79, 159, 13, 8, 224, 29, 145, 194, 240, 25, 150, 50, + 126, 252, 113, 175, 171, 171, 30, 119, 33, 164, 164, 164, 78, 152, 240, 214, 169, 83, 217, 58, + 172, 37, 197, 146, 37, 11, 3, 3, 253, 245, 89, 43, 52, 52, 60, 41, 41, 89, 159, 181, 236, 1, + 59, 44, 101, 228, 228, 228, 134, 132, 244, 214, 97, 161, 186, 117, 235, 244, 234, 213, 195, + 217, 185, 178, 249, 110, 26, 10, 9, 233, 19, 17, 241, 165, 151, 87, 59, 125, 150, 155, 51, 103, + 94, 100, 228, 50, 125, 214, 178, 19, 236, 176, 84, 50, 105, 210, 235, 239, 190, 251, 182, 110, + 203, 253, 244, 211, 145, 160, 160, 144, 252, 252, 124, 221, 86, 212, 212, 170, 85, 75, 59, 119, + 246, 214, 109, 185, 227, 199, 211, 252, 252, 130, 116, 91, 206, 78, 240, 45, 161, 74, 102, 206, + 156, 179, 121, 243, 86, 221, 150, 107, 217, 178, 133, 205, 150, 245, 202, 43, 163, 157, 156, + 156, 116, 91, 84, 184, 138, 21, 43, 244, 235, 23, 154, 146, 146, 168, 103, 91, 157, 57, 115, + 118, 240, 96, 77, 206, 210, 178, 115, 236, 176, 20, 83, 175, 94, 221, 253, 251, 119, 235, 191, + 238, 168, 81, 175, 172, 95, 191, 73, 255, 117, 31, 83, 251, 246, 109, 103, 204, 248, 84, 211, + 167, 5, 30, 170, 87, 175, 231, 247, 239, 63, 168, 243, 162, 246, 128, 29, 150, 98, 206, 157, + 203, 241, 245, 13, 200, 205, 253, 89, 231, 117, 23, 44, 152, 183, 106, 213, 210, 110, 221, 196, + 191, 250, 88, 35, 205, 155, 55, 155, 59, 119, 214, 134, 13, 171, 245, 111, 171, 169, 83, 63, + 163, 173, 52, 194, 14, 75, 73, 99, 198, 140, 248, 219, 223, 62, 148, 178, 244, 205, 155, 55, + 39, 76, 120, 107, 211, 38, 253, 174, 76, 75, 170, 69, 139, 230, 179, 103, 79, 111, 222, 188, + 153, 148, 213, 99, 98, 182, 15, 30, 60, 66, 202, 210, 246, 160, 140, 236, 1, 80, 26, 185, 185, + 231, 101, 45, 237, 236, 236, 188, 112, 225, 252, 244, 244, 140, 31, 126, 136, 90, 189, 122, + 157, 113, 94, 84, 85, 190, 124, 249, 158, 61, 187, 143, 28, 57, 172, 125, 251, 182, 178, 102, + 216, 186, 53, 118, 200, 144, 81, 178, 86, 183, 7, 236, 176, 148, 20, 28, 220, 123, 193, 130, + 185, 178, 167, 176, 252, 246, 168, 227, 186, 149, 43, 215, 108, 223, 190, 67, 226, 12, 158, + 158, 214, 224, 224, 94, 111, 189, 245, 134, 220, 147, 84, 143, 28, 57, 250, 242, 203, 195, 207, + 159, 151, 246, 187, 196, 30, 176, 195, 194, 99, 9, 13, 237, 27, 26, 218, 55, 59, 251, 116, 74, + 74, 234, 134, 13, 155, 183, 110, 141, 213, 109, 233, 160, 160, 192, 214, 173, 159, 9, 12, 236, + 214, 162, 133, 156, 171, 191, 63, 202, 202, 58, 21, 30, 62, 228, 226, 197, 75, 178, 7, 49, 57, + 10, 11, 2, 184, 187, 187, 185, 187, 187, 245, 239, 31, 102, 177, 88, 118, 238, 76, 220, 185, + 51, 113, 222, 188, 249, 247, 239, 23, 104, 177, 86, 72, 72, 239, 118, 237, 218, 140, 29, 107, + 172, 43, 175, 161, 67, 71, 211, 86, 58, 224, 146, 80, 73, 198, 185, 36, 44, 68, 65, 65, 193, + 214, 173, 219, 110, 223, 254, 101, 219, 182, 29, 121, 121, 191, 30, 61, 122, 44, 43, 235, 84, + 137, 18, 106, 214, 172, 209, 161, 131, 151, 163, 163, 163, 143, 79, 199, 26, 53, 106, 116, 238, + 220, 169, 122, 245, 234, 154, 205, 91, 74, 54, 91, 238, 128, 1, 131, 51, 50, 78, 200, 30, 196, + 46, 176, 195, 130, 86, 28, 28, 28, 122, 244, 8, 252, 237, 32, 243, 190, 127, 252, 231, 87, 175, + 94, 219, 178, 37, 230, 220, 185, 156, 135, 254, 169, 106, 213, 170, 118, 235, 246, 92, 163, 70, + 13, 245, 26, 243, 113, 209, 86, 122, 162, 176, 160, 183, 39, 159, 172, 246, 210, 75, 253, 101, + 79, 33, 128, 205, 102, 27, 48, 96, 8, 109, 165, 39, 10, 11, 40, 141, 27, 55, 110, 188, 248, + 226, 192, 147, 39, 179, 100, 15, 98, 95, 184, 211, 29, 40, 177, 189, 123, 247, 245, 238, 29, + 74, 91, 233, 143, 29, 22, 80, 50, 73, 73, 201, 161, 161, 225, 178, 167, 176, 83, 236, 176, 128, + 18, 88, 189, 122, 29, 109, 37, 17, 59, 44, 160, 184, 120, 111, 179, 116, 236, 176, 128, 162, + 157, 60, 153, 53, 100, 200, 72, 218, 74, 58, 118, 88, 64, 17, 182, 108, 137, 25, 58, 116, 180, + 236, 41, 96, 97, 135, 5, 20, 230, 250, 245, 235, 211, 166, 205, 164, 173, 140, 131, 29, 22, + 240, 72, 125, 250, 132, 113, 95, 168, 161, 176, 195, 2, 30, 98, 250, 244, 47, 92, 92, 220, 104, + 43, 163, 97, 135, 5, 252, 47, 233, 233, 25, 147, 38, 189, 195, 25, 199, 198, 68, 97, 217, 169, + 189, 123, 247, 221, 184, 113, 35, 48, 176, 155, 236, 65, 12, 196, 102, 203, 157, 57, 115, 206, + 218, 181, 209, 55, 110, 220, 148, 61, 11, 30, 142, 194, 178, 59, 247, 239, 223, 159, 52, 233, + 157, 101, 203, 86, 252, 254, 98, 81, 217, 19, 25, 194, 198, 141, 155, 199, 143, 127, 227, 206, + 157, 60, 217, 131, 160, 48, 124, 134, 101, 71, 174, 92, 185, 58, 107, 214, 151, 109, 218, 120, + 63, 104, 43, 139, 197, 18, 29, 189, 161, 97, 195, 166, 51, 103, 206, 190, 124, 249, 178, 236, + 233, 164, 137, 142, 222, 24, 28, 28, 54, 98, 196, 56, 218, 202, 248, 40, 44, 123, 145, 148, + 148, 28, 20, 20, 60, 117, 234, 103, 185, 185, 185, 127, 252, 231, 191, 252, 242, 203, 167, 159, + 206, 104, 214, 172, 205, 215, 95, 127, 35, 111, 58, 57, 142, 31, 79, 243, 245, 13, 24, 61, 122, + 124, 74, 74, 170, 236, 89, 80, 44, 20, 150, 249, 165, 167, 103, 188, 246, 218, 155, 161, 161, + 225, 103, 206, 156, 45, 228, 95, 251, 235, 95, 63, 241, 245, 13, 248, 234, 171, 136, 123, 247, + 238, 233, 56, 157, 28, 137, 137, 73, 225, 225, 67, 252, 252, 130, 248, 30, 80, 45, 28, 145, + 172, 164, 226, 31, 145, 252, 218, 107, 111, 174, 88, 177, 170, 164, 249, 253, 251, 135, 205, + 153, 243, 121, 169, 70, 51, 186, 29, 59, 118, 190, 247, 222, 135, 37, 61, 172, 25, 6, 193, 14, + 203, 180, 190, 255, 126, 73, 219, 182, 222, 165, 104, 43, 139, 197, 178, 124, 249, 42, 23, 23, + 183, 119, 223, 253, 32, 54, 54, 78, 131, 209, 36, 176, 217, 114, 63, 255, 124, 118, 215, 174, + 221, 195, 195, 135, 208, 86, 234, 226, 91, 66, 19, 74, 74, 74, 254, 232, 163, 191, 31, 62, 124, + 228, 49, 115, 22, 46, 92, 180, 112, 225, 34, 171, 213, 35, 36, 164, 247, 27, 111, 188, 90, 174, + 92, 57, 65, 3, 234, 42, 33, 97, 215, 242, 229, 171, 86, 172, 88, 45, 123, 16, 8, 192, 37, 161, + 146, 30, 117, 73, 152, 153, 121, 114, 198, 140, 89, 171, 87, 175, 19, 190, 98, 217, 178, 101, + 123, 244, 232, 238, 231, 231, 251, 226, 139, 47, 148, 47, 95, 94, 120, 190, 112, 155, 54, 109, + 221, 179, 39, 101, 235, 214, 152, 236, 236, 51, 178, 103, 129, 48, 20, 150, 146, 30, 90, 88, + 243, 230, 205, 255, 232, 163, 127, 232, 176, 186, 191, 127, 215, 151, 95, 14, 15, 14, 238, 165, + 195, 90, 37, 149, 158, 158, 17, 29, 189, 113, 198, 140, 89, 5, 5, 154, 188, 21, 17, 114, 113, + 73, 104, 6, 243, 231, 127, 51, 111, 94, 132, 205, 150, 171, 207, 114, 113, 113, 59, 227, 226, + 118, 90, 44, 150, 182, 109, 91, 183, 110, 253, 108, 135, 14, 237, 189, 188, 218, 186, 186, 186, + 234, 179, 250, 127, 218, 190, 125, 71, 90, 90, 250, 254, 253, 7, 183, 108, 137, 205, 207, 207, + 151, 53, 6, 116, 192, 14, 75, 73, 142, 142, 142, 7, 15, 238, 113, 117, 117, 57, 123, 246, 220, + 144, 33, 35, 143, 29, 75, 147, 61, 145, 165, 76, 153, 50, 99, 198, 140, 172, 95, 191, 222, 176, + 97, 131, 28, 29, 53, 255, 50, 103, 239, 222, 125, 9, 9, 187, 226, 227, 19, 82, 83, 15, 104, + 189, 22, 140, 131, 194, 82, 152, 175, 175, 79, 98, 98, 146, 236, 41, 30, 162, 114, 229, 74, 93, + 186, 248, 62, 241, 196, 19, 85, 170, 56, 123, 123, 119, 44, 247, 27, 47, 175, 118, 213, 171, + 63, 89, 162, 156, 95, 127, 253, 245, 192, 129, 67, 23, 46, 92, 180, 88, 44, 63, 254, 248, 211, + 233, 211, 103, 30, 220, 237, 153, 153, 121, 82, 179, 217, 97, 104, 20, 22, 36, 120, 242, 201, + 106, 86, 171, 135, 155, 91, 131, 218, 181, 93, 203, 150, 45, 107, 177, 88, 238, 221, 187, 119, + 237, 218, 181, 172, 172, 236, 172, 172, 83, 57, 57, 54, 62, 129, 194, 67, 81, 88, 0, 148, 193, + 141, 163, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, + 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, + 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, + 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, + 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, + 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, + 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, + 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, + 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, + 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, + 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, + 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, + 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, + 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, + 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, + 1, 80, 6, 133, 5, 64, 25, 20, 22, 0, 101, 80, 88, 0, 148, 65, 97, 1, 80, 6, 133, 5, 64, 25, 20, + 22, 0, 101, 80, 88, 0, 148, 241, 127, 2, 0, 0, 255, 255, 236, 61, 134, 14, 191, 70, 226, 46, 0, + 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130, +]; \ No newline at end of file diff --git a/warp/src/multipass/identity.rs b/warp/src/multipass/identity.rs index 79c4b5a61..23ca78798 100644 --- a/warp/src/multipass/identity.rs +++ b/warp/src/multipass/identity.rs @@ -1,6 +1,6 @@ use std::fmt::Display; -use crate::crypto::DID; +use crate::{constellation::file::FileType, crypto::DID}; use chrono::{DateTime, Utc}; use derive_more::Display; use serde::{Deserialize, Serialize}; @@ -71,6 +71,32 @@ impl IdentityProfile { } } +#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +pub struct IdentityImage { + data: Vec, + image_type: FileType, +} + +impl IdentityImage { + pub fn set_data(&mut self, data: Vec) { + self.data = data + } + + pub fn set_image_type(&mut self, image_type: FileType) { + self.image_type = image_type + } +} + +impl IdentityImage { + pub fn data(&self) -> &[u8] { + &self.data + } + + pub fn image_type(&self) -> &FileType { + &self.image_type + } +} + #[derive(Default, Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, FFIFree)] pub struct Relationship { friends: bool, @@ -283,10 +309,10 @@ impl From<&[DID]> for Identifier { #[derive(Debug, Clone, FFIFree)] pub enum IdentityUpdate { Username(String), - Picture(String), + Picture(Vec), PicturePath(std::path::PathBuf), ClearPicture, - Banner(String), + Banner(Vec), BannerPath(std::path::PathBuf), ClearBanner, StatusMessage(Option), @@ -409,33 +435,33 @@ pub mod ffi { Box::into_raw(Box::new(IdentityUpdate::Username(name))) } - #[allow(clippy::missing_safety_doc)] - #[no_mangle] - pub unsafe extern "C" fn multipass_identity_update_set_graphics_picture( - name: *const c_char, - ) -> *mut IdentityUpdate { - if name.is_null() { - return std::ptr::null_mut(); - } + // #[allow(clippy::missing_safety_doc)] + // #[no_mangle] + // pub unsafe extern "C" fn multipass_identity_update_set_graphics_picture( + // name: *const c_char, + // ) -> *mut IdentityUpdate { + // if name.is_null() { + // return std::ptr::null_mut(); + // } - let name = CStr::from_ptr(name).to_string_lossy().to_string(); + // let name = CStr::from_ptr(name).to_string_lossy().to_string(); - Box::into_raw(Box::new(IdentityUpdate::Picture(name))) - } + // Box::into_raw(Box::new(IdentityUpdate::Picture(name))) + // } - #[allow(clippy::missing_safety_doc)] - #[no_mangle] - pub unsafe extern "C" fn multipass_identity_update_set_graphics_banner( - name: *const c_char, - ) -> *mut IdentityUpdate { - if name.is_null() { - return std::ptr::null_mut(); - } + // #[allow(clippy::missing_safety_doc)] + // #[no_mangle] + // pub unsafe extern "C" fn multipass_identity_update_set_graphics_banner( + // name: *const c_char, + // ) -> *mut IdentityUpdate { + // if name.is_null() { + // return std::ptr::null_mut(); + // } - let name = CStr::from_ptr(name).to_string_lossy().to_string(); + // let name = CStr::from_ptr(name).to_string_lossy().to_string(); - Box::into_raw(Box::new(IdentityUpdate::Banner(name))) - } + // Box::into_raw(Box::new(IdentityUpdate::Banner(name))) + // } #[allow(clippy::missing_safety_doc)] #[no_mangle] diff --git a/warp/src/multipass/mod.rs b/warp/src/multipass/mod.rs index cde9ee81f..35464efbd 100644 --- a/warp/src/multipass/mod.rs +++ b/warp/src/multipass/mod.rs @@ -17,7 +17,7 @@ use identity::Identity; use crate::crypto::DID; use crate::multipass::identity::{Identifier, IdentityUpdate}; -use self::identity::{IdentityProfile, IdentityStatus, Platform, Relationship}; +use self::identity::{IdentityProfile, IdentityStatus, Platform, Relationship, IdentityImage}; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, FFIFree)] #[serde(rename_all = "snake_case")] @@ -219,12 +219,12 @@ pub trait FriendsEvent: Sync + Send { #[async_trait::async_trait] pub trait IdentityInformation: Send + Sync { /// Profile picture belonging to the `Identity` - async fn identity_picture(&self, _: &DID) -> Result { + async fn identity_picture(&self, _: &DID) -> Result { Err(Error::Unimplemented) } /// Profile banner belonging to the `Identity` - async fn identity_banner(&self, _: &DID) -> Result { + async fn identity_banner(&self, _: &DID) -> Result { Err(Error::Unimplemented) }