From 265fb3e895e97b3027651121b646d0f202fd3b19 Mon Sep 17 00:00:00 2001 From: Boog900 <108027008+Boog900@users.noreply.github.com> Date: Tue, 7 Mar 2023 22:37:55 +0000 Subject: [PATCH] initial net code (#2) * initial commit not ready * add new levin lib * fix decoding multiple messages * make the levin lib async * saving progress * saving progress * init documention of levin and reorganise net * update monero-wire * remove p2p folder - this PR is just for net * update Cargo.toml * net: update links in cargo.toml --- .gitignore | 3 +- Cargo.toml | 7 +- net/levin/Cargo.toml | 15 + net/levin/src/bucket_sink.rs | 82 ++ net/levin/src/bucket_stream.rs | 137 +++ net/levin/src/header.rs | 212 +++++ net/levin/src/lib.rs | 134 +++ net/levin/src/message_sink.rs | 64 ++ net/levin/src/message_stream.rs | 79 ++ net/monero-wire/Cargo.toml | 19 + net/monero-wire/src/internal_macros.rs | 31 + net/monero-wire/src/lib.rs | 109 +++ net/monero-wire/src/messages.rs | 323 +++++++ net/monero-wire/src/messages/admin.rs | 939 ++++++++++++++++++++ net/monero-wire/src/messages/common.rs | 238 +++++ net/monero-wire/src/messages/protocol.rs | 1030 ++++++++++++++++++++++ net/monero-wire/src/network_address.rs | 144 +++ 17 files changed, 3563 insertions(+), 3 deletions(-) create mode 100644 net/levin/Cargo.toml create mode 100644 net/levin/src/bucket_sink.rs create mode 100644 net/levin/src/bucket_stream.rs create mode 100644 net/levin/src/header.rs create mode 100644 net/levin/src/lib.rs create mode 100644 net/levin/src/message_sink.rs create mode 100644 net/levin/src/message_stream.rs create mode 100644 net/monero-wire/Cargo.toml create mode 100644 net/monero-wire/src/internal_macros.rs create mode 100644 net/monero-wire/src/lib.rs create mode 100644 net/monero-wire/src/messages.rs create mode 100644 net/monero-wire/src/messages/admin.rs create mode 100644 net/monero-wire/src/messages/common.rs create mode 100644 net/monero-wire/src/messages/protocol.rs create mode 100644 net/monero-wire/src/network_address.rs diff --git a/.gitignore b/.gitignore index 4470988..8fddb05 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ target/ -Cargo.lock \ No newline at end of file +Cargo.lock +.vscode \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index b6e6003..2e09e67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,13 +11,16 @@ repository = "https://github.com/SyntheticBird45/cuprate" # All Contributors on github authors=[ - "SyntheticBird45 <@someoneelse495495:matrix.org>" + "SyntheticBird45 <@someoneelse495495:matrix.org>", + "Boog900" ] [workspace] members = [ - "blockchain_db" + "blockchain_db", + "net/levin", + "net/monero-wire" ] [workspace.dependencies] diff --git a/net/levin/Cargo.toml b/net/levin/Cargo.toml new file mode 100644 index 0000000..407cef1 --- /dev/null +++ b/net/levin/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "levin" +version = "0.1.0" +edition = "2021" +description = "A crate for working with the Levin protocol in Rust." +license = "MIT" +authors = ["Boog900"] +repository = "https://github.com/SyntheticBird45/cuprate/tree/main/net/levin" + +[dependencies] +thiserror = "1.0.24" +byteorder = "1.4.3" +futures = "0.3" +bytes = "1" +pin-project = "1" diff --git a/net/levin/src/bucket_sink.rs b/net/levin/src/bucket_sink.rs new file mode 100644 index 0000000..c005f12 --- /dev/null +++ b/net/levin/src/bucket_sink.rs @@ -0,0 +1,82 @@ +//! This module provides a `BucketSink` struct, which writes buckets to the +//! provided `AsyncWrite`. If you are a user of this library you should +//! probably use `MessageSink` instead. + +use std::collections::VecDeque; +use std::pin::Pin; +use std::task::Poll; + +use bytes::{Buf, BytesMut}; +use futures::ready; +use futures::sink::Sink; +use futures::AsyncWrite; +use pin_project::pin_project; + +use crate::{Bucket, BucketError}; + +/// A BucketSink writes Bucket instances to the provided AsyncWrite target. +#[pin_project] +pub struct BucketSink { + #[pin] + writer: W, + buffer: VecDeque, +} + +impl Sink for BucketSink { + type Error = BucketError; + + fn poll_ready( + self: std::pin::Pin<&mut Self>, + _: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + Poll::Ready(Ok(())) + } + + fn start_send(mut self: Pin<&mut Self>, item: Bucket) -> Result<(), Self::Error> { + let buf = item.to_bytes(); + self.buffer.push_back(BytesMut::from(&buf[..])); + Ok(()) + } + + fn poll_flush( + self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + let this = self.project(); + let mut w = this.writer; + let buffer = this.buffer; + + loop { + match ready!(w.as_mut().poll_flush(cx)) { + Err(err) => return Poll::Ready(Err(err.into())), + Ok(()) => { + if let Some(buf) = buffer.front() { + match ready!(w.as_mut().poll_write(cx, buf)) { + Err(e) => match e.kind() { + std::io::ErrorKind::WouldBlock => return std::task::Poll::Pending, + _ => return Poll::Ready(Err(e.into())), + }, + Ok(len) => { + if len == buffer[0].len() { + buffer.pop_front(); + } else { + buffer[0].advance(len); + } + } + } + } else { + return Poll::Ready(Ok(())); + } + } + } + } + } + + fn poll_close( + self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + ready!(self.project().writer.poll_close(cx))?; + Poll::Ready(Ok(())) + } +} diff --git a/net/levin/src/bucket_stream.rs b/net/levin/src/bucket_stream.rs new file mode 100644 index 0000000..5ecb6e2 --- /dev/null +++ b/net/levin/src/bucket_stream.rs @@ -0,0 +1,137 @@ +//! This module provides a `BucketStream` struct, which is a stream of `Bucket`s, +//! where only the header is decoded. If you are a user of this library you should +//! probably use `MessageStream` instead. + +use std::task::Poll; + +use bytes::{Buf, BytesMut}; +use futures::stream::Stream; +use futures::{ready, AsyncRead}; +use pin_project::pin_project; + +use super::{Bucket, BucketError, BucketHead}; + +/// An enum representing the decoding state of a `BucketStream`. +#[derive(Debug, Clone)] +enum BucketDecoder { + /// Waiting for the header of a `Bucket`. + WaitingForHeader, + /// Waiting for the body of a `Bucket` with the given header. + WaitingForBody(BucketHead), +} + +impl BucketDecoder { + /// Returns the number of bytes needed to complete the current decoding state. + pub fn bytes_needed(&self) -> usize { + match self { + Self::WaitingForHeader => BucketHead::SIZE, + Self::WaitingForBody(bucket_head) => bucket_head.size as usize, + } + } + + /// Tries to decode a `Bucket` from the given buffer, returning the decoded `Bucket` and the + /// number of bytes consumed from the buffer. + pub fn try_decode_bucket( + &mut self, + mut buf: &[u8], + ) -> Result<(Option, usize), BucketError> { + let mut len = 0; + + // first we decode header + if let BucketDecoder::WaitingForHeader = self { + if buf.len() < BucketHead::SIZE { + return Ok((None, 0)); + } + let header = BucketHead::from_bytes(&mut buf)?; + len += BucketHead::SIZE; + *self = BucketDecoder::WaitingForBody(header); + }; + + // next we check we have enough bytes to fill the body + if let &mut Self::WaitingForBody(head) = self { + if buf.len() < head.size as usize { + return Ok((None, len)); + } + *self = BucketDecoder::WaitingForHeader; + Ok(( + Some(Bucket { + header: head, + body: buf.copy_to_bytes(buf.len()), + }), + len + head.size as usize, + )) + } else { + unreachable!() + } + } +} + +/// A stream of `Bucket`s, with only the header decoded. +#[pin_project] +#[derive(Debug, Clone)] +pub struct BucketStream { + #[pin] + stream: S, + decoder: BucketDecoder, + buffer: BytesMut, +} + +impl BucketStream { + /// Creates a new `BucketStream` from the given `AsyncRead` stream. + pub fn new(stream: S) -> Self { + BucketStream { + stream, + decoder: BucketDecoder::WaitingForHeader, + buffer: BytesMut::with_capacity(1024), + } + } +} + +impl Stream for BucketStream { + type Item = Result; + + /// Attempt to read from the underlying stream into the buffer until enough bytes are received to construct a `Bucket`. + /// + /// If enough bytes are received, return the decoded `Bucket`, if not enough bytes are received to construct a `Bucket`, + /// return `Poll::Pending`. This will never return `Poll::Ready(None)`. + /// + fn poll_next( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + let this = self.project(); + let mut stream = this.stream; + let decoder = this.decoder; + let buffer = this.buffer; + + loop { + // this is a bit ugly but all we are doing is calculating the amount of bytes we + // need to build the rest of a bucket if this is zero it means we need to start + // reading a new bucket + let mut bytes_needed = buffer.len().saturating_sub(decoder.bytes_needed()); + if bytes_needed == 0 { + bytes_needed = 1024 + } + + let mut buf = vec![0; bytes_needed]; + match ready!(stream.as_mut().poll_read(cx, &mut buf)) { + Err(e) => match e.kind() { + std::io::ErrorKind::WouldBlock => return std::task::Poll::Pending, + std::io::ErrorKind::Interrupted => continue, + _ => return Poll::Ready(Some(Err(BucketError::IO(e)))), + }, + Ok(len) => { + buffer.extend(&buf[..len]); + + let (bucket, len) = decoder.try_decode_bucket(buffer)?; + buffer.advance(len); + if let Some(bucket) = bucket { + return Poll::Ready(Some(Ok(bucket))); + } else { + continue; + } + } + } + } + } +} diff --git a/net/levin/src/header.rs b/net/levin/src/header.rs new file mode 100644 index 0000000..b53e50e --- /dev/null +++ b/net/levin/src/header.rs @@ -0,0 +1,212 @@ +//! This module provides a struct BucketHead for the header of a levin protocol +//! message. + +use std::io::Read; + +use super::{BucketError, LEVIN_SIGNATURE, PROTOCOL_VERSION}; + +use byteorder::{LittleEndian, ReadBytesExt}; + +/// The Flags for the levin header +#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)] +pub struct Flags(u32); + +pub(crate) const REQUEST: Flags = Flags(0b0000_0001); +pub(crate) const RESPONSE: Flags = Flags(0b0000_0010); +const START_FRAGMENT: Flags = Flags(0b0000_0100); +const END_FRAGMENT: Flags = Flags(0b0000_1000); +const DUMMY: Flags = Flags(0b0000_1100); // both start and end fragment set + +impl Flags { + fn contains_flag(&self, rhs: Self) -> bool { + self & &rhs == rhs + } + + /// Converts the inner flags to little endian bytes + pub fn to_le_bytes(&self) -> [u8; 4] { + self.0.to_le_bytes() + } + + /// Checks if the flags have the `REQUEST` flag set and + /// does not have the `RESPONSE` flag set, this does + /// not check for other flags + pub fn is_request(&self) -> bool { + self.contains_flag(REQUEST) && !self.contains_flag(RESPONSE) + } + + /// Checks if the flags have the `RESPONSE` flag set and + /// does not have the `REQUEST` flag set, this does + /// not check for other flags + pub fn is_response(&self) -> bool { + self.contains_flag(RESPONSE) && !self.contains_flag(REQUEST) + } + + /// Checks if the flags have the `START_FRAGMENT`and the + /// `END_FRAGMENT` flags set, this does + /// not check for other flags + pub fn is_dummy(&self) -> bool { + self.contains_flag(DUMMY) + } + + /// Checks if the flags have the `START_FRAGMENT` flag + /// set and does not have the `END_FRAGMENT` flag set, this + /// does not check for other flags + pub fn is_start_fragment(&self) -> bool { + self.contains_flag(START_FRAGMENT) && !self.is_dummy() + } + + /// Checks if the flags have the `END_FRAGMENT` flag + /// set and does not have the `START_FRAGMENT` flag set, this + /// does not check for other flags + pub fn is_end_fragment(&self) -> bool { + self.contains_flag(END_FRAGMENT) && !self.is_dummy() + } + + /// Sets the `REQUEST` flag + pub fn set_flag_request(&mut self) { + *self |= REQUEST + } + + /// Sets the `RESPONSE` flag + pub fn set_flag_response(&mut self) { + *self |= RESPONSE + } + + /// Sets the `START_FRAGMENT` flag + pub fn set_flag_start_fragment(&mut self) { + *self |= START_FRAGMENT + } + + /// Sets the `END_FRAGMENT` flag + pub fn set_flag_end_fragment(&mut self) { + *self |= END_FRAGMENT + } + + /// Sets the `START_FRAGMENT` and `END_FRAGMENT` flag + pub fn set_flag_dummy(&mut self) { + self.set_flag_start_fragment(); + self.set_flag_end_fragment(); + } +} + +impl From for Flags { + fn from(value: u32) -> Self { + Flags(value) + } +} + +impl core::ops::BitAnd for &Flags { + type Output = Flags; + fn bitand(self, rhs: Self) -> Self::Output { + Flags(self.0 & rhs.0) + } +} + +impl core::ops::BitOr for &Flags { + type Output = Flags; + fn bitor(self, rhs: Self) -> Self::Output { + Flags(self.0 | rhs.0) + } +} + +impl core::ops::BitOrAssign for Flags { + fn bitor_assign(&mut self, rhs: Self) { + self.0 |= rhs.0 + } +} + +/// The Header of a Bucket. This contains +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub struct BucketHead { + /// The network signature, should be `LEVIN_SIGNATURE` for Monero + pub signature: u64, + /// The size of the body + pub size: u64, + /// If the peer has to send data in the order of requests - some + /// messages require responses but don't have this set (some notifications) + pub have_to_return_data: bool, + /// Command + pub command: u32, + /// Return Code - will be 0 for requests and >0 for ok responses otherwise will be + /// a negative number corresponding to the error + pub return_code: i32, + /// The Flags of this header + pub flags: Flags, + /// The protocol version, for Monero this is currently 1 + pub protocol_version: u32, +} + +impl BucketHead { + /// The size of the header (in bytes) + pub const SIZE: usize = 33; + + /// Builds the header in a Monero specific way + pub fn build( + payload_size: u64, + have_to_return_data: bool, + command: u32, + flags: Flags, + return_code: i32, + ) -> BucketHead { + BucketHead { + signature: LEVIN_SIGNATURE, + size: payload_size, + have_to_return_data, + command, + return_code, + flags, + protocol_version: PROTOCOL_VERSION, + } + } + + /// Builds the header from bytes, this function does not check any fields should + /// match the expected ones (signature, protocol_version) + pub fn from_bytes(r: &mut R) -> Result { + let header = BucketHead { + signature: r.read_u64::()?, + size: r.read_u64::()?, + have_to_return_data: r.read_u8()? != 0, + command: r.read_u32::()?, + return_code: r.read_i32::()?, + // this is incorrect an will not work for fragmented messages + flags: Flags::from(r.read_u32::()?), + protocol_version: r.read_u32::()?, + }; + + Ok(header) + } + + /// Serializes the header + pub fn to_bytes(&self) -> Vec { + let mut out = Vec::with_capacity(BucketHead::SIZE); + out.extend_from_slice(&self.signature.to_le_bytes()); + out.extend_from_slice(&self.size.to_le_bytes()); + out.push(if self.have_to_return_data { 1 } else { 0 }); + out.extend_from_slice(&self.command.to_le_bytes()); + out.extend_from_slice(&self.return_code.to_le_bytes()); + out.extend_from_slice(&self.flags.to_le_bytes()); + out.extend_from_slice(&self.protocol_version.to_le_bytes()); + out + } +} + +#[cfg(test)] +mod tests { + use super::Flags; + + #[test] + fn set_flags() { + macro_rules! set_and_check { + ($set:ident, $check:ident) => { + let mut flag = Flags::default(); + flag.$set(); + assert!(flag.$check()); + }; + } + set_and_check!(set_flag_request, is_request); + set_and_check!(set_flag_response, is_response); + set_and_check!(set_flag_start_fragment, is_start_fragment); + set_and_check!(set_flag_end_fragment, is_end_fragment); + set_and_check!(set_flag_dummy, is_dummy); + } +} diff --git a/net/levin/src/lib.rs b/net/levin/src/lib.rs new file mode 100644 index 0000000..ce9aee0 --- /dev/null +++ b/net/levin/src/lib.rs @@ -0,0 +1,134 @@ +//! # Rust Levin +//! +//! A crate for working with the Levin protocol in Rust. +//! +//! The Levin protocol is a network protocol used in the Monero cryptocurrency. It is used for +//! peer-to-peer communication between nodes. This crate provides a Rust implementation of the Levin +//! header serialization and allows developers to define their own bucket bodies so this is not a +//! complete Monero networking crate. +//! +//! ## License +//! +//! This project is licensed under the MIT License. + +// Coding conventions +#![forbid(unsafe_code)] +#![deny(non_upper_case_globals)] +#![deny(non_camel_case_types)] +#![deny(unused_mut)] +#![deny(missing_docs)] + +pub mod bucket_sink; +pub mod bucket_stream; +pub mod header; +pub mod message_sink; +pub mod message_stream; + +pub use header::BucketHead; + +use std::fmt::Debug; + +use bytes::Bytes; +use thiserror::Error; + +/// Possible Errors when working with levin buckets +#[derive(Error, Debug)] +pub enum BucketError { + /// Unsupported p2p command. + #[error("Unsupported p2p command: {0}")] + UnsupportedP2pCommand(u32), + /// Revived header with incorrect signature. + #[error("Revived header with incorrect signature: {0}")] + IncorrectSignature(u64), + /// Header contains unknown flags. + #[error("Header contains unknown flags")] + UnknownFlags, + /// Revived header with unknown protocol version. + #[error("Revived header with unknown protocol version: {0}")] + UnknownProtocolVersion(u32), + /// More bytes needed to parse data. + #[error("More bytes needed to parse data")] + NotEnoughBytes, + /// Failed to decode bucket body. + #[error("Failed to decode bucket body: {0}")] + FailedToDecodeBucketBody(String), + /// Failed to encode bucket body. + #[error("Failed to encode bucket body: {0}")] + FailedToEncodeBucketBody(String), + /// IO Error. + #[error("IO Error: {0}")] + IO(#[from] std::io::Error), + /// Peer sent an error response code. + #[error("Peer sent an error response code: {0}")] + Error(i32), +} + +const PROTOCOL_VERSION: u32 = 1; +const LEVIN_SIGNATURE: u64 = 0x0101010101012101; + +/// A levin Bucket +#[derive(Debug)] +pub struct Bucket { + header: BucketHead, + body: Bytes, +} + +impl Bucket { + fn to_bytes(&self) -> Bytes { + let mut buf = self.header.to_bytes(); + buf.extend(self.body.iter()); + buf.into() + } +} + +/// An enum representing if the message is a request or response +#[derive(Debug)] +pub enum MessageType { + /// Request + Request, + /// Response + Response, +} + +impl From for header::Flags { + fn from(val: MessageType) -> Self { + match val { + MessageType::Request => header::REQUEST, + MessageType::Response => header::RESPONSE, + } + } +} + +impl TryInto for header::Flags { + type Error = BucketError; + fn try_into(self) -> Result { + if self.is_request() { + Ok(MessageType::Request) + } else if self.is_response() { + Ok(MessageType::Response) + } else { + Err(BucketError::UnknownFlags) + } + } +} + +/// A levin body +pub trait LevinBody: Sized { + /// Decodes the message from the data in the header + fn decode_message( + buf: &[u8], + typ: MessageType, + have_to_return: bool, + command: u32, + ) -> Result; + + /// Encodes the message + /// + /// returns: + /// return_code: i32, + /// command: u32, + /// have_to_return: bool, + /// message_type: MessageType + /// bytes: Bytes + fn encode(&self) -> Result<(i32, u32, bool, MessageType, Bytes), BucketError>; +} diff --git a/net/levin/src/message_sink.rs b/net/levin/src/message_sink.rs new file mode 100644 index 0000000..2c1f345 --- /dev/null +++ b/net/levin/src/message_sink.rs @@ -0,0 +1,64 @@ +//! This module provides a `MessageSink` struct, which is a stream of user defined +//! messages. + +use std::marker::PhantomData; +use std::pin::Pin; +use std::task::Poll; + +use futures::AsyncWrite; +use futures::Sink; +use pin_project::pin_project; + +use crate::bucket_sink::BucketSink; +use crate::Bucket; +use crate::BucketError; +use crate::BucketHead; +use crate::LevinBody; + +/// A Sink that converts levin messages to buckets and passes them onto the `BucketSink` +#[pin_project] +pub struct MessageSink { + #[pin] + bucket_sink: BucketSink, + phantom: PhantomData, +} + +impl Sink for MessageSink { + type Error = BucketError; + + fn poll_ready( + self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + self.project().bucket_sink.poll_ready(cx) + } + + fn start_send(self: Pin<&mut Self>, item: E) -> Result<(), Self::Error> { + let (return_code, command, have_to_return_data, flags, body) = item.encode()?; + let header = BucketHead::build( + body.len() as u64, + have_to_return_data, + command, + flags.into(), + return_code, + ); + + let bucket = Bucket { header, body }; + + self.project().bucket_sink.start_send(bucket) + } + + fn poll_flush( + self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + self.project().bucket_sink.poll_flush(cx) + } + + fn poll_close( + self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + self.project().bucket_sink.poll_close(cx) + } +} diff --git a/net/levin/src/message_stream.rs b/net/levin/src/message_stream.rs new file mode 100644 index 0000000..52bb77c --- /dev/null +++ b/net/levin/src/message_stream.rs @@ -0,0 +1,79 @@ +//! This contains +//! + +use std::marker::PhantomData; +use std::task::Poll; + +use futures::ready; +use futures::AsyncRead; +use futures::Stream; +use pin_project::pin_project; + +use crate::bucket_stream::BucketStream; +use crate::BucketError; +use crate::LevinBody; +use crate::LEVIN_SIGNATURE; +use crate::PROTOCOL_VERSION; + +/// A stream that reads from the underlying `BucketStream` and uses the the +/// methods on the `LevinBody` trait to decode the inner messages(bodies) +#[pin_project] +pub struct MessageStream { + #[pin] + bucket_stream: BucketStream, + phantom: PhantomData, +} + +impl MessageStream { + /// Creates a new stream from the provided `AsyncRead` + pub fn new(stream: S) -> Self { + MessageStream { + bucket_stream: BucketStream::new(stream), + phantom: PhantomData, + } + } +} + +impl Stream for MessageStream { + type Item = Result; + + fn poll_next( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> Poll> { + let this = self.project(); + match ready!(this.bucket_stream.poll_next(cx)).expect("BucketStream will never return None") + { + Err(e) => Poll::Ready(Some(Err(e))), + Ok(bucket) => { + if bucket.header.signature != LEVIN_SIGNATURE { + return Err(BucketError::IncorrectSignature(bucket.header.signature))?; + } + + if bucket.header.protocol_version != PROTOCOL_VERSION { + return Err(BucketError::UnknownProtocolVersion( + bucket.header.protocol_version, + ))?; + } + + if bucket.header.return_code < 0 + || (bucket.header.return_code == 0 && bucket.header.flags.is_response()) + { + return Err(BucketError::Error(bucket.header.return_code))?; + } + + if bucket.header.flags.is_dummy() { + cx.waker().wake_by_ref(); + return Poll::Pending; + } + + Poll::Ready(Some(D::decode_message( + &bucket.body, + bucket.header.flags.try_into()?, + bucket.header.have_to_return_data, + bucket.header.command, + ))) + } + } + } +} diff --git a/net/monero-wire/Cargo.toml b/net/monero-wire/Cargo.toml new file mode 100644 index 0000000..2b9cd32 --- /dev/null +++ b/net/monero-wire/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "monero-wire" +version = "0.1.0" +edition = "2021" +license = "MIT" +authors = ["Boog900"] +repository = "https://github.com/SyntheticBird45/cuprate/tree/main/net/monero-wire" + + +[dependencies] +serde = {version = "1.0", features =["derive"]} +serde_with = "2.2.0" +epee-serde = {git="https://github.com/Boog900/epee_serde.git"} +monero = "0.18.2" +levin = {path="../levin"} +byteorder = "1.4.3" +bytes = "1" +thiserror = "1.0.24" + diff --git a/net/monero-wire/src/internal_macros.rs b/net/monero-wire/src/internal_macros.rs new file mode 100644 index 0000000..5b453a8 --- /dev/null +++ b/net/monero-wire/src/internal_macros.rs @@ -0,0 +1,31 @@ +macro_rules! get_field_from_map { + ($map:ident, $field_name:expr) => { + $map.get($field_name) + .ok_or_else(|| serde::de::Error::missing_field($field_name))? + }; +} + +macro_rules! get_val_from_map { + ($map:ident, $field_name:expr, $get_fn:ident, $expected_ty:expr) => { + $map.get($field_name) + .ok_or_else(|| serde::de::Error::missing_field($field_name))? + .$get_fn() + .ok_or_else(|| { + serde::de::Error::invalid_type($map.get_value_type_as_unexpected(), &$expected_ty) + })? + }; +} + +macro_rules! get_internal_val { + ($value:ident, $get_fn:ident, $expected_ty:expr) => { + $value.$get_fn().ok_or_else(|| { + serde::de::Error::invalid_type($value.get_value_type_as_unexpected(), &$expected_ty) + })? + }; +} + +macro_rules! monero_decode_into_serde_err { + ($ty:ty, $buf:ident) => { + monero::consensus::deserialize::<$ty>($buf).map_err(serde::de::Error::custom)? + }; +} diff --git a/net/monero-wire/src/lib.rs b/net/monero-wire/src/lib.rs new file mode 100644 index 0000000..a60eca6 --- /dev/null +++ b/net/monero-wire/src/lib.rs @@ -0,0 +1,109 @@ +//! # Monero Wire +//! +//! A crate defining Monero network messages and network addresses, +//! built on top of the levin crate. +//! +//! ## License +//! +//! This project is licensed under the MIT License. + +// Coding conventions +#![forbid(unsafe_code)] +#![deny(non_upper_case_globals)] +#![deny(non_camel_case_types)] +#![deny(unused_mut)] +#![deny(missing_docs)] + +#[macro_use] +mod internal_macros; +pub mod messages; +pub mod network_address; + +pub use network_address::NetworkAddress; + +// re-exports +pub use levin; +pub use levin::message_sink::MessageSink; +pub use levin::message_stream::MessageStream; + +use levin::BucketError; + +/// The possible commands that can be in a levin header +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum P2pCommand { + // 100* admin commands + /// Handshake + Handshake, + /// TimedSync + TimedSync, + /// Ping + Ping, + /// SupportFlags + SupportFlags, + + // 200* protocol commands + /// NewBlock + NewBlock, + /// NewTransactions + NewTransactions, + /// RequestGetObject + RequestGetObject, + /// ResponseGetObject + ResponseGetObject, + /// RequestChain + RequestChain, + /// ResponseChainEntry + ResponseChainEntry, + /// NewFluffyBlock + NewFluffyBlock, + /// RequestFluffyMissingTx + RequestFluffyMissingTx, + /// GetTxPoolComplement + GetTxPoolComplement, +} + +impl TryFrom for P2pCommand { + type Error = BucketError; + + fn try_from(value: u32) -> Result { + match value { + 1001 => Ok(P2pCommand::Handshake), + 1002 => Ok(P2pCommand::TimedSync), + 1003 => Ok(P2pCommand::Ping), + 1007 => Ok(P2pCommand::SupportFlags), + + 2001 => Ok(P2pCommand::NewBlock), + 2002 => Ok(P2pCommand::NewTransactions), + 2003 => Ok(P2pCommand::RequestGetObject), + 2004 => Ok(P2pCommand::ResponseGetObject), + 2006 => Ok(P2pCommand::RequestChain), + 2007 => Ok(P2pCommand::ResponseChainEntry), + 2008 => Ok(P2pCommand::NewFluffyBlock), + 2009 => Ok(P2pCommand::RequestFluffyMissingTx), + 2010 => Ok(P2pCommand::GetTxPoolComplement), + + _ => Err(BucketError::UnsupportedP2pCommand(value)), + } + } +} + +impl From for u32 { + fn from(val: P2pCommand) -> Self { + match val { + P2pCommand::Handshake => 1001, + P2pCommand::TimedSync => 1002, + P2pCommand::Ping => 1003, + P2pCommand::SupportFlags => 1007, + + P2pCommand::NewBlock => 2001, + P2pCommand::NewTransactions => 2002, + P2pCommand::RequestGetObject => 2003, + P2pCommand::ResponseGetObject => 2004, + P2pCommand::RequestChain => 2006, + P2pCommand::ResponseChainEntry => 2007, + P2pCommand::NewFluffyBlock => 2008, + P2pCommand::RequestFluffyMissingTx => 2009, + P2pCommand::GetTxPoolComplement => 2010, + } + } +} diff --git a/net/monero-wire/src/messages.rs b/net/monero-wire/src/messages.rs new file mode 100644 index 0000000..55c45fb --- /dev/null +++ b/net/monero-wire/src/messages.rs @@ -0,0 +1,323 @@ +//! This module defines a Monero `Message` enum which contains +//! every possible Monero network message (levin body) + +pub mod admin; +pub mod common; +pub mod protocol; + +pub use common::{BasicNodeData, CoreSyncData, PeerID, PeerListEntryBase}; + +use bytes::Bytes; +use levin::BucketError; +use levin::MessageType; + +use crate::P2pCommand; + +fn zero_val>() -> T { + T::from(0_u8) +} + +fn default_true() -> bool { + true +} + +fn default_false() -> bool { + false +} + +/// A message request +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum MessageRequest { + /// Handshake + Handshake(admin::HandshakeRequest), + /// TimedSync + TimedSync(admin::TimedSyncRequest), + /// Ping + Ping(admin::PingRequest), + /// SupportFlags + SupportFlags(admin::SupportFlagsRequest), +} + +/// A message response +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum MessageResponse { + /// Handshake + Handshake(admin::HandshakeResponse), + /// TimedSync + TimedSync(admin::TimedSyncResponse), + /// Ping + Ping(admin::PingResponse), + /// SupportFlags + SupportFlags(admin::SupportFlagsResponse), +} + +/// A messages notification +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum MessageNotification { + /// NewBlock + NewBlock(protocol::NewBlock), + /// NewTransactions + NewTransactions(protocol::NewTransactions), + /// RequestGetObject + RequestGetObject(protocol::GetObjectsRequest), + /// ResponseGetObject + ResponseGetObject(protocol::GetObjectsResponse), + /// RequestChain + RequestChain(protocol::ChainRequest), + /// ResponseChainEntry + ResponseChainEntry(protocol::ChainResponse), + /// NewFluffyBlock + NewFluffyBlock(protocol::NewFluffyBlock), + /// RequestFluffyMissingTx + RequestFluffyMissingTx(protocol::FluffyMissingTransactionsRequest), + /// GetTxPoolComplement + GetTxPoolComplement(protocol::TxPoolCompliment), +} + +/// A Monero Message (levin body) +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Message { + /// Request + Request(MessageRequest), + /// Response + Response(MessageResponse), + /// Notification + Notification(Box), // check benefits/ drawbacks of doing this, im just boxing it for now to satisfy clippy +} + +fn epee_encode_error_to_levin(err: epee_serde::Error) -> BucketError { + BucketError::FailedToEncodeBucketBody(err.to_string()) +} + +fn encode_message(message: &T) -> Result, BucketError> { + epee_serde::to_bytes(message).map_err(epee_encode_error_to_levin) +} + +fn epee_decode_error_to_levin(err: epee_serde::Error) -> BucketError { + BucketError::FailedToDecodeBucketBody(err.to_string()) +} + +fn decode_message(buf: &[u8]) -> Result { + epee_serde::from_bytes(buf).map_err(epee_decode_error_to_levin) +} + +impl levin::LevinBody for Message { + fn decode_message( + buf: &[u8], + typ: MessageType, + have_to_return: bool, + command: u32, + ) -> Result { + let command = P2pCommand::try_from(command)?; + + Ok(match typ { + MessageType::Response => Message::Response(match command { + P2pCommand::Handshake => MessageResponse::Handshake(decode_message(buf)?), + P2pCommand::TimedSync => MessageResponse::TimedSync(decode_message(buf)?), + P2pCommand::Ping => MessageResponse::Ping(decode_message(buf)?), + P2pCommand::SupportFlags => MessageResponse::SupportFlags(decode_message(buf)?), + _ => { + return Err(levin::BucketError::FailedToDecodeBucketBody( + "Invalid header flag/command/have_to_return combination".to_string(), + )) + } + }), + + MessageType::Request if have_to_return => Message::Request(match command { + P2pCommand::Handshake => MessageRequest::Handshake(decode_message(buf)?), + P2pCommand::TimedSync => MessageRequest::TimedSync(decode_message(buf)?), + P2pCommand::Ping => MessageRequest::Ping(admin::PingRequest), + P2pCommand::SupportFlags => { + MessageRequest::SupportFlags(admin::SupportFlagsRequest) + } + _ => { + return Err(levin::BucketError::FailedToDecodeBucketBody( + "Invalid header flag/command/have_to_return combination".to_string(), + )) + } + }), + + MessageType::Request if !have_to_return => { + Message::Notification(Box::new(match command { + P2pCommand::NewBlock => MessageNotification::NewBlock(decode_message(buf)?), + P2pCommand::NewTransactions => { + MessageNotification::NewTransactions(decode_message(buf)?) + } + P2pCommand::RequestGetObject => { + MessageNotification::RequestGetObject(decode_message(buf)?) + } + P2pCommand::ResponseGetObject => { + MessageNotification::ResponseGetObject(decode_message(buf)?) + } + P2pCommand::RequestChain => { + MessageNotification::RequestChain(decode_message(buf)?) + } + P2pCommand::ResponseChainEntry => { + MessageNotification::ResponseChainEntry(decode_message(buf)?) + } + P2pCommand::NewFluffyBlock => { + MessageNotification::NewFluffyBlock(decode_message(buf)?) + } + P2pCommand::RequestFluffyMissingTx => { + MessageNotification::RequestFluffyMissingTx(decode_message(buf)?) + } + P2pCommand::GetTxPoolComplement => { + MessageNotification::GetTxPoolComplement(decode_message(buf)?) + } + _ => { + return Err(levin::BucketError::FailedToDecodeBucketBody( + "Invalid header flag/command/have_to_return combination".to_string(), + )) + } + })) + } + _ => unreachable!("All typs are handleded"), + }) + } + + fn encode(&self) -> Result<(i32, u32, bool, MessageType, Bytes), BucketError> { + let return_code; + let command; + let have_to_return_data; + let flag; + let bytes; + + match self { + Message::Request(req) => { + return_code = 0; + have_to_return_data = true; + flag = MessageType::Request; + match req { + MessageRequest::Handshake(handshake) => { + command = P2pCommand::Handshake; + bytes = encode_message(handshake)?; + } + MessageRequest::TimedSync(timedsync) => { + command = P2pCommand::TimedSync; + bytes = encode_message(timedsync)?; + } + MessageRequest::Ping(_) => { + command = P2pCommand::Ping; + bytes = Vec::new(); + } + MessageRequest::SupportFlags(_) => { + command = P2pCommand::SupportFlags; + bytes = Vec::new(); + } + } + } + Message::Response(res) => { + return_code = 1; + have_to_return_data = false; + flag = MessageType::Response; + match res { + MessageResponse::Handshake(handshake) => { + command = P2pCommand::Handshake; + bytes = encode_message(handshake)?; + } + MessageResponse::TimedSync(timed_sync) => { + command = P2pCommand::TimedSync; + bytes = encode_message(timed_sync)?; + } + MessageResponse::Ping(ping) => { + command = P2pCommand::Ping; + bytes = encode_message(ping)?; + } + MessageResponse::SupportFlags(support_flags) => { + command = P2pCommand::SupportFlags; + bytes = encode_message(support_flags)?; + } + } + } + Message::Notification(noti) => { + return_code = 0; + have_to_return_data = false; + flag = MessageType::Response; + match noti.as_ref() { + MessageNotification::NewBlock(new_block) => { + command = P2pCommand::NewBlock; + bytes = encode_message(new_block)?; + } + MessageNotification::NewTransactions(new_txs) => { + command = P2pCommand::NewTransactions; + bytes = encode_message(new_txs)?; + } + MessageNotification::RequestGetObject(obj) => { + command = P2pCommand::RequestGetObject; + bytes = encode_message(obj)?; + } + MessageNotification::ResponseGetObject(obj) => { + command = P2pCommand::ResponseGetObject; + bytes = encode_message(obj)?; + } + MessageNotification::RequestChain(chain) => { + command = P2pCommand::RequestChain; + bytes = encode_message(chain)?; + } + MessageNotification::ResponseChainEntry(chain_entry) => { + command = P2pCommand::ResponseChainEntry; + bytes = encode_message(chain_entry)?; + } + MessageNotification::NewFluffyBlock(fluffy_block) => { + command = P2pCommand::NewFluffyBlock; + bytes = encode_message(fluffy_block)?; + } + MessageNotification::RequestFluffyMissingTx(txs) => { + command = P2pCommand::RequestFluffyMissingTx; + bytes = encode_message(txs)?; + } + MessageNotification::GetTxPoolComplement(txpool) => { + command = P2pCommand::GetTxPoolComplement; + bytes = encode_message(txpool)?; + } + } + } + } + return Ok(( + return_code, + command.into(), + have_to_return_data, + flag, + bytes.into(), + )); + } +} + +#[cfg(test)] +mod tests { + use super::Message; + use levin::{LevinBody, MessageType}; + + #[test] + fn decode_handshake_request() { + let buf = [ + 1, 17, 1, 1, 1, 1, 2, 1, 1, 12, 9, 110, 111, 100, 101, 95, 100, 97, 116, 97, 12, 24, 7, + 109, 121, 95, 112, 111, 114, 116, 6, 168, 70, 0, 0, 10, 110, 101, 116, 119, 111, 114, + 107, 95, 105, 100, 10, 64, 18, 48, 241, 113, 97, 4, 65, 97, 23, 49, 0, 130, 22, 161, + 161, 16, 7, 112, 101, 101, 114, 95, 105, 100, 5, 153, 5, 227, 61, 188, 214, 159, 10, + 13, 115, 117, 112, 112, 111, 114, 116, 95, 102, 108, 97, 103, 115, 6, 1, 0, 0, 0, 8, + 114, 112, 99, 95, 112, 111, 114, 116, 7, 0, 0, 20, 114, 112, 99, 95, 99, 114, 101, 100, + 105, 116, 115, 95, 112, 101, 114, 95, 104, 97, 115, 104, 6, 0, 0, 0, 0, 12, 112, 97, + 121, 108, 111, 97, 100, 95, 100, 97, 116, 97, 12, 24, 21, 99, 117, 109, 117, 108, 97, + 116, 105, 118, 101, 95, 100, 105, 102, 102, 105, 99, 117, 108, 116, 121, 5, 59, 90, + 163, 153, 0, 0, 0, 0, 27, 99, 117, 109, 117, 108, 97, 116, 105, 118, 101, 95, 100, 105, + 102, 102, 105, 99, 117, 108, 116, 121, 95, 116, 111, 112, 54, 52, 5, 0, 0, 0, 0, 0, 0, + 0, 0, 14, 99, 117, 114, 114, 101, 110, 116, 95, 104, 101, 105, 103, 104, 116, 5, 190, + 50, 0, 0, 0, 0, 0, 0, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, + 0, 0, 0, 0, 6, 116, 111, 112, 95, 105, 100, 10, 128, 230, 40, 186, 45, 79, 79, 224, + 164, 117, 133, 84, 130, 185, 94, 4, 1, 57, 126, 74, 145, 238, 238, 122, 44, 214, 85, + 129, 237, 230, 14, 67, 218, 11, 116, 111, 112, 95, 118, 101, 114, 115, 105, 111, 110, + 8, 1, 18, 108, 111, 99, 97, 108, 95, 112, 101, 101, 114, 108, 105, 115, 116, 95, 110, + 101, 119, 140, 4, 24, 3, 97, 100, 114, 12, 8, 4, 116, 121, 112, 101, 8, 1, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 225, 219, 21, 0, 6, 109, 95, 112, 111, 114, + 116, 7, 0, 0, 2, 105, 100, 5, 0, 0, 0, 0, 0, 0, 0, 0, 9, 108, 97, 115, 116, 95, 115, + 101, 101, 110, 1, 0, 0, 0, 0, 0, 0, 0, 0, 12, 112, 114, 117, 110, 105, 110, 103, 95, + 115, 101, 101, 100, 6, 0, 0, 0, 0, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 0, 0, + 20, 114, 112, 99, 95, 99, 114, 101, 100, 105, 116, 115, 95, 112, 101, 114, 95, 104, 97, + 115, 104, 6, 0, 0, 0, 0, + ]; + + let message = Message::decode_message(&buf, MessageType::Request, true, 1001); + println!("{:?}", message); + } +} diff --git a/net/monero-wire/src/messages/admin.rs b/net/monero-wire/src/messages/admin.rs new file mode 100644 index 0000000..9ff110e --- /dev/null +++ b/net/monero-wire/src/messages/admin.rs @@ -0,0 +1,939 @@ +//! This module defines Monero admin messages +//! +//! Admin message requests must be responded to in order unlike +//! protocol messages. + +use serde::{Deserialize, Serialize}; + +use super::{ + common::{BasicNodeData, CoreSyncData, PeerListEntryBase}, + PeerID, +}; + +/// A Handshake Request +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct HandshakeRequest { + /// Basic Node Data + pub node_data: BasicNodeData, + /// Core Sync Data + pub payload_data: CoreSyncData, +} + +/// A Handshake Response +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct HandshakeResponse { + /// Basic Node Data + pub node_data: BasicNodeData, + /// Core Sync Data + pub payload_data: CoreSyncData, + /// PeerList + pub local_peerlist_new: Vec, +} + +/// A TimedSync Request +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct TimedSyncRequest { + /// Core Sync Data + pub payload_data: CoreSyncData, +} + +/// A TimedSync Response +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct TimedSyncResponse { + /// Core Sync Data + pub payload_data: CoreSyncData, + /// PeerList + pub local_peerlist_new: Vec, +} + +/// The status field of an okay ping response +pub const PING_OK_RESPONSE_STATUS_TEXT: &str = "OK"; + +/// A Ping Request +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct PingRequest; + +/// A Ping Response +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct PingResponse { + /// Status: should be `PING_OK_RESPONSE_STATUS_TEXT` + pub status: String, + /// Peer ID + pub peer_id: PeerID, +} + +/// A Support Flags Request +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct SupportFlagsRequest; + +/// A Support Flags Response +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct SupportFlagsResponse { + /// Support Flags + pub support_flags: u32, +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + + use monero::Hash; + + use super::{BasicNodeData, CoreSyncData, HandshakeRequest, HandshakeResponse}; + use crate::messages::common::PeerID; + + #[test] + fn serde_handshake_req() { + let bytes = [ + 1, 17, 1, 1, 1, 1, 2, 1, 1, 8, 9, 110, 111, 100, 101, 95, 100, 97, 116, 97, 12, 16, 7, + 109, 121, 95, 112, 111, 114, 116, 6, 0, 0, 0, 0, 10, 110, 101, 116, 119, 111, 114, 107, + 95, 105, 100, 10, 64, 18, 48, 241, 113, 97, 4, 65, 97, 23, 49, 0, 130, 22, 161, 161, + 16, 7, 112, 101, 101, 114, 95, 105, 100, 5, 95, 135, 39, 132, 254, 187, 55, 134, 13, + 115, 117, 112, 112, 111, 114, 116, 95, 102, 108, 97, 103, 115, 6, 1, 0, 0, 0, 12, 112, + 97, 121, 108, 111, 97, 100, 95, 100, 97, 116, 97, 12, 16, 21, 99, 117, 109, 117, 108, + 97, 116, 105, 118, 101, 95, 100, 105, 102, 102, 105, 99, 117, 108, 116, 121, 5, 1, 0, + 0, 0, 0, 0, 0, 0, 14, 99, 117, 114, 114, 101, 110, 116, 95, 104, 101, 105, 103, 104, + 116, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 116, 111, 112, 95, 105, 100, 10, 128, 65, 128, 21, + 187, 154, 233, 130, 161, 151, 93, 167, 215, 146, 119, 194, 112, 87, 39, 165, 104, 148, + 186, 15, 178, 70, 173, 170, 187, 31, 70, 50, 227, 11, 116, 111, 112, 95, 118, 101, 114, + 115, 105, 111, 110, 8, 1, + ]; + let handshake: HandshakeRequest = epee_serde::from_bytes(bytes).unwrap(); + let basic_node_data = BasicNodeData { + my_port: 0, + network_id: [ + 18, 48, 241, 113, 97, 4, 65, 97, 23, 49, 0, 130, 22, 161, 161, 16, + ], + peer_id: PeerID(9671405426614699871), + support_flags: 1, + rpc_port: 0, + rpc_credits_per_hash: 0, + }; + + let core_sync_data = CoreSyncData { + cumulative_difficulty: 1, + cumulative_difficulty_top64: 0, + current_height: 0, + pruning_seed: 0, + top_id: Hash::from_str( + "0x418015bb9ae982a1975da7d79277c2705727a56894ba0fb246adaabb1f4632e3", + ) + .unwrap(), + top_version: 1, + }; + + assert_eq!(basic_node_data, handshake.node_data); + assert_eq!(core_sync_data, handshake.payload_data); + + let encoded_bytes = epee_serde::to_bytes(&handshake).unwrap(); + let handshake_2: HandshakeRequest = epee_serde::from_bytes(encoded_bytes).unwrap(); + + assert_eq!(handshake, handshake_2); + } + + #[test] + fn serde_handshake_res() { + let bytes = [ + 1, 17, 1, 1, 1, 1, 2, 1, 1, 12, 18, 108, 111, 99, 97, 108, 95, 112, 101, 101, 114, 108, + 105, 115, 116, 95, 110, 101, 119, 140, 233, 3, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 107, 200, 125, 246, 6, 109, 95, 112, 111, + 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 136, 104, 95, 61, + 247, 215, 186, 88, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, + 105, 112, 6, 184, 166, 147, 112, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 104, 35, 236, 206, 255, 98, 40, 247, 8, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 94, 23, 147, + 238, 6, 109, 95, 112, 111, 114, 116, 7, 64, 9, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 204, 213, 226, 217, 141, 205, 23, 171, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, + 65, 144, 135, 125, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, + 8, 2, 2, 105, 100, 5, 142, 211, 149, 235, 68, 76, 58, 116, 8, 114, 112, 99, 95, 112, + 111, 114, 116, 7, 169, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, + 109, 95, 105, 112, 6, 85, 25, 198, 233, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, + 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 239, 118, 5, 143, 245, 175, 79, 79, 12, 3, + 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 128, 199, + 45, 242, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, + 105, 100, 5, 53, 123, 81, 158, 161, 118, 88, 49, 8, 114, 112, 99, 95, 112, 111, 114, + 116, 7, 169, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, + 105, 112, 6, 49, 12, 239, 176, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, + 112, 101, 8, 1, 2, 105, 100, 5, 231, 115, 240, 106, 33, 156, 129, 168, 12, 3, 97, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 72, 83, 1, 29, 6, + 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, + 163, 230, 52, 192, 29, 175, 184, 138, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, + 101, 101, 100, 6, 133, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, + 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 24, 46, 131, 31, + 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, + 5, 254, 139, 52, 145, 46, 192, 114, 218, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 144, + 76, 58, 247, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, + 2, 105, 100, 5, 22, 231, 179, 203, 218, 156, 64, 157, 12, 112, 114, 117, 110, 105, 110, + 103, 95, 115, 101, 101, 100, 6, 128, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, + 46, 4, 27, 39, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, + 2, 105, 100, 5, 190, 246, 23, 85, 132, 101, 46, 120, 12, 3, 97, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 93, 95, 228, 51, 6, 109, 95, 112, 111, + 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 76, 184, 195, 205, + 119, 55, 205, 223, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 8, 3, 97, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 89, 36, 78, 249, 6, + 109, 95, 112, 111, 114, 116, 7, 40, 230, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, + 146, 84, 128, 27, 45, 173, 110, 233, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, + 12, 8, 4, 109, 95, 105, 112, 6, 159, 203, 65, 163, 6, 109, 95, 112, 111, 114, 116, 7, + 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 36, 140, 127, 49, 80, 143, 75, + 170, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 12, 3, 97, 100, 114, 12, 8, + 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 89, 163, 225, 22, 6, 109, 95, + 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 202, 167, + 239, 104, 191, 245, 206, 114, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, + 100, 6, 128, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, + 95, 105, 112, 6, 51, 38, 53, 106, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 26, 47, 180, 164, 45, 11, 4, 137, 12, 3, 97, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 98, 28, 252, 84, 6, + 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, + 109, 204, 107, 31, 61, 229, 138, 61, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, + 101, 101, 100, 6, 130, 1, 0, 0, 16, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, + 8, 4, 109, 95, 105, 112, 6, 35, 142, 222, 141, 6, 109, 95, 112, 111, 114, 116, 7, 160, + 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 74, 23, 146, 223, 157, 219, 198, 96, + 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 135, 1, 0, 0, 8, 114, + 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 168, 119, 134, 54, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 210, 66, 174, 96, 27, + 169, 14, 141, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, + 112, 6, 24, 246, 38, 201, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, + 101, 8, 1, 2, 105, 100, 5, 29, 41, 255, 104, 159, 199, 248, 152, 8, 3, 97, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 255, 255, 5, 161, 65, 201, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 2, 2, 105, 100, 5, 97, 17, 31, 195, 85, 103, 254, 119, 8, 3, 97, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 76, 89, 170, 52, 6, + 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, + 191, 241, 183, 135, 6, 109, 186, 8, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 184, 153, + 84, 228, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, 2, + 105, 100, 5, 211, 11, 202, 189, 127, 164, 118, 13, 16, 3, 97, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 66, 42, 82, 58, 6, 109, 95, 112, 111, + 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 209, 217, 109, 131, + 173, 212, 169, 138, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, + 135, 1, 0, 0, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 8, 3, 97, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 70, 93, 166, 98, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 35, + 43, 193, 141, 6, 220, 30, 115, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, + 4, 109, 95, 105, 112, 6, 99, 17, 41, 20, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, + 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 56, 45, 55, 79, 80, 200, 73, 54, 8, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 130, 180, 116, + 214, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 101, 87, 57, 29, 16, 210, 163, 114, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, + 114, 12, 8, 4, 109, 95, 105, 112, 6, 148, 163, 81, 34, 6, 109, 95, 112, 111, 114, 116, + 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 118, 209, 9, 62, 203, 181, + 144, 55, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, + 6, 67, 85, 160, 39, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, + 8, 1, 2, 105, 100, 5, 8, 54, 90, 44, 129, 203, 30, 229, 8, 114, 112, 99, 95, 112, 111, + 114, 116, 7, 161, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, + 95, 105, 112, 6, 162, 218, 65, 223, 6, 109, 95, 112, 111, 114, 116, 7, 163, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 8, 95, 132, 221, 20, 172, 44, 131, 8, 3, 97, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 83, 78, 142, 101, 6, + 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, + 53, 254, 109, 4, 238, 54, 246, 88, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, + 12, 8, 4, 109, 95, 105, 112, 6, 18, 169, 212, 248, 6, 109, 95, 112, 111, 114, 116, 7, + 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 239, 181, 136, 45, 48, 0, 23, + 111, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 161, 70, 8, 3, 97, 100, 114, 12, 8, 4, + 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 138, 201, 50, 228, 6, 109, 95, 112, + 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 100, 143, 145, + 170, 221, 44, 134, 40, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, + 95, 105, 112, 6, 96, 2, 101, 49, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 175, 162, 146, 137, 96, 124, 179, 123, 8, 114, + 112, 99, 95, 112, 111, 114, 116, 7, 161, 70, 16, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 194, 55, 15, 70, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 200, 230, 46, 22, 61, + 113, 146, 207, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 131, + 1, 0, 0, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 8, 3, 97, 100, 114, 12, + 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 255, 255, 24, 144, 51, 151, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 2, 2, 105, 100, 5, 92, 225, 176, 105, 146, 76, 126, 246, 8, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 51, 89, 43, 165, + 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, + 5, 227, 169, 44, 172, 218, 27, 134, 20, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 138, + 201, 50, 11, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, + 2, 105, 100, 5, 77, 159, 65, 201, 154, 203, 137, 189, 8, 3, 97, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 37, 19, 221, 165, 6, 109, 95, 112, 111, + 114, 116, 7, 101, 225, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 16, 236, 61, 198, + 179, 107, 122, 230, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, + 95, 105, 112, 6, 211, 104, 25, 222, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 141, 18, 233, 140, 158, 178, 117, 2, 12, 112, 114, + 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 133, 1, 0, 0, 8, 3, 97, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 79, 225, 232, 232, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 25, + 41, 192, 83, 178, 152, 49, 39, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, + 4, 109, 95, 105, 112, 6, 45, 44, 224, 220, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, + 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 43, 192, 235, 1, 175, 51, 244, 209, 12, + 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 133, 1, 0, 0, 8, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 44, 198, 160, + 153, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 255, 168, 200, 48, 53, 200, 228, 34, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 85, 214, 100, 187, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 237, 118, 70, 209, 142, + 252, 124, 105, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 132, + 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, + 6, 104, 52, 169, 164, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, + 101, 8, 1, 2, 105, 100, 5, 7, 180, 60, 132, 208, 115, 38, 78, 8, 3, 97, 100, 114, 12, + 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 255, 255, 188, 214, 129, 182, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 2, 2, 105, 100, 5, 6, 110, 8, 120, 108, 89, 215, 109, 8, 3, 97, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 81, 79, 96, 58, 6, + 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, + 29, 242, 12, 182, 32, 31, 164, 147, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, + 12, 8, 4, 109, 95, 105, 112, 6, 50, 246, 254, 202, 6, 109, 95, 112, 111, 114, 116, 7, + 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 200, 152, 38, 71, 152, 168, 148, + 130, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, + 75, 168, 213, 32, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, + 1, 2, 105, 100, 5, 89, 66, 99, 25, 23, 47, 236, 47, 12, 3, 97, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 80, 217, 6, 170, 6, 109, 95, 112, 111, + 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 25, 65, 171, 45, 39, + 65, 82, 0, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 16, 3, 97, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 24, 27, 96, 242, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 11, 5, + 248, 49, 46, 9, 138, 92, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, + 6, 133, 1, 0, 0, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 8, 3, 97, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 72, 239, 241, 242, 6, + 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, + 77, 192, 17, 161, 34, 186, 222, 123, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, + 12, 8, 4, 109, 95, 105, 112, 6, 144, 217, 70, 139, 6, 109, 95, 112, 111, 114, 116, 7, + 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 144, 82, 41, 18, 67, 173, 224, + 251, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 129, 1, 0, 0, + 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 24, + 216, 239, 98, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, + 2, 105, 100, 5, 135, 151, 188, 127, 59, 20, 95, 161, 12, 112, 114, 117, 110, 105, 110, + 103, 95, 115, 101, 101, 100, 6, 134, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 91, 65, 190, 110, 6, 109, 95, 112, 111, 114, + 116, 7, 169, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 96, 33, 127, 102, 27, + 224, 111, 185, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 134, 122, 61, 72, 6, 109, 95, + 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 29, 223, + 119, 202, 113, 165, 81, 7, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 8, 3, + 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 37, 15, 95, + 252, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 219, 64, 229, 115, 235, 126, 213, 173, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 178, 62, 9, 149, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 151, 68, 31, 187, 63, + 163, 185, 18, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 8, 3, 97, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 23, 115, 236, 180, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 205, + 12, 26, 50, 3, 165, 53, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, + 109, 95, 105, 112, 6, 71, 78, 74, 138, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, + 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 206, 121, 181, 161, 29, 110, 53, 18, 8, 3, + 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 73, 216, + 104, 205, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, + 105, 100, 5, 243, 216, 53, 122, 144, 182, 239, 255, 8, 3, 97, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 85, 241, 6, 106, 6, 109, 95, 112, 111, + 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 249, 166, 55, 155, + 51, 129, 124, 12, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, + 105, 112, 6, 79, 199, 36, 70, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, + 112, 101, 8, 1, 2, 105, 100, 5, 43, 26, 130, 68, 205, 92, 233, 62, 12, 3, 97, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 255, 255, 73, 113, 165, 163, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, + 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 125, 189, 171, 153, 83, 86, 245, 62, 12, 112, + 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 132, 1, 0, 0, 8, 3, 97, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 137, 118, 214, 52, 6, + 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, + 28, 94, 51, 157, 189, 105, 178, 114, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, + 12, 8, 4, 109, 95, 105, 112, 6, 75, 82, 185, 108, 6, 109, 95, 112, 111, 114, 116, 7, + 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 76, 196, 240, 134, 116, 222, 86, + 142, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 68, 118, 240, 19, 6, 109, 95, 112, 111, + 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 213, 192, 104, 120, + 74, 119, 165, 194, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, + 105, 112, 6, 51, 83, 179, 106, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, + 112, 101, 8, 1, 2, 105, 100, 5, 27, 33, 186, 12, 194, 25, 75, 31, 8, 3, 97, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 178, 162, 153, 157, 6, + 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, + 4, 66, 90, 148, 24, 80, 49, 170, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, + 8, 4, 109, 95, 105, 112, 6, 92, 170, 92, 127, 6, 109, 95, 112, 111, 114, 116, 7, 160, + 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 213, 45, 208, 229, 123, 172, 173, 241, + 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 193, + 72, 32, 187, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, + 2, 105, 100, 5, 50, 33, 217, 128, 43, 173, 61, 224, 8, 3, 97, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 24, 218, 108, 30, 6, 109, 95, 112, 111, + 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 115, 212, 228, 103, + 43, 138, 93, 217, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, + 105, 112, 6, 163, 172, 90, 168, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 135, 51, 116, 56, 95, 226, 184, 221, 12, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 255, 255, 5, 39, 91, 20, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, + 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 10, 81, 175, 58, 168, 40, 36, 112, 12, + 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 131, 1, 0, 0, 12, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 255, 255, 45, 142, 235, 46, 6, 109, 95, 112, 111, 114, 116, 7, 160, + 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 183, 57, 59, 58, 77, 216, 203, 0, 12, + 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 130, 1, 0, 0, 16, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 185, 157, 160, + 119, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 115, 192, 241, 99, 119, 228, 23, 129, 20, 114, 112, 99, 95, 99, 114, 101, 100, + 105, 116, 115, 95, 112, 101, 114, 95, 104, 97, 115, 104, 6, 0, 0, 64, 0, 8, 114, 112, + 99, 95, 112, 111, 114, 116, 7, 169, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, + 114, 12, 8, 4, 109, 95, 105, 112, 6, 5, 129, 54, 131, 6, 109, 95, 112, 111, 114, 116, + 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 180, 136, 168, 128, 35, 8, + 229, 160, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, + 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 185, 10, 68, 240, 6, 109, 95, 112, 111, + 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 105, 127, 240, 231, + 209, 2, 20, 136, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, + 105, 112, 6, 32, 221, 180, 229, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 107, 14, 156, 75, 92, 180, 143, 152, 8, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 218, 88, 21, + 188, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 51, 234, 157, 182, 229, 103, 39, 88, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 5, 161, 73, 151, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 209, 162, 121, 222, 241, + 125, 142, 156, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, + 112, 6, 162, 226, 61, 8, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, + 101, 8, 1, 2, 105, 100, 5, 6, 64, 210, 168, 209, 134, 142, 135, 16, 3, 97, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 104, 238, 128, 24, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 252, + 199, 163, 220, 223, 220, 85, 167, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, + 101, 100, 6, 132, 1, 0, 0, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 12, 3, + 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 89, 147, + 109, 91, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, + 105, 100, 5, 90, 73, 143, 67, 50, 148, 50, 51, 8, 114, 112, 99, 95, 112, 111, 114, 116, + 7, 169, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, + 112, 6, 60, 225, 148, 220, 6, 109, 95, 112, 111, 114, 116, 7, 169, 70, 4, 116, 121, + 112, 101, 8, 1, 2, 105, 100, 5, 246, 236, 191, 85, 5, 65, 238, 143, 8, 3, 97, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 84, 255, 235, 77, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 204, + 171, 86, 75, 156, 202, 194, 17, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, + 8, 4, 109, 95, 105, 112, 6, 172, 86, 75, 188, 6, 109, 95, 112, 111, 114, 116, 7, 160, + 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 102, 18, 220, 13, 62, 231, 50, 12, 12, + 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 128, 1, 0, 0, 8, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 47, 154, 174, + 191, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 142, 90, 23, 242, 187, 113, 45, 135, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 162, 253, 155, 86, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 115, 140, 18, 86, 209, 1, + 136, 191, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, + 6, 192, 42, 253, 215, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, + 101, 8, 1, 2, 105, 100, 5, 172, 48, 83, 16, 150, 49, 179, 117, 8, 3, 97, 100, 114, 12, + 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 213, 239, 210, 144, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 191, + 25, 48, 149, 62, 193, 163, 51, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, + 4, 109, 95, 105, 112, 6, 213, 251, 235, 252, 6, 109, 95, 112, 111, 114, 116, 7, 160, + 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 30, 76, 94, 11, 19, 53, 222, 168, 8, + 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 82, 101, + 246, 21, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, + 105, 100, 5, 79, 214, 218, 34, 12, 184, 235, 67, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 88, 19, 42, 245, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 252, 148, 134, 97, 173, + 59, 174, 174, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, + 112, 6, 94, 63, 121, 77, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, + 101, 8, 1, 2, 105, 100, 5, 218, 250, 149, 133, 175, 197, 220, 9, 12, 112, 114, 117, + 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 134, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, + 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 24, 49, 114, 184, 6, 109, 95, + 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 71, 65, + 104, 43, 162, 145, 13, 85, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, + 109, 95, 105, 112, 6, 76, 185, 18, 32, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, + 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 7, 159, 72, 170, 11, 137, 53, 215, 12, 112, + 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 135, 1, 0, 0, 8, 3, 97, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 68, 73, 201, 40, 6, + 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, + 172, 77, 69, 220, 58, 59, 195, 192, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 84, 255, + 235, 77, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, 2, + 105, 100, 5, 204, 171, 86, 75, 156, 202, 194, 17, 8, 3, 97, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 165, 227, 34, 105, 6, 109, 95, 112, 111, + 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 154, 230, 103, 180, + 139, 210, 99, 101, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, + 105, 112, 6, 35, 236, 113, 185, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 49, 104, 224, 149, 51, 239, 29, 76, 16, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 165, 22, 12, + 133, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 246, 50, 244, 226, 219, 198, 24, 105, 12, 112, 114, 117, 110, 105, 110, 103, + 95, 115, 101, 101, 100, 6, 130, 1, 0, 0, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, + 169, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, + 6, 94, 156, 174, 100, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, + 101, 8, 1, 2, 105, 100, 5, 183, 117, 141, 111, 95, 90, 58, 204, 12, 3, 97, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 5, 255, 100, 208, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 125, + 25, 139, 251, 139, 116, 172, 24, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 161, 70, + 16, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 86, + 94, 156, 130, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, + 2, 105, 100, 5, 181, 75, 11, 73, 214, 93, 48, 250, 12, 112, 114, 117, 110, 105, 110, + 103, 95, 115, 101, 101, 100, 6, 130, 1, 0, 0, 8, 114, 112, 99, 95, 112, 111, 114, 116, + 7, 169, 70, 16, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, + 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 93, 95, 230, 245, 6, 109, 95, 112, + 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 84, 157, 243, + 239, 183, 35, 54, 0, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, + 130, 1, 0, 0, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 8, 3, 97, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 86, 14, 58, 98, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 131, + 145, 164, 127, 110, 147, 147, 166, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, + 8, 4, 109, 95, 105, 112, 6, 52, 15, 111, 162, 6, 109, 95, 112, 111, 114, 116, 7, 160, + 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 196, 112, 61, 95, 122, 150, 241, 171, + 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 135, 181, 164, 52, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 52, 20, 78, 121, 22, 214, + 174, 79, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, + 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 159, 69, 121, 11, 6, 109, 95, 112, 111, + 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 205, 44, 250, 54, + 193, 111, 54, 245, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, + 128, 1, 0, 0, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, + 112, 6, 185, 241, 197, 18, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, + 112, 101, 8, 1, 2, 105, 100, 5, 161, 144, 210, 66, 72, 38, 182, 154, 8, 114, 112, 99, + 95, 112, 111, 114, 116, 7, 161, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, + 12, 8, 4, 109, 95, 105, 112, 6, 24, 165, 109, 172, 6, 109, 95, 112, 111, 114, 116, 7, + 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 139, 244, 62, 181, 35, 101, 190, + 130, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, + 95, 168, 216, 7, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, + 1, 2, 105, 100, 5, 113, 28, 114, 184, 37, 154, 224, 95, 8, 3, 97, 100, 114, 12, 8, 4, + 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 138, 201, 120, 71, 6, 109, 95, 112, + 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 189, 245, 211, + 35, 245, 56, 24, 89, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, + 95, 105, 112, 6, 91, 206, 14, 98, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 43, 84, 225, 240, 218, 249, 219, 193, 8, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 61, 245, 153, + 149, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 111, 172, 135, 36, 174, 143, 223, 112, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, + 31, 28, 25, 99, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, + 2, 2, 105, 100, 5, 129, 160, 102, 202, 168, 75, 67, 246, 8, 3, 97, 100, 114, 12, 8, 4, + 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 217, 168, 137, 14, 6, 109, 95, 112, + 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 198, 134, 120, + 100, 110, 70, 149, 242, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, + 95, 105, 112, 6, 65, 21, 134, 181, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 192, 152, 237, 245, 35, 179, 133, 92, 8, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 82, 29, 15, 7, + 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, + 5, 93, 238, 22, 254, 190, 156, 170, 53, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, + 114, 12, 8, 4, 109, 95, 105, 112, 6, 100, 36, 215, 42, 6, 109, 95, 112, 111, 114, 116, + 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 225, 217, 27, 239, 55, 77, + 130, 218, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, + 6, 221, 138, 212, 98, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, + 101, 8, 1, 2, 105, 100, 5, 221, 115, 168, 71, 115, 113, 123, 226, 8, 3, 97, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 95, 158, 72, 195, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 169, + 55, 84, 253, 73, 235, 126, 1, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, + 4, 109, 95, 105, 112, 6, 47, 5, 146, 126, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, + 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 36, 7, 132, 185, 123, 44, 79, 9, 8, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 255, 255, 199, 102, 237, 44, 6, 109, 95, 112, 111, 114, 116, 7, 160, + 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 23, 191, 140, 80, 125, 5, 151, 123, 8, + 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 69, 163, + 90, 6, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 2, 215, 175, 128, 152, 162, 90, 120, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 147, 135, 136, 35, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 151, 75, 230, 186, 160, + 198, 175, 124, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, + 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 83, 137, 41, 10, 6, 109, 95, 112, + 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 180, 29, 120, + 16, 126, 72, 126, 35, 16, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, + 95, 105, 112, 6, 45, 62, 207, 10, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 131, 144, 70, 177, 35, 135, 112, 205, 12, 112, + 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 134, 1, 0, 0, 8, 114, 112, 99, + 95, 112, 111, 114, 116, 7, 161, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, + 12, 8, 4, 109, 95, 105, 112, 6, 98, 225, 91, 191, 6, 109, 95, 112, 111, 114, 116, 7, + 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 19, 165, 172, 148, 44, 52, 241, + 105, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, + 88, 212, 32, 151, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, + 1, 2, 105, 100, 5, 183, 237, 176, 171, 69, 241, 107, 86, 8, 114, 112, 99, 95, 112, 111, + 114, 116, 7, 161, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 51, 68, 214, 143, 6, + 109, 95, 112, 111, 114, 116, 7, 48, 17, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, + 206, 248, 161, 56, 86, 125, 195, 243, 16, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, + 12, 8, 4, 109, 95, 105, 112, 6, 152, 67, 175, 91, 6, 109, 95, 112, 111, 114, 116, 7, + 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 17, 83, 56, 240, 65, 163, 170, + 158, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 130, 1, 0, 0, 8, + 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 216, 232, 100, 178, 6, 109, 95, 112, + 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 167, 109, 78, + 13, 99, 252, 5, 228, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 146, 59, 0, 16, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 177, + 145, 118, 10, 116, 105, 64, 90, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, + 4, 109, 95, 105, 112, 6, 185, 10, 68, 240, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, + 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 105, 127, 240, 231, 209, 2, 20, 136, 12, + 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 89, 2, + 142, 180, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, + 105, 100, 5, 1, 21, 198, 102, 36, 134, 38, 249, 8, 114, 112, 99, 95, 112, 111, 114, + 116, 7, 161, 70, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 158, 140, 230, 233, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 0, 77, + 233, 80, 62, 71, 201, 59, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, + 100, 6, 130, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, + 95, 105, 112, 6, 78, 106, 12, 87, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 119, 128, 137, 92, 63, 246, 81, 72, 12, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 145, 255, 252, + 43, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 209, 7, 199, 121, 195, 30, 91, 168, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, + 169, 70, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, + 6, 71, 219, 43, 129, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, + 8, 1, 2, 105, 100, 5, 165, 255, 243, 173, 120, 214, 100, 239, 12, 112, 114, 117, 110, + 105, 110, 103, 95, 115, 101, 101, 100, 6, 130, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, + 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 255, 65, 21, 137, 242, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, + 112, 101, 8, 2, 2, 105, 100, 5, 56, 81, 223, 232, 243, 53, 150, 199, 8, 3, 97, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 76, 183, 153, 43, 6, + 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, + 2, 169, 223, 201, 166, 219, 0, 108, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, + 12, 8, 4, 109, 95, 105, 112, 6, 146, 190, 226, 170, 6, 109, 95, 112, 111, 114, 116, 7, + 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 184, 126, 145, 86, 17, 171, 106, + 193, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 130, 1, 0, 0, 8, + 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 99, 234, + 74, 130, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, + 105, 100, 5, 75, 225, 51, 71, 34, 147, 131, 93, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 34, 243, 233, 242, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 241, 169, 58, 47, 204, + 254, 64, 194, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, + 112, 6, 37, 1, 201, 53, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, + 101, 8, 1, 2, 105, 100, 5, 218, 61, 215, 233, 72, 244, 247, 85, 8, 3, 97, 100, 114, 12, + 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 100, 0, 31, 209, 6, 109, 95, + 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 254, 223, + 214, 77, 175, 11, 224, 27, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, + 109, 95, 105, 112, 6, 38, 242, 201, 74, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, + 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 55, 246, 56, 7, 244, 33, 111, 185, 8, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 178, 128, 226, + 166, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 100, 250, 203, 11, 176, 225, 42, 24, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 45, 238, 67, 67, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 5, 230, 42, 159, 3, 83, + 146, 72, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 8, 3, 97, 100, 114, 12, + 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 178, 237, 47, 93, 6, 109, 95, + 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 217, 28, + 236, 27, 5, 79, 1, 193, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, + 95, 105, 112, 6, 104, 243, 43, 115, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 182, 193, 32, 251, 5, 189, 35, 25, 12, 3, 97, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 99, 190, 128, 178, 6, + 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, + 147, 131, 114, 216, 68, 204, 57, 31, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, + 101, 101, 100, 6, 134, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, + 4, 109, 95, 105, 112, 6, 72, 49, 210, 248, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, + 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 87, 24, 255, 212, 205, 237, 120, 57, 8, 3, + 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 85, 158, 27, + 112, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 108, 53, 202, 66, 69, 64, 211, 203, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 144, 76, 58, 247, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 22, 231, 179, 203, 218, + 156, 64, 157, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 128, 1, + 0, 0, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, + 144, 24, 238, 60, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, + 1, 2, 105, 100, 5, 196, 95, 184, 97, 94, 165, 98, 28, 12, 112, 114, 117, 110, 105, 110, + 103, 95, 115, 101, 101, 100, 6, 133, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 142, 112, 70, 86, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 2, 21, 138, 98, 236, 208, + 52, 197, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, + 6, 213, 29, 219, 208, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, + 101, 8, 1, 2, 105, 100, 5, 101, 229, 157, 96, 78, 149, 79, 16, 8, 3, 97, 100, 114, 12, + 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 64, 44, 139, 100, 6, 109, 95, + 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 7, 203, + 58, 177, 99, 127, 167, 27, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, + 109, 95, 105, 112, 6, 104, 63, 131, 202, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, + 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 177, 178, 79, 176, 17, 114, 135, 128, 12, 3, + 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 58, 211, + 149, 42, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, + 105, 100, 5, 254, 82, 29, 104, 17, 156, 165, 19, 12, 112, 114, 117, 110, 105, 110, 103, + 95, 115, 101, 101, 100, 6, 131, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, + 114, 12, 8, 4, 109, 95, 105, 112, 6, 66, 235, 43, 120, 6, 109, 95, 112, 111, 114, 116, + 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 140, 48, 91, 174, 88, 66, 197, + 27, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, + 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 209, 182, 235, 183, 6, 109, 95, 112, 111, + 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 20, 196, 15, 35, + 230, 214, 44, 106, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, + 105, 112, 6, 107, 213, 91, 83, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, + 112, 101, 8, 1, 2, 105, 100, 5, 43, 184, 117, 30, 44, 105, 95, 158, 12, 112, 114, 117, + 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 128, 1, 0, 0, 16, 3, 97, 100, 114, 12, + 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 134, 122, 101, 227, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 34, + 132, 26, 158, 228, 246, 37, 122, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, + 101, 100, 6, 135, 1, 0, 0, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 8, 3, + 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 5, 144, 96, + 90, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 53, 151, 49, 57, 210, 176, 123, 26, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, + 45, 129, 183, 236, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, + 8, 2, 2, 105, 100, 5, 114, 226, 183, 173, 149, 80, 29, 207, 12, 112, 114, 117, 110, + 105, 110, 103, 95, 115, 101, 101, 100, 6, 132, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, + 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 96, 48, 253, 223, 6, 109, 95, 112, + 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 138, 193, 53, + 95, 29, 24, 29, 67, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, + 95, 105, 112, 6, 209, 141, 137, 143, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, + 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 142, 18, 157, 53, 139, 6, 171, 205, 12, 112, + 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 132, 1, 0, 0, 12, 3, 97, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 195, 252, 42, 19, 6, + 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, + 11, 193, 221, 161, 77, 26, 136, 247, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 161, + 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, + 136, 34, 220, 232, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, + 8, 1, 2, 105, 100, 5, 188, 71, 195, 46, 165, 220, 100, 247, 8, 3, 97, 100, 114, 12, 8, + 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 136, 50, 23, 101, 6, 109, 95, + 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 142, 104, + 228, 114, 184, 184, 155, 149, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, + 4, 109, 95, 105, 112, 6, 79, 23, 184, 106, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, + 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 9, 143, 211, 219, 201, 209, 78, 126, 12, + 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 131, 1, 0, 0, 8, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 70, 172, 62, + 186, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 90, 74, 7, 27, 88, 104, 96, 63, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, + 114, 12, 8, 4, 109, 95, 105, 112, 6, 83, 48, 63, 194, 6, 109, 95, 112, 111, 114, 116, + 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 157, 41, 130, 225, 209, 57, + 190, 227, 16, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, + 112, 6, 192, 18, 141, 11, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, + 101, 8, 1, 2, 105, 100, 5, 47, 149, 84, 128, 33, 31, 39, 27, 12, 112, 114, 117, 110, + 105, 110, 103, 95, 115, 101, 101, 100, 6, 128, 1, 0, 0, 8, 114, 112, 99, 95, 112, 111, + 114, 116, 7, 169, 70, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 198, 251, 83, 134, 6, + 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, + 240, 74, 2, 160, 144, 140, 44, 91, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, + 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 173, + 255, 205, 142, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, + 2, 105, 100, 5, 13, 193, 21, 155, 217, 217, 26, 41, 12, 112, 114, 117, 110, 105, 110, + 103, 95, 115, 101, 101, 100, 6, 130, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 170, 39, 103, 46, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 110, 132, 154, 110, 72, + 158, 220, 125, 16, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, + 105, 112, 6, 149, 202, 95, 149, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 227, 35, 58, 212, 189, 211, 121, 171, 12, 112, + 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 131, 1, 0, 0, 8, 114, 112, 99, + 95, 112, 111, 114, 116, 7, 169, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, + 12, 8, 4, 109, 95, 105, 112, 6, 20, 200, 83, 5, 6, 109, 95, 112, 111, 114, 116, 7, 160, + 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 76, 28, 183, 239, 120, 19, 32, 226, 8, + 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 67, 191, + 0, 235, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, + 105, 100, 5, 46, 88, 119, 219, 137, 174, 116, 168, 12, 3, 97, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 178, 174, 135, 72, 6, 109, 95, 112, 111, + 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 196, 76, 198, 87, + 49, 143, 40, 85, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 128, + 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, + 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 139, 99, 124, 170, 6, 109, 95, 112, + 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 144, 217, 56, + 205, 38, 203, 209, 20, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, + 95, 105, 112, 6, 46, 124, 180, 230, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 26, 138, 117, 131, 113, 28, 20, 89, 12, 112, 114, + 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 134, 1, 0, 0, 8, 3, 97, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 185, 64, 105, 115, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 35, + 92, 145, 24, 195, 195, 28, 241, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, + 4, 109, 95, 105, 112, 6, 136, 36, 57, 103, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, + 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 121, 160, 232, 102, 215, 85, 156, 52, 12, + 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 168, 235, + 93, 184, 6, 109, 95, 112, 111, 114, 116, 7, 51, 212, 4, 116, 121, 112, 101, 8, 1, 2, + 105, 100, 5, 158, 89, 86, 15, 219, 4, 128, 76, 12, 112, 114, 117, 110, 105, 110, 103, + 95, 115, 101, 101, 100, 6, 133, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, + 114, 12, 8, 4, 109, 95, 105, 112, 6, 66, 205, 213, 214, 6, 109, 95, 112, 111, 114, 116, + 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 169, 3, 234, 0, 122, 41, 147, + 3, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, + 141, 98, 255, 143, 6, 109, 95, 112, 111, 114, 116, 7, 177, 214, 4, 116, 121, 112, 101, + 8, 1, 2, 105, 100, 5, 73, 127, 80, 122, 34, 152, 103, 89, 12, 3, 97, 100, 114, 12, 8, + 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 255, 255, 172, 104, 177, 190, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 2, 2, 105, 100, 5, 55, 98, 90, 98, 247, 151, 65, 145, 8, 114, 112, + 99, 95, 112, 111, 114, 116, 7, 161, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, + 114, 12, 8, 4, 109, 95, 105, 112, 6, 77, 172, 230, 31, 6, 109, 95, 112, 111, 114, 116, + 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 37, 18, 78, 110, 19, 172, 149, + 68, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, + 162, 218, 65, 156, 6, 109, 95, 112, 111, 114, 116, 7, 204, 71, 4, 116, 121, 112, 101, + 8, 1, 2, 105, 100, 5, 34, 212, 28, 89, 219, 217, 198, 30, 8, 3, 97, 100, 114, 12, 8, 4, + 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 109, 145, 130, 189, 6, 109, 95, 112, + 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 210, 119, 203, + 62, 62, 33, 221, 76, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, + 95, 105, 112, 6, 73, 97, 224, 138, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 233, 45, 113, 162, 132, 119, 238, 222, 8, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 255, 255, 221, 234, 36, 39, 6, 109, 95, 112, 111, 114, 116, 7, 160, + 70, 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 231, 98, 155, 99, 120, 161, 139, 47, + 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 68, + 109, 164, 26, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, + 2, 105, 100, 5, 143, 41, 243, 191, 26, 133, 133, 148, 8, 3, 97, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, + 255, 99, 234, 74, 130, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, + 101, 8, 2, 2, 105, 100, 5, 75, 225, 51, 71, 34, 147, 131, 93, 12, 3, 97, 100, 114, 12, + 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 172, 104, 177, 190, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 55, + 98, 90, 98, 247, 151, 65, 145, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 161, 70, 8, + 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 89, 39, + 107, 63, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, + 105, 100, 5, 253, 235, 42, 162, 145, 123, 118, 118, 8, 3, 97, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 86, 19, 164, 20, 6, 109, 95, 112, 111, + 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 254, 16, 203, 169, + 195, 236, 197, 71, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, + 105, 112, 6, 45, 132, 245, 124, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 203, 217, 203, 62, 235, 68, 79, 246, 8, 114, 112, + 99, 95, 112, 111, 114, 116, 7, 169, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, + 114, 12, 8, 4, 109, 95, 105, 112, 6, 78, 47, 1, 42, 6, 109, 95, 112, 111, 114, 116, 7, + 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 62, 193, 188, 52, 253, 250, 177, + 78, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, + 24, 9, 196, 18, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, + 1, 2, 105, 100, 5, 181, 175, 149, 70, 255, 230, 120, 144, 12, 112, 114, 117, 110, 105, + 110, 103, 95, 115, 101, 101, 100, 6, 131, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 81, 174, 147, 70, 6, 109, 95, 112, 111, + 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 139, 117, 247, 251, + 252, 120, 207, 122, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, + 105, 112, 6, 24, 46, 131, 31, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, + 112, 101, 8, 1, 2, 105, 100, 5, 254, 139, 52, 145, 46, 192, 114, 218, 12, 3, 97, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 96, 41, 220, 52, 6, + 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, + 132, 117, 138, 75, 120, 0, 85, 225, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, + 70, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, + 185, 104, 122, 37, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, + 8, 1, 2, 105, 100, 5, 134, 166, 173, 179, 232, 66, 0, 248, 8, 114, 112, 99, 95, 112, + 111, 114, 116, 7, 161, 70, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, + 109, 95, 105, 112, 6, 71, 127, 156, 63, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, + 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 173, 130, 134, 129, 151, 73, 173, 117, 8, + 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 132, 248, 211, 188, 6, 109, 95, 112, + 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 243, 244, 6, + 201, 85, 211, 59, 11, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, + 95, 105, 112, 6, 221, 121, 132, 104, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, + 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 164, 8, 50, 88, 16, 202, 71, 19, 8, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 98, 177, 226, + 32, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 13, 149, 116, 215, 92, 35, 192, 137, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 107, 191, 99, 95, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 35, 130, 252, 209, 208, + 87, 41, 16, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, + 112, 6, 82, 64, 20, 76, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, + 101, 8, 1, 2, 105, 100, 5, 96, 72, 181, 187, 232, 78, 92, 185, 12, 3, 97, 100, 114, 12, + 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 188, 68, 50, 194, 6, 109, 95, + 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 135, 253, + 6, 30, 218, 46, 47, 159, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 161, 70, 8, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 159, 100, 254, + 56, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 106, 11, 135, 247, 255, 124, 31, 27, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 23, 128, 248, 240, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 86, 157, 138, 8, 39, 38, + 167, 237, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, + 6, 95, 142, 45, 13, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, + 8, 1, 2, 105, 100, 5, 68, 53, 120, 88, 65, 106, 55, 62, 8, 3, 97, 100, 114, 12, 8, 4, + 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 139, 99, 124, 170, 6, 109, 95, 112, + 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 144, 217, 56, + 205, 38, 203, 209, 20, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, + 95, 105, 112, 6, 149, 102, 137, 246, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, + 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 252, 192, 231, 60, 235, 176, 190, 192, 8, 3, + 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 82, 66, 187, + 193, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 167, 249, 42, 214, 200, 13, 147, 63, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 54, 36, 174, 4, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 1, 91, 183, 129, 113, + 151, 228, 218, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, + 105, 112, 6, 192, 9, 184, 123, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, + 112, 101, 8, 1, 2, 105, 100, 5, 237, 203, 144, 195, 93, 91, 36, 253, 12, 112, 114, 117, + 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 132, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, + 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 146, 190, 105, 218, 6, 109, 95, + 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 106, 83, + 142, 16, 72, 134, 65, 203, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, + 109, 95, 105, 112, 6, 202, 112, 0, 98, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, + 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 254, 101, 149, 141, 81, 187, 225, 93, 12, 3, + 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 45, 67, 217, + 103, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 0, 127, 172, 186, 143, 155, 201, 145, 8, 114, 112, 99, 95, 112, 111, 114, 116, + 7, 169, 70, 16, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, + 112, 6, 85, 247, 59, 77, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, + 101, 8, 1, 2, 105, 100, 5, 226, 116, 172, 104, 27, 129, 198, 120, 12, 112, 114, 117, + 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 129, 1, 0, 0, 8, 114, 112, 99, 95, 112, + 111, 114, 116, 7, 169, 70, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, + 109, 95, 105, 112, 6, 172, 93, 53, 9, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, + 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 41, 95, 47, 152, 22, 90, 49, 102, 12, 112, + 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 132, 1, 0, 0, 16, 3, 97, 100, + 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 255, 255, 71, 237, 129, 0, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, + 4, 116, 121, 112, 101, 8, 2, 2, 105, 100, 5, 115, 63, 166, 229, 245, 229, 122, 239, 12, + 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 135, 1, 0, 0, 8, 114, + 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 82, 121, 36, 202, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 216, 167, 229, 40, 235, + 137, 72, 52, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 131, 1, + 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, + 118, 36, 228, 156, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, + 8, 1, 2, 105, 100, 5, 33, 1, 180, 80, 243, 161, 76, 54, 8, 3, 97, 100, 114, 12, 8, 4, + 97, 100, 100, 114, 12, 8, 4, 97, 100, 100, 114, 10, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 255, 73, 235, 168, 79, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, + 112, 101, 8, 2, 2, 105, 100, 5, 120, 102, 85, 162, 254, 2, 48, 208, 8, 3, 97, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 204, 12, 201, 36, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 239, + 100, 244, 177, 67, 52, 196, 181, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, + 8, 4, 109, 95, 105, 112, 6, 216, 249, 90, 57, 6, 109, 95, 112, 111, 114, 116, 7, 160, + 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 222, 93, 114, 147, 216, 204, 49, 151, + 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 83, + 137, 41, 10, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, + 2, 105, 100, 5, 180, 29, 120, 16, 126, 72, 126, 35, 8, 3, 97, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 63, 143, 48, 18, 6, 109, 95, 112, 111, + 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 193, 47, 218, 50, + 81, 222, 85, 43, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, + 105, 112, 6, 152, 89, 216, 153, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 31, 11, 87, 67, 7, 192, 1, 13, 8, 3, 97, 100, 114, + 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 77, 95, 229, 224, 6, 109, + 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 160, + 119, 196, 130, 136, 75, 140, 54, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, + 8, 4, 109, 95, 105, 112, 6, 82, 69, 12, 29, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, + 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 208, 247, 146, 51, 217, 73, 193, 226, 12, + 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 49, 12, + 239, 156, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, + 105, 100, 5, 146, 129, 163, 49, 89, 133, 44, 64, 8, 114, 112, 99, 95, 112, 111, 114, + 116, 7, 169, 70, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, + 105, 112, 6, 185, 240, 242, 36, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, + 121, 112, 101, 8, 1, 2, 105, 100, 5, 197, 219, 86, 2, 247, 136, 229, 29, 12, 3, 97, + 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 134, 122, 61, + 72, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, + 100, 5, 29, 223, 119, 202, 113, 165, 81, 7, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, + 169, 70, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, + 6, 195, 154, 242, 41, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, + 101, 8, 1, 2, 105, 100, 5, 177, 250, 184, 155, 105, 57, 83, 47, 8, 114, 112, 99, 95, + 112, 111, 114, 116, 7, 169, 70, 16, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, + 8, 4, 109, 95, 105, 112, 6, 99, 248, 2, 29, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, + 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 10, 209, 218, 249, 58, 74, 147, 253, 12, + 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 133, 1, 0, 0, 8, 114, + 112, 99, 95, 112, 111, 114, 116, 7, 169, 70, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, + 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 51, 75, 64, 249, 6, 109, 95, 112, 111, 114, + 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 183, 101, 253, 145, 35, + 156, 129, 45, 12, 112, 114, 117, 110, 105, 110, 103, 95, 115, 101, 101, 100, 6, 134, 1, + 0, 0, 12, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, + 185, 203, 56, 7, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, + 1, 2, 105, 100, 5, 241, 202, 217, 195, 142, 200, 163, 55, 12, 112, 114, 117, 110, 105, + 110, 103, 95, 115, 101, 101, 100, 6, 133, 1, 0, 0, 8, 3, 97, 100, 114, 12, 8, 4, 97, + 100, 100, 114, 12, 8, 4, 109, 95, 105, 112, 6, 136, 243, 145, 198, 6, 109, 95, 112, + 111, 114, 116, 7, 160, 70, 4, 116, 121, 112, 101, 8, 1, 2, 105, 100, 5, 53, 77, 124, + 92, 86, 55, 9, 77, 8, 3, 97, 100, 114, 12, 8, 4, 97, 100, 100, 114, 12, 8, 4, 109, 95, + 105, 112, 6, 46, 28, 204, 223, 6, 109, 95, 112, 111, 114, 116, 7, 160, 70, 4, 116, 121, + 112, 101, 8, 1, 2, 105, 100, 5, 183, 162, 58, 143, 188, 33, 92, 33, 9, 110, 111, 100, + 101, 95, 100, 97, 116, 97, 12, 20, 7, 109, 121, 95, 112, 111, 114, 116, 6, 160, 70, 0, + 0, 10, 110, 101, 116, 119, 111, 114, 107, 95, 105, 100, 10, 64, 18, 48, 241, 113, 97, + 4, 65, 97, 23, 49, 0, 130, 22, 161, 161, 16, 7, 112, 101, 101, 114, 95, 105, 100, 5, + 172, 170, 135, 122, 19, 151, 202, 83, 8, 114, 112, 99, 95, 112, 111, 114, 116, 7, 169, + 70, 13, 115, 117, 112, 112, 111, 114, 116, 95, 102, 108, 97, 103, 115, 6, 1, 0, 0, 0, + 12, 112, 97, 121, 108, 111, 97, 100, 95, 100, 97, 116, 97, 12, 24, 21, 99, 117, 109, + 117, 108, 97, 116, 105, 118, 101, 95, 100, 105, 102, 102, 105, 99, 117, 108, 116, 121, + 5, 25, 78, 56, 125, 251, 152, 97, 3, 27, 99, 117, 109, 117, 108, 97, 116, 105, 118, + 101, 95, 100, 105, 102, 102, 105, 99, 117, 108, 116, 121, 95, 116, 111, 112, 54, 52, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 14, 99, 117, 114, 114, 101, 110, 116, 95, 104, 101, 105, 103, + 104, 116, 5, 127, 88, 42, 0, 0, 0, 0, 0, 12, 112, 114, 117, 110, 105, 110, 103, 95, + 115, 101, 101, 100, 6, 130, 1, 0, 0, 6, 116, 111, 112, 95, 105, 100, 10, 128, 64, 120, + 0, 114, 218, 233, 18, 49, 8, 89, 154, 159, 101, 133, 242, 71, 77, 3, 247, 182, 219, + 181, 216, 193, 135, 23, 186, 168, 207, 119, 86, 235, 11, 116, 111, 112, 95, 118, 101, + 114, 115, 105, 111, 110, 8, 16, + ]; + let handshake: HandshakeResponse = epee_serde::from_bytes(bytes).unwrap(); + + let basic_node_data = BasicNodeData { + my_port: 18080, + network_id: [ + 18, 48, 241, 113, 97, 4, 65, 97, 23, 49, 0, 130, 22, 161, 161, 16, + ], + peer_id: PeerID(6037804360359455404), + support_flags: 1, + rpc_port: 18089, + rpc_credits_per_hash: 0, + }; + + let core_sync_data = CoreSyncData { + cumulative_difficulty: 243644060759772697, + cumulative_difficulty_top64: 0, + current_height: 2775167, + pruning_seed: 386, + top_id: Hash::from_str( + "0x40780072dae9123108599a9f6585f2474d03f7b6dbb5d8c18717baa8cf7756eb", + ) + .unwrap(), + top_version: 16, + }; + + assert_eq!(basic_node_data, handshake.node_data); + assert_eq!(core_sync_data, handshake.payload_data); + assert_eq!(250, handshake.local_peerlist_new.len()); + + let encoded_bytes = epee_serde::to_bytes(&handshake).unwrap(); + let handshake_2: HandshakeResponse = epee_serde::from_bytes(encoded_bytes).unwrap(); + + assert_eq!(handshake, handshake_2); + } +} diff --git a/net/monero-wire/src/messages/common.rs b/net/monero-wire/src/messages/common.rs new file mode 100644 index 0000000..9799aec --- /dev/null +++ b/net/monero-wire/src/messages/common.rs @@ -0,0 +1,238 @@ +//! Common types that are used across multiple messages. +// + +use epee_serde::Value; +use monero::{Block, Hash, Transaction}; +use serde::de; +use serde::ser::SerializeStruct; +use serde::{Deserialize, Serialize}; +use serde_with::serde_as; +use serde_with::TryFromInto; + +use super::zero_val; +use crate::NetworkAddress; + +/// A PeerID, different from a `NetworkAddress` +#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] +#[serde(transparent)] +pub struct PeerID(pub u64); + +/// Basic Node Data, information on the connected peer +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct BasicNodeData { + /// Port + pub my_port: u32, + /// The Network Id + pub network_id: [u8; 16], + /// Peer ID + pub peer_id: PeerID, + /// The Peers Support Flags + /// (If this is not in the message the default is 0) + #[serde(default = "zero_val")] + pub support_flags: u32, + /// RPC Port + /// (If this is not in the message the default is 0) + #[serde(default = "zero_val")] + pub rpc_port: u16, + /// RPC Credits Per Hash + /// (If this is not in the message the default is 0) + #[serde(default = "zero_val")] + pub rpc_credits_per_hash: u32, +} + +/// Core Sync Data, information on the sync state of a peer +#[serde_as] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct CoreSyncData { + /// Cumulative Difficulty Low + /// The lower 64 bits of the 128 bit cumulative difficulty + pub cumulative_difficulty: u64, + /// Cumulative Difficulty High + /// The upper 64 bits of the 128 bit cumulative difficulty + #[serde(default = "zero_val")] + pub cumulative_difficulty_top64: u64, + /// Current Height of the peer + pub current_height: u64, + /// Pruning Seed of the peer + /// (If this is not in the message the default is 0) + #[serde(default = "zero_val")] + pub pruning_seed: u32, + /// Hash of the top block + #[serde_as(as = "TryFromInto<[u8; 32]>")] + pub top_id: Hash, + /// Version of the top block + #[serde(default = "zero_val")] + pub top_version: u8, +} + +impl CoreSyncData { + /// Returns the 128 bit cumulative difficulty of the peers blockchain + pub fn cumulative_difficulty(&self) -> u128 { + let mut ret: u128 = self.cumulative_difficulty_top64 as u128; + ret <<= 64; + ret | self.cumulative_difficulty as u128 + } +} + +/// PeerListEntryBase, information kept on a peer which will be entered +/// in a peer list/store. +#[derive(Clone, Copy, Deserialize, Serialize, Debug, Eq, PartialEq)] +pub struct PeerListEntryBase { + /// The Peer Address + pub adr: NetworkAddress, + /// The Peer ID + pub id: PeerID, + /// The last Time The Peer Was Seen + #[serde(default = "zero_val")] + pub last_seen: i64, + /// The Pruning Seed + #[serde(default = "zero_val")] + pub pruning_seed: u32, + /// The RPC port + #[serde(default = "zero_val")] + pub rpc_port: u16, + /// The RPC credits per hash + #[serde(default = "zero_val")] + pub rpc_credits_per_hash: u32, +} + +/// A pruned tx with the hash of the missing prunable data +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct TxBlobEntry { + /// The Tx + pub tx: Transaction, // ########### use pruned transaction when PR is merged ############## + /// The Prunable Tx Hash + pub prunable_hash: Hash, +} + +impl TxBlobEntry { + fn from_epee_value(value: &Value) -> Result { + let tx_blob = get_val_from_map!(value, "blob", get_bytes, "Vec"); + + let tx = monero_decode_into_serde_err!(Transaction, tx_blob); + + let prunable_hash_blob = get_val_from_map!(value, "prunable_hash", get_bytes, "Vec"); + + let prunable_hash = Hash::from_slice(prunable_hash_blob); + + Ok(Self { tx, prunable_hash }) + } +} + +impl Serialize for TxBlobEntry { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("", 2)?; + let tx_blob = monero::consensus::serialize(&self.tx); + state.serialize_field("blob", &tx_blob)?; + let prunable_hash = self.prunable_hash.as_bytes(); + state.serialize_field("prunable_hash", prunable_hash)?; + state.end() + } +} + +/// A Block that can contain transactions +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct BlockCompleteEntry { + /// True if tx data is pruned + pub pruned: bool, + /// The Block + pub block: Block, + /// The Block Weight/Size + pub block_weight: u64, + /// If the Block is pruned the txs will be here + pub txs_pruned: Vec, + /// If the Block is not pruned the txs will be here + pub txs: Vec, +} + +impl<'de> Deserialize<'de> for BlockCompleteEntry { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let value = Value::deserialize(deserializer)?; + let mut pruned = false; + if let Some(val) = value.get("pruned") { + pruned = *get_internal_val!(val, get_bool, "bool"); + } + + let block_bytes = get_val_from_map!(value, "block", get_bytes, "Vec"); + + let block = monero_decode_into_serde_err!(Block, block_bytes); + + let mut block_weight = 0; + + let mut txs_pruned = vec![]; + let mut txs = vec![]; + + if pruned { + block_weight = *get_val_from_map!(value, "block_weight", get_u64, "u64"); + + if let Some(v) = value.get("txs") { + let v = get_internal_val!(v, get_seq, "a sequence"); + + txs_pruned.reserve(v.len()); + for val in v { + txs_pruned.push(TxBlobEntry::from_epee_value(val)?); + } + } + } else if let Some(v) = value.get("txs") { + let v = get_internal_val!(v, get_seq, "a sequence"); + + txs.reserve(v.len()); + for val in v { + let tx_buf = get_internal_val!(val, get_bytes, "Vec"); + txs.push(monero_decode_into_serde_err!(Transaction, tx_buf)); + } + } + Ok(BlockCompleteEntry { + pruned, + block, + block_weight, + txs_pruned, + txs, + }) + } +} + +impl Serialize for BlockCompleteEntry { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut len = 1; + if !self.txs.is_empty() || !self.txs_pruned.is_empty() { + len += 1; + } + if self.pruned { + // one field to store the value of `pruned` + // another to sore the block weight + len += 2; + } + + let mut state = serializer.serialize_struct("", len)?; + + let block = monero::consensus::serialize(&self.block); + state.serialize_field("block", &block)?; + + if self.pruned { + state.serialize_field("pruned", &true)?; + state.serialize_field("block_weight", &self.block_weight)?; + + if !self.txs_pruned.is_empty() { + state.serialize_field("txs", &self.txs_pruned)?; + } + } else if !self.txs.is_empty() { + let mut tx_blobs = vec![]; + for tx in self.txs.iter() { + tx_blobs.push(monero::consensus::serialize(tx)); + } + state.serialize_field("txs", &tx_blobs)?; + } + + state.end() + } +} diff --git a/net/monero-wire/src/messages/protocol.rs b/net/monero-wire/src/messages/protocol.rs new file mode 100644 index 0000000..2542d63 --- /dev/null +++ b/net/monero-wire/src/messages/protocol.rs @@ -0,0 +1,1030 @@ +//! This module defines Monero protocol messages +//! +//! Protocol message requests don't have to be responded to in order unlike +//! admin messages. + +use monero::Hash; +use monero::Transaction; +use serde::Deserialize; +use serde::Serialize; +use serde_with::serde_as; +use serde_with::Bytes; +use serde_with::TryFromInto; + +use super::common::BlockCompleteEntry; +use super::{default_false, default_true}; + +/// A block that SHOULD have transactions +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct NewBlock { + /// Block with txs + pub b: BlockCompleteEntry, + /// The Blocks height + pub current_blockchain_height: u64, +} + +/// A Block that doesn't have transactions unless requested +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct NewFluffyBlock { + /// Block which might have transactions + pub b: BlockCompleteEntry, + /// The Block height + pub current_blockchain_height: u64, +} + +/// A Tx Pool transaction blob +#[serde_as] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +#[serde(transparent)] +pub struct TxBlob(#[serde_as(as = "Bytes")] pub Vec); + +impl TxBlob { + /// Deserialize the transaction + pub fn deserialize(&self) -> Result { + monero::consensus::deserialize(&self.0) + } +} + +/// New Tx Pool Transactions +#[serde_as] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct NewTransactions { + /// Tx Blobs + pub txs: Vec, + /// Dandelionpp true if fluff - backwards compatible mode is fluff + #[serde(default = "default_true")] + pub dandelionpp_fluff: bool, + /// Padding + #[serde(rename = "_")] + #[serde_as(as = "Bytes")] + pub padding: Vec, +} + +/// A Request For Blocks +#[serde_as] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct GetObjectsRequest { + /// Blocks + #[serde_as(as = "Vec>")] + pub blocks: Vec, + /// Pruned + #[serde(default = "default_false")] + pub pruned: bool, +} + +/// A Blocks Response +#[serde_as] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct GetObjectsResponse { + /// Blocks + pub blocks: Vec, + /// Missed IDs + #[serde_as(as = "Vec>")] + pub missed_ids: Vec, + /// The height of the peers blockchain + pub current_blockchain_height: u64, +} + +/// A Chain Request +#[serde_as] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct ChainRequest { + /// Block IDs + #[serde_as(as = "Vec>")] + pub block_ids: Vec, + /// Prune + #[serde(default = "default_false")] + pub prune: bool, +} + +/// A Chain Response +#[serde_as] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct ChainResponse { + /// Start Height + pub start_height: u64, + /// Total Height + pub total_height: u64, + /// Cumulative Difficulty Low + pub cumulative_difficulty_low: u64, + /// Cumulative Difficulty High + pub cumulative_difficulty_high: u64, + /// Block IDs + #[serde_as(as = "Vec>")] + pub m_block_ids: Vec, + /// Block Weights + pub m_block_weights: Vec, + /// The first Block in the blockchain + #[serde_as(as = "Bytes")] + pub first_block: Vec, +} + +/// A request for Txs we are missing from our TxPool +#[serde_as] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct FluffyMissingTransactionsRequest { + /// The Block we are missing the Txs in + #[serde_as(as = "TryFromInto<[u8; 32]>")] + pub block_hash: Hash, + /// The current blockchain height + pub current_blockchain_height: u64, + /// The Tx Indices + pub missing_tx_indices: Vec, +} + +/// TxPoolCompliment +#[serde_as] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct TxPoolCompliment { + /// Tx Hashes + #[serde_as(as = "Vec>")] + pub hashes: Vec, +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + + use monero::Hash; + + use super::{NewFluffyBlock, NewTransactions}; + + #[test] + fn serde_new_transactions() { + let bytes = [ + 1, 17, 1, 1, 1, 1, 2, 1, 1, 8, 1, 95, 10, 0, 3, 116, 120, 115, 138, 16, 237, 23, 2, 0, + 1, 2, 0, 16, 147, 177, 222, 29, 201, 207, 93, 150, 216, 25, 241, 102, 226, 193, 3, 138, + 55, 145, 246, 2, 141, 137, 3, 159, 70, 177, 152, 2, 161, 64, 159, 33, 150, 86, 155, + 159, 4, 237, 124, 146, 12, 90, 216, 224, 178, 145, 59, 110, 99, 189, 78, 14, 21, 155, + 24, 47, 25, 96, 200, 172, 168, 21, 180, 181, 81, 99, 86, 186, 123, 99, 15, 70, 81, 2, + 0, 3, 83, 139, 14, 66, 250, 103, 160, 182, 164, 9, 115, 93, 215, 254, 183, 198, 1, 209, + 103, 195, 176, 180, 208, 21, 58, 136, 169, 52, 166, 38, 25, 216, 105, 0, 3, 248, 132, + 179, 217, 15, 166, 253, 77, 217, 81, 238, 113, 251, 24, 184, 236, 94, 38, 79, 150, 72, + 162, 192, 189, 104, 33, 144, 82, 184, 179, 46, 240, 53, 44, 1, 108, 67, 128, 106, 35, + 254, 2, 119, 151, 11, 209, 120, 227, 170, 127, 47, 74, 159, 142, 114, 204, 249, 153, + 164, 14, 120, 72, 41, 182, 157, 138, 155, 2, 9, 1, 232, 124, 137, 236, 83, 119, 82, + 235, 6, 224, 242, 204, 14, 49, 220, 130, 232, 86, 91, 22, 46, 31, 177, 160, 237, 220, + 53, 249, 68, 5, 86, 16, 219, 190, 12, 140, 157, 73, 193, 16, 70, 153, 242, 14, 37, 26, + 193, 6, 86, 209, 44, 140, 102, 233, 70, 145, 105, 250, 135, 162, 98, 137, 87, 186, 166, + 154, 219, 56, 247, 179, 219, 93, 108, 136, 240, 222, 181, 177, 62, 194, 158, 49, 161, + 34, 60, 224, 147, 224, 198, 110, 19, 132, 52, 1, 211, 251, 218, 42, 134, 99, 86, 81, + 30, 181, 160, 61, 148, 172, 91, 59, 204, 154, 33, 91, 124, 44, 5, 163, 200, 78, 177, + 122, 87, 177, 209, 11, 107, 112, 64, 51, 131, 142, 156, 114, 201, 146, 155, 229, 185, + 60, 162, 142, 140, 22, 210, 164, 48, 93, 182, 227, 24, 213, 64, 61, 186, 167, 253, 85, + 0, 219, 18, 227, 11, 0, 68, 79, 87, 86, 37, 92, 11, 97, 167, 98, 50, 241, 175, 153, + 156, 188, 133, 53, 76, 102, 81, 150, 123, 122, 23, 242, 37, 172, 169, 165, 11, 128, + 128, 197, 185, 248, 160, 180, 72, 18, 81, 139, 162, 230, 71, 214, 204, 238, 232, 205, + 6, 89, 52, 228, 158, 23, 90, 5, 111, 253, 22, 188, 135, 249, 166, 131, 216, 212, 116, + 136, 217, 207, 222, 252, 77, 109, 159, 202, 164, 106, 7, 140, 202, 170, 223, 16, 118, + 51, 205, 0, 21, 161, 241, 18, 241, 12, 56, 115, 186, 155, 30, 192, 193, 29, 250, 161, + 181, 104, 88, 132, 111, 70, 39, 179, 166, 188, 213, 200, 113, 35, 97, 5, 7, 166, 91, + 231, 74, 190, 207, 67, 198, 70, 68, 112, 25, 245, 17, 215, 246, 45, 75, 23, 116, 8, + 211, 168, 230, 23, 10, 10, 152, 184, 67, 226, 188, 6, 125, 254, 166, 69, 14, 237, 99, + 105, 25, 15, 178, 244, 129, 147, 245, 57, 93, 154, 195, 243, 134, 121, 178, 117, 158, + 131, 136, 162, 221, 241, 20, 245, 40, 224, 115, 238, 122, 52, 143, 120, 208, 21, 147, + 67, 173, 114, 128, 10, 98, 70, 139, 167, 67, 174, 182, 200, 225, 73, 58, 111, 34, 44, + 26, 156, 19, 230, 106, 216, 214, 241, 136, 59, 132, 89, 22, 12, 6, 28, 69, 98, 191, + 168, 67, 30, 248, 237, 199, 13, 173, 40, 51, 23, 232, 93, 222, 42, 63, 131, 199, 75, + 172, 91, 157, 105, 31, 198, 226, 15, 9, 56, 127, 102, 170, 214, 68, 238, 217, 45, 89, + 24, 118, 231, 126, 79, 127, 197, 93, 130, 136, 150, 20, 134, 163, 140, 160, 110, 134, + 247, 60, 33, 146, 61, 103, 122, 112, 196, 168, 46, 188, 212, 183, 15, 121, 142, 186, + 203, 138, 210, 75, 150, 82, 217, 84, 151, 238, 131, 115, 173, 27, 12, 70, 127, 3, 38, + 143, 156, 83, 223, 101, 191, 87, 240, 101, 170, 242, 22, 95, 113, 175, 44, 131, 7, 36, + 99, 244, 94, 113, 77, 92, 63, 134, 187, 101, 8, 136, 227, 215, 163, 193, 73, 181, 155, + 227, 137, 186, 188, 81, 206, 131, 69, 93, 237, 128, 112, 54, 98, 232, 150, 20, 215, + 162, 3, 138, 18, 210, 84, 120, 200, 253, 68, 60, 133, 87, 56, 216, 239, 161, 229, 220, + 98, 179, 56, 244, 90, 23, 12, 22, 30, 185, 22, 33, 239, 89, 209, 199, 16, 93, 134, 208, + 187, 58, 224, 92, 137, 157, 207, 198, 216, 11, 156, 5, 110, 223, 128, 245, 27, 162, 32, + 65, 197, 35, 216, 86, 104, 61, 114, 7, 91, 31, 136, 255, 109, 43, 25, 171, 48, 212, 27, + 141, 65, 200, 88, 42, 119, 222, 190, 236, 108, 77, 144, 17, 193, 155, 226, 230, 127, + 29, 95, 115, 112, 185, 136, 49, 129, 4, 157, 57, 226, 131, 234, 51, 78, 136, 163, 133, + 114, 220, 175, 19, 39, 90, 235, 166, 116, 164, 17, 3, 75, 93, 97, 154, 136, 248, 172, + 109, 29, 54, 218, 153, 230, 73, 195, 167, 107, 182, 153, 134, 170, 223, 183, 215, 72, + 250, 135, 85, 196, 214, 211, 88, 218, 40, 60, 126, 62, 202, 13, 130, 12, 74, 191, 120, + 148, 222, 155, 3, 218, 254, 74, 110, 220, 119, 117, 221, 52, 221, 48, 125, 35, 167, 57, + 114, 177, 67, 120, 227, 37, 110, 48, 93, 35, 144, 41, 55, 1, 240, 206, 57, 129, 110, + 189, 45, 152, 20, 159, 195, 79, 93, 8, 120, 168, 24, 154, 80, 30, 245, 152, 175, 118, + 125, 254, 153, 134, 248, 229, 62, 104, 47, 162, 238, 84, 15, 186, 177, 29, 244, 51, + 158, 18, 164, 8, 81, 84, 14, 159, 109, 207, 199, 225, 6, 225, 217, 68, 193, 66, 217, + 192, 62, 3, 7, 145, 107, 98, 11, 64, 227, 156, 161, 249, 180, 42, 1, 10, 46, 244, 78, + 163, 32, 107, 229, 239, 189, 111, 29, 89, 76, 134, 51, 200, 100, 184, 248, 124, 216, + 44, 166, 183, 241, 179, 212, 19, 185, 232, 218, 15, 242, 16, 135, 14, 131, 57, 64, 253, + 242, 220, 217, 22, 159, 17, 4, 97, 110, 129, 159, 239, 233, 214, 209, 67, 146, 94, 58, + 4, 86, 170, 176, 7, 150, 88, 65, 218, 35, 85, 182, 170, 161, 212, 236, 142, 121, 213, + 199, 126, 155, 75, 132, 231, 149, 120, 20, 253, 39, 239, 144, 26, 224, 251, 180, 14, 3, + 58, 115, 22, 250, 96, 217, 189, 39, 67, 52, 47, 137, 129, 157, 235, 251, 112, 188, 2, + 99, 183, 58, 29, 96, 255, 128, 125, 154, 135, 82, 8, 40, 101, 113, 52, 227, 4, 86, 144, + 169, 163, 193, 10, 148, 92, 34, 120, 88, 1, 21, 214, 172, 131, 11, 68, 214, 201, 157, + 255, 213, 89, 116, 7, 51, 137, 122, 49, 237, 54, 66, 123, 13, 102, 116, 3, 26, 54, 123, + 130, 31, 249, 152, 85, 213, 67, 25, 35, 117, 22, 90, 79, 181, 246, 154, 5, 192, 152, + 89, 98, 107, 48, 138, 228, 197, 59, 216, 49, 200, 114, 183, 41, 199, 3, 75, 117, 106, + 63, 190, 140, 129, 210, 125, 154, 241, 52, 205, 7, 150, 43, 118, 164, 138, 40, 164, + 181, 175, 239, 17, 153, 132, 121, 130, 130, 26, 169, 199, 234, 60, 197, 173, 98, 40, + 235, 56, 96, 68, 64, 130, 13, 77, 203, 56, 32, 74, 160, 216, 246, 218, 165, 215, 181, + 8, 223, 16, 234, 134, 202, 111, 181, 206, 207, 11, 223, 130, 161, 34, 186, 252, 189, + 246, 11, 114, 46, 252, 39, 40, 169, 73, 48, 20, 181, 155, 183, 60, 230, 178, 70, 58, + 29, 35, 30, 43, 69, 160, 93, 78, 146, 32, 156, 42, 246, 69, 3, 193, 95, 177, 169, 121, + 3, 244, 236, 24, 105, 38, 171, 118, 31, 93, 244, 64, 65, 67, 130, 107, 113, 45, 145, + 86, 93, 163, 183, 88, 109, 44, 0, 160, 147, 198, 104, 201, 16, 44, 79, 225, 4, 43, 167, + 112, 149, 85, 244, 196, 163, 213, 125, 220, 75, 124, 224, 71, 203, 70, 148, 112, 222, + 72, 2, 37, 157, 207, 164, 203, 174, 13, 43, 196, 26, 167, 87, 55, 14, 161, 242, 1, 35, + 183, 213, 179, 60, 212, 88, 227, 134, 28, 165, 60, 65, 217, 6, 27, 198, 25, 141, 229, + 199, 37, 74, 136, 155, 205, 225, 154, 182, 159, 1, 249, 91, 211, 244, 18, 202, 230, 8, + 37, 102, 106, 208, 73, 201, 85, 0, 245, 85, 20, 129, 173, 185, 120, 30, 61, 136, 149, + 126, 21, 15, 60, 156, 158, 113, 174, 161, 74, 73, 73, 239, 214, 70, 52, 49, 126, 107, + 116, 184, 87, 248, 49, 227, 55, 164, 206, 88, 124, 219, 230, 183, 223, 12, 115, 154, + 34, 85, 121, 252, 254, 215, 169, 182, 201, 0, 246, 158, 242, 110, 3, 191, 197, 34, 2, + 0, 2, 2, 0, 16, 152, 135, 203, 26, 230, 130, 176, 2, 248, 165, 34, 245, 147, 98, 246, + 212, 89, 188, 252, 4, 208, 253, 1, 136, 213, 3, 181, 190, 1, 151, 62, 130, 128, 1, 222, + 104, 227, 123, 237, 126, 162, 31, 240, 7, 250, 3, 94, 92, 123, 141, 201, 35, 196, 225, + 45, 46, 155, 10, 249, 197, 61, 141, 198, 180, 144, 252, 205, 174, 218, 33, 249, 109, + 244, 88, 75, 168, 2, 0, 16, 169, 188, 204, 11, 244, 244, 176, 15, 187, 130, 217, 1, + 243, 180, 69, 161, 174, 51, 154, 196, 97, 130, 218, 37, 174, 138, 6, 233, 143, 3, 213, + 164, 2, 227, 172, 4, 151, 137, 1, 210, 56, 234, 22, 137, 215, 1, 189, 30, 101, 8, 165, + 81, 217, 21, 216, 73, 252, 224, 131, 90, 35, 16, 187, 149, 38, 130, 152, 101, 185, 74, + 197, 22, 119, 66, 155, 85, 133, 73, 137, 49, 2, 0, 3, 234, 196, 86, 37, 79, 23, 112, + 72, 124, 14, 28, 62, 226, 154, 167, 70, 62, 139, 28, 11, 219, 7, 189, 186, 172, 179, 0, + 87, 29, 170, 108, 217, 70, 0, 3, 94, 111, 32, 85, 177, 43, 121, 159, 207, 120, 161, + 238, 188, 15, 174, 243, 113, 211, 192, 155, 204, 34, 18, 92, 69, 40, 39, 24, 183, 88, + 21, 188, 147, 44, 1, 66, 84, 235, 241, 48, 252, 38, 23, 247, 212, 79, 229, 82, 246, 10, + 171, 121, 149, 141, 171, 25, 220, 157, 70, 142, 108, 156, 171, 6, 114, 255, 166, 2, 9, + 1, 114, 186, 118, 78, 228, 29, 194, 144, 6, 160, 136, 156, 21, 247, 239, 217, 223, 235, + 176, 160, 203, 194, 85, 177, 56, 165, 115, 3, 86, 49, 38, 46, 70, 252, 50, 34, 241, + 187, 219, 2, 205, 152, 187, 196, 227, 31, 207, 114, 13, 192, 69, 142, 71, 176, 52, 134, + 11, 207, 149, 228, 28, 9, 253, 8, 205, 123, 86, 233, 139, 97, 181, 200, 226, 173, 157, + 97, 184, 65, 207, 124, 243, 26, 67, 81, 107, 127, 16, 11, 158, 235, 228, 109, 40, 1, + 141, 174, 147, 220, 241, 131, 61, 177, 42, 28, 16, 25, 41, 139, 83, 7, 43, 86, 48, 129, + 131, 112, 69, 119, 196, 175, 205, 190, 73, 98, 76, 167, 31, 62, 143, 157, 95, 178, 105, + 248, 134, 9, 220, 204, 225, 225, 145, 106, 177, 91, 226, 68, 130, 119, 108, 41, 173, + 87, 246, 50, 57, 97, 241, 19, 166, 71, 200, 68, 193, 181, 4, 130, 29, 6, 212, 2, 84, + 219, 106, 212, 45, 144, 169, 198, 87, 194, 132, 199, 47, 99, 184, 156, 59, 70, 177, 94, + 17, 67, 104, 151, 36, 160, 173, 211, 66, 217, 239, 99, 242, 204, 73, 103, 132, 188, 23, + 139, 105, 111, 84, 218, 213, 179, 59, 214, 133, 95, 14, 12, 227, 30, 222, 190, 34, 220, + 48, 39, 196, 171, 234, 33, 161, 189, 143, 27, 46, 37, 14, 3, 250, 121, 92, 98, 220, 88, + 25, 235, 163, 114, 74, 7, 98, 224, 11, 8, 154, 89, 148, 62, 63, 8, 226, 203, 91, 75, 6, + 186, 253, 69, 217, 98, 109, 152, 161, 68, 8, 92, 209, 154, 53, 116, 106, 10, 7, 66, 77, + 167, 160, 78, 152, 6, 170, 96, 139, 142, 132, 63, 167, 172, 202, 206, 51, 60, 93, 240, + 113, 45, 172, 242, 110, 11, 203, 154, 137, 202, 163, 71, 39, 133, 240, 211, 44, 199, + 136, 205, 114, 191, 104, 57, 53, 136, 92, 210, 41, 110, 250, 45, 81, 214, 245, 157, + 222, 66, 120, 117, 164, 117, 87, 158, 164, 252, 24, 141, 13, 1, 32, 2, 133, 130, 219, + 149, 110, 107, 142, 237, 110, 116, 83, 231, 107, 50, 32, 62, 43, 223, 129, 114, 35, 15, + 66, 195, 183, 148, 127, 96, 202, 22, 117, 102, 87, 121, 26, 203, 0, 183, 29, 255, 253, + 205, 217, 36, 178, 157, 5, 126, 242, 23, 106, 146, 17, 230, 142, 58, 119, 246, 84, 207, + 142, 49, 166, 176, 140, 117, 47, 157, 223, 245, 142, 209, 171, 33, 138, 229, 110, 208, + 205, 162, 122, 158, 69, 224, 189, 249, 212, 180, 82, 251, 189, 55, 44, 198, 93, 11, + 212, 223, 198, 178, 2, 26, 66, 145, 64, 155, 50, 88, 46, 99, 229, 157, 243, 21, 65, + 152, 185, 56, 230, 234, 101, 246, 191, 139, 62, 187, 170, 132, 88, 214, 9, 175, 67, 12, + 67, 205, 175, 185, 31, 103, 198, 3, 57, 196, 33, 23, 24, 246, 186, 179, 57, 7, 160, + 114, 97, 160, 242, 234, 104, 54, 91, 221, 31, 140, 41, 186, 220, 221, 223, 101, 252, + 171, 2, 251, 13, 121, 248, 234, 80, 138, 242, 195, 80, 12, 44, 216, 237, 233, 238, 248, + 97, 43, 243, 131, 16, 69, 156, 131, 1, 254, 57, 196, 191, 27, 192, 239, 162, 217, 40, + 237, 213, 151, 112, 107, 4, 81, 117, 34, 109, 23, 80, 99, 123, 134, 76, 84, 129, 36, + 103, 0, 96, 77, 140, 114, 230, 153, 3, 115, 119, 39, 78, 165, 138, 219, 181, 237, 145, + 216, 144, 107, 82, 174, 27, 68, 48, 70, 208, 66, 254, 142, 214, 22, 79, 218, 15, 4, 21, + 250, 80, 245, 195, 23, 63, 175, 207, 176, 227, 240, 56, 60, 250, 71, 82, 9, 136, 46, + 40, 101, 59, 89, 171, 64, 57, 183, 24, 147, 203, 204, 98, 79, 250, 77, 243, 177, 165, + 222, 68, 245, 238, 194, 228, 102, 192, 47, 99, 194, 174, 164, 235, 179, 10, 201, 240, + 201, 82, 13, 244, 224, 238, 201, 155, 251, 20, 13, 18, 132, 158, 56, 82, 194, 57, 69, + 249, 142, 48, 212, 233, 214, 152, 241, 189, 193, 133, 191, 42, 21, 148, 239, 198, 86, + 54, 194, 127, 221, 136, 28, 75, 108, 119, 175, 36, 129, 245, 68, 128, 139, 25, 51, 197, + 15, 221, 139, 97, 227, 43, 183, 254, 143, 19, 137, 13, 1, 116, 65, 216, 58, 114, 218, + 93, 224, 97, 8, 185, 110, 138, 228, 206, 4, 36, 78, 209, 82, 167, 251, 250, 176, 9, 70, + 19, 211, 89, 20, 170, 208, 165, 214, 252, 159, 29, 178, 226, 64, 126, 132, 86, 15, 69, + 19, 238, 12, 22, 176, 114, 167, 68, 166, 101, 202, 6, 215, 229, 36, 94, 163, 28, 108, + 104, 145, 173, 164, 42, 151, 65, 186, 161, 94, 4, 244, 222, 36, 23, 15, 74, 252, 202, + 178, 69, 217, 184, 2, 177, 235, 242, 159, 160, 76, 45, 205, 121, 19, 5, 49, 169, 178, + 113, 69, 141, 174, 173, 231, 217, 136, 74, 7, 89, 114, 33, 173, 74, 94, 223, 159, 160, + 0, 51, 106, 176, 104, 218, 60, 76, 178, 157, 240, 239, 247, 30, 222, 60, 246, 3, 189, + 160, 13, 67, 9, 166, 205, 125, 71, 1, 48, 184, 114, 7, 196, 154, 210, 192, 89, 248, + 213, 193, 187, 158, 226, 196, 247, 111, 203, 255, 131, 14, 221, 235, 68, 118, 13, 64, + 163, 162, 178, 210, 72, 5, 218, 158, 48, 42, 143, 85, 165, 83, 244, 169, 4, 78, 109, + 164, 240, 117, 178, 204, 113, 99, 59, 91, 177, 207, 15, 26, 247, 217, 139, 120, 196, + 210, 110, 56, 28, 164, 73, 254, 149, 171, 19, 12, 181, 162, 55, 220, 93, 249, 115, 11, + 9, 71, 224, 75, 70, 187, 4, 73, 136, 211, 40, 46, 42, 189, 130, 35, 54, 229, 124, 96, + 31, 35, 195, 199, 96, 38, 3, 72, 230, 126, 189, 197, 20, 102, 60, 26, 222, 217, 12, 66, + 22, 221, 48, 250, 134, 216, 205, 203, 229, 70, 134, 163, 182, 65, 226, 6, 139, 154, + 170, 78, 199, 20, 156, 39, 138, 147, 118, 102, 28, 108, 1, 11, 139, 215, 250, 109, 42, + 145, 14, 82, 76, 171, 255, 249, 11, 0, 50, 109, 31, 254, 234, 138, 83, 165, 226, 213, + 7, 60, 167, 15, 47, 159, 0, 78, 103, 80, 238, 101, 92, 59, 75, 23, 8, 191, 186, 229, + 126, 122, 67, 137, 179, 37, 44, 89, 125, 182, 36, 123, 119, 57, 30, 198, 128, 65, 3, + 75, 209, 28, 198, 190, 172, 44, 245, 152, 176, 112, 114, 16, 123, 65, 193, 47, 169, + 199, 21, 27, 21, 67, 115, 249, 52, 201, 74, 46, 64, 244, 7, 197, 217, 138, 47, 238, 57, + 10, 41, 180, 85, 71, 154, 56, 217, 58, 180, 119, 219, 119, 224, 116, 230, 95, 202, 164, + 149, 60, 164, 212, 65, 148, 7, 82, 50, 206, 81, 210, 194, 48, 28, 178, 88, 17, 212, + 231, 80, 177, 151, 16, 168, 238, 2, 20, 140, 254, 98, 131, 92, 160, 56, 209, 22, 240, + 13, 119, 216, 216, 26, 113, 215, 55, 38, 227, 52, 15, 222, 240, 98, 191, 255, 186, 28, + 192, 193, 147, 16, 34, 111, 113, 146, 138, 165, 118, 182, 73, 9, 54, 245, 214, 136, + 161, 237, 253, 58, 173, 81, 197, 254, 70, 89, 189, 151, 252, 194, 213, 218, 183, 28, + 238, 128, 127, 254, 95, 83, 126, 190, 98, 14, 72, 141, 165, 95, 79, 188, 84, 138, 190, + 144, 151, 194, 5, 69, 25, 93, 85, 136, 169, 142, 13, 44, 96, 127, 246, 129, 93, 73, + 141, 62, 77, 129, 255, 75, 27, 183, 143, 22, 140, 170, 138, 181, 194, 237, 109, 163, + 253, 60, 35, 84, 83, 193, 192, 67, 135, 231, 174, 134, 201, 15, 97, 11, 74, 0, 38, 140, + 53, 69, 91, 250, 47, 242, 134, 229, 223, 158, 156, 157, 229, 228, 243, 115, 115, 25, + 57, 72, 147, 5, 68, 32, 187, 125, 157, 171, 211, 4, 110, 22, 218, 211, 248, 109, 130, + 118, 125, 190, 178, 30, 134, 54, 222, 38, 81, 31, 7, 13, 91, 251, 211, 223, 55, 254, + 115, 212, 106, 75, 18, 14, 56, 44, 223, 95, 9, 53, 197, 193, 5, 247, 86, 43, 32, 222, + 122, 133, 174, 109, 150, 225, 75, 54, 202, 224, 38, 214, 5, 164, 230, 186, 250, 1, 24, + 40, 52, 12, 19, 79, 219, 243, 99, 199, 123, 196, 79, 24, 250, 129, 237, 244, 208, 38, + 40, 193, 142, 135, 205, 147, 100, 90, 234, 243, 250, 4, 203, 210, 39, 109, 23, 248, 99, + 217, 135, 115, 183, 110, 153, 85, 128, 17, 242, 82, 231, 59, 27, 68, 253, 102, 139, + 239, 87, 25, 50, 116, 83, 14, 204, 96, 72, 36, 245, 7, 140, 84, 107, 164, 98, 173, 186, + 142, 56, 182, 232, 7, 99, 254, 239, 254, 222, 84, 129, 6, 51, 120, 245, 200, 112, 6, 9, + 160, 0, 121, 168, 87, 62, 77, 204, 143, 100, 178, 38, 7, 19, 190, 225, 122, 116, 33, + 127, 143, 94, 244, 168, 35, 97, 219, 184, 207, 13, 14, 206, 103, 93, 118, 134, 137, + 144, 196, 45, 84, 52, 229, 93, 223, 35, 250, 212, 196, 26, 151, 184, 8, 132, 196, 27, + 144, 130, 196, 190, 247, 209, 2, 22, 145, 195, 164, 20, 55, 34, 22, 51, 229, 138, 219, + 164, 252, 99, 54, 108, 131, 10, 44, 195, 192, 20, 2, 69, 69, 155, 96, 183, 195, 244, + 11, 80, 224, 115, 235, 249, 171, 108, 13, 167, 214, 13, 173, 136, 173, 191, 216, 45, + 113, 184, 230, 209, 12, 199, 43, 112, 114, 142, 34, 122, 202, 147, 6, 188, 161, 83, + 107, 192, 232, 53, 78, 72, 90, 220, 29, 180, 72, 251, 118, 99, 166, 193, 173, 202, 236, + 249, 150, 73, 188, 249, 29, 3, 156, 83, 2, 70, 90, 114, 213, 10, 69, 1, 29, 231, 58, + 59, 99, 94, 4, 178, 251, 240, 66, 89, 37, 56, 157, 160, 9, 48, 77, 87, 148, 149, 43, 4, + 1, 211, 145, 238, 121, 148, 68, 185, 232, 254, 147, 89, 126, 20, 104, 235, 255, 137, + 235, 205, 8, 61, 165, 202, 241, 231, 200, 117, 26, 210, 224, 244, 15, 19, 79, 194, 129, + 84, 136, 99, 90, 217, 182, 42, 241, 136, 45, 174, 11, 28, 234, 27, 144, 94, 109, 26, + 248, 197, 84, 165, 20, 193, 123, 151, 14, 216, 164, 223, 241, 12, 96, 168, 105, 205, + 33, 185, 25, 61, 124, 11, 43, 140, 55, 57, 109, 213, 248, 109, 164, 246, 217, 10, 110, + 218, 16, 128, 2, 157, 243, 179, 227, 196, 137, 137, 139, 215, 105, 69, 149, 157, 191, + 153, 23, 247, 252, 64, 152, 244, 237, 249, 60, 153, 230, 88, 26, 209, 80, 29, 11, 75, + 5, 236, 126, 19, 167, 74, 141, 156, 159, 225, 17, 167, 71, 34, 223, 117, 83, 122, 24, + 156, 59, 21, 96, 190, 185, 33, 224, 76, 56, 213, 131, 116, 117, 186, 64, 200, 126, 31, + 138, 62, 211, 73, 130, 95, 90, 103, 36, 208, 134, 166, 250, 218, 3, 46, 184, 111, 149, + 157, 212, 5, 21, 229, 64, 103, 110, 179, 153, 242, 182, 83, 108, 142, 148, 47, 104, 94, + 229, 103, 211, 113, 58, 231, 42, 37, 63, 98, 130, 156, 56, 157, 173, 52, 192, 162, 238, + 169, 34, 2, 0, 2, 2, 0, 16, 188, 187, 216, 28, 211, 175, 73, 254, 178, 93, 233, 234, + 43, 169, 180, 38, 132, 232, 15, 191, 135, 4, 167, 143, 2, 247, 95, 133, 51, 143, 33, + 206, 20, 155, 7, 154, 39, 241, 28, 181, 23, 162, 23, 238, 3, 188, 108, 61, 19, 91, 160, + 10, 250, 18, 115, 163, 122, 199, 208, 223, 86, 139, 4, 192, 156, 134, 254, 95, 127, + 166, 139, 0, 239, 2, 0, 16, 179, 200, 253, 27, 249, 134, 180, 1, 146, 159, 37, 227, + 214, 10, 247, 183, 93, 251, 236, 20, 128, 78, 135, 163, 5, 181, 147, 12, 250, 241, 1, + 198, 63, 134, 13, 252, 7, 210, 41, 181, 110, 166, 37, 118, 171, 27, 110, 50, 166, 95, + 90, 34, 57, 7, 197, 97, 227, 47, 217, 88, 110, 184, 201, 198, 134, 36, 34, 213, 8, 148, + 237, 78, 86, 143, 0, 2, 0, 3, 74, 88, 134, 143, 1, 211, 54, 13, 131, 155, 129, 86, 230, + 179, 36, 21, 218, 103, 4, 241, 28, 79, 163, 33, 178, 215, 215, 92, 239, 46, 6, 147, 16, + 0, 3, 205, 95, 122, 225, 56, 246, 26, 83, 202, 92, 95, 184, 1, 166, 128, 219, 254, 146, + 10, 195, 174, 150, 154, 63, 178, 124, 176, 223, 233, 7, 123, 158, 25, 44, 1, 138, 21, + 58, 186, 252, 138, 231, 73, 3, 108, 130, 120, 161, 39, 134, 253, 131, 249, 6, 131, 69, + 70, 239, 162, 165, 25, 242, 187, 93, 0, 240, 251, 2, 9, 1, 65, 126, 216, 3, 190, 73, + 49, 90, 6, 208, 190, 165, 163, 1, 111, 149, 230, 178, 244, 87, 228, 44, 113, 63, 218, + 182, 218, 158, 186, 56, 167, 236, 74, 163, 5, 66, 198, 29, 200, 195, 51, 174, 57, 120, + 179, 184, 71, 85, 88, 130, 176, 8, 3, 248, 193, 207, 197, 44, 152, 4, 149, 198, 223, + 207, 154, 142, 103, 45, 216, 90, 239, 211, 236, 45, 127, 209, 113, 5, 14, 212, 90, 85, + 225, 127, 15, 74, 72, 36, 108, 13, 191, 60, 82, 245, 1, 96, 155, 33, 154, 135, 139, + 141, 66, 8, 151, 10, 145, 93, 87, 165, 106, 65, 178, 133, 1, 139, 85, 177, 82, 40, 252, + 34, 57, 24, 94, 59, 83, 38, 201, 247, 187, 171, 200, 25, 59, 61, 40, 155, 82, 51, 139, + 249, 61, 209, 157, 248, 8, 196, 68, 121, 160, 141, 207, 108, 12, 39, 134, 123, 151, 0, + 185, 250, 101, 38, 207, 188, 130, 23, 182, 86, 138, 68, 135, 30, 119, 189, 167, 99, + 135, 121, 226, 140, 56, 46, 205, 194, 80, 104, 142, 255, 3, 11, 29, 210, 127, 214, 105, + 237, 220, 52, 248, 41, 185, 33, 198, 230, 230, 217, 228, 69, 57, 234, 219, 86, 48, 66, + 220, 19, 149, 101, 131, 149, 15, 130, 6, 185, 6, 70, 64, 212, 241, 209, 187, 197, 48, + 5, 164, 194, 140, 15, 92, 250, 160, 232, 241, 182, 38, 18, 104, 250, 232, 82, 108, 221, + 0, 179, 216, 137, 117, 75, 81, 212, 239, 29, 75, 182, 158, 179, 108, 45, 156, 162, 37, + 124, 51, 167, 153, 74, 139, 107, 181, 19, 174, 135, 173, 247, 4, 7, 3, 223, 121, 197, + 165, 116, 55, 111, 246, 1, 147, 195, 105, 154, 102, 133, 111, 104, 249, 244, 75, 128, + 222, 69, 107, 75, 19, 53, 34, 48, 185, 75, 114, 176, 67, 8, 174, 53, 252, 72, 205, 65, + 106, 99, 69, 63, 177, 81, 221, 56, 163, 152, 61, 29, 16, 36, 93, 180, 13, 2, 26, 148, + 133, 170, 203, 173, 36, 221, 93, 41, 76, 189, 225, 243, 250, 240, 232, 206, 81, 64, + 147, 200, 132, 118, 216, 200, 211, 131, 18, 94, 157, 224, 8, 244, 59, 86, 207, 163, + 200, 38, 183, 215, 50, 206, 40, 157, 104, 153, 191, 38, 212, 105, 251, 147, 91, 30, + 220, 168, 68, 252, 174, 155, 138, 12, 166, 255, 208, 3, 137, 127, 106, 254, 161, 25, + 195, 112, 197, 83, 175, 209, 179, 184, 43, 191, 125, 235, 252, 65, 18, 226, 48, 99, + 167, 236, 242, 41, 213, 169, 62, 186, 40, 147, 26, 64, 106, 53, 236, 109, 107, 172, 88, + 244, 154, 120, 134, 123, 245, 157, 65, 116, 210, 42, 13, 116, 3, 142, 246, 81, 165, + 212, 227, 175, 189, 78, 21, 234, 58, 161, 187, 152, 153, 41, 0, 44, 27, 240, 171, 133, + 157, 168, 117, 117, 11, 186, 18, 23, 44, 248, 191, 221, 121, 70, 250, 242, 7, 175, 190, + 111, 219, 240, 196, 193, 255, 201, 22, 216, 69, 35, 39, 141, 143, 199, 205, 131, 106, + 75, 226, 225, 81, 190, 14, 146, 46, 174, 147, 9, 128, 46, 39, 21, 141, 155, 77, 112, + 251, 227, 232, 198, 16, 185, 67, 220, 21, 181, 128, 218, 160, 120, 201, 28, 65, 52, 64, + 14, 58, 67, 157, 98, 7, 62, 115, 231, 36, 248, 140, 121, 29, 94, 215, 7, 240, 44, 67, + 89, 108, 235, 243, 80, 51, 6, 114, 206, 185, 39, 10, 169, 114, 208, 201, 133, 170, 234, + 139, 187, 45, 29, 135, 29, 245, 127, 0, 32, 157, 187, 108, 240, 58, 251, 92, 216, 216, + 141, 207, 103, 221, 254, 13, 95, 197, 212, 227, 247, 188, 81, 119, 95, 12, 11, 103, + 169, 40, 123, 149, 113, 99, 87, 124, 252, 215, 1, 195, 78, 210, 3, 118, 242, 153, 80, + 91, 244, 24, 195, 199, 103, 22, 36, 210, 191, 15, 140, 16, 191, 136, 34, 228, 209, 82, + 165, 0, 65, 54, 231, 126, 212, 121, 212, 182, 138, 254, 216, 114, 101, 6, 116, 116, + 153, 19, 106, 128, 82, 125, 248, 25, 121, 201, 63, 81, 186, 242, 141, 25, 201, 118, 95, + 227, 119, 40, 188, 203, 53, 95, 93, 205, 254, 172, 167, 28, 168, 27, 208, 252, 141, + 103, 235, 72, 124, 24, 156, 177, 128, 254, 18, 242, 179, 221, 176, 118, 205, 221, 222, + 148, 158, 26, 210, 255, 218, 165, 88, 167, 63, 3, 86, 83, 107, 151, 9, 88, 245, 18, + 244, 99, 217, 139, 82, 127, 149, 5, 61, 112, 201, 243, 229, 9, 37, 50, 231, 187, 152, + 19, 92, 191, 224, 1, 150, 101, 101, 249, 227, 124, 204, 33, 227, 101, 70, 176, 143, 77, + 147, 70, 127, 225, 208, 201, 247, 121, 142, 1, 249, 83, 64, 190, 100, 234, 136, 10, + 198, 11, 122, 206, 146, 13, 125, 84, 104, 248, 122, 61, 241, 147, 119, 175, 90, 32, + 153, 163, 163, 202, 188, 22, 136, 79, 29, 22, 90, 193, 113, 2, 240, 6, 65, 127, 139, + 43, 93, 53, 5, 12, 37, 172, 93, 92, 72, 143, 130, 160, 227, 25, 146, 153, 208, 213, 40, + 33, 114, 4, 169, 86, 176, 1, 0, 56, 196, 145, 251, 72, 136, 97, 36, 23, 32, 135, 233, + 73, 21, 131, 92, 191, 18, 3, 214, 31, 151, 12, 91, 190, 8, 82, 233, 180, 16, 6, 119, + 216, 150, 163, 40, 54, 136, 195, 231, 173, 26, 239, 29, 141, 8, 195, 192, 52, 170, 119, + 228, 39, 62, 141, 207, 121, 107, 4, 105, 169, 217, 14, 154, 107, 114, 248, 115, 148, + 163, 67, 251, 86, 155, 151, 40, 204, 202, 255, 29, 161, 210, 6, 52, 100, 251, 168, 80, + 101, 144, 176, 139, 37, 3, 12, 39, 34, 56, 102, 121, 142, 115, 170, 87, 187, 24, 46, + 240, 69, 177, 116, 107, 59, 149, 137, 17, 159, 181, 51, 81, 203, 216, 154, 158, 157, + 168, 14, 150, 203, 248, 49, 23, 110, 193, 29, 166, 134, 100, 28, 200, 76, 132, 157, 85, + 182, 215, 94, 138, 139, 233, 239, 189, 106, 102, 9, 236, 198, 238, 15, 46, 161, 125, + 209, 170, 80, 101, 85, 149, 237, 15, 183, 170, 120, 242, 204, 175, 40, 255, 173, 172, + 67, 190, 46, 63, 141, 207, 175, 252, 156, 34, 0, 238, 194, 117, 61, 95, 76, 206, 140, + 100, 38, 108, 5, 112, 40, 14, 180, 197, 16, 15, 43, 210, 137, 250, 79, 177, 225, 241, + 107, 25, 182, 97, 3, 91, 50, 67, 129, 243, 181, 103, 167, 34, 239, 209, 253, 81, 165, + 90, 235, 26, 32, 31, 98, 215, 119, 124, 93, 1, 108, 253, 232, 170, 49, 179, 5, 49, 167, + 35, 206, 3, 218, 61, 186, 93, 57, 206, 204, 252, 35, 129, 25, 255, 71, 129, 45, 188, + 71, 186, 137, 139, 39, 80, 76, 138, 169, 70, 11, 138, 176, 184, 22, 129, 106, 208, 204, + 127, 11, 14, 182, 93, 107, 23, 255, 147, 120, 61, 244, 174, 1, 120, 86, 108, 228, 216, + 44, 200, 196, 185, 12, 152, 40, 189, 231, 89, 112, 233, 219, 129, 183, 18, 102, 195, + 248, 213, 144, 1, 5, 117, 161, 177, 218, 183, 194, 112, 222, 102, 209, 44, 92, 121, 7, + 237, 250, 123, 72, 74, 43, 209, 28, 94, 195, 154, 129, 245, 77, 204, 164, 35, 0, 50, + 113, 117, 184, 175, 147, 238, 232, 18, 164, 41, 151, 95, 4, 144, 191, 30, 104, 247, + 230, 239, 195, 48, 168, 60, 92, 41, 25, 85, 15, 11, 65, 9, 135, 175, 124, 202, 232, + 222, 145, 111, 232, 130, 145, 140, 214, 136, 171, 117, 232, 153, 57, 3, 253, 9, 167, + 81, 13, 238, 231, 84, 18, 79, 67, 131, 163, 48, 226, 4, 13, 62, 199, 158, 113, 237, + 127, 201, 0, 219, 190, 79, 1, 13, 37, 149, 34, 33, 86, 98, 159, 161, 162, 204, 247, + 116, 242, 233, 151, 220, 25, 27, 158, 34, 102, 247, 92, 58, 60, 85, 1, 77, 71, 190, + 123, 17, 219, 6, 154, 79, 244, 16, 21, 60, 221, 129, 77, 5, 131, 38, 7, 17, 35, 28, + 252, 168, 89, 26, 197, 121, 18, 234, 8, 41, 202, 173, 54, 88, 117, 114, 179, 198, 200, + 80, 122, 170, 182, 27, 89, 102, 37, 117, 65, 131, 159, 98, 65, 36, 123, 223, 239, 27, + 124, 28, 11, 117, 117, 4, 230, 164, 46, 82, 90, 52, 165, 204, 215, 104, 220, 204, 197, + 179, 12, 50, 159, 239, 196, 110, 226, 84, 104, 5, 164, 2, 44, 198, 12, 162, 123, 14, + 230, 99, 145, 168, 62, 186, 100, 239, 9, 240, 231, 124, 29, 90, 247, 66, 165, 232, 125, + 95, 203, 152, 123, 0, 159, 20, 145, 244, 3, 12, 245, 45, 113, 121, 220, 182, 64, 166, + 207, 74, 27, 40, 248, 133, 13, 86, 216, 67, 249, 19, 240, 234, 33, 136, 196, 85, 201, + 42, 85, 191, 15, 88, 108, 223, 218, 120, 226, 147, 111, 15, 70, 208, 187, 23, 10, 96, + 93, 238, 174, 86, 117, 95, 227, 53, 112, 48, 1, 191, 236, 40, 250, 171, 3, 46, 230, + 220, 4, 2, 21, 55, 27, 190, 13, 95, 152, 194, 8, 196, 119, 168, 236, 149, 14, 53, 34, + 228, 85, 189, 138, 194, 184, 68, 59, 234, 14, 46, 14, 121, 32, 76, 46, 146, 38, 82, + 154, 95, 153, 209, 99, 242, 9, 177, 238, 142, 154, 193, 59, 185, 157, 236, 238, 117, + 64, 74, 144, 178, 10, 47, 199, 157, 220, 38, 141, 214, 135, 163, 9, 58, 119, 177, 128, + 182, 176, 162, 196, 115, 166, 62, 75, 108, 83, 249, 91, 112, 146, 177, 76, 217, 5, 195, + 156, 32, 88, 107, 248, 194, 97, 95, 221, 82, 149, 116, 8, 46, 212, 105, 39, 198, 165, + 119, 134, 28, 8, 128, 235, 168, 114, 111, 141, 166, 13, 232, 14, 114, 209, 177, 59, + 150, 133, 121, 209, 53, 182, 81, 21, 32, 160, 134, 58, 49, 121, 183, 118, 23, 255, 225, + 87, 201, 121, 106, 28, 191, 0, 219, 126, 30, 198, 13, 7, 158, 223, 144, 30, 117, 6, + 139, 125, 122, 26, 91, 130, 111, 239, 181, 127, 63, 12, 230, 172, 130, 234, 158, 203, + 231, 6, 74, 190, 225, 198, 1, 57, 242, 232, 180, 167, 220, 47, 36, 83, 115, 86, 178, + 151, 24, 52, 224, 74, 23, 103, 33, 129, 130, 159, 228, 217, 183, 13, 49, 177, 39, 58, + 133, 198, 225, 206, 87, 174, 125, 112, 11, 53, 51, 206, 97, 100, 212, 112, 198, 177, + 57, 217, 131, 109, 204, 252, 139, 151, 146, 13, 119, 222, 10, 206, 238, 250, 145, 203, + 184, 102, 214, 116, 24, 247, 223, 213, 252, 67, 1, 37, 44, 215, 181, 180, 48, 210, 246, + 82, 109, 254, 63, 1, 0, 179, 5, 36, 22, 100, 10, 249, 50, 223, 149, 246, 58, 73, 52, + 178, 197, 26, 187, 174, 86, 107, 220, 109, 206, 66, 86, 71, 8, 48, 19, 52, 52, 97, 176, + 185, 46, 175, 139, 216, 80, 145, 254, 137, 114, 224, 64, 89, 33, 253, 29, 50, 225, 131, + 194, 36, 28, 111, 178, 47, 235, 131, 48, 155, 233, 198, 73, 145, 184, 20, 139, 114, + 129, 222, 74, 62, 241, 211, 144, 185, 61, 106, 215, 11, 213, 189, 148, 84, 67, 173, + 208, 125, 254, 220, 67, 42, 69, 56, 2, 0, 4, 2, 0, 16, 160, 214, 249, 28, 132, 158, 42, + 198, 199, 85, 165, 153, 50, 165, 218, 42, 128, 176, 1, 160, 139, 2, 150, 241, 12, 212, + 142, 1, 152, 56, 180, 38, 206, 47, 198, 16, 197, 2, 251, 76, 254, 25, 233, 71, 121, + 154, 24, 236, 247, 169, 178, 140, 69, 18, 192, 10, 149, 137, 49, 81, 232, 34, 233, 72, + 153, 131, 132, 124, 131, 86, 248, 173, 104, 220, 2, 0, 16, 129, 198, 205, 23, 219, 166, + 224, 3, 240, 182, 202, 2, 245, 238, 63, 168, 216, 24, 164, 139, 3, 136, 27, 190, 241, + 12, 226, 118, 194, 26, 136, 165, 4, 190, 178, 1, 242, 76, 212, 133, 1, 135, 46, 171, 6, + 180, 88, 27, 32, 127, 27, 173, 55, 113, 159, 179, 128, 75, 32, 237, 79, 180, 58, 80, + 218, 87, 53, 250, 168, 242, 72, 237, 14, 37, 209, 183, 27, 2, 0, 16, 131, 205, 220, 6, + 248, 192, 217, 12, 234, 183, 136, 7, 204, 178, 253, 2, 226, 197, 122, 251, 200, 25, + 243, 182, 1, 134, 132, 6, 205, 161, 4, 213, 220, 8, 213, 202, 2, 216, 38, 157, 7, 158, + 134, 1, 194, 39, 227, 99, 162, 37, 185, 111, 52, 232, 229, 94, 113, 237, 208, 227, 42, + 127, 203, 218, 103, 196, 88, 81, 251, 50, 255, 109, 151, 30, 86, 178, 192, 1, 7, 122, + 2, 0, 16, 205, 182, 227, 8, 178, 213, 249, 12, 245, 174, 248, 5, 142, 249, 226, 2, 224, + 237, 2, 241, 143, 12, 187, 189, 16, 238, 148, 5, 172, 180, 3, 203, 223, 6, 199, 37, + 180, 91, 223, 152, 1, 213, 16, 153, 1, 200, 40, 66, 190, 30, 10, 167, 248, 228, 128, + 177, 167, 158, 12, 207, 6, 221, 233, 36, 16, 224, 37, 234, 112, 122, 3, 73, 110, 28, + 219, 146, 227, 22, 221, 2, 0, 3, 40, 22, 9, 114, 87, 70, 165, 43, 124, 234, 203, 66, + 187, 206, 235, 90, 214, 243, 219, 140, 23, 125, 75, 12, 209, 84, 160, 109, 79, 185, + 246, 198, 126, 0, 3, 118, 35, 47, 114, 202, 8, 242, 12, 224, 46, 58, 65, 77, 205, 74, + 150, 170, 166, 155, 5, 203, 159, 244, 194, 242, 248, 119, 193, 210, 219, 36, 88, 214, + 44, 1, 133, 60, 193, 177, 126, 82, 83, 208, 217, 70, 7, 191, 53, 193, 159, 211, 141, + 18, 235, 157, 182, 94, 187, 7, 92, 88, 248, 194, 176, 99, 87, 50, 2, 9, 1, 17, 90, 103, + 147, 170, 141, 221, 160, 6, 160, 224, 171, 34, 188, 239, 150, 143, 152, 220, 124, 199, + 185, 86, 234, 213, 161, 169, 253, 131, 109, 179, 163, 219, 169, 250, 51, 108, 55, 92, + 20, 111, 174, 192, 5, 208, 58, 139, 36, 116, 219, 138, 198, 226, 191, 196, 34, 66, 129, + 130, 180, 229, 133, 25, 254, 223, 238, 203, 43, 224, 253, 159, 7, 87, 86, 255, 183, + 102, 1, 122, 141, 109, 50, 23, 64, 22, 56, 38, 110, 22, 189, 182, 6, 97, 1, 207, 157, + 222, 178, 195, 188, 84, 95, 243, 18, 232, 121, 64, 15, 120, 1, 174, 137, 34, 7, 128, + 97, 31, 26, 16, 47, 163, 49, 188, 81, 172, 214, 44, 163, 45, 208, 99, 229, 166, 153, + 198, 240, 175, 115, 50, 2, 94, 38, 242, 154, 246, 239, 57, 218, 163, 199, 10, 161, 152, + 163, 194, 161, 70, 18, 17, 245, 79, 44, 17, 1, 6, 60, 226, 42, 71, 93, 238, 81, 172, + 68, 118, 6, 176, 242, 222, 44, 185, 240, 163, 40, 50, 96, 116, 132, 152, 75, 202, 248, + 131, 209, 183, 0, 62, 222, 166, 220, 161, 75, 44, 117, 234, 192, 31, 114, 216, 100, + 120, 155, 178, 48, 184, 165, 244, 159, 52, 57, 145, 7, 206, 213, 229, 92, 236, 47, 58, + 75, 205, 52, 40, 198, 2, 55, 15, 28, 50, 176, 98, 47, 217, 100, 48, 94, 12, 139, 32, + 214, 218, 240, 10, 15, 11, 169, 137, 132, 23, 185, 172, 225, 16, 254, 88, 75, 240, 85, + 137, 19, 89, 148, 57, 15, 178, 177, 187, 96, 7, 94, 235, 2, 216, 34, 128, 6, 7, 19, + 167, 235, 97, 31, 29, 137, 64, 39, 193, 227, 222, 149, 144, 181, 26, 185, 226, 55, 121, + 59, 142, 102, 17, 242, 227, 228, 225, 120, 140, 103, 10, 40, 6, 209, 165, 4, 35, 33, + 178, 123, 183, 188, 250, 179, 202, 190, 44, 216, 179, 156, 52, 62, 173, 126, 178, 148, + 128, 75, 222, 109, 140, 248, 89, 9, 176, 163, 243, 149, 211, 52, 216, 75, 162, 102, + 189, 38, 166, 244, 96, 111, 2, 239, 176, 47, 58, 244, 6, 190, 44, 107, 252, 223, 130, + 185, 133, 60, 186, 21, 66, 195, 22, 130, 65, 139, 243, 45, 146, 29, 37, 215, 143, 255, + 181, 0, 156, 78, 155, 212, 146, 0, 248, 253, 151, 160, 163, 156, 186, 160, 223, 151, + 113, 223, 128, 195, 55, 144, 43, 173, 25, 178, 37, 134, 249, 235, 36, 219, 138, 46, + 216, 95, 54, 230, 72, 9, 245, 83, 44, 187, 214, 79, 220, 114, 217, 147, 76, 133, 190, + 127, 227, 216, 102, 206, 3, 125, 186, 63, 101, 242, 36, 230, 208, 5, 201, 82, 80, 199, + 220, 198, 161, 50, 146, 175, 123, 74, 239, 237, 141, 23, 190, 243, 55, 132, 160, 123, + 70, 27, 180, 221, 28, 14, 233, 247, 52, 16, 205, 239, 169, 138, 24, 125, 228, 128, 47, + 7, 78, 251, 60, 144, 204, 164, 39, 57, 118, 0, 213, 47, 22, 254, 34, 142, 1, 17, 107, + 151, 203, 68, 137, 83, 145, 251, 3, 214, 243, 52, 18, 130, 17, 1, 0, 91, 245, 184, 107, + 172, 215, 147, 215, 128, 122, 201, 238, 7, 69, 33, 245, 5, 61, 222, 87, 241, 55, 147, + 225, 196, 67, 228, 115, 249, 211, 29, 200, 204, 10, 80, 193, 110, 7, 80, 139, 65, 120, + 24, 47, 114, 59, 224, 240, 222, 203, 54, 244, 199, 70, 248, 66, 100, 182, 194, 191, + 173, 116, 117, 135, 132, 250, 161, 54, 255, 28, 20, 40, 34, 174, 124, 147, 252, 196, + 133, 97, 25, 231, 1, 76, 224, 92, 33, 206, 44, 164, 70, 132, 54, 166, 253, 170, 139, + 186, 27, 54, 246, 45, 198, 194, 178, 96, 174, 87, 159, 124, 192, 199, 180, 10, 238, + 129, 95, 147, 24, 188, 128, 193, 68, 101, 199, 95, 99, 245, 214, 79, 8, 133, 143, 147, + 155, 200, 2, 174, 190, 136, 38, 76, 84, 157, 192, 207, 133, 56, 57, 66, 135, 191, 34, + 85, 223, 63, 160, 110, 157, 120, 13, 43, 186, 6, 223, 104, 129, 18, 110, 128, 58, 255, + 26, 14, 167, 177, 121, 5, 241, 69, 120, 68, 34, 85, 169, 35, 198, 39, 177, 211, 133, 5, + 220, 74, 78, 249, 198, 8, 29, 83, 3, 147, 116, 145, 128, 51, 137, 201, 151, 19, 165, + 223, 147, 160, 12, 116, 201, 69, 54, 17, 5, 74, 253, 34, 100, 127, 162, 61, 224, 157, + 142, 65, 226, 169, 139, 48, 25, 8, 94, 141, 226, 172, 128, 17, 43, 21, 32, 23, 25, 1, + 171, 211, 1, 155, 71, 171, 119, 24, 230, 55, 191, 182, 187, 109, 101, 151, 126, 50, 37, + 238, 30, 45, 162, 169, 223, 78, 219, 191, 158, 199, 11, 60, 160, 200, 13, 77, 18, 169, + 47, 65, 175, 41, 41, 39, 189, 206, 107, 43, 125, 254, 17, 118, 181, 201, 228, 171, 160, + 205, 77, 109, 112, 12, 56, 194, 234, 219, 13, 111, 173, 38, 212, 112, 3, 91, 93, 111, + 39, 16, 223, 21, 3, 156, 70, 8, 69, 97, 89, 68, 108, 24, 29, 142, 38, 27, 7, 120, 251, + 132, 5, 47, 16, 240, 56, 193, 202, 122, 228, 20, 183, 179, 41, 120, 11, 224, 78, 205, + 154, 198, 252, 118, 160, 119, 213, 168, 148, 188, 221, 168, 6, 77, 5, 240, 39, 157, + 131, 88, 149, 226, 191, 200, 30, 156, 28, 63, 67, 137, 59, 177, 156, 200, 61, 44, 230, + 133, 164, 250, 14, 172, 64, 236, 161, 51, 12, 175, 220, 144, 116, 26, 159, 127, 165, + 15, 130, 192, 91, 93, 206, 251, 251, 244, 68, 167, 89, 238, 235, 164, 9, 156, 237, 131, + 49, 77, 62, 144, 6, 82, 223, 110, 127, 29, 106, 115, 33, 66, 119, 24, 43, 199, 23, 40, + 48, 70, 22, 114, 229, 196, 36, 217, 129, 21, 152, 239, 244, 143, 37, 192, 7, 161, 117, + 238, 251, 227, 125, 49, 203, 166, 79, 128, 70, 225, 77, 155, 104, 101, 188, 172, 155, + 234, 29, 61, 1, 43, 46, 145, 84, 66, 210, 188, 4, 253, 22, 47, 177, 60, 249, 21, 138, + 18, 109, 39, 150, 224, 242, 15, 84, 49, 194, 101, 90, 250, 20, 29, 240, 99, 226, 138, + 131, 245, 140, 185, 0, 232, 56, 121, 21, 83, 87, 171, 29, 134, 133, 82, 110, 38, 87, + 212, 133, 193, 183, 160, 5, 209, 4, 58, 182, 46, 252, 70, 148, 17, 57, 39, 1, 4, 198, + 23, 113, 228, 101, 35, 120, 248, 183, 7, 214, 125, 173, 210, 233, 241, 190, 102, 251, + 185, 119, 52, 133, 12, 92, 166, 191, 35, 83, 245, 7, 41, 145, 20, 182, 81, 35, 134, + 146, 152, 48, 69, 88, 235, 243, 26, 158, 126, 73, 15, 78, 138, 243, 25, 158, 14, 248, + 137, 240, 128, 86, 106, 12, 121, 94, 219, 122, 82, 115, 187, 230, 4, 61, 137, 199, 206, + 5, 245, 148, 153, 232, 181, 162, 133, 27, 64, 210, 103, 240, 245, 229, 18, 146, 93, 5, + 142, 206, 94, 12, 54, 165, 44, 120, 250, 204, 225, 64, 171, 156, 164, 108, 31, 79, 115, + 79, 184, 62, 243, 13, 79, 18, 78, 63, 117, 120, 208, 5, 244, 31, 117, 188, 244, 142, + 163, 41, 161, 126, 6, 166, 182, 25, 41, 113, 196, 6, 177, 15, 245, 42, 62, 213, 179, + 68, 200, 132, 26, 2, 71, 4, 43, 160, 130, 242, 51, 233, 178, 213, 88, 90, 246, 251, + 182, 141, 48, 35, 29, 154, 187, 81, 99, 161, 115, 32, 100, 110, 173, 222, 150, 200, 81, + 67, 66, 49, 58, 35, 241, 126, 138, 80, 51, 90, 146, 211, 22, 118, 57, 144, 180, 58, + 190, 198, 120, 201, 17, 154, 42, 74, 205, 12, 47, 139, 201, 14, 77, 45, 223, 182, 210, + 175, 66, 198, 225, 164, 69, 233, 72, 59, 153, 53, 228, 232, 70, 210, 173, 39, 14, 56, + 249, 140, 127, 99, 15, 57, 32, 5, 136, 43, 189, 226, 120, 17, 209, 235, 206, 168, 254, + 95, 224, 239, 39, 83, 40, 191, 103, 184, 19, 238, 132, 153, 5, 145, 196, 253, 184, 86, + 84, 14, 44, 13, 74, 107, 87, 194, 13, 4, 38, 152, 211, 104, 198, 163, 85, 167, 129, 14, + 93, 70, 0, 168, 104, 18, 235, 15, 229, 2, 105, 104, 69, 11, 160, 205, 80, 152, 91, 100, + 75, 229, 229, 61, 197, 227, 68, 60, 169, 235, 159, 102, 26, 179, 198, 77, 221, 163, + 229, 74, 81, 204, 110, 222, 210, 1, 93, 253, 163, 208, 200, 216, 122, 180, 106, 87, + 210, 129, 215, 74, 200, 239, 2, 221, 79, 230, 132, 158, 157, 87, 112, 7, 117, 195, 232, + 157, 71, 13, 34, 58, 204, 201, 93, 230, 45, 130, 208, 15, 251, 152, 38, 198, 81, 134, + 100, 254, 136, 123, 204, 199, 27, 218, 16, 19, 253, 66, 84, 105, 105, 4, 224, 60, 237, + 76, 94, 234, 4, 245, 5, 153, 20, 20, 171, 139, 82, 132, 88, 212, 79, 29, 79, 239, 10, + 32, 11, 210, 180, 115, 253, 144, 41, 5, 241, 76, 250, 165, 126, 114, 138, 19, 3, 231, + 137, 136, 53, 148, 214, 218, 43, 67, 1, 10, 208, 220, 55, 221, 90, 218, 55, 8, 21, 223, + 32, 7, 143, 163, 103, 43, 164, 248, 169, 219, 131, 184, 221, 130, 154, 30, 32, 158, + 137, 247, 182, 23, 42, 185, 49, 5, 159, 176, 255, 157, 4, 253, 239, 10, 206, 154, 12, + 116, 141, 70, 111, 96, 143, 13, 133, 180, 215, 3, 8, 122, 149, 190, 229, 188, 194, 91, + 87, 182, 20, 51, 106, 171, 72, 51, 209, 10, 7, 75, 197, 74, 74, 75, 237, 206, 76, 180, + 223, 109, 134, 15, 251, 124, 121, 203, 250, 96, 155, 242, 162, 205, 171, 74, 163, 95, + 3, 119, 114, 15, 190, 142, 187, 58, 145, 155, 52, 62, 249, 210, 33, 100, 35, 50, 82, + 236, 29, 109, 179, 187, 221, 229, 246, 138, 38, 176, 240, 119, 230, 239, 41, 10, 182, + 226, 6, 90, 27, 91, 28, 86, 243, 8, 98, 87, 197, 141, 19, 84, 121, 15, 210, 204, 248, + 52, 192, 238, 229, 151, 94, 9, 73, 7, 111, 11, 122, 24, 77, 58, 219, 16, 190, 161, 36, + 226, 140, 255, 164, 18, 63, 71, 0, 1, 177, 250, 136, 216, 116, 169, 115, 167, 212, 186, + 111, 248, 5, 7, 50, 210, 98, 65, 144, 161, 41, 128, 178, 26, 113, 249, 37, 87, 185, + 146, 176, 143, 177, 190, 84, 76, 181, 204, 190, 23, 126, 47, 210, 157, 190, 5, 40, 202, + 34, 135, 216, 85, 41, 212, 185, 239, 183, 61, 183, 10, 89, 237, 103, 239, 240, 95, 69, + 111, 213, 141, 253, 226, 224, 159, 100, 61, 150, 0, 236, 4, 27, 46, 165, 123, 21, 172, + 135, 0, 228, 239, 191, 75, 7, 133, 12, 129, 89, 59, 221, 9, 31, 247, 90, 191, 142, 158, + 4, 34, 60, 156, 104, 38, 16, 101, 29, 232, 98, 137, 31, 157, 212, 18, 125, 152, 49, + 137, 115, 218, 0, 38, 179, 230, 73, 215, 58, 53, 189, 101, 16, 231, 76, 14, 90, 143, + 185, 239, 172, 41, 211, 242, 224, 154, 215, 150, 106, 180, 23, 225, 86, 211, 27, 9, 40, + 136, 152, 91, 116, 143, 216, 73, 27, 103, 21, 1, 13, 182, 35, 74, 21, 217, 191, 10, 87, + 0, 243, 131, 199, 236, 166, 48, 178, 130, 232, 28, 34, 217, 164, 185, 148, 34, 169, + 197, 158, 185, 207, 12, 235, 128, 235, 81, 206, 163, 204, 44, 100, 6, 209, 168, 243, + 79, 83, 98, 111, 94, 208, 173, 156, 0, 40, 61, 35, 131, 202, 13, 83, 172, 153, 0, 159, + 118, 58, 130, 82, 217, 22, 217, 159, 81, 205, 152, 180, 24, 82, 79, 77, 237, 241, 156, + 75, 76, 22, 158, 208, 231, 128, 214, 30, 66, 88, 8, 95, 96, 198, 214, 61, 175, 185, + 108, 180, 91, 205, 212, 64, 235, 116, 152, 238, 185, 40, 177, 235, 183, 39, 74, 22, + 225, 161, 221, 199, 178, 134, 9, 247, 105, 229, 244, 189, 41, 195, 232, 100, 84, 123, + 51, 248, 197, 55, 61, 208, 13, 30, 70, 43, 159, 226, 234, 31, 134, 102, 32, 189, 200, + 168, 0, 181, 38, 241, 185, 46, 162, 22, 111, 99, 214, 84, 92, 79, 214, 159, 30, 212, + 75, 132, 37, 163, 208, 43, 86, 226, 97, 12, 152, 79, 21, 16, 0, 90, 196, 155, 51, 41, + 61, 120, 20, 216, 130, 86, 139, 251, 167, 9, 132, 88, 46, 215, 166, 172, 116, 124, 57, + 178, 225, 186, 123, 231, 229, 0, 2, 17, 82, 94, 215, 153, 173, 171, 58, 159, 155, 198, + 53, 181, 115, 255, 237, 208, 251, 111, 23, 184, 141, 84, 2, 158, 114, 233, 77, 179, 99, + 183, 3, 180, 238, 79, 213, 151, 55, 34, 23, 196, 178, 194, 209, 228, 25, 10, 56, 10, + 46, 68, 4, 46, 31, 116, 177, 30, 132, 223, 218, 125, 113, 40, 0, 131, 73, 204, 118, 39, + 7, 137, 142, 181, 178, 235, 127, 36, 55, 251, 223, 174, 232, 74, 169, 134, 12, 5, 119, + 46, 98, 39, 158, 146, 83, 118, 0, 45, 29, 117, 108, 78, 246, 32, 115, 44, 16, 180, 188, + 174, 169, 157, 190, 229, 87, 213, 184, 246, 49, 29, 239, 135, 10, 221, 163, 150, 188, + 42, 3, 159, 86, 4, 205, 246, 27, 204, 65, 142, 255, 161, 114, 178, 148, 54, 103, 3, 3, + 67, 84, 63, 33, 143, 91, 149, 94, 196, 64, 137, 104, 182, 12, 174, 216, 149, 175, 250, + 105, 203, 112, 248, 38, 0, 1, 210, 116, 172, 44, 236, 238, 165, 241, 183, 79, 121, 20, + 140, 230, 255, 243, 174, 44, 143, 8, 16, 43, 115, 247, 196, 161, 134, 123, 127, 224, + 120, 228, 57, 113, 216, 63, 162, 250, 198, 40, 93, 88, 71, 117, 253, 114, 115, 57, 170, + 119, 63, 15, 98, 212, 149, 91, 27, 189, 213, 165, 199, 240, 224, 177, 94, 4, 63, 132, + 214, 44, 29, 150, 229, 110, 25, 104, 100, 204, 140, 163, 148, 178, 229, 8, 232, 234, + 219, 49, 104, 78, 255, 98, 254, 222, 80, 97, 224, 243, 12, 193, 6, 193, 222, 71, 21, + 253, 52, 140, 165, 64, 161, 51, 140, 67, 150, 58, 244, 119, 165, 214, 140, 139, 229, + 61, 155, 27, 98, 34, 107, 149, 118, 252, 149, 46, 44, 244, 187, 236, 90, 67, 61, 38, + 46, 59, 177, 180, 43, 15, 154, 109, 220, 238, 114, 98, 60, 180, 112, 106, 228, 177, 20, + 70, 87, 248, 194, 9, 193, 171, 183, 225, 172, 148, 69, 79, 238, 206, 115, 150, 26, 10, + 141, 201, 201, 159, 120, 210, 148, 175, 224, 12, 119, 192, 45, 245, 188, 131, 7, 116, + 168, 194, 220, 236, 198, 91, 100, 176, 15, 151, 227, 32, 65, 11, 102, 123, 81, 226, + 170, 206, 203, 74, 189, 231, 93, 156, 92, 119, 239, 213, 13, 105, 233, 26, 255, 231, + 34, 195, 153, 146, 82, 126, 86, 198, 230, 1, 189, 158, 30, 90, 82, 206, 101, 190, 234, + 59, 25, 251, 33, 185, 82, 110, 216, 136, 212, 14, 163, 234, 1, 65, 27, 95, 14, 9, 13, + 1, 215, 15, 148, 210, 23, 242, 66, 173, 90, 238, 8, 224, 75, 106, 57, 39, 69, 200, 61, + 153, 228, 106, 189, 196, 16, 95, 151, 91, 115, 218, 111, 5, 133, 1, 157, 35, 193, 213, + 165, 174, 77, 60, 40, 50, 38, 230, 234, 171, 46, 71, 127, 9, 131, 118, 156, 238, 70, + 173, 18, 116, 50, 17, 203, 242, 58, 3, 4, 255, 80, 231, 140, 101, 43, 85, 73, 251, 194, + 95, 252, 220, 239, 51, 218, 13, 100, 163, 4, 69, 172, 104, 31, 52, 41, 157, 218, 189, + 232, 15, 99, 28, 203, 224, 141, 209, 24, 163, 166, 166, 141, 207, 35, 28, 90, 131, 237, + 145, 153, 9, 230, 22, 126, 199, 8, 65, 46, 255, 55, 21, 246, 12, 93, 209, 68, 187, 255, + 114, 154, 81, 88, 178, 253, 67, 117, 102, 19, 192, 76, 160, 227, 163, 181, 4, 198, 112, + 15, 18, 38, 49, 139, 255, 59, 6, 188, 120, 76, 55, 87, 78, 162, 23, 71, 20, 180, 13, + 172, 160, 93, 210, 190, 126, 100, 156, 242, 124, 209, 21, 13, 251, 105, 207, 53, 159, + 43, 9, 83, 148, 213, 207, 223, 213, 114, 199, 243, 126, 38, 71, 2, 189, 28, 211, 19, + 223, 37, 141, 122, 136, 41, 200, 234, 4, 23, 6, 102, 197, 83, 11, 196, 0, 89, 195, 219, + 40, 126, 27, 26, 112, 131, 130, 34, 36, 10, 233, 93, 20, 191, 108, 108, 89, 139, 232, + 21, 184, 28, 179, 32, 154, 64, 15, 225, 193, 44, 238, 80, 114, 230, 200, 37, 128, 98, + 69, 133, 172, 76, 210, 197, 186, 185, 184, 56, 194, 149, 60, 201, 221, 252, 16, 249, 6, + 249, 5, 38, 206, 223, 162, 144, 146, 134, 247, 255, 228, 10, 94, 84, 13, 133, 137, 112, + 64, 238, 100, 186, 126, 213, 42, 66, 144, 80, 114, 174, 254, 9, 12, 37, 142, 39, 67, + 55, 78, 209, 213, 91, 22, 205, 243, 20, 76, 182, 91, 53, 180, 71, 67, 181, 210, 179, + 78, 109, 157, 160, 147, 77, 54, 106, 7, 195, 187, 204, 136, 216, 181, 68, 223, 227, + 159, 58, 27, 19, 255, 163, 29, 186, 59, 219, 13, 30, 34, 126, 212, 91, 1, 192, 16, 61, + 79, 59, 9, 178, 146, 171, 236, 190, 158, 203, 164, 162, 70, 201, 36, 11, 223, 73, 118, + 160, 2, 100, 234, 107, 250, 156, 26, 47, 15, 247, 29, 171, 21, 121, 216, 245, 78, 8, + 122, 191, 183, 235, 253, 227, 248, 246, 22, 93, 210, 102, 175, 191, 40, 58, 252, 241, + 251, 27, 209, 34, 249, 42, 205, 59, 207, 46, 143, 78, 234, 230, 122, 233, 152, 236, + 115, 166, 166, 72, 24, 141, 65, 213, 25, 88, 242, 74, 161, 229, 226, 0, 252, 128, 169, + 83, 46, 179, 185, 8, 146, 15, 203, 9, 116, 88, 85, 200, 157, 3, 170, 108, 41, 38, 62, + 63, 109, 184, 51, 141, 229, 113, 182, 252, 56, 113, 117, 181, 208, 41, 83, 191, 38, + 253, 161, 8, 26, 63, 227, 242, 49, 240, 193, 59, 178, 3, 197, 245, 89, 85, 30, 161, 45, + 248, 248, 91, 110, 107, 144, 12, 175, 253, 21, 121, 28, + ]; + + let new_transactions: NewTransactions = epee_serde::from_bytes(bytes).unwrap(); + + assert_eq!(4, new_transactions.txs.len()); + + for transaction in new_transactions.txs.iter() { + transaction.deserialize().unwrap(); + } + + let encoded_bytes = epee_serde::to_bytes(&new_transactions).unwrap(); + let new_transactions_2: NewTransactions = epee_serde::from_bytes(encoded_bytes).unwrap(); + + assert_eq!(new_transactions, new_transactions_2); + } + + #[test] + fn serde_notify_new_fluffy_block() { + let bytes = [ + 1, 17, 1, 1, 1, 1, 2, 1, 1, 8, 1, 98, 12, 4, 5, 98, 108, 111, 99, 107, 10, 161, 98, 16, + 16, 140, 164, 136, 156, 6, 49, 161, 93, 25, 45, 71, 46, 192, 50, 103, 189, 225, 237, + 40, 206, 185, 185, 56, 69, 131, 250, 198, 43, 26, 0, 26, 25, 93, 75, 254, 157, 49, 31, + 2, 3, 167, 2, 140, 220, 168, 1, 1, 255, 208, 219, 168, 1, 80, 250, 252, 242, 123, 3, + 183, 77, 188, 253, 60, 32, 58, 245, 14, 46, 90, 54, 86, 73, 155, 24, 153, 97, 128, 135, + 9, 232, 56, 147, 0, 204, 108, 150, 238, 213, 85, 175, 43, 158, 188, 192, 135, 4, 3, + 204, 46, 193, 70, 141, 56, 200, 90, 47, 42, 57, 83, 39, 40, 2, 191, 68, 188, 191, 192, + 233, 193, 170, 240, 184, 84, 158, 31, 243, 68, 239, 183, 64, 179, 242, 247, 129, 1, 3, + 124, 131, 127, 116, 64, 62, 207, 52, 69, 7, 233, 66, 226, 232, 210, 76, 36, 22, 245, + 157, 4, 57, 115, 88, 195, 102, 210, 213, 21, 64, 70, 144, 28, 140, 133, 178, 124, 3, + 179, 204, 27, 119, 139, 54, 182, 214, 61, 112, 90, 25, 103, 207, 89, 254, 116, 186, 13, + 101, 230, 209, 117, 18, 230, 202, 154, 136, 56, 82, 150, 93, 0, 199, 253, 171, 132, 2, + 3, 81, 180, 221, 207, 120, 93, 216, 207, 155, 0, 45, 58, 113, 180, 60, 206, 24, 136, + 77, 149, 39, 72, 235, 225, 18, 106, 50, 253, 17, 24, 167, 228, 46, 168, 166, 178, 129, + 2, 3, 23, 81, 11, 40, 189, 214, 184, 250, 33, 50, 58, 190, 136, 142, 177, 145, 90, 124, + 47, 220, 23, 95, 69, 72, 61, 88, 166, 124, 204, 145, 220, 158, 122, 154, 186, 180, 205, + 105, 3, 234, 84, 218, 103, 94, 8, 198, 168, 147, 18, 73, 40, 99, 90, 87, 173, 25, 47, + 35, 79, 157, 26, 253, 137, 66, 202, 5, 199, 240, 227, 189, 204, 229, 143, 222, 235, + 135, 2, 3, 97, 127, 94, 65, 87, 94, 145, 40, 17, 100, 240, 213, 25, 64, 73, 243, 18, + 221, 14, 249, 149, 237, 222, 247, 29, 14, 96, 101, 194, 25, 209, 227, 113, 250, 153, + 219, 104, 3, 114, 241, 143, 239, 231, 225, 164, 129, 43, 111, 163, 105, 148, 35, 41, + 214, 105, 14, 99, 230, 67, 181, 230, 105, 77, 236, 65, 16, 246, 209, 164, 71, 151, 206, + 219, 255, 125, 3, 26, 39, 116, 90, 19, 66, 187, 32, 50, 241, 68, 29, 223, 51, 95, 123, + 7, 189, 40, 53, 38, 114, 27, 9, 197, 206, 208, 164, 20, 193, 128, 55, 81, 197, 226, + 239, 125, 3, 107, 10, 42, 89, 249, 149, 16, 240, 34, 208, 194, 120, 146, 4, 180, 203, + 172, 199, 97, 74, 229, 4, 246, 175, 218, 204, 1, 158, 194, 94, 245, 248, 180, 221, 222, + 152, 155, 3, 3, 219, 188, 131, 55, 179, 251, 91, 117, 35, 147, 127, 77, 203, 220, 148, + 2, 200, 47, 123, 2, 6, 114, 127, 210, 170, 82, 69, 236, 196, 30, 138, 70, 7, 210, 191, + 159, 132, 1, 3, 185, 120, 237, 163, 233, 17, 115, 83, 169, 204, 224, 213, 225, 231, 31, + 143, 128, 121, 41, 181, 213, 12, 115, 219, 50, 220, 167, 135, 136, 180, 87, 21, 198, + 181, 178, 227, 126, 3, 243, 27, 254, 13, 49, 23, 153, 34, 80, 180, 230, 53, 146, 115, + 81, 94, 236, 43, 92, 167, 53, 128, 114, 216, 62, 149, 104, 178, 38, 213, 184, 84, 11, + 241, 174, 220, 131, 1, 3, 203, 150, 158, 182, 20, 150, 123, 22, 198, 119, 74, 3, 69, + 210, 235, 181, 205, 133, 196, 241, 14, 56, 201, 107, 127, 139, 66, 251, 147, 186, 102, + 216, 7, 135, 204, 159, 129, 1, 3, 54, 219, 16, 212, 210, 93, 25, 230, 156, 6, 251, 100, + 98, 7, 158, 43, 179, 121, 227, 167, 219, 9, 54, 168, 199, 251, 255, 180, 220, 189, 65, + 36, 181, 246, 204, 160, 253, 5, 3, 132, 191, 155, 238, 225, 193, 213, 210, 189, 55, + 254, 66, 135, 12, 145, 189, 193, 42, 57, 38, 19, 225, 81, 72, 123, 11, 205, 98, 141, + 91, 115, 130, 128, 179, 146, 128, 166, 4, 3, 114, 158, 152, 248, 140, 133, 123, 199, + 131, 202, 92, 113, 109, 165, 160, 20, 142, 37, 10, 212, 48, 75, 234, 62, 171, 222, 55, + 166, 111, 117, 134, 220, 12, 248, 246, 204, 132, 1, 3, 48, 138, 156, 70, 100, 208, 124, + 1, 93, 17, 150, 229, 127, 254, 37, 96, 178, 214, 125, 29, 104, 34, 85, 172, 166, 243, + 35, 138, 155, 113, 76, 83, 86, 246, 214, 151, 123, 3, 21, 181, 14, 233, 205, 28, 57, + 18, 68, 140, 197, 8, 88, 51, 197, 123, 53, 202, 231, 195, 177, 103, 82, 180, 71, 138, + 115, 99, 204, 165, 165, 177, 106, 204, 250, 198, 131, 1, 3, 102, 225, 42, 195, 2, 104, + 11, 179, 38, 10, 17, 192, 238, 64, 167, 231, 121, 89, 189, 185, 139, 95, 251, 108, 95, + 183, 193, 160, 242, 42, 206, 145, 163, 237, 223, 149, 129, 1, 3, 84, 38, 34, 107, 191, + 116, 151, 3, 124, 56, 107, 63, 159, 123, 69, 70, 218, 245, 63, 38, 206, 108, 30, 31, + 126, 203, 214, 151, 14, 234, 232, 179, 35, 205, 188, 213, 152, 2, 3, 236, 10, 92, 66, + 144, 31, 213, 77, 141, 110, 43, 163, 39, 38, 14, 77, 185, 208, 68, 79, 77, 119, 209, 1, + 102, 69, 53, 7, 160, 181, 255, 137, 109, 179, 180, 245, 124, 3, 6, 85, 76, 119, 239, + 166, 33, 206, 225, 15, 212, 183, 195, 161, 167, 19, 145, 184, 39, 220, 84, 100, 191, + 107, 70, 127, 110, 153, 211, 1, 41, 99, 75, 240, 229, 187, 214, 191, 2, 3, 33, 102, + 230, 92, 86, 7, 78, 170, 73, 244, 53, 90, 64, 42, 104, 246, 227, 16, 170, 251, 222, 13, + 108, 99, 199, 144, 212, 188, 55, 252, 172, 159, 243, 150, 220, 199, 159, 173, 1, 3, 30, + 38, 82, 146, 107, 165, 7, 121, 30, 136, 178, 168, 114, 25, 36, 13, 68, 191, 211, 119, + 99, 6, 17, 201, 153, 204, 15, 69, 65, 182, 79, 130, 130, 214, 198, 228, 128, 1, 3, 39, + 228, 139, 76, 120, 12, 67, 220, 189, 113, 159, 40, 191, 56, 249, 193, 94, 64, 189, 188, + 121, 132, 242, 188, 19, 162, 136, 93, 234, 49, 22, 125, 157, 151, 172, 147, 141, 9, 3, + 5, 110, 212, 221, 154, 156, 118, 233, 130, 237, 158, 6, 147, 220, 242, 196, 205, 89, + 51, 26, 207, 92, 106, 153, 127, 219, 79, 241, 47, 86, 14, 34, 85, 134, 137, 128, 135, + 5, 3, 232, 163, 75, 103, 63, 218, 176, 22, 183, 48, 231, 231, 85, 87, 156, 156, 98, 8, + 225, 165, 57, 223, 244, 24, 136, 61, 135, 182, 214, 56, 78, 17, 89, 228, 204, 225, 255, + 1, 3, 115, 142, 46, 163, 219, 167, 170, 21, 143, 238, 240, 240, 74, 212, 10, 93, 87, + 91, 227, 62, 4, 17, 138, 46, 206, 41, 41, 183, 28, 218, 129, 203, 143, 219, 143, 199, + 157, 5, 3, 52, 201, 61, 12, 18, 127, 26, 91, 223, 29, 25, 84, 109, 125, 249, 195, 223, + 9, 40, 46, 36, 227, 168, 136, 26, 154, 209, 213, 95, 182, 138, 138, 171, 233, 240, 192, + 131, 1, 3, 184, 21, 99, 38, 144, 184, 67, 98, 72, 124, 169, 189, 188, 217, 192, 5, 224, + 206, 132, 213, 35, 193, 88, 214, 78, 188, 240, 104, 233, 9, 51, 76, 192, 143, 147, 172, + 240, 3, 3, 112, 45, 221, 240, 56, 59, 36, 186, 181, 165, 140, 68, 188, 23, 37, 211, 22, + 24, 86, 87, 14, 198, 33, 69, 28, 249, 3, 160, 20, 186, 165, 143, 116, 238, 194, 178, + 131, 1, 3, 23, 170, 112, 78, 7, 204, 227, 211, 93, 245, 61, 124, 142, 26, 239, 49, 30, + 213, 119, 169, 236, 9, 246, 175, 134, 56, 108, 110, 106, 214, 239, 86, 135, 191, 210, + 232, 205, 210, 6, 3, 12, 255, 192, 121, 194, 237, 19, 17, 151, 102, 108, 103, 204, 174, + 146, 108, 97, 20, 88, 107, 113, 22, 68, 50, 90, 106, 135, 220, 150, 82, 145, 42, 174, + 238, 156, 242, 128, 1, 3, 187, 56, 99, 196, 229, 246, 146, 90, 202, 43, 147, 152, 60, + 63, 125, 222, 23, 217, 109, 85, 161, 94, 225, 112, 249, 147, 231, 186, 96, 104, 45, + 248, 30, 212, 205, 235, 129, 2, 3, 19, 135, 245, 245, 214, 149, 29, 182, 1, 116, 87, + 157, 57, 87, 69, 255, 108, 156, 242, 41, 59, 65, 73, 4, 200, 40, 189, 35, 166, 157, + 239, 175, 214, 247, 196, 161, 141, 7, 3, 26, 230, 214, 237, 51, 7, 174, 242, 206, 189, + 151, 17, 215, 29, 1, 6, 97, 21, 85, 169, 214, 0, 113, 34, 245, 247, 185, 103, 1, 55, + 122, 170, 234, 175, 246, 223, 176, 23, 3, 64, 195, 103, 77, 197, 94, 161, 86, 77, 199, + 86, 23, 144, 27, 148, 121, 191, 134, 88, 238, 249, 213, 145, 249, 98, 247, 194, 52, + 202, 153, 252, 47, 125, 236, 206, 158, 126, 3, 238, 72, 213, 179, 131, 246, 255, 97, + 203, 80, 143, 166, 57, 110, 163, 198, 100, 245, 28, 163, 160, 94, 69, 248, 60, 152, + 209, 166, 6, 185, 71, 167, 163, 145, 155, 238, 128, 1, 3, 138, 41, 107, 125, 76, 12, + 54, 116, 85, 193, 151, 253, 111, 71, 29, 148, 126, 74, 90, 99, 73, 37, 118, 181, 23, 5, + 115, 43, 238, 100, 20, 183, 104, 168, 140, 168, 132, 2, 3, 171, 116, 186, 72, 217, 51, + 62, 209, 131, 23, 86, 231, 52, 169, 209, 1, 173, 39, 238, 159, 234, 147, 177, 153, 212, + 211, 135, 202, 155, 184, 253, 109, 134, 168, 234, 181, 104, 3, 165, 207, 136, 198, 142, + 86, 253, 241, 180, 198, 94, 57, 233, 18, 155, 199, 139, 233, 174, 215, 142, 143, 84, + 170, 156, 99, 225, 145, 47, 243, 162, 38, 231, 186, 249, 149, 158, 8, 3, 226, 205, 107, + 138, 214, 189, 1, 8, 18, 120, 81, 4, 31, 146, 164, 87, 88, 152, 66, 40, 44, 180, 110, + 233, 42, 41, 130, 85, 20, 41, 143, 129, 87, 213, 222, 227, 124, 3, 174, 12, 43, 177, + 211, 82, 109, 153, 156, 122, 151, 229, 124, 63, 18, 214, 149, 12, 234, 134, 24, 115, + 147, 214, 42, 134, 140, 147, 228, 148, 135, 219, 138, 146, 239, 211, 130, 1, 3, 254, + 86, 147, 9, 140, 98, 168, 180, 174, 50, 251, 115, 190, 215, 194, 228, 253, 192, 162, + 90, 85, 10, 249, 24, 62, 211, 67, 99, 22, 146, 230, 109, 137, 230, 252, 188, 129, 1, 3, + 19, 197, 43, 33, 160, 131, 20, 30, 178, 208, 73, 139, 19, 6, 112, 57, 162, 237, 150, + 15, 141, 167, 160, 93, 100, 180, 170, 96, 175, 131, 75, 150, 127, 254, 237, 183, 127, + 3, 157, 181, 20, 71, 187, 159, 94, 134, 128, 17, 22, 250, 171, 34, 11, 251, 17, 153, + 237, 237, 46, 229, 112, 156, 19, 75, 252, 95, 241, 237, 203, 169, 70, 242, 246, 138, + 129, 1, 3, 130, 39, 111, 240, 80, 68, 64, 218, 144, 198, 5, 120, 141, 175, 42, 78, 191, + 42, 132, 2, 240, 89, 244, 96, 124, 77, 30, 144, 153, 66, 32, 136, 224, 190, 138, 138, + 157, 58, 3, 20, 85, 185, 66, 53, 81, 47, 213, 134, 231, 94, 229, 87, 93, 44, 225, 124, + 153, 41, 214, 222, 220, 7, 152, 117, 71, 246, 229, 90, 173, 104, 163, 171, 193, 246, + 154, 129, 1, 3, 112, 228, 238, 195, 117, 225, 164, 240, 35, 173, 171, 41, 246, 112, + 116, 7, 160, 32, 23, 142, 177, 62, 149, 116, 248, 26, 111, 237, 66, 192, 199, 238, 251, + 172, 187, 128, 132, 1, 3, 66, 240, 108, 170, 188, 246, 244, 59, 39, 46, 163, 64, 40, + 133, 105, 251, 240, 203, 30, 173, 87, 9, 68, 156, 123, 118, 120, 215, 35, 192, 168, 91, + 115, 239, 168, 152, 239, 5, 3, 234, 161, 19, 160, 80, 117, 105, 142, 139, 2, 250, 191, + 30, 209, 120, 238, 69, 116, 106, 33, 43, 204, 37, 174, 62, 12, 125, 112, 152, 165, 153, + 108, 14, 215, 149, 235, 127, 3, 218, 207, 61, 96, 63, 169, 207, 116, 134, 184, 9, 9, + 195, 119, 15, 7, 48, 140, 179, 250, 116, 163, 17, 249, 35, 98, 111, 9, 234, 222, 237, + 199, 41, 167, 169, 178, 129, 4, 3, 193, 88, 180, 154, 187, 167, 55, 244, 142, 135, 28, + 59, 120, 254, 125, 227, 222, 63, 217, 180, 227, 183, 68, 56, 81, 117, 85, 80, 27, 43, + 171, 117, 169, 231, 191, 136, 255, 1, 3, 221, 225, 184, 20, 58, 162, 35, 190, 129, 242, + 121, 155, 83, 87, 29, 66, 119, 156, 136, 62, 161, 194, 57, 176, 210, 164, 29, 194, 85, + 59, 101, 83, 248, 132, 203, 156, 143, 2, 3, 115, 92, 232, 127, 54, 72, 152, 95, 8, 52, + 233, 251, 230, 187, 214, 29, 140, 194, 36, 202, 194, 248, 41, 109, 36, 4, 91, 161, 205, + 21, 132, 221, 137, 191, 138, 213, 130, 1, 3, 93, 198, 84, 162, 44, 171, 107, 150, 227, + 134, 4, 244, 129, 24, 18, 44, 238, 152, 90, 200, 178, 39, 180, 252, 20, 226, 118, 100, + 201, 75, 192, 87, 147, 244, 173, 245, 129, 2, 3, 141, 107, 166, 116, 191, 106, 19, 178, + 108, 124, 117, 48, 196, 182, 178, 179, 30, 192, 160, 230, 171, 52, 191, 205, 153, 239, + 228, 220, 93, 190, 44, 171, 30, 220, 154, 212, 128, 1, 3, 126, 51, 135, 155, 51, 43, + 83, 134, 135, 116, 93, 95, 15, 138, 121, 84, 6, 231, 202, 125, 43, 146, 219, 75, 107, + 21, 229, 33, 46, 183, 32, 178, 196, 150, 248, 140, 129, 1, 3, 252, 191, 53, 103, 190, + 239, 10, 45, 166, 108, 202, 167, 130, 221, 101, 122, 89, 34, 127, 130, 84, 199, 47, + 231, 40, 166, 54, 123, 244, 218, 163, 141, 255, 152, 135, 220, 151, 60, 3, 35, 9, 209, + 159, 224, 165, 170, 87, 151, 210, 238, 176, 159, 167, 144, 139, 91, 57, 93, 181, 166, + 41, 249, 70, 125, 160, 199, 87, 103, 127, 207, 128, 130, 205, 232, 252, 232, 4, 3, 81, + 79, 136, 56, 29, 96, 84, 45, 7, 149, 21, 14, 46, 116, 24, 90, 132, 219, 9, 41, 189, + 247, 217, 132, 105, 117, 202, 97, 55, 211, 91, 183, 58, 247, 198, 159, 125, 3, 219, 71, + 45, 240, 184, 98, 2, 93, 11, 134, 118, 64, 133, 249, 172, 240, 195, 36, 148, 4, 129, + 53, 93, 66, 51, 202, 95, 34, 254, 90, 236, 119, 168, 185, 251, 161, 131, 1, 3, 67, 116, + 151, 6, 88, 238, 134, 253, 132, 111, 168, 46, 159, 138, 185, 66, 238, 57, 136, 9, 218, + 120, 153, 117, 105, 241, 111, 128, 44, 199, 181, 125, 252, 244, 236, 236, 152, 4, 3, + 70, 113, 123, 8, 203, 96, 249, 238, 140, 63, 52, 102, 105, 3, 26, 133, 251, 222, 30, + 250, 190, 81, 49, 58, 5, 63, 85, 223, 61, 112, 164, 241, 207, 168, 156, 181, 131, 6, 3, + 107, 72, 13, 16, 24, 51, 79, 160, 255, 17, 145, 125, 170, 224, 159, 209, 181, 1, 67, + 175, 215, 28, 204, 100, 186, 8, 165, 98, 133, 253, 10, 73, 116, 139, 245, 202, 151, + 139, 4, 3, 253, 58, 194, 0, 47, 244, 117, 150, 68, 156, 46, 78, 42, 20, 14, 104, 122, + 159, 114, 241, 184, 225, 140, 122, 165, 156, 25, 195, 47, 81, 79, 144, 210, 168, 242, + 245, 212, 10, 3, 235, 84, 46, 107, 209, 155, 64, 137, 11, 238, 31, 103, 76, 26, 221, + 78, 5, 1, 63, 219, 143, 229, 178, 220, 173, 192, 219, 214, 59, 219, 223, 239, 208, 239, + 165, 229, 128, 1, 3, 166, 165, 45, 105, 184, 38, 228, 214, 202, 119, 173, 150, 254, + 219, 10, 24, 241, 239, 155, 254, 59, 40, 240, 118, 238, 213, 106, 161, 16, 16, 61, 50, + 237, 185, 165, 226, 132, 2, 3, 1, 97, 94, 41, 143, 250, 229, 96, 95, 45, 52, 213, 11, + 6, 27, 192, 125, 195, 29, 192, 158, 164, 57, 169, 79, 87, 68, 7, 131, 197, 68, 230, + 231, 235, 190, 191, 123, 3, 189, 74, 195, 239, 42, 45, 188, 17, 22, 206, 243, 222, 241, + 201, 40, 17, 159, 17, 127, 236, 161, 75, 198, 235, 190, 115, 132, 69, 237, 244, 184, 8, + 27, 141, 192, 192, 129, 1, 3, 37, 103, 171, 180, 254, 123, 176, 191, 82, 161, 189, 42, + 193, 50, 241, 120, 22, 140, 62, 98, 143, 92, 209, 61, 36, 47, 233, 234, 140, 32, 18, + 34, 41, 177, 247, 150, 209, 20, 3, 198, 7, 153, 138, 157, 60, 105, 172, 208, 188, 119, + 183, 134, 190, 64, 162, 88, 21, 190, 97, 80, 173, 91, 59, 128, 66, 4, 110, 99, 31, 203, + 222, 104, 132, 176, 145, 131, 1, 3, 52, 188, 19, 32, 43, 137, 136, 134, 216, 13, 166, + 144, 89, 165, 67, 127, 124, 13, 128, 187, 25, 151, 17, 64, 120, 232, 154, 196, 218, + 121, 27, 232, 122, 176, 237, 147, 129, 1, 3, 93, 81, 215, 108, 40, 1, 121, 45, 180, + 241, 112, 157, 47, 9, 175, 106, 34, 240, 76, 97, 87, 217, 125, 140, 134, 163, 213, 116, + 106, 7, 74, 7, 16, 249, 249, 249, 132, 2, 3, 147, 248, 217, 118, 172, 12, 60, 87, 211, + 132, 235, 251, 196, 8, 138, 244, 86, 11, 188, 11, 173, 213, 131, 141, 242, 226, 27, + 226, 209, 165, 191, 4, 203, 228, 206, 156, 131, 2, 3, 96, 135, 31, 118, 16, 175, 51, + 232, 182, 57, 175, 113, 199, 58, 200, 42, 87, 205, 106, 56, 114, 247, 203, 57, 187, + 210, 64, 229, 240, 21, 15, 89, 155, 206, 224, 227, 185, 15, 3, 213, 174, 237, 38, 137, + 161, 166, 22, 250, 190, 38, 53, 162, 72, 61, 104, 76, 251, 178, 113, 243, 195, 212, + 140, 75, 33, 146, 234, 240, 92, 230, 166, 134, 211, 154, 194, 138, 7, 3, 209, 234, 31, + 70, 188, 125, 63, 140, 207, 214, 237, 237, 251, 194, 19, 215, 102, 233, 242, 86, 151, + 186, 132, 112, 149, 6, 35, 131, 251, 5, 239, 190, 157, 73, 1, 190, 47, 58, 49, 109, + 223, 242, 235, 155, 152, 255, 65, 116, 25, 24, 149, 146, 144, 30, 8, 150, 106, 129, + 241, 77, 167, 210, 126, 43, 11, 247, 150, 2, 4, 243, 221, 94, 176, 3, 32, 230, 222, + 234, 62, 23, 138, 112, 133, 94, 48, 17, 141, 27, 248, 89, 154, 154, 237, 224, 70, 6, + 216, 88, 134, 42, 43, 78, 99, 127, 116, 178, 62, 0, 96, 78, 174, 240, 87, 120, 243, 39, + 191, 99, 150, 206, 105, 9, 176, 171, 113, 205, 150, 153, 243, 103, 229, 22, 164, 15, + 241, 245, 119, 20, 113, 29, 194, 183, 171, 171, 230, 143, 216, 240, 106, 137, 113, 157, + 187, 24, 69, 233, 136, 159, 128, 193, 208, 149, 79, 199, 15, 241, 106, 199, 116, 102, + 78, 40, 133, 42, 238, 155, 237, 231, 104, 162, 14, 153, 171, 96, 132, 60, 234, 88, 34, + 26, 231, 71, 23, 118, 237, 107, 77, 76, 141, 79, 137, 77, 129, 254, 141, 90, 143, 115, + 225, 207, 6, 187, 236, 203, 129, 158, 2, 252, 150, 200, 63, 166, 12, 81, 165, 197, 202, + 218, 179, 71, 128, 93, 81, 181, 73, 5, 6, 0, 251, 202, 10, 108, 235, 123, 59, 32, 46, + 118, 90, 167, 210, 95, 17, 30, 4, 170, 1, 21, 93, 28, 108, 241, 254, 22, 240, 14, 131, + 132, 64, 15, 43, 230, 81, 18, 77, 27, 189, 97, 245, 117, 60, 140, 133, 197, 194, 110, + 237, 56, 135, 255, 82, 194, 125, 27, 124, 207, 187, 68, 194, 89, 70, 42, 148, 202, 178, + 138, 154, 139, 246, 25, 252, 13, 223, 37, 167, 150, 244, 109, 154, 152, 89, 16, 179, + 253, 75, 0, 29, 115, 31, 54, 43, 219, 204, 45, 49, 174, 8, 135, 134, 168, 107, 105, 31, + 47, 120, 55, 180, 61, 223, 161, 1, 143, 111, 239, 209, 232, 50, 74, 73, 63, 78, 109, + 23, 97, 221, 4, 212, 180, 55, 8, 221, 141, 146, 145, 175, 116, 248, 32, 240, 189, 124, + 16, 30, 66, 206, 5, 72, 216, 167, 255, 11, 201, 105, 129, 151, 143, 26, 245, 149, 34, + 86, 127, 184, 221, 219, 137, 234, 152, 126, 10, 116, 60, 203, 94, 28, 96, 110, 59, 172, + 252, 112, 230, 140, 42, 152, 179, 226, 34, 164, 120, 221, 31, 36, 24, 160, 100, 44, + 253, 4, 174, 17, 231, 1, 117, 184, 169, 97, 69, 123, 172, 68, 12, 150, 168, 117, 39, + 194, 241, 13, 103, 114, 18, 253, 140, 214, 15, 17, 7, 133, 9, 177, 134, 210, 20, 167, + 20, 95, 163, 187, 193, 113, 190, 219, 213, 56, 20, 235, 6, 153, 246, 59, 76, 125, 111, + 122, 198, 181, 121, 44, 21, 36, 158, 108, 86, 94, 64, 194, 234, 33, 231, 60, 23, 158, + 78, 200, 91, 8, 52, 179, 86, 12, 237, 195, 108, 222, 166, 102, 180, 168, 78, 95, 218, + 56, 131, 177, 100, 244, 131, 243, 247, 144, 220, 62, 231, 244, 184, 67, 71, 122, 8, + 252, 210, 191, 99, 81, 130, 113, 48, 46, 194, 3, 21, 108, 243, 22, 201, 193, 160, 94, + 148, 63, 67, 18, 249, 108, 40, 70, 87, 10, 74, 62, 191, 176, 218, 196, 41, 199, 11, + 235, 85, 163, 38, 148, 25, 110, 34, 158, 186, 207, 24, 100, 122, 11, 60, 221, 18, 131, + 10, 217, 57, 171, 47, 244, 29, 251, 187, 27, 241, 169, 79, 184, 178, 51, 251, 120, 52, + 229, 119, 242, 173, 68, 222, 135, 119, 79, 111, 89, 4, 23, 17, 169, 37, 9, 37, 166, + 167, 60, 229, 147, 158, 237, 171, 62, 106, 126, 48, 46, 130, 72, 167, 156, 140, 220, + 229, 100, 136, 136, 70, 212, 104, 52, 0, 143, 217, 31, 193, 158, 189, 218, 73, 54, 137, + 11, 108, 61, 225, 138, 190, 143, 95, 135, 226, 168, 55, 71, 111, 48, 61, 90, 104, 254, + 188, 152, 42, 5, 95, 241, 162, 6, 78, 195, 211, 251, 128, 207, 37, 214, 204, 234, 140, + 36, 205, 155, 244, 131, 14, 175, 193, 43, 42, 19, 140, 231, 163, 234, 244, 24, 28, 194, + 210, 51, 193, 22, 129, 135, 56, 155, 73, 61, 107, 41, 81, 204, 0, 118, 99, 25, 85, 132, + 66, 163, 189, 90, 48, 148, 28, 221, 2, 63, 243, 132, 79, 35, 17, 137, 3, 19, 107, 57, + 12, 28, 84, 199, 152, 237, 187, 37, 48, 131, 85, 30, 222, 7, 15, 152, 75, 10, 74, 82, + 188, 178, 122, 57, 99, 252, 10, 220, 105, 60, 63, 108, 181, 41, 61, 242, 161, 40, 81, + 25, 125, 139, 2, 125, 19, 99, 239, 190, 117, 5, 224, 148, 162, 248, 188, 70, 198, 216, + 147, 184, 115, 58, 188, 57, 130, 120, 72, 107, 190, 155, 73, 238, 6, 220, 138, 29, 23, + 93, 129, 113, 122, 63, 218, 150, 112, 45, 74, 117, 63, 7, 133, 251, 169, 228, 21, 242, + 118, 175, 213, 24, 237, 112, 140, 85, 44, 196, 194, 126, 72, 235, 56, 33, 94, 164, 90, + 154, 24, 205, 97, 226, 31, 155, 23, 16, 246, 37, 165, 117, 16, 38, 54, 153, 179, 206, + 237, 113, 219, 167, 179, 151, 100, 131, 157, 104, 216, 47, 22, 18, 91, 151, 27, 190, + 135, 208, 82, 192, 231, 74, 226, 187, 15, 192, 112, 239, 132, 214, 253, 36, 79, 104, + 241, 142, 45, 53, 45, 190, 189, 195, 242, 90, 29, 165, 76, 36, 208, 1, 224, 23, 229, + 109, 130, 117, 50, 74, 142, 49, 161, 143, 165, 87, 67, 241, 83, 52, 52, 250, 12, 160, + 228, 100, 122, 32, 4, 12, 250, 13, 2, 182, 236, 130, 127, 166, 245, 218, 107, 41, 145, + 168, 62, 196, 188, 223, 35, 136, 72, 90, 152, 37, 22, 133, 107, 197, 79, 131, 8, 52, + 108, 229, 230, 89, 103, 45, 106, 110, 226, 117, 175, 99, 226, 64, 151, 179, 82, 220, + 159, 199, 217, 6, 104, 29, 84, 73, 178, 98, 55, 95, 22, 230, 16, 34, 13, 52, 57, 79, + 100, 139, 32, 119, 153, 154, 131, 16, 64, 70, 85, 27, 160, 202, 25, 207, 78, 39, 72, + 49, 71, 144, 221, 208, 144, 95, 162, 49, 133, 130, 15, 140, 197, 182, 18, 128, 182, + 219, 115, 71, 179, 82, 40, 119, 39, 229, 90, 54, 221, 70, 205, 24, 17, 2, 22, 231, 12, + 10, 226, 110, 171, 214, 22, 132, 32, 71, 173, 108, 44, 233, 209, 55, 176, 88, 169, 112, + 215, 84, 22, 56, 134, 90, 25, 67, 6, 166, 61, 87, 2, 191, 13, 111, 208, 218, 236, 197, + 201, 70, 248, 92, 190, 239, 123, 215, 10, 10, 19, 255, 248, 21, 105, 164, 73, 183, 88, + 216, 53, 128, 1, 55, 245, 210, 12, 65, 80, 102, 19, 227, 36, 207, 82, 234, 51, 64, 31, + 202, 71, 23, 97, 183, 169, 176, 69, 126, 103, 43, 160, 115, 50, 174, 84, 38, 34, 253, + 172, 48, 217, 182, 139, 88, 175, 246, 161, 222, 71, 133, 25, 235, 38, 222, 26, 35, 16, + 181, 59, 161, 192, 231, 125, 232, 30, 155, 189, 17, 31, 168, 103, 51, 137, 137, 18, + 232, 196, 116, 93, 23, 179, 238, 181, 225, 188, 14, 183, 73, 202, 167, 238, 217, 139, + 37, 39, 190, 75, 213, 94, 170, 153, 149, 71, 77, 180, 182, 21, 181, 159, 214, 218, 107, + 247, 132, 80, 53, 23, 135, 114, 190, 168, 76, 82, 97, 115, 58, 169, 247, 92, 217, 36, + 247, 228, 166, 106, 248, 4, 228, 152, 89, 60, 44, 201, 201, 119, 80, 239, 201, 17, 12, + 67, 104, 95, 119, 20, 79, 55, 108, 132, 221, 18, 87, 185, 175, 110, 238, 89, 54, 73, + 177, 190, 237, 60, 217, 151, 72, 43, 157, 216, 92, 60, 172, 255, 79, 210, 112, 203, + 115, 33, 36, 197, 133, 178, 218, 139, 84, 59, 102, 97, 86, 231, 149, 224, 23, 16, 225, + 31, 179, 56, 72, 198, 205, 249, 163, 165, 37, 91, 181, 5, 177, 3, 13, 128, 30, 173, 15, + 223, 194, 36, 108, 57, 181, 122, 43, 7, 163, 135, 43, 32, 194, 122, 32, 58, 61, 211, + 40, 70, 70, 11, 69, 196, 195, 178, 46, 87, 243, 193, 251, 235, 37, 101, 48, 151, 83, + 170, 22, 68, 8, 7, 81, 243, 205, 149, 89, 198, 253, 112, 85, 211, 203, 39, 29, 69, 212, + 152, 48, 126, 19, 178, 45, 232, 171, 104, 63, 122, 31, 143, 219, 98, 174, 173, 89, 5, + 16, 79, 72, 128, 192, 103, 212, 122, 199, 220, 57, 149, 27, 173, 184, 215, 93, 76, 123, + 225, 31, 90, 142, 69, 9, 102, 179, 109, 204, 197, 245, 24, 248, 4, 190, 243, 117, 23, + 127, 192, 119, 234, 37, 36, 10, 42, 177, 57, 135, 100, 229, 88, 43, 125, 51, 136, 227, + 161, 178, 85, 29, 44, 198, 167, 154, 24, 228, 65, 72, 3, 108, 206, 207, 131, 177, 228, + 171, 170, 10, 51, 177, 186, 212, 9, 178, 97, 67, 102, 48, 137, 177, 160, 240, 221, 126, + 4, 12, 80, 220, 181, 45, 30, 78, 33, 204, 167, 27, 242, 91, 125, 172, 90, 146, 114, 70, + 231, 24, 153, 170, 74, 222, 77, 218, 46, 32, 97, 64, 140, 159, 241, 203, 118, 90, 106, + 148, 23, 161, 78, 216, 55, 49, 61, 93, 103, 66, 237, 106, 64, 251, 15, 228, 223, 176, + 254, 212, 15, 181, 53, 60, 243, 60, 87, 226, 186, 12, 99, 43, 205, 10, 183, 139, 249, + 182, 131, 232, 99, 83, 77, 141, 176, 133, 13, 33, 68, 87, 31, 169, 101, 53, 114, 47, + 23, 61, 14, 188, 152, 85, 119, 111, 173, 34, 128, 22, 190, 54, 51, 114, 165, 32, 139, + 208, 188, 12, 22, 230, 254, 115, 150, 100, 23, 64, 100, 212, 6, 90, 84, 204, 19, 117, + 161, 17, 27, 142, 61, 102, 42, 62, 11, 146, 22, 222, 58, 81, 224, 113, 214, 215, 243, + 32, 153, 132, 157, 2, 178, 188, 243, 131, 140, 67, 236, 32, 153, 117, 46, 109, 94, 135, + 127, 203, 201, 83, 100, 100, 122, 176, 219, 178, 172, 40, 196, 208, 184, 215, 57, 145, + 68, 130, 100, 105, 146, 194, 182, 214, 92, 246, 168, 73, 28, 131, 227, 85, 216, 92, + 221, 193, 19, 232, 23, 16, 247, 199, 233, 192, 37, 215, 198, 43, 235, 69, 68, 20, 238, + 73, 188, 74, 103, 154, 111, 141, 170, 33, 230, 251, 73, 156, 240, 197, 227, 20, 47, + 167, 129, 149, 103, 216, 11, 207, 124, 66, 253, 73, 138, 166, 21, 68, 167, 151, 87, 12, + 53, 88, 89, 168, 51, 51, 95, 7, 131, 225, 146, 149, 129, 30, 140, 111, 181, 70, 8, 228, + 168, 171, 231, 37, 3, 237, 169, 87, 79, 239, 203, 156, 45, 100, 85, 201, 95, 60, 174, + 15, 209, 116, 25, 78, 157, 248, 205, 152, 52, 220, 167, 121, 92, 236, 107, 232, 196, + 30, 48, 184, 181, 48, 137, 63, 198, 163, 8, 25, 62, 230, 169, 110, 96, 2, 169, 232, 64, + 146, 125, 90, 201, 183, 128, 97, 70, 176, 83, 156, 252, 37, 128, 120, 160, 227, 62, + 209, 98, 5, 211, 18, 37, 177, 65, 182, 177, 161, 60, 222, 61, 217, 247, 98, 216, 28, + 132, 45, 94, 204, 183, 147, 215, 158, 148, 119, 150, 20, 206, 120, 209, 88, 227, 177, + 117, 7, 155, 233, 125, 80, 70, 243, 244, 116, 157, 159, 145, 220, 17, 124, 128, 5, 253, + 69, 126, 146, 105, 91, 171, 65, 229, 159, 116, 185, 133, 136, 14, 130, 25, 98, 175, + 244, 209, 117, 131, 188, 56, 230, 163, 176, 210, 88, 190, 171, 139, 1, 162, 137, 195, + 177, 87, 226, 71, 49, 214, 131, 214, 27, 177, 235, 185, 166, 121, 57, 47, 231, 236, + 137, 76, 193, 9, 92, 146, 130, 238, 141, 38, 36, 187, 3, 105, 14, 182, 207, 29, 79, 62, + 106, 52, 218, 20, 74, 206, 4, 123, 12, 247, 59, 35, 2, 140, 206, 81, 0, 229, 50, 232, + 205, 156, 41, 220, 54, 39, 199, 174, 199, 176, 57, 24, 201, 248, 216, 142, 138, 144, + 54, 105, 75, 234, 134, 83, 41, 9, 107, 25, 254, 162, 47, 241, 189, 130, 229, 101, 56, + 127, 214, 225, 61, 29, 18, 79, 105, 150, 161, 46, 90, 253, 217, 148, 110, 176, 155, + 226, 167, 212, 18, 201, 201, 200, 41, 111, 253, 37, 98, 243, 29, 112, 14, 249, 251, + 102, 66, 63, 183, 103, 120, 138, 60, 163, 200, 251, 196, 62, 67, 171, 91, 151, 160, 4, + 88, 182, 27, 18, 176, 200, 131, 120, 48, 181, 114, 184, 168, 143, 139, 233, 110, 145, + 226, 32, 168, 210, 81, 97, 146, 121, 170, 59, 204, 140, 62, 29, 9, 216, 86, 253, 232, + 78, 218, 137, 18, 148, 16, 217, 231, 206, 244, 149, 220, 56, 63, 22, 54, 43, 71, 115, + 52, 138, 51, 91, 173, 204, 131, 96, 199, 168, 200, 164, 208, 40, 116, 238, 147, 171, + 240, 57, 203, 115, 37, 131, 154, 60, 52, 153, 23, 27, 199, 40, 207, 255, 204, 208, 81, + 171, 103, 68, 157, 130, 52, 73, 137, 175, 114, 130, 201, 153, 188, 223, 23, 67, 185, + 99, 231, 117, 148, 44, 73, 220, 157, 52, 20, 209, 145, 96, 162, 240, 40, 83, 30, 167, + 111, 199, 139, 51, 92, 198, 182, 183, 236, 182, 63, 189, 242, 73, 228, 215, 186, 192, + 224, 22, 166, 242, 39, 149, 127, 56, 212, 159, 114, 111, 156, 98, 191, 147, 83, 168, + 134, 96, 214, 147, 137, 254, 45, 104, 225, 149, 128, 85, 30, 213, 113, 91, 39, 142, + 151, 179, 109, 104, 228, 143, 197, 13, 20, 210, 240, 44, 12, 218, 10, 134, 205, 41, 94, + 106, 207, 104, 130, 24, 30, 198, 111, 226, 147, 118, 43, 253, 35, 198, 122, 138, 202, + 71, 233, 19, 170, 200, 72, 205, 14, 121, 59, 79, 194, 110, 55, 146, 163, 0, 223, 194, + 135, 151, 140, 142, 212, 195, 33, 50, 227, 225, 128, 231, 66, 28, 176, 37, 208, 51, + 221, 231, 249, 251, 187, 252, 215, 169, 42, 172, 160, 149, 4, 145, 220, 143, 205, 150, + 30, 23, 234, 1, 104, 200, 79, 122, 137, 245, 167, 71, 76, 77, 176, 78, 34, 236, 102, + 233, 212, 223, 244, 3, 242, 113, 12, 105, 80, 94, 56, 68, 210, 186, 66, 122, 181, 181, + 40, 100, 57, 7, 74, 208, 147, 74, 123, 71, 115, 29, 225, 241, 24, 144, 150, 216, 37, + 56, 205, 168, 115, 252, 218, 41, 19, 60, 166, 140, 227, 129, 75, 162, 109, 133, 235, + 14, 91, 62, 39, 102, 156, 203, 21, 147, 103, 252, 13, 1, 106, 125, 211, 136, 212, 89, + 16, 5, 191, 34, 99, 47, 151, 219, 64, 151, 233, 96, 47, 152, 237, 141, 88, 89, 21, 42, + 245, 247, 95, 250, 254, 227, 136, 7, 175, 64, 7, 164, 72, 244, 16, 17, 17, 91, 120, + 179, 33, 240, 116, 159, 90, 69, 168, 120, 59, 62, 5, 209, 134, 182, 86, 94, 62, 48, + 101, 46, 224, 142, 230, 13, 32, 135, 150, 144, 128, 238, 220, 155, 137, 4, 95, 90, 57, + 122, 111, 80, 172, 35, 69, 250, 162, 3, 56, 255, 152, 58, 253, 32, 121, 90, 99, 53, + 155, 21, 185, 93, 144, 64, 110, 109, 33, 188, 75, 169, 229, 104, 237, 193, 105, 222, + 250, 250, 230, 90, 54, 179, 235, 149, 34, 37, 51, 108, 66, 76, 115, 212, 120, 223, 207, + 111, 209, 204, 113, 206, 12, 29, 248, 206, 160, 234, 100, 190, 13, 155, 34, 122, 172, + 84, 157, 236, 111, 206, 175, 233, 52, 40, 9, 235, 65, 250, 51, 52, 83, 97, 100, 237, + 118, 26, 240, 219, 52, 142, 82, 149, 79, 178, 240, 99, 117, 23, 105, 62, 150, 0, 115, + 162, 103, 221, 38, 101, 247, 213, 252, 51, 109, 179, 212, 63, 182, 140, 37, 251, 104, + 234, 120, 171, 31, 188, 160, 92, 32, 31, 236, 147, 173, 146, 89, 177, 43, 206, 99, 0, + 62, 116, 148, 199, 152, 140, 191, 254, 163, 174, 119, 79, 114, 172, 168, 5, 104, 208, + 122, 236, 83, 138, 21, 102, 218, 133, 5, 162, 254, 58, 190, 162, 87, 6, 37, 221, 85, + 128, 249, 113, 204, 59, 176, 121, 76, 224, 248, 77, 7, 194, 199, 182, 74, 25, 81, 244, + 1, 21, 103, 127, 242, 0, 188, 225, 67, 192, 81, 248, 173, 123, 79, 185, 88, 246, 79, + 177, 111, 174, 2, 196, 165, 166, 83, 48, 41, 194, 37, 95, 187, 130, 99, 75, 48, 164, + 23, 251, 194, 246, 161, 229, 194, 210, 53, 38, 86, 118, 214, 167, 16, 164, 61, 109, + 132, 104, 98, 193, 178, 117, 135, 205, 193, 135, 220, 118, 128, 171, 203, 34, 152, 220, + 162, 227, 92, 204, 216, 125, 111, 102, 250, 47, 102, 251, 207, 189, 80, 228, 91, 71, + 82, 98, 67, 200, 198, 156, 57, 150, 114, 102, 192, 49, 131, 43, 27, 95, 228, 241, 1, + 121, 207, 55, 6, 7, 244, 173, 7, 155, 79, 109, 218, 71, 95, 219, 198, 161, 249, 170, + 81, 185, 36, 28, 210, 184, 55, 173, 202, 122, 42, 178, 101, 41, 4, 110, 186, 233, 210, + 182, 154, 75, 8, 239, 104, 108, 128, 217, 83, 235, 106, 155, 9, 60, 217, 30, 12, 48, + 122, 180, 19, 64, 43, 203, 209, 156, 48, 246, 68, 59, 197, 176, 62, 158, 210, 137, 247, + 74, 88, 249, 245, 19, 82, 62, 135, 226, 71, 141, 151, 179, 184, 232, 229, 196, 9, 207, + 228, 211, 27, 87, 228, 252, 191, 242, 30, 15, 99, 53, 93, 233, 37, 96, 94, 11, 17, 58, + 1, 239, 236, 44, 2, 12, 85, 87, 248, 98, 199, 243, 26, 71, 129, 47, 13, 52, 184, 218, + 58, 170, 47, 242, 87, 139, 42, 173, 237, 131, 151, 221, 51, 214, 224, 180, 207, 219, + 71, 152, 163, 228, 14, 5, 144, 245, 121, 232, 178, 247, 22, 193, 165, 27, 118, 239, + 121, 49, 216, 40, 215, 186, 159, 112, 185, 136, 153, 103, 165, 6, 147, 238, 150, 174, + 117, 76, 152, 104, 49, 156, 133, 35, 133, 128, 18, 142, 127, 158, 60, 119, 16, 48, 242, + 37, 73, 209, 238, 166, 125, 126, 170, 31, 164, 173, 134, 167, 212, 188, 59, 59, 215, + 197, 208, 100, 8, 3, 73, 43, 62, 121, 95, 215, 152, 164, 27, 25, 99, 117, 114, 114, + 101, 110, 116, 95, 98, 108, 111, 99, 107, 99, 104, 97, 105, 110, 95, 104, 101, 105, + 103, 104, 116, 5, 209, 45, 42, 0, 0, 0, 0, 0, + ]; + let fluffy_block: NewFluffyBlock = epee_serde::from_bytes(bytes).unwrap(); + let hash = + Hash::from_str("0x0bb7f7cfc8fcf55d3da64093a9ef7e9efb57e14249ef6a392b407aeecb1cd844") + .unwrap(); + + assert_eq!(hash, fluffy_block.b.block.id()); + + let encoded_bytes = epee_serde::to_bytes(&fluffy_block).unwrap(); + let fluffy_block_2: NewFluffyBlock = epee_serde::from_bytes(encoded_bytes).unwrap(); + + assert_eq!(fluffy_block, fluffy_block_2); + } +} diff --git a/net/monero-wire/src/network_address.rs b/net/monero-wire/src/network_address.rs new file mode 100644 index 0000000..74bb052 --- /dev/null +++ b/net/monero-wire/src/network_address.rs @@ -0,0 +1,144 @@ +//! This module defines the addresses that will get passed around the +//! Monero network. Core Monero has 4 main addresses: IPv4, IPv6, Tor, +//! I2p. Currently this module only has IPv(4/6). +//! +use std::{hash::Hash, net}; + +use epee_serde::Value; +use serde::{de, ser::SerializeStruct, Deserialize, Serialize}; + +/// An IPv4 address with a port +#[derive(Clone, Copy, Serialize, Debug, PartialEq, Eq, Hash)] +pub struct IPv4Address { + /// IP address + pub m_ip: u32, + /// Port + pub m_port: u16, +} + +impl From for IPv4Address { + fn from(value: net::SocketAddrV4) -> Self { + IPv4Address { + m_ip: u32::from_le_bytes(value.ip().octets()), + m_port: value.port(), + } + } +} + +impl IPv4Address { + fn from_value(value: &Value) -> Result { + let m_ip = get_val_from_map!(value, "m_ip", get_u32, "u32"); + + let m_port = get_val_from_map!(value, "m_port", get_u16, "u16"); + + Ok(IPv4Address { + m_ip: *m_ip, + m_port: *m_port, + }) + } +} + +/// An IPv6 address with a port +#[derive(Clone, Copy, Serialize, Debug, PartialEq, Eq, Hash)] +pub struct IPv6Address { + /// Address + pub addr: [u8; 16], + /// Port + pub m_port: u16, +} + +impl From for IPv6Address { + fn from(value: net::SocketAddrV6) -> Self { + IPv6Address { + addr: value.ip().octets(), + m_port: value.port(), + } + } +} + +impl IPv6Address { + fn from_value(value: &Value) -> Result { + let addr = get_val_from_map!(value, "addr", get_bytes, "Vec"); + + let m_port = get_val_from_map!(value, "m_port", get_u16, "u16"); + + Ok(IPv6Address { + addr: addr + .clone() + .try_into() + .map_err(|_| E::invalid_length(addr.len(), &"a 16-byte array"))?, + m_port: *m_port, + }) + } +} + +/// A network address which can be encoded into the format required +/// to send to other Monero peers. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum NetworkAddress { + /// IPv4 + IPv4(IPv4Address), + /// IPv6 + IPv6(IPv6Address), +} + +impl From for NetworkAddress { + fn from(value: net::SocketAddrV4) -> Self { + NetworkAddress::IPv4(value.into()) + } +} + +impl From for NetworkAddress { + fn from(value: net::SocketAddrV6) -> Self { + NetworkAddress::IPv6(value.into()) + } +} + +impl From for NetworkAddress { + fn from(value: net::SocketAddr) -> Self { + match value { + net::SocketAddr::V4(v4) => v4.into(), + net::SocketAddr::V6(v6) => v6.into(), + } + } +} + +impl<'de> Deserialize<'de> for NetworkAddress { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let value = Value::deserialize(deserializer)?; + let addr_type = get_val_from_map!(value, "type", get_u8, "u8"); + + Ok(match addr_type { + 1 => NetworkAddress::IPv4(IPv4Address::from_value(get_field_from_map!(value, "addr"))?), + 2 => NetworkAddress::IPv6(IPv6Address::from_value(get_field_from_map!(value, "addr"))?), + _ => { + return Err(de::Error::custom( + "Network address type currently unsupported", + )) + } + }) + } +} + +impl Serialize for NetworkAddress { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("", 2)?; + match self { + NetworkAddress::IPv4(v) => { + state.serialize_field("type", &1_u8)?; + state.serialize_field("addr", v)?; + } + NetworkAddress::IPv6(v) => { + state.serialize_field("type", &2_u8)?; + state.serialize_field("addr", v)?; + } + } + state.end() + } +}