From 6351982cb2ca3525f34f1fbc1e43a90a18f0f4f9 Mon Sep 17 00:00:00 2001 From: Richard Hua Date: Fri, 2 Feb 2024 15:29:54 -0800 Subject: [PATCH] Add legacy credential type (#425) This adds the legacy credential type. Support for generating these credentials will be added in the next PR. - Apply the changes from https://github.com/xmtp/proto/pull/131 - Add ValidatedLegacySignedPublicKey type and tests - Add LegacyCreateIdentityAssociation - cannot add tests until I have support for serializing into proto, will add in next PR - Significant refactoring. We use separate classes in separate files for different associations. The strong typing ensures we can't mix them up (for example confusing grant messaging access with revoke messaging access). Because the protos have changed, some steps are required to avoid errors for those who already have libxmtp running: - Run `./dev/down && ./dev/up` from `libxmtp`. This rebuilds the validation service, and clears out any data stored on the server. - Remove any existing databases, for example from the CLI and Android/iOS/flutter/RN --- Cargo.lock | 11 +- bindings_ffi/Cargo.lock | 1 + mls_validation_service/src/handlers.rs | 6 +- xmtp_mls/Cargo.toml | 1 + xmtp_mls/IDENTITY.md | 23 +- xmtp_mls/src/association.rs | 456 ------ .../grant_messaging_access_association.rs | 291 ++++ .../legacy_create_identity_association.rs | 107 ++ xmtp_mls/src/credential/mod.rs | 165 ++ .../validated_legacy_signed_public_key.rs | 147 ++ xmtp_mls/src/identity.rs | 16 +- xmtp_mls/src/lib.rs | 2 +- xmtp_mls/src/utils/time.rs | 2 + xmtp_proto/Cargo.toml | 2 +- .../src/gen/xmtp.mls.message_contents.rs | 1433 +++++++++-------- .../gen/xmtp.mls.message_contents.serde.rs | 633 ++++++-- xmtp_v2/src/k256_helper.rs | 13 +- 17 files changed, 2019 insertions(+), 1290 deletions(-) delete mode 100644 xmtp_mls/src/association.rs create mode 100644 xmtp_mls/src/credential/grant_messaging_access_association.rs create mode 100644 xmtp_mls/src/credential/legacy_create_identity_association.rs create mode 100644 xmtp_mls/src/credential/mod.rs create mode 100644 xmtp_mls/src/credential/validated_legacy_signed_public_key.rs diff --git a/Cargo.lock b/Cargo.lock index 097660547..9f4cf3def 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3425,7 +3425,7 @@ dependencies = [ [[package]] name = "openmls" version = "0.5.0" -source = "git+https://github.com/xmtp/openmls?branch=main#a12c7435209b6714531bc0a1619f4fdf7c57d7c0" +source = "git+https://github.com/xmtp/openmls?branch=main#acc326fc8fc66ba57192cd822894b02f9f94cb46" dependencies = [ "backtrace", "itertools 0.10.5", @@ -3446,7 +3446,7 @@ dependencies = [ [[package]] name = "openmls_basic_credential" version = "0.2.0" -source = "git+https://github.com/xmtp/openmls?branch=main#a12c7435209b6714531bc0a1619f4fdf7c57d7c0" +source = "git+https://github.com/xmtp/openmls?branch=main#acc326fc8fc66ba57192cd822894b02f9f94cb46" dependencies = [ "ed25519-dalek", "openmls_traits", @@ -3459,7 +3459,7 @@ dependencies = [ [[package]] name = "openmls_memory_keystore" version = "0.2.0" -source = "git+https://github.com/xmtp/openmls?branch=main#a12c7435209b6714531bc0a1619f4fdf7c57d7c0" +source = "git+https://github.com/xmtp/openmls?branch=main#acc326fc8fc66ba57192cd822894b02f9f94cb46" dependencies = [ "openmls_traits", "serde_json", @@ -3469,7 +3469,7 @@ dependencies = [ [[package]] name = "openmls_rust_crypto" version = "0.2.0" -source = "git+https://github.com/xmtp/openmls?branch=main#a12c7435209b6714531bc0a1619f4fdf7c57d7c0" +source = "git+https://github.com/xmtp/openmls?branch=main#acc326fc8fc66ba57192cd822894b02f9f94cb46" dependencies = [ "aes-gcm", "chacha20poly1305", @@ -3493,7 +3493,7 @@ dependencies = [ [[package]] name = "openmls_traits" version = "0.2.0" -source = "git+https://github.com/xmtp/openmls?branch=main#a12c7435209b6714531bc0a1619f4fdf7c57d7c0" +source = "git+https://github.com/xmtp/openmls?branch=main#acc326fc8fc66ba57192cd822894b02f9f94cb46" dependencies = [ "serde", "tls_codec", @@ -6648,6 +6648,7 @@ dependencies = [ "xmtp_api_grpc", "xmtp_cryptography", "xmtp_proto", + "xmtp_v2", ] [[package]] diff --git a/bindings_ffi/Cargo.lock b/bindings_ffi/Cargo.lock index ea62af86b..c03da6408 100644 --- a/bindings_ffi/Cargo.lock +++ b/bindings_ffi/Cargo.lock @@ -5225,6 +5225,7 @@ dependencies = [ "tracing", "xmtp_cryptography", "xmtp_proto", + "xmtp_v2", ] [[package]] diff --git a/mls_validation_service/src/handlers.rs b/mls_validation_service/src/handlers.rs index 99928e63b..696a53129 100644 --- a/mls_validation_service/src/handlers.rs +++ b/mls_validation_service/src/handlers.rs @@ -135,7 +135,7 @@ mod tests { use openmls_basic_credential::SignatureKeyPair; use openmls_rust_crypto::OpenMlsRustCrypto; use prost::Message; - use xmtp_mls::{association::Credential, InboxOwner}; + use xmtp_mls::{credential::Credential, InboxOwner}; use xmtp_proto::xmtp::{ mls::message_contents::MlsCredential as CredentialProto, mls_validation::v1::validate_key_packages_request::KeyPackage as KeyPackageProtoWrapper, @@ -152,8 +152,8 @@ mod tests { let _pub_key = signature_key_pair.public(); let account_address = wallet.get_address(); - let credential = Credential::create_eip191(&signature_key_pair, &wallet) - .expect("failed to create credential"); + let credential = + Credential::create(&signature_key_pair, &wallet).expect("failed to create credential"); let credential_proto: CredentialProto = credential.into(); ( diff --git a/xmtp_mls/Cargo.toml b/xmtp_mls/Cargo.toml index f69d3a200..9c95874b8 100644 --- a/xmtp_mls/Cargo.toml +++ b/xmtp_mls/Cargo.toml @@ -48,6 +48,7 @@ toml = "0.7.4" tracing = "0.1.37" xmtp_cryptography = { path = "../xmtp_cryptography" } xmtp_proto = { path = "../xmtp_proto", features = ["proto_full"] } +xmtp_v2 = { path = "../xmtp_v2" } [dev-dependencies] ctor = "0.2" diff --git a/xmtp_mls/IDENTITY.md b/xmtp_mls/IDENTITY.md index 3078ad5d5..12dd180f5 100644 --- a/xmtp_mls/IDENTITY.md +++ b/xmtp_mls/IDENTITY.md @@ -51,11 +51,13 @@ XMTP installations consist of a long-lived Ed25519 key-pair (the 'installation k 2. The app prompts the user to sign the public key with their Ethereum wallet. The user is expected to inspect the text and reject the signing request if the data is invalid, for example if the account address is not the one they intended. The format for version 1 of the association text is as follows: ``` - XMTP: Grant Messaging Access + XMTP : Grant Messaging Access Current Time: Account Address: Installation ID: + + For more info: https://xmtp.org/signatures/ ``` 3. The signature and related data is then protobuf-serialized to form the MLS Credential: @@ -64,14 +66,14 @@ XMTP installations consist of a long-lived Ed25519 key-pair (the 'installation k struct { association_text_version: i32, signature: bytes, - iso8601_time: string, + created_ns: u64, account_address: string, - } Eip191Association; + } GrantMessagingAccessAssociation; struct { installation_public_key: bytes, - eip191_association: Eip191Association + association: GrantMessagingAccessAssociation } MlsCredential; ``` @@ -100,19 +102,28 @@ Users may revoke an installation as follows: 1. The app prompts the user to sign the revocation with their Ethereum wallet. The user is expected to inspect the text and reject the signing request if the data is invalid, for example if the account address is not the one they intended. The format for version 1 of the association text is as follows: ``` - XMTP: Revoke Messaging Access + XMTP : Revoke Messaging Access Current Time: Account Address: Installation ID: + + For more info: https://xmtp.org/signatures/ ``` 1. The signature and related data is then protobuf-serialized to form the revocation: ``` + struct { + association_text_version: i32, + signature: bytes, + created_ns: u64, + account_address: string, + } RevokeMessagingAccessAssociation; + struct { installation_public_key: bytes, - eip191_association: Eip191Association + association: RevokeMessagingAccessAssociation } InstallationRevocation; ``` diff --git a/xmtp_mls/src/association.rs b/xmtp_mls/src/association.rs deleted file mode 100644 index 6a9f622c5..000000000 --- a/xmtp_mls/src/association.rs +++ /dev/null @@ -1,456 +0,0 @@ -use crate::utils::address::sanitize_evm_addresses; -use crate::utils::address::AddressValidationError; -use crate::{types::Address, InboxOwner}; -use chrono::Utc; -use openmls_basic_credential::SignatureKeyPair; -use serde::{Deserialize, Serialize}; -use thiserror::Error; -use xmtp_cryptography::signature::{ - ed25519_public_key_to_address, RecoverableSignature, SignatureError, -}; -use xmtp_proto::xmtp::mls::message_contents::{ - mls_credential::Association as AssociationProto, Eip191Association as Eip191AssociationProto, - MlsCredential as MlsCredentialProto, - RecoverableEcdsaSignature as RecoverableEcdsaSignatureProto, -}; - -#[derive(Debug, Error)] -pub enum AssociationError { - #[error("Bad signature")] - BadSignature(#[from] SignatureError), - #[error("Association text mismatch")] - TextMismatch, - #[error("Installation public key mismatch")] - InstallationPublicKeyMismatch, - #[error( - "Address mismatch in Association: Provided:{provided_addr:?} != signed:{signing_addr:?}" - )] - AddressMismatch { - provided_addr: Address, - signing_addr: Address, - }, - #[error("Bad address")] - BadAddress(#[from] AddressValidationError), - #[error("Malformed association")] - MalformedAssociation, -} - -enum Association { - Eip191(Eip191Association), -} - -pub struct Credential { - association: Association, -} - -impl Credential { - pub fn create_eip191( - installation_keys: &SignatureKeyPair, - owner: &impl InboxOwner, - ) -> Result { - // Generate association - let iso8601_time = format!("{}", Utc::now().format("%+")); - let assoc_text = AssociationText::new_static( - AssociationContext::GrantMessagingAccess, - owner.get_address(), - installation_keys.to_public_vec(), - iso8601_time, - )?; - let signature = owner.sign(&assoc_text.text())?; - let association = Eip191Association::new_validated(assoc_text, signature)?; - Ok(Self { - association: Association::Eip191(association), - }) - } - - pub fn from_external_signer( - association_data: AssociationText, - signature: Vec, - ) -> Result { - let association = Eip191Association::new_validated( - association_data, - RecoverableSignature::Eip191Signature(signature), - )?; - Ok(Self { - association: Association::Eip191(association), - }) - } - - pub fn from_proto_validated( - proto: MlsCredentialProto, - expected_account_address: Option<&str>, // Must validate when fetching identity updates - expected_installation_public_key: Option<&[u8]>, // Must cross-reference against leaf node when relevant - ) -> Result { - let association = match proto - .association - .ok_or(AssociationError::MalformedAssociation)? - { - AssociationProto::Eip191(assoc) => Eip191Association::from_proto_validated( - assoc, - AssociationContext::GrantMessagingAccess, - &proto.installation_public_key, - ) - .map(Association::Eip191), - }?; - let credential = Self { association }; - if let Some(address) = expected_account_address { - if credential.address() != address { - return Err(AssociationError::AddressMismatch { - provided_addr: address.to_string(), - signing_addr: credential.address(), - }); - } - } - if let Some(public_key) = expected_installation_public_key { - if credential.installation_public_key() != public_key { - return Err(AssociationError::InstallationPublicKeyMismatch); - } - } - Ok(credential) - } - - pub fn address(&self) -> String { - match &self.association { - Association::Eip191(assoc) => assoc.address(), - } - } - - pub fn installation_public_key(&self) -> Vec { - match &self.association { - Association::Eip191(assoc) => assoc.installation_public_key(), - } - } - - pub fn iso8601_time(&self) -> String { - match &self.association { - Association::Eip191(assoc) => assoc.iso8601_time(), - } - } -} - -impl From for MlsCredentialProto { - fn from(credential: Credential) -> Self { - Self { - installation_public_key: credential.installation_public_key(), - association: match credential.association { - Association::Eip191(assoc) => Some(AssociationProto::Eip191(assoc.into())), - }, - } - } -} - -/// An Association is link between a blockchain account and an xmtp installation for the purposes of -/// authentication. -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -struct Eip191Association { - text: AssociationText, - signature: RecoverableSignature, -} - -impl Eip191Association { - pub fn new_validated( - text: AssociationText, - signature: RecoverableSignature, - ) -> Result { - let this = Self { text, signature }; - this.is_valid()?; - Ok(this) - } - - pub fn from_proto_validated( - proto: Eip191AssociationProto, - expected_context: AssociationContext, - expected_installation_public_key: &[u8], - ) -> Result { - let text = AssociationText::new_static( - expected_context, - proto.account_address, - expected_installation_public_key.to_vec(), - proto.iso8601_time, - )?; - let signature = RecoverableSignature::Eip191Signature(proto.signature.unwrap().bytes); - Self::new_validated(text, signature) - } - - fn is_valid(&self) -> Result<(), AssociationError> { - let assumed_context = self.text.get_context(); - let assumed_addr = self.text.get_address(); - let assumed_installation_public_key = self.text.get_installation_public_key(); - let assumed_time = self.text.get_iso8601_time(); - - // Ensure the Text properly links the Address and Keybytes - self.text.is_valid( - assumed_context, - &assumed_addr, - &assumed_installation_public_key, - &assumed_time, - )?; - - let addr = self.signature.recover_address(&self.text.text())?; - - let sanitized_addresses = sanitize_evm_addresses(vec![assumed_addr, addr])?; - if sanitized_addresses[0] != sanitized_addresses[1] { - Err(AssociationError::AddressMismatch { - provided_addr: sanitized_addresses[0].clone(), - signing_addr: sanitized_addresses[1].clone(), - }) - } else { - Ok(()) - } - } - - pub fn address(&self) -> String { - self.text.get_address() - } - - pub fn installation_public_key(&self) -> Vec { - self.text.get_installation_public_key() - } - - pub fn iso8601_time(&self) -> String { - self.text.get_iso8601_time() - } -} - -impl From for Eip191AssociationProto { - fn from(assoc: Eip191Association) -> Self { - let account_address = assoc.address(); - let iso8601_time = assoc.iso8601_time(); - Self { - account_address, - // Hardcoded version for now - association_text_version: 1, - signature: Some(RecoverableEcdsaSignatureProto { - bytes: assoc.signature.into(), - }), - iso8601_time, - } - } -} - -/// AssociationText represents the string which was signed by the authorizing blockchain account. A -/// valid AssociationText must contain the address of the blockchain account and a representation of -/// the XMTP installation public key. Different standards may choose how this information is -/// encoded, as well as adding extra requirements for increased security. -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -pub struct AssociationText { - context: AssociationContext, - data: AssociationData, -} - -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -pub enum AssociationContext { - GrantMessagingAccess, - RevokeMessagingAccess, -} - -impl AssociationContext {} - -#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] -enum AssociationData { - Static { - account_address: Address, - installation_public_key: Vec, - iso8601_time: String, - }, -} - -impl AssociationText { - pub fn get_context(&self) -> AssociationContext { - self.context.clone() - } - - pub fn get_address(&self) -> Address { - match &self.data { - AssociationData::Static { - account_address, .. - } => account_address.clone(), - } - } - - pub fn get_installation_public_key(&self) -> Vec { - match &self.data { - AssociationData::Static { - installation_public_key, - .. - } => installation_public_key.clone(), - } - } - - pub fn get_iso8601_time(&self) -> String { - match &self.data { - AssociationData::Static { iso8601_time, .. } => iso8601_time.clone(), - } - } - - fn header_text(&self) -> String { - let label = match &self.context { - AssociationContext::GrantMessagingAccess => "Grant messaging access".to_string(), - AssociationContext::RevokeMessagingAccess => "Revoke messaging access".to_string(), - }; - format!("XMTP: {}\n\n", label) - } - - fn body_text(&self) -> String { - match &self.data { - AssociationData::Static { - account_address, - installation_public_key, - iso8601_time, - } => gen_static_text_v1(account_address, installation_public_key, iso8601_time), - } - } - - pub fn text(&self) -> String { - format!("{}{}", self.header_text(), self.body_text()).to_string() - } - - pub fn is_valid( - &self, - context: AssociationContext, - account_address: &str, - installation_public_key: &[u8], - iso8601_time: &str, - ) -> Result<(), AssociationError> { - if self.text() - == AssociationText::new_static( - context, - account_address.to_string(), - installation_public_key.to_vec(), - iso8601_time.to_string(), - )? - .text() - { - return Ok(()); - } - - Err(AssociationError::TextMismatch) - } - - pub fn new_static( - context: AssociationContext, - account_address: String, - installation_public_key: Vec, - iso8601_time: String, - ) -> Result { - let account_address = sanitize_evm_addresses(vec![account_address])?[0].clone(); - Ok(Self { - context, - data: AssociationData::Static { - account_address, - installation_public_key, - iso8601_time, - }, - }) - } -} - -fn gen_static_text_v1(addr: &str, key_bytes: &[u8], iso8601_time: &str) -> String { - format!( - "Current Time: {}\nAccount Address: {}\nInstallation ID: {}", - iso8601_time, - addr, - ed25519_public_key_to_address(key_bytes) - ) -} - -#[cfg(test)] -pub mod tests { - use ethers::signers::{LocalWallet, Signer}; - use xmtp_cryptography::{signature::h160addr_to_string, utils::rng}; - use xmtp_proto::xmtp::mls::message_contents::Eip191Association as Eip191AssociationProto; - - use crate::association::AssociationContext; - - use super::{AssociationText, Eip191Association}; - - #[tokio::test] - async fn assoc_gen() { - let key_bytes = vec![22, 33, 44, 55]; - - let wallet = LocalWallet::new(&mut rng()); - let other_wallet = LocalWallet::new(&mut rng()); - let addr = h160addr_to_string(wallet.address()); - let other_addr = h160addr_to_string(other_wallet.address()); - let grant_time = "2021-01-01T00:00:00Z"; - let bad_grant_time = "2021-01-01T00:00:01Z"; - let text = AssociationText::new_static( - AssociationContext::GrantMessagingAccess, - addr.clone(), - key_bytes.clone(), - grant_time.to_string(), - ) - .unwrap(); - let sig = wallet.sign_message(text.text()).await.expect("BadSign"); - - let bad_key_bytes = vec![11, 22, 33]; - let bad_text1 = AssociationText::new_static( - AssociationContext::GrantMessagingAccess, - addr.clone(), - bad_key_bytes.clone(), - grant_time.to_string(), - ) - .unwrap(); - let bad_text2 = AssociationText::new_static( - AssociationContext::GrantMessagingAccess, - other_addr.clone(), - key_bytes.clone(), - grant_time.to_string(), - ) - .unwrap(); - let bad_text3 = AssociationText::new_static( - AssociationContext::GrantMessagingAccess, - addr.clone(), - key_bytes.clone(), - bad_grant_time.to_string(), - ) - .unwrap(); - let bad_text4 = AssociationText::new_static( - AssociationContext::RevokeMessagingAccess, - addr.clone(), - key_bytes.clone(), - grant_time.to_string(), - ) - .unwrap(); - let other_text = AssociationText::new_static( - AssociationContext::GrantMessagingAccess, - other_addr.clone(), - key_bytes.clone(), - grant_time.to_string(), - ) - .unwrap(); - - let other_sig = wallet - .sign_message(other_text.text()) - .await - .expect("BadSign"); - - assert!(Eip191Association::new_validated(text.clone(), sig.into()).is_ok()); - assert!(Eip191Association::new_validated(bad_text1.clone(), sig.into()).is_err()); - assert!(Eip191Association::new_validated(bad_text2.clone(), sig.into()).is_err()); - assert!(Eip191Association::new_validated(bad_text3.clone(), sig.into()).is_err()); - assert!(Eip191Association::new_validated(bad_text4.clone(), sig.into()).is_err()); - assert!(Eip191Association::new_validated(text.clone(), other_sig.into()).is_err()); - } - - #[tokio::test] - async fn to_proto() { - let key_bytes = vec![22, 33, 44, 55]; - let wallet = LocalWallet::new(&mut rng()); - let addr = h160addr_to_string(wallet.address()); - let text = AssociationText::new_static( - AssociationContext::GrantMessagingAccess, - addr.clone(), - key_bytes.clone(), - "2021-01-01T00:00:00Z".to_string(), - ) - .unwrap(); - let sig = wallet.sign_message(text.text()).await.expect("BadSign"); - - let assoc = Eip191Association::new_validated(text.clone(), sig.into()).unwrap(); - let proto_signature: Eip191AssociationProto = assoc.into(); - - assert_eq!(proto_signature.association_text_version, 1); - assert_eq!(proto_signature.signature.unwrap().bytes, sig.to_vec()); - } -} diff --git a/xmtp_mls/src/credential/grant_messaging_access_association.rs b/xmtp_mls/src/credential/grant_messaging_access_association.rs new file mode 100644 index 000000000..de174a2d4 --- /dev/null +++ b/xmtp_mls/src/credential/grant_messaging_access_association.rs @@ -0,0 +1,291 @@ +use chrono::DateTime; +use serde::{Deserialize, Serialize}; +use xmtp_cryptography::signature::{ed25519_public_key_to_address, RecoverableSignature}; +use xmtp_proto::xmtp::mls::message_contents::{ + GrantMessagingAccessAssociation as GrantMessagingAccessAssociationProto, + RecoverableEcdsaSignature as RecoverableEcdsaSignatureProto, +}; + +use crate::{ + types::Address, + utils::{address::sanitize_evm_addresses, time::NS_IN_SEC}, + InboxOwner, +}; + +use super::AssociationError; + +#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +pub struct UnsignedGrantMessagingAccessData { + pub(crate) account_address: Address, + pub(crate) installation_public_key: Vec, + pub(crate) created_ns: u64, + iso8601_time: String, +} + +impl UnsignedGrantMessagingAccessData { + pub fn new( + account_address: Address, + installation_public_key: Vec, + created_ns: u64, + ) -> Result { + let account_address = sanitize_evm_addresses(vec![account_address])?[0].clone(); + let created_time = DateTime::from_timestamp( + created_ns as i64 / NS_IN_SEC, + (created_ns as i64 % NS_IN_SEC) as u32, + ) + .ok_or(AssociationError::MalformedAssociation)?; + let iso8601_time = format!("{}", created_time.format("%+")); + + Ok(Self { + account_address, + installation_public_key, + created_ns, + iso8601_time, + }) + } + + pub fn account_address(&self) -> Address { + self.account_address.clone() + } + + pub fn installation_public_key(&self) -> Vec { + self.installation_public_key.clone() + } + + pub fn created_ns(&self) -> u64 { + self.created_ns + } + + fn header_text() -> String { + let label = "Grant Messaging Access".to_string(); + format!("XMTP : {}", label) + } + + fn body_text( + account_address: &Address, + installation_public_key: &[u8], + iso8601_time: &str, + ) -> String { + format!( + "\nCurrent Time: {}\nAccount Address: {}\nInstallation ID: {}", + iso8601_time, + account_address, + ed25519_public_key_to_address(installation_public_key) + ) + } + + fn footer_text() -> String { + "For more info: https://xmtp.org/signatures/".to_string() + } + + pub fn text(&self) -> String { + format!( + "{}\n{}\n\n{}", + Self::header_text(), + Self::body_text( + &self.account_address, + &self.installation_public_key, + &self.iso8601_time + ), + Self::footer_text() + ) + .to_string() + } +} + +/// An Association is link between a blockchain account and an xmtp installation for the purposes of +/// authentication. +#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +pub struct GrantMessagingAccessAssociation { + association_data: UnsignedGrantMessagingAccessData, + signature: RecoverableSignature, +} + +impl GrantMessagingAccessAssociation { + pub(crate) fn new_validated( + association_data: UnsignedGrantMessagingAccessData, + signature: RecoverableSignature, + ) -> Result { + let this = Self { + association_data, + signature, + }; + this.is_valid()?; + Ok(this) + } + + pub(crate) fn create( + owner: &impl InboxOwner, + installation_public_key: Vec, + created_ns: u64, + ) -> Result { + let unsigned_data = UnsignedGrantMessagingAccessData::new( + owner.get_address(), + installation_public_key, + created_ns, + )?; + let text = unsigned_data.text(); + let signature = owner.sign(&text)?; + Self::new_validated(unsigned_data, signature) + } + + pub(crate) fn from_proto_validated( + proto: GrantMessagingAccessAssociationProto, + expected_installation_public_key: &[u8], + ) -> Result { + let signature = RecoverableSignature::Eip191Signature( + proto + .signature + .ok_or(AssociationError::MalformedAssociation)? + .bytes, + ); + Self::new_validated( + UnsignedGrantMessagingAccessData::new( + proto.account_address, + expected_installation_public_key.to_vec(), + proto.created_ns, + )?, + signature, + ) + } + + fn is_valid(&self) -> Result<(), AssociationError> { + let assumed_addr = self.association_data.account_address(); + + let addr = self + .signature + .recover_address(&self.association_data.text())?; + + let sanitized_addresses = sanitize_evm_addresses(vec![assumed_addr, addr])?; + if sanitized_addresses[0] != sanitized_addresses[1] { + Err(AssociationError::AddressMismatch { + provided_addr: sanitized_addresses[0].clone(), + signing_addr: sanitized_addresses[1].clone(), + }) + } else { + Ok(()) + } + } + + pub fn account_address(&self) -> String { + self.association_data.account_address() + } + + pub fn installation_public_key(&self) -> Vec { + self.association_data.installation_public_key() + } + + pub fn created_ns(&self) -> u64 { + self.association_data.created_ns() + } +} + +impl From for GrantMessagingAccessAssociationProto { + fn from(assoc: GrantMessagingAccessAssociation) -> Self { + let account_address = assoc.account_address(); + let created_ns = assoc.created_ns(); + Self { + account_address, + // Hardcoded version for now + association_text_version: 1, + signature: Some(RecoverableEcdsaSignatureProto { + bytes: assoc.signature.into(), + }), + created_ns, + } + } +} + +#[cfg(test)] +pub mod tests { + use ethers::signers::{LocalWallet, Signer}; + + use xmtp_cryptography::{signature::h160addr_to_string, utils::rng}; + use xmtp_proto::xmtp::mls::message_contents::GrantMessagingAccessAssociation as GrantMessagingAccessAssociationProto; + + use crate::credential::{ + grant_messaging_access_association::GrantMessagingAccessAssociation, + UnsignedGrantMessagingAccessData, + }; + + #[tokio::test] + async fn assoc_gen() { + let key_bytes = vec![22, 33, 44, 55]; + + let wallet = LocalWallet::new(&mut rng()); + let other_wallet = LocalWallet::new(&mut rng()); + let addr = h160addr_to_string(wallet.address()); + let other_addr = h160addr_to_string(other_wallet.address()); + let grant_time = 1609459200000000; + let bad_grant_time = 1609459200000001; + + let data = + UnsignedGrantMessagingAccessData::new(addr.clone(), key_bytes.clone(), grant_time) + .unwrap(); + let sig = wallet.sign_message(data.text()).await.expect("BadSign"); + + let other_data = UnsignedGrantMessagingAccessData::new( + other_addr.clone(), + key_bytes.clone(), + grant_time, + ) + .unwrap(); + let other_sig = wallet + .sign_message(other_data.text()) + .await + .expect("BadSign"); + + let bad_key_bytes = vec![11, 22, 33]; + + assert!(GrantMessagingAccessAssociation::new_validated( + UnsignedGrantMessagingAccessData::new(addr.clone(), key_bytes.clone(), grant_time) + .unwrap(), + sig.into() + ) + .is_ok()); + assert!(GrantMessagingAccessAssociation::new_validated( + UnsignedGrantMessagingAccessData::new(addr.clone(), bad_key_bytes.clone(), grant_time) + .unwrap(), + sig.into() + ) + .is_err()); + assert!(GrantMessagingAccessAssociation::new_validated( + UnsignedGrantMessagingAccessData::new( + other_addr.clone(), + key_bytes.clone(), + grant_time, + ) + .unwrap(), + sig.into() + ) + .is_err()); + assert!(GrantMessagingAccessAssociation::new_validated( + UnsignedGrantMessagingAccessData::new(addr.clone(), key_bytes.clone(), bad_grant_time) + .unwrap(), + sig.into() + ) + .is_err()); + assert!(GrantMessagingAccessAssociation::new_validated( + UnsignedGrantMessagingAccessData::new(addr.clone(), key_bytes.clone(), grant_time) + .unwrap(), + other_sig.into() + ) + .is_err()); + } + + #[tokio::test] + async fn to_proto() { + let key_bytes = vec![22, 33, 44, 55]; + let wallet = LocalWallet::new(&mut rng()); + let addr = h160addr_to_string(wallet.address()); + let created_ns = 1609459200000000; + let data = UnsignedGrantMessagingAccessData::new(addr, key_bytes, created_ns).unwrap(); + let sig = wallet.sign_message(data.text()).await.expect("BadSign"); + + let assoc = GrantMessagingAccessAssociation::new_validated(data, sig.into()).unwrap(); + let proto_signature: GrantMessagingAccessAssociationProto = assoc.into(); + + assert_eq!(proto_signature.association_text_version, 1); + assert_eq!(proto_signature.signature.unwrap().bytes, sig.to_vec()); + } +} diff --git a/xmtp_mls/src/credential/legacy_create_identity_association.rs b/xmtp_mls/src/credential/legacy_create_identity_association.rs new file mode 100644 index 000000000..0933b50fd --- /dev/null +++ b/xmtp_mls/src/credential/legacy_create_identity_association.rs @@ -0,0 +1,107 @@ +use prost::Message; +use xmtp_proto::xmtp::{ + message_contents::{signed_private_key, SignedPrivateKey as LegacySignedPrivateKeyProto}, + mls::message_contents::LegacyCreateIdentityAssociation as LegacyCreateIdentityAssociationProto, +}; +use xmtp_v2::k256_helper; + +use super::{validated_legacy_signed_public_key::ValidatedLegacySignedPublicKey, AssociationError}; + +/// An Association is link between a blockchain account and an xmtp installation for the purposes of +/// authentication. +pub struct LegacyCreateIdentityAssociation { + installation_public_key: Vec, + delegating_signature: Vec, + legacy_signed_public_key: ValidatedLegacySignedPublicKey, +} + +impl LegacyCreateIdentityAssociation { + fn new_validated( + installation_public_key: Vec, + delegating_signature: Vec, + legacy_signed_public_key: ValidatedLegacySignedPublicKey, + ) -> Result { + let this = Self { + installation_public_key, + delegating_signature, + legacy_signed_public_key, + }; + this.is_valid()?; + Ok(this) + } + + pub(crate) fn create( + legacy_signed_private_key: Vec, + installation_public_key: Vec, + ) -> Result { + let legacy_signed_private_key_proto = + LegacySignedPrivateKeyProto::decode(legacy_signed_private_key.as_slice())?; + let signed_private_key::Union::Secp256k1(secp256k1) = legacy_signed_private_key_proto + .union + .ok_or(AssociationError::MalformedLegacyKey)?; + let legacy_private_key = secp256k1.bytes; + let (mut delegating_signature, recovery_id) = k256_helper::sign_sha256( + &legacy_private_key, // secret_key + &installation_public_key, // message + ) + .map_err(AssociationError::LegacySignature)?; + delegating_signature.push(recovery_id); // TODO: normalize recovery ID if necessary + + let legacy_signed_public_key_proto = legacy_signed_private_key_proto + .public_key + .ok_or(AssociationError::MalformedLegacyKey)?; + Self::new_validated( + installation_public_key, + delegating_signature, + legacy_signed_public_key_proto.try_into()?, // ValidatedLegacySignedPublicKey + ) + } + + pub(crate) fn from_proto_validated( + proto: LegacyCreateIdentityAssociationProto, + expected_installation_public_key: &[u8], + ) -> Result { + let delegating_signature = proto + .signature + .ok_or(AssociationError::MalformedAssociation)? + .bytes; + let legacy_signed_public_key_proto = proto + .signed_legacy_create_identity_key + .ok_or(AssociationError::MalformedAssociation)?; + + Self::new_validated( + expected_installation_public_key.to_vec(), + delegating_signature, + legacy_signed_public_key_proto.try_into()?, // ValidatedLegacySignedPublicKey + ) + } + + fn is_valid(&self) -> Result<(), AssociationError> { + // Validate legacy key signs installation key + if self.delegating_signature.len() != 65 { + return Err(AssociationError::MalformedAssociation); + } + assert!(k256_helper::verify_sha256( + &self.legacy_signed_public_key.key_bytes(), // signed_by + &self.installation_public_key, // message + &self.delegating_signature[0..64], // signature + self.delegating_signature[64], // recovery_id + ) + .map_err(AssociationError::LegacySignature)?); // always returns true if no error + + // Wallet signature of legacy key is internally validated by ValidatedLegacySignedPublicKey on creation + Ok(()) + } + + pub fn account_address(&self) -> String { + self.legacy_signed_public_key.account_address() + } + + pub fn installation_public_key(&self) -> Vec { + self.installation_public_key.clone() + } + + pub fn created_ns(&self) -> u64 { + self.legacy_signed_public_key.created_ns() + } +} diff --git a/xmtp_mls/src/credential/mod.rs b/xmtp_mls/src/credential/mod.rs new file mode 100644 index 000000000..c16aa0748 --- /dev/null +++ b/xmtp_mls/src/credential/mod.rs @@ -0,0 +1,165 @@ +mod grant_messaging_access_association; +mod legacy_create_identity_association; +mod validated_legacy_signed_public_key; + +use crate::utils::address::AddressValidationError; +use crate::utils::time::now_ns; +use crate::{types::Address, InboxOwner}; + +use openmls_basic_credential::SignatureKeyPair; + +use prost::DecodeError; +use thiserror::Error; +use xmtp_cryptography::signature::{RecoverableSignature, SignatureError}; + +use xmtp_proto::xmtp::mls::message_contents::{ + mls_credential::Association as AssociationProto, MlsCredential as MlsCredentialProto, +}; + +use self::grant_messaging_access_association::GrantMessagingAccessAssociation; +pub use self::grant_messaging_access_association::UnsignedGrantMessagingAccessData; +use self::legacy_create_identity_association::LegacyCreateIdentityAssociation; + +#[derive(Debug, Error)] +pub enum AssociationError { + #[error("bad signature")] + BadSignature(#[from] SignatureError), + #[error("decode error")] + DecodeError(#[from] DecodeError), + #[error("legacy key")] + MalformedLegacyKey, + #[error("legacy signature: {0}")] + LegacySignature(String), + #[error("Association text mismatch")] + TextMismatch, + #[error("Installation public key mismatch")] + InstallationPublicKeyMismatch, + #[error( + "Address mismatch in Association: Provided:{provided_addr:?} != signed:{signing_addr:?}" + )] + AddressMismatch { + provided_addr: Address, + signing_addr: Address, + }, + #[error("Bad address")] + BadAddress(#[from] AddressValidationError), + #[error("Malformed association")] + MalformedAssociation, +} + +pub enum Credential { + GrantMessagingAccess(GrantMessagingAccessAssociation), + LegacyCreateIdentity(LegacyCreateIdentityAssociation), +} + +impl Credential { + pub fn create( + installation_keys: &SignatureKeyPair, + owner: &impl InboxOwner, + ) -> Result { + let created_ns = now_ns() as u64; + let association = GrantMessagingAccessAssociation::create( + owner, + installation_keys.to_public_vec(), + created_ns, + )?; + Ok(Self::GrantMessagingAccess(association)) + } + + pub fn create_from_external_signer( + association_data: UnsignedGrantMessagingAccessData, + signature: Vec, + ) -> Result { + let association = GrantMessagingAccessAssociation::new_validated( + association_data, + RecoverableSignature::Eip191Signature(signature), + )?; + Ok(Self::GrantMessagingAccess(association)) + } + + pub fn create_legacy( + legacy_signed_private_key: Vec, + installation_public_key: Vec, + ) -> Result { + let association = LegacyCreateIdentityAssociation::create( + legacy_signed_private_key, + installation_public_key, + )?; + Ok(Self::LegacyCreateIdentity(association)) + } + + pub fn from_proto_validated( + proto: MlsCredentialProto, + expected_account_address: Option<&str>, // Must validate when fetching identity updates + expected_installation_public_key: Option<&[u8]>, // Must cross-reference against leaf node when relevant + ) -> Result { + let credential = match proto + .association + .ok_or(AssociationError::MalformedAssociation)? + { + AssociationProto::MessagingAccess(assoc) => { + GrantMessagingAccessAssociation::from_proto_validated( + assoc, + &proto.installation_public_key, + ) + .map(Credential::GrantMessagingAccess) + } + AssociationProto::LegacyCreateIdentity(assoc) => { + LegacyCreateIdentityAssociation::from_proto_validated( + assoc, + &proto.installation_public_key, + ) + .map(Credential::LegacyCreateIdentity) + } + }?; + if let Some(address) = expected_account_address { + if credential.address() != address { + return Err(AssociationError::AddressMismatch { + provided_addr: address.to_string(), + signing_addr: credential.address(), + }); + } + } + if let Some(public_key) = expected_installation_public_key { + if credential.installation_public_key() != public_key { + return Err(AssociationError::InstallationPublicKeyMismatch); + } + } + Ok(credential) + } + + pub fn address(&self) -> String { + match &self { + Credential::GrantMessagingAccess(assoc) => assoc.account_address(), + Credential::LegacyCreateIdentity(assoc) => assoc.account_address(), + } + } + + pub fn installation_public_key(&self) -> Vec { + match &self { + Credential::GrantMessagingAccess(assoc) => assoc.installation_public_key(), + Credential::LegacyCreateIdentity(assoc) => assoc.installation_public_key(), + } + } + + pub fn created_ns(&self) -> u64 { + match &self { + Credential::GrantMessagingAccess(assoc) => assoc.created_ns(), + Credential::LegacyCreateIdentity(assoc) => assoc.created_ns(), + } + } +} + +impl From for MlsCredentialProto { + fn from(credential: Credential) -> Self { + Self { + installation_public_key: credential.installation_public_key(), + association: match credential { + Credential::GrantMessagingAccess(assoc) => { + Some(AssociationProto::MessagingAccess(assoc.into())) + } + Credential::LegacyCreateIdentity(_assoc) => todo!(), + }, + } + } +} diff --git a/xmtp_mls/src/credential/validated_legacy_signed_public_key.rs b/xmtp_mls/src/credential/validated_legacy_signed_public_key.rs new file mode 100644 index 000000000..445e6f331 --- /dev/null +++ b/xmtp_mls/src/credential/validated_legacy_signed_public_key.rs @@ -0,0 +1,147 @@ +use crate::{types::Address, utils::address::sanitize_evm_addresses}; + +use prost::Message; +use xmtp_cryptography::signature::RecoverableSignature; +use xmtp_proto::xmtp::message_contents::{ + signature::Union, unsigned_public_key, SignedPublicKey as LegacySignedPublicKeyProto, + UnsignedPublicKey as LegacyUnsignedPublicKeyProto, +}; + +use super::AssociationError; + +pub struct ValidatedLegacySignedPublicKey { + account_address: Address, + _serialized_key_data: Vec, + _wallet_signature: RecoverableSignature, + public_key_bytes: Vec, + created_ns: u64, +} + +impl ValidatedLegacySignedPublicKey { + fn header_text() -> String { + let label = "Create Identity".to_string(); + format!("XMTP : {}", label) + } + + fn body_text(serialized_legacy_key: &[u8]) -> String { + hex::encode(serialized_legacy_key) + } + + fn footer_text() -> String { + "For more info: https://xmtp.org/signatures/".to_string() + } + + fn text(serialized_legacy_key: &[u8]) -> String { + format!( + "{}\n{}\n\n{}", + Self::header_text(), + Self::body_text(serialized_legacy_key), + Self::footer_text() + ) + .to_string() + } + + pub fn account_address(&self) -> Address { + self.account_address.clone() + } + + pub fn key_bytes(&self) -> Vec { + self.public_key_bytes.clone() + } + + pub fn created_ns(&self) -> u64 { + self.created_ns + } +} + +impl TryFrom for ValidatedLegacySignedPublicKey { + type Error = AssociationError; + + fn try_from(proto: LegacySignedPublicKeyProto) -> Result { + let serialized_key_data = proto.key_bytes; + let Union::WalletEcdsaCompact(wallet_ecdsa_compact) = proto + .signature + .ok_or(AssociationError::MalformedLegacyKey)? + .union + .ok_or(AssociationError::MalformedLegacyKey)? + else { + return Err(AssociationError::MalformedLegacyKey); + }; + let mut wallet_signature = wallet_ecdsa_compact.bytes.clone(); + wallet_signature.push(wallet_ecdsa_compact.recovery as u8); // TODO: normalize recovery ID if necessary + let wallet_signature = RecoverableSignature::Eip191Signature(wallet_signature); + let account_address = + wallet_signature.recover_address(&Self::text(&serialized_key_data))?; + let account_address = sanitize_evm_addresses(vec![account_address])?[0].clone(); + + let legacy_unsigned_public_key_proto = + LegacyUnsignedPublicKeyProto::decode(serialized_key_data.as_slice()) + .or(Err(AssociationError::MalformedAssociation))?; + let public_key_bytes = match legacy_unsigned_public_key_proto + .union + .ok_or(AssociationError::MalformedAssociation)? + { + unsigned_public_key::Union::Secp256k1Uncompressed(secp256k1_uncompressed) => { + secp256k1_uncompressed.bytes + } + }; + let created_ns = legacy_unsigned_public_key_proto.created_ns; + + Ok(Self { + account_address, + _wallet_signature: wallet_signature, + _serialized_key_data: serialized_key_data, + public_key_bytes, + created_ns, + }) + } +} + +#[cfg(test)] +pub mod tests { + use crate::{assert_err, credential::AssociationError}; + + use super::ValidatedLegacySignedPublicKey; + use prost::Message; + use xmtp_proto::xmtp::message_contents::SignedPublicKey as LegacySignedPublicKeyProto; + + #[tokio::test] + async fn validate_good_key() { + let proto_bytes = vec![ + 10, 79, 8, 192, 195, 165, 174, 203, 153, 231, 213, 23, 26, 67, 10, 65, 4, 216, 84, 174, + 252, 198, 225, 219, 168, 239, 166, 62, 233, 206, 108, 53, 155, 87, 132, 8, 43, 91, 36, + 91, 81, 93, 213, 67, 241, 69, 5, 31, 249, 186, 129, 119, 144, 4, 44, 54, 76, 185, 95, + 61, 23, 231, 72, 7, 169, 18, 70, 113, 79, 173, 82, 13, 37, 146, 201, 43, 174, 180, 33, + 125, 43, 18, 70, 18, 68, 10, 64, 7, 136, 100, 172, 155, 247, 230, 255, 253, 247, 78, + 50, 212, 226, 41, 78, 239, 183, 136, 247, 122, 88, 155, 245, 219, 183, 215, 202, 42, + 89, 162, 128, 96, 96, 120, 131, 17, 70, 38, 231, 2, 27, 91, 29, 66, 110, 128, 140, 1, + 42, 217, 185, 2, 181, 208, 100, 143, 143, 219, 159, 174, 1, 233, 191, 16, 1, + ]; + let account_address = "0x220ca99fb7fafa18cb623d924794dde47b4bc2e9"; + + let proto = LegacySignedPublicKeyProto::decode(proto_bytes.as_slice()).unwrap(); + let validated_key = ValidatedLegacySignedPublicKey::try_from(proto) + .expect("Key should validate successfully"); + assert_eq!(validated_key.account_address(), account_address); + } + + #[tokio::test] + async fn validate_malformed_key() { + let proto_bytes = vec![ + 10, 79, 8, 192, 195, 165, 174, 203, 153, 231, 213, 23, 26, 67, 10, 65, 4, 216, 84, 174, + 252, 198, 225, 219, 168, 239, 166, 62, 233, 206, 108, 53, 155, 87, 132, 8, 43, 91, 36, + 91, 81, 93, 213, 67, 241, 69, 5, 31, 249, 186, 129, 119, 144, 4, 44, 54, 76, 185, 95, + 61, 23, 231, 72, 7, 169, 18, 70, 113, 79, 173, 82, 13, 37, 146, 201, 43, 174, 180, 33, + 125, 43, 18, 70, 18, 68, 10, 64, 7, 136, 100, 172, 155, 247, 230, 255, 253, 247, 78, + 50, 212, 226, 41, 78, 239, 183, 136, 247, 122, 88, 155, 245, 219, 183, 215, 202, 42, + 89, 162, 128, 96, 96, 120, 131, 17, 70, 38, 231, 2, 27, 91, 29, 66, 110, 128, 140, 1, + 42, 217, 185, 2, 181, 208, 100, 143, 143, 219, 159, 174, 1, 233, 191, 16, 1, + ]; + let mut proto = LegacySignedPublicKeyProto::decode(proto_bytes.as_slice()).unwrap(); + proto.key_bytes[0] += 1; // Corrupt the serialized key data + assert_err!( + ValidatedLegacySignedPublicKey::try_from(proto), + AssociationError::MalformedAssociation + ); + } +} diff --git a/xmtp_mls/src/identity.rs b/xmtp_mls/src/identity.rs index 550f8f96c..5f21f1a9c 100644 --- a/xmtp_mls/src/identity.rs +++ b/xmtp_mls/src/identity.rs @@ -1,6 +1,5 @@ use std::sync::RwLock; -use chrono::Utc; use openmls::{ credentials::errors::CredentialError, extensions::{errors::InvalidExtensionError, ApplicationIdExtension, LastResortExtension}, @@ -23,10 +22,11 @@ use xmtp_proto::{ use crate::{ api_client_wrapper::ApiClientWrapper, - association::{AssociationContext, AssociationError, AssociationText, Credential}, configuration::CIPHERSUITE, + credential::{AssociationError, Credential, UnsignedGrantMessagingAccessData}, storage::{identity::StoredIdentity, StorageError}, types::Address, + utils::time::now_ns, xmtp_openmls_provider::XmtpOpenMlsProvider, Fetch, InboxOwner, Store, }; @@ -64,7 +64,7 @@ pub struct Identity { pub(crate) account_address: Address, pub(crate) installation_keys: SignatureKeyPair, pub(crate) credential: RwLock>, - pub(crate) unsigned_association_data: Option, + pub(crate) unsigned_association_data: Option, } impl Identity { @@ -84,12 +84,10 @@ impl Identity { pub(crate) fn new_unsigned(account_address: String) -> Result { let signature_keys = SignatureKeyPair::new(CIPHERSUITE.signature_algorithm())?; - let iso8601_time = format!("{}", Utc::now().format("%+")); - let unsigned_association_data = AssociationText::new_static( - AssociationContext::GrantMessagingAccess, + let unsigned_association_data = UnsignedGrantMessagingAccessData::new( account_address.clone(), signature_keys.to_public_vec(), - iso8601_time, + now_ns() as u64, )?; let identity = Self { account_address, @@ -119,7 +117,7 @@ impl Identity { return Err(IdentityError::WalletSignatureRequired); } - let credential_proto: CredentialProto = Credential::from_external_signer( + let credential_proto: CredentialProto = Credential::create_from_external_signer( self.unsigned_association_data .clone() .expect("Unsigned identity is always created with unsigned_association_data"), @@ -213,7 +211,7 @@ impl Identity { installation_keys: &SignatureKeyPair, owner: &impl InboxOwner, ) -> Result { - let credential = Credential::create_eip191(installation_keys, owner)?; + let credential = Credential::create(installation_keys, owner)?; let credential_proto: CredentialProto = credential.into(); Ok(OpenMlsCredential::new( credential_proto.encode_to_vec(), diff --git a/xmtp_mls/src/lib.rs b/xmtp_mls/src/lib.rs index 686ecc4d9..3461f610a 100644 --- a/xmtp_mls/src/lib.rs +++ b/xmtp_mls/src/lib.rs @@ -1,9 +1,9 @@ pub mod api_client_wrapper; -pub mod association; pub mod builder; pub mod client; pub mod codecs; mod configuration; +pub mod credential; pub mod groups; mod hpke; pub mod identity; diff --git a/xmtp_mls/src/utils/time.rs b/xmtp_mls/src/utils/time.rs index 455bf56e0..71917ed39 100644 --- a/xmtp_mls/src/utils/time.rs +++ b/xmtp_mls/src/utils/time.rs @@ -1,5 +1,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; +pub const NS_IN_SEC: i64 = 1_000_000_000; + pub fn now_ns() -> i64 { let now = SystemTime::now(); diff --git a/xmtp_proto/Cargo.toml b/xmtp_proto/Cargo.toml index ef0aa5548..6e3275fe8 100644 --- a/xmtp_proto/Cargo.toml +++ b/xmtp_proto/Cargo.toml @@ -27,6 +27,6 @@ proto_full = ["xmtp-keystore_api-v1","xmtp-message_api-v1","xmtp-message_content "xmtp-message_contents" = [] "xmtp-mls-api-v1" = ["xmtp-message_contents"] "xmtp-mls-database" = [] -"xmtp-mls-message_contents" = [] +"xmtp-mls-message_contents" = ["xmtp-message_contents"] "xmtp-mls_validation-v1" = [] ## @@protoc_insertion_point(features) \ No newline at end of file diff --git a/xmtp_proto/src/gen/xmtp.mls.message_contents.rs b/xmtp_proto/src/gen/xmtp.mls.message_contents.rs index d4357621b..9a45b437e 100644 --- a/xmtp_proto/src/gen/xmtp.mls.message_contents.rs +++ b/xmtp_proto/src/gen/xmtp.mls.message_contents.rs @@ -1,22 +1,51 @@ // @generated -/// EIP191Association is used for all EIP 191 compliant wallet signatures +/// Used for "Grant Messaging Access" associations #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] -pub struct Eip191Association { +pub struct GrantMessagingAccessAssociation { #[prost(enumeration="AssociationTextVersion", tag="1")] pub association_text_version: i32, + /// EIP-191 signature #[prost(message, optional, tag="2")] pub signature: ::core::option::Option, #[prost(string, tag="3")] pub account_address: ::prost::alloc::string::String, - #[prost(string, tag="4")] - pub iso8601_time: ::prost::alloc::string::String, + #[prost(uint64, tag="4")] + pub created_ns: u64, +} +/// Used for "Revoke Messaging Access" associations +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RevokeMessagingAccessAssociation { + #[prost(enumeration="AssociationTextVersion", tag="1")] + pub association_text_version: i32, + /// EIP-191 signature + #[prost(message, optional, tag="2")] + pub signature: ::core::option::Option, + #[prost(string, tag="3")] + pub account_address: ::prost::alloc::string::String, + #[prost(uint64, tag="4")] + pub created_ns: u64, +} +/// LegacyCreateIdentityAssociation is used when a v3 installation key +/// is signed by a v2 identity key, which in turn is signed via a +/// 'CreateIdentity' wallet signature +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct LegacyCreateIdentityAssociation { + /// Signs SHA-256 hash of installation key + #[prost(message, optional, tag="1")] + pub signature: ::core::option::Option, + /// created_ns is encoded inside serialized key, account_address is recoverable + /// from the SignedPublicKey signature + #[prost(message, optional, tag="2")] + pub signed_legacy_create_identity_key: ::core::option::Option, } /// RecoverableEcdsaSignature #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RecoverableEcdsaSignature { - /// Includes recovery id as the last byte + /// 65-bytes [ R || S || V ], with recovery id as the last byte #[prost(bytes="vec", tag="1")] pub bytes: ::prost::alloc::vec::Vec, } @@ -130,7 +159,7 @@ impl Compression { pub struct MlsCredential { #[prost(bytes="vec", tag="1")] pub installation_public_key: ::prost::alloc::vec::Vec, - #[prost(oneof="mls_credential::Association", tags="2")] + #[prost(oneof="mls_credential::Association", tags="2, 3")] pub association: ::core::option::Option, } /// Nested message and enum types in `MlsCredential`. @@ -139,25 +168,37 @@ pub mod mls_credential { #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Association { #[prost(message, tag="2")] - Eip191(super::Eip191Association), + MessagingAccess(super::GrantMessagingAccessAssociation), + #[prost(message, tag="3")] + LegacyCreateIdentity(super::LegacyCreateIdentityAssociation), } } /// A declaration and proof that a credential is no longer valid #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CredentialRevocation { - #[prost(bytes="vec", tag="1")] - pub installation_public_key: ::prost::alloc::vec::Vec, - #[prost(oneof="credential_revocation::Association", tags="2")] + #[prost(oneof="credential_revocation::PublicKey", tags="1, 2")] + pub public_key: ::core::option::Option, + #[prost(oneof="credential_revocation::Association", tags="3")] pub association: ::core::option::Option, } /// Nested message and enum types in `CredentialRevocation`. pub mod credential_revocation { #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum PublicKey { + /// The 'installation_public_key' field of the MlsCredential proto + #[prost(bytes, tag="1")] + InstallationKey(::prost::alloc::vec::Vec), + /// The 'key_bytes' field of the legacy SignedPublicKey proto + #[prost(bytes, tag="2")] + UnsignedLegacyCreateIdentityKey(::prost::alloc::vec::Vec), + } + #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Association { - #[prost(message, tag="2")] - Eip191(super::Eip191Association), + #[prost(message, tag="3")] + MessagingAccess(super::RevokeMessagingAccessAssociation), } } /// Parent message for group metadata @@ -309,650 +350,770 @@ pub struct GroupMembershipChanges { } /// Encoded file descriptor set for the `xmtp.mls.message_contents` package pub const FILE_DESCRIPTOR_SET: &[u8] = &[ - 0x0a, 0x83, 0x0d, 0x0a, 0x26, 0x6d, 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x0a, 0xf0, 0x17, 0x0a, 0x26, 0x6d, 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xa0, 0x02, 0x0a, 0x11, 0x45, 0x69, 0x70, 0x31, 0x39, - 0x31, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6b, 0x0a, 0x18, - 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x78, 0x74, - 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, - 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x6f, 0x63, - 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x78, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x52, 0x16, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, - 0x78, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x09, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x78, - 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, - 0x61, 0x62, 0x6c, 0x65, 0x45, 0x63, 0x64, 0x73, 0x61, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x27, 0x0a, - 0x0f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x6f, 0x38, 0x36, 0x30, - 0x31, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x73, - 0x6f, 0x38, 0x36, 0x30, 0x31, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x31, 0x0a, 0x19, 0x52, 0x65, 0x63, - 0x6f, 0x76, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x63, 0x64, 0x73, 0x61, 0x53, 0x69, 0x67, - 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0x26, 0x0a, 0x0e, - 0x45, 0x64, 0x44, 0x73, 0x61, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x2a, 0x62, 0x0a, 0x16, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x78, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, - 0x0a, 0x24, 0x41, 0x53, 0x53, 0x4f, 0x43, 0x49, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x45, - 0x58, 0x54, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, 0x1a, 0x41, 0x53, 0x53, 0x4f, - 0x43, 0x49, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x45, 0x58, 0x54, 0x5f, 0x56, 0x45, 0x52, - 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x10, 0x01, 0x42, 0xe5, 0x01, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, - 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x10, 0x41, 0x73, 0x73, 0x6f, - 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x6d, 0x74, 0x70, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6c, 0x73, 0x2f, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, - 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x4d, 0xaa, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, 0x2e, 0x4d, 0x6c, - 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x73, 0xca, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0xe2, 0x02, 0x24, 0x58, - 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x58, 0x6d, 0x74, 0x70, 0x3a, 0x3a, 0x4d, 0x6c, 0x73, 0x3a, - 0x3a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, - 0x4a, 0xeb, 0x06, 0x0a, 0x06, 0x12, 0x04, 0x01, 0x00, 0x20, 0x01, 0x0a, 0x27, 0x0a, 0x01, 0x0c, - 0x12, 0x03, 0x01, 0x00, 0x12, 0x1a, 0x1d, 0x20, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x73, 0x0a, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x03, 0x00, 0x22, 0x0a, 0x08, - 0x0a, 0x01, 0x08, 0x12, 0x03, 0x05, 0x00, 0x47, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, - 0x05, 0x00, 0x47, 0x0a, 0x6f, 0x0a, 0x02, 0x05, 0x00, 0x12, 0x04, 0x0a, 0x00, 0x0d, 0x01, 0x1a, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x21, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, + 0x6b, 0x65, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xaa, 0x02, 0x0a, 0x1f, 0x47, 0x72, + 0x61, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6b, 0x0a, + 0x18, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x78, + 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x31, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x6f, + 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x78, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x16, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x65, 0x78, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, + 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, + 0x72, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x63, 0x64, 0x73, 0x61, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x27, + 0x0a, 0x0f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x4e, 0x73, 0x22, 0xab, 0x02, 0x0a, 0x20, 0x52, 0x65, 0x76, 0x6f, 0x6b, + 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x6b, 0x0a, 0x18, 0x61, + 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, + 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x78, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x16, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x78, + 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x78, 0x6d, + 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, + 0x62, 0x6c, 0x65, 0x45, 0x63, 0x64, 0x73, 0x61, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x27, 0x0a, 0x0f, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x4e, 0x73, 0x22, 0xe7, 0x01, 0x0a, 0x1f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x73, 0x73, + 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x78, 0x6d, + 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, + 0x62, 0x6c, 0x65, 0x45, 0x63, 0x64, 0x73, 0x61, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x70, 0x0a, 0x21, + 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x6b, 0x65, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, + 0x1d, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4b, 0x65, 0x79, 0x22, 0x31, + 0x0a, 0x19, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x63, 0x64, + 0x73, 0x61, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x22, 0x26, 0x0a, 0x0e, 0x45, 0x64, 0x44, 0x73, 0x61, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2a, 0x62, 0x0a, 0x16, 0x41, 0x73, 0x73, + 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, 0x78, 0x74, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x24, 0x41, 0x53, 0x53, 0x4f, 0x43, 0x49, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x54, 0x45, 0x58, 0x54, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1e, 0x0a, + 0x1a, 0x41, 0x53, 0x53, 0x4f, 0x43, 0x49, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x45, 0x58, + 0x54, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x31, 0x10, 0x01, 0x42, 0xe5, 0x01, + 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x42, + 0x10, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x78, 0x6d, 0x74, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, 0x6f, + 0x2f, 0x6d, 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x73, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x4d, 0xaa, 0x02, 0x18, 0x58, 0x6d, + 0x74, 0x70, 0x2e, 0x4d, 0x6c, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0xca, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, + 0x73, 0x5c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x73, 0xe2, 0x02, 0x24, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x5c, 0x47, 0x50, 0x42, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x58, 0x6d, 0x74, 0x70, 0x3a, + 0x3a, 0x4d, 0x6c, 0x73, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x73, 0x4a, 0x93, 0x0d, 0x0a, 0x06, 0x12, 0x04, 0x01, 0x00, 0x35, 0x01, + 0x0a, 0x27, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x01, 0x00, 0x12, 0x1a, 0x1d, 0x20, 0x41, 0x73, 0x73, + 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x0a, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, + 0x03, 0x00, 0x22, 0x0a, 0x09, 0x0a, 0x02, 0x03, 0x00, 0x12, 0x03, 0x05, 0x00, 0x2b, 0x0a, 0x08, + 0x0a, 0x01, 0x08, 0x12, 0x03, 0x07, 0x00, 0x47, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, + 0x07, 0x00, 0x47, 0x0a, 0x6f, 0x0a, 0x02, 0x05, 0x00, 0x12, 0x04, 0x0c, 0x00, 0x0f, 0x01, 0x1a, 0x63, 0x20, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x75, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x65, 0x78, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x0a, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x74, 0x69, 0x72, 0x65, 0x20, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x05, 0x00, 0x01, 0x12, 0x03, 0x0a, 0x05, 0x1b, - 0x0a, 0x0b, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x00, 0x12, 0x03, 0x0b, 0x02, 0x2b, 0x0a, 0x0c, 0x0a, - 0x05, 0x05, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0b, 0x02, 0x26, 0x0a, 0x0c, 0x0a, 0x05, 0x05, - 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x0b, 0x29, 0x2a, 0x0a, 0x0b, 0x0a, 0x04, 0x05, 0x00, 0x02, - 0x01, 0x12, 0x03, 0x0c, 0x02, 0x21, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x01, 0x01, 0x12, - 0x03, 0x0c, 0x02, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x0c, - 0x1f, 0x20, 0x0a, 0x53, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x10, 0x00, 0x15, 0x01, 0x1a, 0x47, - 0x20, 0x45, 0x49, 0x50, 0x31, 0x39, 0x31, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, - 0x6c, 0x6c, 0x20, 0x45, 0x49, 0x50, 0x20, 0x31, 0x39, 0x31, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, - 0x69, 0x61, 0x6e, 0x74, 0x20, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, - 0x10, 0x08, 0x19, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x11, 0x02, 0x36, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x11, 0x02, 0x18, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x11, 0x19, 0x31, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x11, 0x34, 0x35, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, - 0x02, 0x01, 0x12, 0x03, 0x12, 0x02, 0x2a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x06, - 0x12, 0x03, 0x12, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, - 0x12, 0x1c, 0x25, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x12, 0x28, - 0x29, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x13, 0x02, 0x1d, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x05, 0x12, 0x03, 0x13, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x13, 0x09, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, - 0x02, 0x02, 0x03, 0x12, 0x03, 0x13, 0x1b, 0x1c, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x03, - 0x12, 0x03, 0x14, 0x02, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x05, 0x12, 0x03, - 0x14, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, 0x14, 0x09, - 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x03, 0x12, 0x03, 0x14, 0x18, 0x19, 0x0a, - 0x27, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x18, 0x00, 0x1b, 0x01, 0x1a, 0x1b, 0x20, 0x52, 0x65, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x63, 0x64, 0x73, 0x61, 0x53, 0x69, - 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, - 0x03, 0x18, 0x08, 0x21, 0x0a, 0x34, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x00, 0x12, 0x03, 0x1a, 0x02, - 0x12, 0x1a, 0x27, 0x20, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x20, 0x72, 0x65, 0x63, - 0x6f, 0x76, 0x65, 0x72, 0x79, 0x20, 0x69, 0x64, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x6c, 0x61, 0x73, 0x74, 0x20, 0x62, 0x79, 0x74, 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, - 0x02, 0x00, 0x05, 0x12, 0x03, 0x1a, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, - 0x01, 0x12, 0x03, 0x1a, 0x08, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, - 0x03, 0x1a, 0x10, 0x11, 0x0a, 0x35, 0x0a, 0x02, 0x04, 0x02, 0x12, 0x04, 0x1e, 0x00, 0x20, 0x01, - 0x1a, 0x29, 0x20, 0x45, 0x64, 0x44, 0x53, 0x41, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x65, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, - 0x67, 0x20, 0x52, 0x46, 0x43, 0x20, 0x38, 0x30, 0x33, 0x32, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, - 0x02, 0x01, 0x12, 0x03, 0x1e, 0x08, 0x16, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x00, 0x12, - 0x03, 0x1f, 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x05, 0x12, 0x03, 0x1f, - 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x1f, 0x08, 0x0d, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x1f, 0x10, 0x11, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x0a, 0xb5, 0x14, 0x0a, 0x22, 0x6d, 0x6c, 0x73, 0x2f, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2f, - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x78, - 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x95, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x17, 0x0a, - 0x07, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x74, 0x79, 0x70, 0x65, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x5f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0c, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x6f, 0x72, - 0x22, 0x8f, 0x03, 0x0a, 0x0e, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x28, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x49, 0x64, 0x52, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x12, 0x59, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, - 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x73, 0x2e, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x08, - 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, - 0x52, 0x08, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x88, 0x01, 0x01, 0x12, 0x4d, 0x0a, - 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x43, - 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x01, 0x52, 0x0b, 0x63, 0x6f, - 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x18, 0x0a, 0x07, - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, - 0x63, 0x6b, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x2a, 0x3c, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, - 0x5f, 0x44, 0x45, 0x46, 0x4c, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x4f, - 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x5a, 0x49, 0x50, 0x10, 0x01, - 0x42, 0xe1, 0x01, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, - 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x73, 0x42, 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, - 0x6d, 0x74, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, 0x6f, 0x2f, + 0x6f, 0x74, 0x6f, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x05, 0x00, 0x01, 0x12, 0x03, 0x0c, 0x05, 0x1b, + 0x0a, 0x0b, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x00, 0x12, 0x03, 0x0d, 0x02, 0x2b, 0x0a, 0x0c, 0x0a, + 0x05, 0x05, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0d, 0x02, 0x26, 0x0a, 0x0c, 0x0a, 0x05, 0x05, + 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x0d, 0x29, 0x2a, 0x0a, 0x0b, 0x0a, 0x04, 0x05, 0x00, 0x02, + 0x01, 0x12, 0x03, 0x0e, 0x02, 0x21, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x01, 0x01, 0x12, + 0x03, 0x0e, 0x02, 0x1c, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x0e, + 0x1f, 0x20, 0x0a, 0x3c, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x12, 0x00, 0x17, 0x01, 0x1a, 0x30, + 0x20, 0x55, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x22, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x20, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x22, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, + 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x12, 0x08, 0x27, 0x0a, 0x0b, 0x0a, 0x04, + 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x13, 0x02, 0x36, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, + 0x00, 0x06, 0x12, 0x03, 0x13, 0x02, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, + 0x12, 0x03, 0x13, 0x19, 0x31, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, + 0x13, 0x34, 0x35, 0x0a, 0x20, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x14, 0x02, 0x2a, + 0x22, 0x13, 0x20, 0x45, 0x49, 0x50, 0x2d, 0x31, 0x39, 0x31, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x06, 0x12, 0x03, + 0x14, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x14, 0x1c, + 0x25, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x14, 0x28, 0x29, 0x0a, + 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x15, 0x02, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x00, 0x02, 0x02, 0x05, 0x12, 0x03, 0x15, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, + 0x02, 0x02, 0x01, 0x12, 0x03, 0x15, 0x09, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, + 0x03, 0x12, 0x03, 0x15, 0x1b, 0x1c, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x03, 0x12, 0x03, + 0x16, 0x02, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x05, 0x12, 0x03, 0x16, 0x02, + 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, 0x16, 0x09, 0x13, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x03, 0x12, 0x03, 0x16, 0x16, 0x17, 0x0a, 0x3d, 0x0a, + 0x02, 0x04, 0x01, 0x12, 0x04, 0x1a, 0x00, 0x1f, 0x01, 0x1a, 0x31, 0x20, 0x55, 0x73, 0x65, 0x64, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x22, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x20, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x20, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x20, 0x61, + 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, + 0x04, 0x01, 0x01, 0x12, 0x03, 0x1a, 0x08, 0x28, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x00, + 0x12, 0x03, 0x1b, 0x02, 0x36, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x06, 0x12, 0x03, + 0x1b, 0x02, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x1b, 0x19, + 0x31, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x1b, 0x34, 0x35, 0x0a, + 0x20, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x03, 0x1c, 0x02, 0x2a, 0x22, 0x13, 0x20, 0x45, + 0x49, 0x50, 0x2d, 0x31, 0x39, 0x31, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x06, 0x12, 0x03, 0x1c, 0x02, 0x1b, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x1c, 0x1c, 0x25, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x02, 0x01, 0x03, 0x12, 0x03, 0x1c, 0x28, 0x29, 0x0a, 0x0b, 0x0a, 0x04, 0x04, + 0x01, 0x02, 0x02, 0x12, 0x03, 0x1d, 0x02, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, + 0x05, 0x12, 0x03, 0x1d, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x01, 0x12, + 0x03, 0x1d, 0x09, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x03, 0x12, 0x03, 0x1d, + 0x1b, 0x1c, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x03, 0x12, 0x03, 0x1e, 0x02, 0x18, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x05, 0x12, 0x03, 0x1e, 0x02, 0x08, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x02, 0x03, 0x01, 0x12, 0x03, 0x1e, 0x09, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x01, 0x02, 0x03, 0x03, 0x12, 0x03, 0x1e, 0x16, 0x17, 0x0a, 0xb3, 0x01, 0x0a, 0x02, 0x04, 0x02, + 0x12, 0x04, 0x24, 0x00, 0x2a, 0x01, 0x1a, 0xa6, 0x01, 0x20, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x73, + 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, + 0x64, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x61, 0x20, 0x76, 0x33, 0x20, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6b, 0x65, 0x79, 0x0a, 0x20, 0x69, 0x73, + 0x20, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x76, 0x32, 0x20, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x6b, 0x65, 0x79, 0x2c, 0x20, 0x77, 0x68, + 0x69, 0x63, 0x68, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x73, + 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x76, 0x69, 0x61, 0x20, 0x61, 0x0a, 0x20, 0x27, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x27, 0x20, 0x77, 0x61, + 0x6c, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x0a, 0x0a, + 0x0a, 0x0a, 0x03, 0x04, 0x02, 0x01, 0x12, 0x03, 0x24, 0x08, 0x27, 0x0a, 0x35, 0x0a, 0x04, 0x04, + 0x02, 0x02, 0x00, 0x12, 0x03, 0x26, 0x02, 0x2a, 0x1a, 0x28, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x73, + 0x20, 0x53, 0x48, 0x41, 0x2d, 0x32, 0x35, 0x36, 0x20, 0x68, 0x61, 0x73, 0x68, 0x20, 0x6f, 0x66, + 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6b, 0x65, + 0x79, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x06, 0x12, 0x03, 0x26, 0x02, 0x1b, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, 0x03, 0x26, 0x1c, 0x25, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x26, 0x28, 0x29, 0x0a, 0x7e, 0x0a, 0x04, + 0x04, 0x02, 0x02, 0x01, 0x12, 0x03, 0x29, 0x02, 0x4e, 0x1a, 0x71, 0x20, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x5f, 0x6e, 0x73, 0x20, 0x69, 0x73, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, + 0x64, 0x20, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x20, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, + 0x7a, 0x65, 0x64, 0x20, 0x6b, 0x65, 0x79, 0x2c, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x02, 0x02, 0x01, 0x06, 0x12, 0x03, 0x29, 0x02, 0x27, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, + 0x02, 0x01, 0x01, 0x12, 0x03, 0x29, 0x28, 0x49, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, + 0x03, 0x12, 0x03, 0x29, 0x4c, 0x4d, 0x0a, 0x27, 0x0a, 0x02, 0x04, 0x03, 0x12, 0x04, 0x2d, 0x00, + 0x30, 0x01, 0x1a, 0x1b, 0x20, 0x52, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, + 0x45, 0x63, 0x64, 0x73, 0x61, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x0a, 0x0a, + 0x0a, 0x0a, 0x03, 0x04, 0x03, 0x01, 0x12, 0x03, 0x2d, 0x08, 0x21, 0x0a, 0x4a, 0x0a, 0x04, 0x04, + 0x03, 0x02, 0x00, 0x12, 0x03, 0x2f, 0x02, 0x12, 0x1a, 0x3d, 0x20, 0x36, 0x35, 0x2d, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x20, 0x5b, 0x20, 0x52, 0x20, 0x7c, 0x7c, 0x20, 0x53, 0x20, 0x7c, 0x7c, 0x20, + 0x56, 0x20, 0x5d, 0x2c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, + 0x72, 0x79, 0x20, 0x69, 0x64, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x61, 0x73, + 0x74, 0x20, 0x62, 0x79, 0x74, 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x05, + 0x12, 0x03, 0x2f, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x01, 0x12, 0x03, + 0x2f, 0x08, 0x0d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x03, 0x02, 0x00, 0x03, 0x12, 0x03, 0x2f, 0x10, + 0x11, 0x0a, 0x35, 0x0a, 0x02, 0x04, 0x04, 0x12, 0x04, 0x33, 0x00, 0x35, 0x01, 0x1a, 0x29, 0x20, + 0x45, 0x64, 0x44, 0x53, 0x41, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x52, + 0x46, 0x43, 0x20, 0x38, 0x30, 0x33, 0x32, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x04, 0x01, 0x12, + 0x03, 0x33, 0x08, 0x16, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x04, 0x02, 0x00, 0x12, 0x03, 0x34, 0x02, + 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, 0x00, 0x05, 0x12, 0x03, 0x34, 0x02, 0x07, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x04, 0x02, 0x00, 0x01, 0x12, 0x03, 0x34, 0x08, 0x0d, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x04, 0x02, 0x00, 0x03, 0x12, 0x03, 0x34, 0x10, 0x11, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, 0x0a, 0xb5, 0x14, 0x0a, 0x22, 0x6d, 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x78, 0x6d, 0x74, 0x70, + 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x95, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x79, 0x70, + 0x65, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, + 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0c, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x69, 0x6e, 0x6f, 0x72, 0x22, 0x8f, 0x03, + 0x0a, 0x0e, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x12, 0x3c, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, + 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x49, 0x64, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x59, + 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x45, + 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x08, 0x66, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x66, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x88, 0x01, 0x01, 0x12, 0x4d, 0x0a, 0x0b, 0x63, 0x6f, + 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x26, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x70, + 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x01, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x72, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x42, + 0x0e, 0x0a, 0x0c, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x2a, + 0x3c, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x17, + 0x0a, 0x13, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, + 0x46, 0x4c, 0x41, 0x54, 0x45, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x4f, 0x4d, 0x50, 0x52, + 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x47, 0x5a, 0x49, 0x50, 0x10, 0x01, 0x42, 0xe1, 0x01, + 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x42, + 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x6d, 0x74, 0x70, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6c, 0x73, + 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x73, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x4d, 0xaa, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, 0x2e, 0x4d, + 0x6c, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x73, 0xca, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0xe2, 0x02, 0x24, + 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x58, 0x6d, 0x74, 0x70, 0x3a, 0x3a, 0x4d, 0x6c, 0x73, + 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x73, 0x4a, 0x9f, 0x0d, 0x0a, 0x06, 0x12, 0x04, 0x02, 0x00, 0x29, 0x01, 0x0a, 0x7c, 0x0a, 0x01, + 0x0c, 0x12, 0x03, 0x02, 0x00, 0x12, 0x1a, 0x72, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, + 0x67, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x73, 0x0a, 0x20, 0x43, 0x6f, + 0x70, 0x69, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x56, 0x32, 0x20, 0x63, 0x6f, 0x64, + 0x65, 0x20, 0x73, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x65, 0x20, 0x63, 0x61, 0x6e, + 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x72, 0x65, 0x74, 0x69, + 0x72, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x56, 0x32, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x0a, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, + 0x03, 0x04, 0x00, 0x22, 0x0a, 0x08, 0x0a, 0x01, 0x08, 0x12, 0x03, 0x06, 0x00, 0x47, 0x0a, 0x09, + 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, 0x06, 0x00, 0x47, 0x0a, 0x58, 0x0a, 0x02, 0x04, 0x00, 0x12, + 0x04, 0x0a, 0x00, 0x0f, 0x01, 0x1a, 0x4c, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x49, 0x64, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, + 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x2e, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x0a, 0x08, 0x15, 0x0a, + 0x34, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x0b, 0x02, 0x1a, 0x22, 0x27, 0x20, 0x61, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, + 0x0b, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0b, 0x09, + 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0b, 0x18, 0x19, 0x0a, + 0x1e, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x0c, 0x02, 0x15, 0x22, 0x11, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x0a, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x0c, 0x02, 0x08, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x0c, 0x09, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x0c, 0x13, 0x14, 0x0a, 0x28, 0x0a, 0x04, 0x04, 0x00, 0x02, + 0x02, 0x12, 0x03, 0x0d, 0x02, 0x1b, 0x22, 0x1b, 0x20, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x20, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x05, 0x12, 0x03, 0x0d, 0x02, + 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x0d, 0x09, 0x16, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x0d, 0x19, 0x1a, 0x0a, 0x28, 0x0a, + 0x04, 0x04, 0x00, 0x02, 0x03, 0x12, 0x03, 0x0e, 0x02, 0x1b, 0x22, 0x1b, 0x20, 0x6d, 0x69, 0x6e, + 0x6f, 0x72, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x05, + 0x12, 0x03, 0x0e, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, + 0x0e, 0x09, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x03, 0x12, 0x03, 0x0e, 0x19, + 0x1a, 0x0a, 0x67, 0x0a, 0x02, 0x05, 0x00, 0x12, 0x04, 0x13, 0x00, 0x16, 0x01, 0x1a, 0x5b, 0x20, + 0x52, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, + 0x73, 0x0a, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6c, 0x69, 0x6e, 0x74, 0x3a, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, + 0x4e, 0x41, 0x4d, 0x45, 0x53, 0x5f, 0x5a, 0x45, 0x52, 0x4f, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, + 0x5f, 0x45, 0x4e, 0x44, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x05, 0x00, + 0x01, 0x12, 0x03, 0x13, 0x05, 0x10, 0x0a, 0x0b, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x00, 0x12, 0x03, + 0x14, 0x02, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x14, 0x02, + 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x14, 0x18, 0x19, 0x0a, + 0x0b, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x01, 0x12, 0x03, 0x15, 0x02, 0x17, 0x0a, 0x0c, 0x0a, 0x05, + 0x05, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x15, 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, + 0x02, 0x01, 0x02, 0x12, 0x03, 0x15, 0x15, 0x16, 0x0a, 0xa3, 0x01, 0x0a, 0x02, 0x04, 0x01, 0x12, + 0x04, 0x1b, 0x00, 0x29, 0x01, 0x1a, 0x96, 0x01, 0x20, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x74, 0x73, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, 0x72, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x72, 0x72, + 0x65, 0x63, 0x74, 0x20, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x0a, 0x0a, 0x0a, + 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x1b, 0x08, 0x16, 0x0a, 0x65, 0x0a, 0x04, 0x04, 0x01, + 0x02, 0x00, 0x12, 0x03, 0x1e, 0x02, 0x19, 0x1a, 0x58, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, + 0x72, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x0a, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x64, 0x65, + 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x72, 0x79, + 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x06, 0x12, 0x03, 0x1e, 0x02, 0x0f, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x1e, 0x10, 0x14, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x1e, 0x17, 0x18, 0x0a, 0x54, 0x0a, 0x04, 0x04, + 0x01, 0x02, 0x01, 0x12, 0x03, 0x20, 0x02, 0x25, 0x1a, 0x47, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x20, 0x64, 0x65, + 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x06, 0x12, 0x03, 0x20, 0x02, 0x15, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x20, 0x16, 0x20, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x02, 0x01, 0x03, 0x12, 0x03, 0x20, 0x23, 0x24, 0x0a, 0x84, 0x01, 0x0a, 0x04, + 0x04, 0x01, 0x02, 0x02, 0x12, 0x03, 0x23, 0x02, 0x1f, 0x1a, 0x77, 0x20, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x63, 0x61, + 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x61, 0x73, + 0x65, 0x0a, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x61, + 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x72, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x04, 0x12, 0x03, 0x23, 0x02, 0x0a, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x05, 0x12, 0x03, 0x23, 0x0b, 0x11, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x01, 0x12, 0x03, 0x23, 0x12, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x01, 0x02, 0x02, 0x03, 0x12, 0x03, 0x23, 0x1d, 0x1e, 0x0a, 0x6e, 0x0a, 0x04, 0x04, 0x01, + 0x02, 0x03, 0x12, 0x03, 0x26, 0x02, 0x27, 0x1a, 0x61, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3b, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x73, 0x20, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x20, 0x75, 0x73, + 0x65, 0x64, 0x20, 0x74, 0x6f, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, + 0x02, 0x03, 0x04, 0x12, 0x03, 0x26, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, + 0x06, 0x12, 0x03, 0x26, 0x0b, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x01, 0x12, + 0x03, 0x26, 0x17, 0x22, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x03, 0x12, 0x03, 0x26, + 0x25, 0x26, 0x0a, 0x25, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x04, 0x12, 0x03, 0x28, 0x02, 0x14, 0x1a, + 0x18, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x20, 0x69, 0x74, 0x73, 0x65, 0x6c, 0x66, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, + 0x04, 0x05, 0x12, 0x03, 0x28, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x01, + 0x12, 0x03, 0x28, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, 0x03, 0x12, 0x03, + 0x28, 0x12, 0x13, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x0a, 0xca, 0x0d, 0x0a, 0x25, 0x6d, 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x73, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x4d, 0xaa, 0x02, 0x18, 0x58, 0x6d, 0x74, - 0x70, 0x2e, 0x4d, 0x6c, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x73, 0xca, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, - 0x5c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, - 0xe2, 0x02, 0x24, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x58, 0x6d, 0x74, 0x70, 0x3a, 0x3a, - 0x4d, 0x6c, 0x73, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x73, 0x4a, 0x9f, 0x0d, 0x0a, 0x06, 0x12, 0x04, 0x02, 0x00, 0x29, 0x01, 0x0a, - 0x7c, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x02, 0x00, 0x12, 0x1a, 0x72, 0x20, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x65, 0x6e, 0x63, 0x6f, - 0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x73, 0x0a, - 0x20, 0x43, 0x6f, 0x70, 0x69, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x56, 0x32, 0x20, - 0x63, 0x6f, 0x64, 0x65, 0x20, 0x73, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x77, 0x65, 0x20, - 0x63, 0x61, 0x6e, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x72, - 0x65, 0x74, 0x69, 0x72, 0x65, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x56, 0x32, 0x20, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x0a, 0x0a, 0x08, 0x0a, - 0x01, 0x02, 0x12, 0x03, 0x04, 0x00, 0x22, 0x0a, 0x08, 0x0a, 0x01, 0x08, 0x12, 0x03, 0x06, 0x00, - 0x47, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, 0x06, 0x00, 0x47, 0x0a, 0x58, 0x0a, 0x02, - 0x04, 0x00, 0x12, 0x04, 0x0a, 0x00, 0x0f, 0x01, 0x1a, 0x4c, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x49, 0x64, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, - 0x20, 0x74, 0x6f, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x2e, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x0a, - 0x08, 0x15, 0x0a, 0x34, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x0b, 0x02, 0x1a, 0x22, - 0x27, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x67, 0x6f, 0x76, 0x65, - 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, - 0x05, 0x12, 0x03, 0x0b, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, - 0x03, 0x0b, 0x09, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0b, - 0x18, 0x19, 0x0a, 0x1e, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x0c, 0x02, 0x15, 0x22, - 0x11, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, - 0x72, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x0c, 0x02, 0x08, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x0c, 0x09, 0x10, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x0c, 0x13, 0x14, 0x0a, 0x28, 0x0a, 0x04, - 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x0d, 0x02, 0x1b, 0x22, 0x1b, 0x20, 0x6d, 0x61, 0x6a, 0x6f, - 0x72, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x05, 0x12, - 0x03, 0x0d, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x0d, - 0x09, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x0d, 0x19, 0x1a, - 0x0a, 0x28, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x03, 0x12, 0x03, 0x0e, 0x02, 0x1b, 0x22, 0x1b, 0x20, - 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, - 0x02, 0x03, 0x05, 0x12, 0x03, 0x0e, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, - 0x01, 0x12, 0x03, 0x0e, 0x09, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x03, 0x03, 0x12, - 0x03, 0x0e, 0x19, 0x1a, 0x0a, 0x67, 0x0a, 0x02, 0x05, 0x00, 0x12, 0x04, 0x13, 0x00, 0x16, 0x01, - 0x1a, 0x5b, 0x20, 0x52, 0x65, 0x63, 0x6f, 0x67, 0x6e, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x63, 0x6f, - 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, - 0x74, 0x68, 0x6d, 0x73, 0x0a, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6c, 0x69, 0x6e, 0x74, 0x3a, - 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x46, 0x49, 0x45, - 0x4c, 0x44, 0x5f, 0x4e, 0x41, 0x4d, 0x45, 0x53, 0x5f, 0x5a, 0x45, 0x52, 0x4f, 0x5f, 0x56, 0x41, - 0x4c, 0x55, 0x45, 0x5f, 0x45, 0x4e, 0x44, 0x5f, 0x57, 0x49, 0x54, 0x48, 0x0a, 0x0a, 0x0a, 0x0a, - 0x03, 0x05, 0x00, 0x01, 0x12, 0x03, 0x13, 0x05, 0x10, 0x0a, 0x0b, 0x0a, 0x04, 0x05, 0x00, 0x02, - 0x00, 0x12, 0x03, 0x14, 0x02, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00, 0x01, 0x12, - 0x03, 0x14, 0x02, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x14, - 0x18, 0x19, 0x0a, 0x0b, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x01, 0x12, 0x03, 0x15, 0x02, 0x17, 0x0a, - 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x15, 0x02, 0x12, 0x0a, 0x0c, 0x0a, - 0x05, 0x05, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x15, 0x15, 0x16, 0x0a, 0xa3, 0x01, 0x0a, 0x02, - 0x04, 0x01, 0x12, 0x04, 0x1b, 0x00, 0x29, 0x01, 0x1a, 0x96, 0x01, 0x20, 0x45, 0x6e, 0x63, 0x6f, - 0x64, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x75, 0x6e, 0x64, 0x6c, - 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x77, - 0x69, 0x74, 0x68, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x20, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x66, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x74, 0x73, 0x20, 0x74, 0x79, 0x70, - 0x65, 0x0a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, - 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, - 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x1b, 0x08, 0x16, 0x0a, 0x65, 0x0a, - 0x04, 0x04, 0x01, 0x02, 0x00, 0x12, 0x03, 0x1e, 0x02, 0x19, 0x1a, 0x58, 0x20, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x66, 0x69, 0x65, 0x72, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x77, - 0x69, 0x74, 0x68, 0x0a, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, - 0x20, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, - 0x65, 0x72, 0x79, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x06, 0x12, 0x03, 0x1e, - 0x02, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x1e, 0x10, 0x14, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x1e, 0x17, 0x18, 0x0a, 0x54, - 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x03, 0x20, 0x02, 0x25, 0x1a, 0x47, 0x20, 0x6f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x20, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x20, 0x72, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, - 0x20, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x06, 0x12, 0x03, 0x20, - 0x02, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x20, 0x16, 0x20, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x03, 0x12, 0x03, 0x20, 0x23, 0x24, 0x0a, 0x84, - 0x01, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x02, 0x12, 0x03, 0x23, 0x02, 0x1f, 0x1a, 0x77, 0x20, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, - 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x61, 0x74, - 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, - 0x63, 0x61, 0x73, 0x65, 0x0a, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, - 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x6f, - 0x72, 0x20, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x04, 0x12, 0x03, - 0x23, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x05, 0x12, 0x03, 0x23, 0x0b, - 0x11, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x01, 0x12, 0x03, 0x23, 0x12, 0x1a, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x03, 0x12, 0x03, 0x23, 0x1d, 0x1e, 0x0a, 0x6e, 0x0a, - 0x04, 0x04, 0x01, 0x02, 0x03, 0x12, 0x03, 0x26, 0x02, 0x27, 0x1a, 0x61, 0x20, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x3b, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x69, 0x6e, 0x64, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x20, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, - 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, - 0x73, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x0a, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x01, 0x02, 0x03, 0x04, 0x12, 0x03, 0x26, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x01, 0x02, 0x03, 0x06, 0x12, 0x03, 0x26, 0x0b, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, - 0x03, 0x01, 0x12, 0x03, 0x26, 0x17, 0x22, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x03, - 0x12, 0x03, 0x26, 0x25, 0x26, 0x0a, 0x25, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x04, 0x12, 0x03, 0x28, - 0x02, 0x14, 0x1a, 0x18, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x74, 0x73, 0x65, 0x6c, 0x66, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x01, 0x02, 0x04, 0x05, 0x12, 0x03, 0x28, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, - 0x02, 0x04, 0x01, 0x12, 0x03, 0x28, 0x08, 0x0f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x04, - 0x03, 0x12, 0x03, 0x28, 0x12, 0x13, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x0a, 0xb9, - 0x09, 0x0a, 0x25, 0x6d, 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, - 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x73, 0x1a, 0x26, 0x6d, 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9f, 0x01, 0x0a, 0x0d, - 0x4d, 0x6c, 0x73, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x36, 0x0a, - 0x17, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x15, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x47, 0x0a, 0x07, 0x65, 0x69, 0x70, 0x5f, 0x31, 0x39, 0x31, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, - 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x73, 0x2e, 0x45, 0x69, 0x70, 0x31, 0x39, 0x31, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x06, 0x65, 0x69, 0x70, 0x31, 0x39, 0x31, 0x42, 0x0d, - 0x0a, 0x0b, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa6, 0x01, - 0x0a, 0x14, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x76, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x17, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x15, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x47, - 0x0a, 0x07, 0x65, 0x69, 0x70, 0x5f, 0x31, 0x39, 0x31, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2c, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x45, 0x69, 0x70, 0x31, - 0x39, 0x31, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, - 0x06, 0x65, 0x69, 0x70, 0x31, 0x39, 0x31, 0x42, 0x0d, 0x0a, 0x0b, 0x61, 0x73, 0x73, 0x6f, 0x63, - 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0xe4, 0x01, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x78, + 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, + 0x1a, 0x26, 0x6d, 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb3, 0x02, 0x0a, 0x0d, 0x4d, 0x6c, 0x73, + 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x36, 0x0a, 0x17, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x15, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, + 0x65, 0x79, 0x12, 0x67, 0x0a, 0x10, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x5f, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x0f, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x6d, 0x74, 0x70, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0xa2, 0x02, 0x03, - 0x58, 0x4d, 0x4d, 0xaa, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, 0x2e, 0x4d, 0x6c, 0x73, 0x2e, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0xca, 0x02, - 0x18, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0xe2, 0x02, 0x24, 0x58, 0x6d, 0x74, 0x70, - 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0xea, 0x02, 0x1a, 0x58, 0x6d, 0x74, 0x70, 0x3a, 0x3a, 0x4d, 0x6c, 0x73, 0x3a, 0x3a, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x4a, 0x92, 0x04, - 0x0a, 0x06, 0x12, 0x04, 0x01, 0x00, 0x18, 0x01, 0x0a, 0x27, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x01, - 0x00, 0x12, 0x1a, 0x1d, 0x20, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, - 0x20, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x0a, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x03, 0x00, 0x22, 0x0a, 0x09, 0x0a, 0x02, 0x03, - 0x00, 0x12, 0x03, 0x05, 0x00, 0x30, 0x0a, 0x08, 0x0a, 0x01, 0x08, 0x12, 0x03, 0x07, 0x00, 0x47, - 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, 0x07, 0x00, 0x47, 0x0a, 0x3d, 0x0a, 0x02, 0x04, - 0x00, 0x12, 0x04, 0x0b, 0x00, 0x10, 0x01, 0x1a, 0x31, 0x20, 0x41, 0x20, 0x63, 0x72, 0x65, 0x64, - 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x63, 0x61, 0x6e, 0x20, - 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x4d, 0x4c, 0x53, 0x20, 0x6c, - 0x65, 0x61, 0x66, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, - 0x01, 0x12, 0x03, 0x0b, 0x08, 0x15, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, - 0x0c, 0x02, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x0c, 0x02, - 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0c, 0x08, 0x1f, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0c, 0x22, 0x23, 0x0a, 0x0c, 0x0a, - 0x04, 0x04, 0x00, 0x08, 0x00, 0x12, 0x04, 0x0d, 0x02, 0x0f, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x00, 0x08, 0x00, 0x01, 0x12, 0x03, 0x0d, 0x08, 0x13, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, - 0x01, 0x12, 0x03, 0x0e, 0x04, 0x22, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x06, 0x12, - 0x03, 0x0e, 0x04, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x0e, - 0x16, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x0e, 0x20, 0x21, - 0x0a, 0x4a, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x13, 0x00, 0x18, 0x01, 0x1a, 0x3e, 0x20, 0x41, - 0x20, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x20, 0x63, 0x72, - 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x6c, - 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, - 0x04, 0x01, 0x01, 0x12, 0x03, 0x13, 0x08, 0x1c, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x00, - 0x12, 0x03, 0x14, 0x02, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x05, 0x12, 0x03, - 0x14, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x14, 0x08, - 0x1f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x14, 0x22, 0x23, 0x0a, - 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x08, 0x00, 0x12, 0x04, 0x15, 0x02, 0x17, 0x03, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x01, 0x08, 0x00, 0x01, 0x12, 0x03, 0x15, 0x08, 0x13, 0x0a, 0x0b, 0x0a, 0x04, 0x04, - 0x01, 0x02, 0x01, 0x12, 0x03, 0x16, 0x04, 0x22, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, - 0x06, 0x12, 0x03, 0x16, 0x04, 0x15, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x01, 0x12, - 0x03, 0x16, 0x16, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x03, 0x12, 0x03, 0x16, - 0x20, 0x21, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x0a, 0x8d, 0x17, 0x0a, 0x29, 0x6d, - 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x73, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, - 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x0f, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x56, 0x31, 0x12, 0x58, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x76, 0x65, - 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x43, - 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x10, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x15, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x40, 0x0a, 0x08, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x6d, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x41, 0x73, 0x73, + 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0f, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x72, 0x0a, 0x16, 0x6c, + 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x65, - 0x74, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x22, 0xc3, 0x01, 0x0a, 0x09, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x65, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x61, 0x64, 0x64, - 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, - 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x52, 0x0f, 0x61, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x12, 0x5d, 0x0a, 0x14, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x6d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x73, 0x73, 0x6f, + 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x14, 0x6c, 0x65, 0x67, 0x61, 0x63, + 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x42, + 0x0d, 0x0a, 0x0b, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x9a, + 0x02, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x76, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x48, 0x00, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x4b, 0x65, 0x79, 0x12, 0x4e, 0x0a, 0x23, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, + 0x5f, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x48, 0x00, 0x52, 0x1f, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x4c, 0x65, 0x67, + 0x61, 0x63, 0x79, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x4b, 0x65, 0x79, 0x12, 0x68, 0x0a, 0x10, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x69, 0x6e, + 0x67, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, + 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, + 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x01, 0x52, 0x0f, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x42, 0x0c, + 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x42, 0x0d, 0x0a, 0x0b, + 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0xe4, 0x01, 0x0a, 0x1d, + 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x0f, 0x43, + 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x6d, 0x74, + 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6c, + 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x73, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x4d, 0xaa, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, 0x2e, + 0x4d, 0x6c, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x73, 0xca, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0xe2, 0x02, + 0x24, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x58, 0x6d, 0x74, 0x70, 0x3a, 0x3a, 0x4d, 0x6c, + 0x73, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x73, 0x4a, 0x9b, 0x06, 0x0a, 0x06, 0x12, 0x04, 0x01, 0x00, 0x1e, 0x01, 0x0a, 0x27, 0x0a, + 0x01, 0x0c, 0x12, 0x03, 0x01, 0x00, 0x12, 0x1a, 0x1d, 0x20, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x65, 0x76, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x03, 0x00, 0x22, + 0x0a, 0x09, 0x0a, 0x02, 0x03, 0x00, 0x12, 0x03, 0x05, 0x00, 0x30, 0x0a, 0x08, 0x0a, 0x01, 0x08, + 0x12, 0x03, 0x07, 0x00, 0x47, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, 0x07, 0x00, 0x47, + 0x0a, 0x3d, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x0b, 0x00, 0x11, 0x01, 0x1a, 0x31, 0x20, 0x41, + 0x20, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x61, 0x74, + 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, + 0x4d, 0x4c, 0x53, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x0a, 0x0a, + 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x0b, 0x08, 0x15, 0x0a, 0x0b, 0x0a, 0x04, 0x04, + 0x00, 0x02, 0x00, 0x12, 0x03, 0x0c, 0x02, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, + 0x05, 0x12, 0x03, 0x0c, 0x02, 0x07, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, + 0x03, 0x0c, 0x08, 0x1f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0c, + 0x22, 0x23, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x00, 0x08, 0x00, 0x12, 0x04, 0x0d, 0x02, 0x10, 0x03, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x08, 0x00, 0x01, 0x12, 0x03, 0x0d, 0x08, 0x13, 0x0a, 0x0b, + 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x0e, 0x04, 0x39, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x00, 0x02, 0x01, 0x06, 0x12, 0x03, 0x0e, 0x04, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, + 0x01, 0x01, 0x12, 0x03, 0x0e, 0x24, 0x34, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x03, + 0x12, 0x03, 0x0e, 0x37, 0x38, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x0f, + 0x04, 0x3f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x06, 0x12, 0x03, 0x0f, 0x04, 0x23, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x0f, 0x24, 0x3a, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x0f, 0x3d, 0x3e, 0x0a, 0x4a, 0x0a, 0x02, + 0x04, 0x01, 0x12, 0x04, 0x14, 0x00, 0x1e, 0x01, 0x1a, 0x3e, 0x20, 0x41, 0x20, 0x64, 0x65, 0x63, + 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x72, 0x6f, + 0x6f, 0x66, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61, 0x20, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x65, + 0x72, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, + 0x03, 0x14, 0x08, 0x1c, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x01, 0x08, 0x00, 0x12, 0x04, 0x15, 0x02, + 0x1a, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x08, 0x00, 0x01, 0x12, 0x03, 0x15, 0x08, 0x12, + 0x0a, 0x4d, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x00, 0x12, 0x03, 0x17, 0x04, 0x1f, 0x1a, 0x40, 0x20, + 0x54, 0x68, 0x65, 0x20, 0x27, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x27, 0x20, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4d, 0x6c, 0x73, 0x43, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x0a, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x05, 0x12, 0x03, 0x17, 0x04, 0x09, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x17, 0x0a, 0x1a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x17, 0x1d, 0x1e, 0x0a, 0x48, 0x0a, 0x04, 0x04, 0x01, 0x02, + 0x01, 0x12, 0x03, 0x19, 0x04, 0x32, 0x1a, 0x3b, 0x20, 0x54, 0x68, 0x65, 0x20, 0x27, 0x6b, 0x65, + 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x27, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x6f, + 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x20, 0x53, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x20, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x05, 0x12, 0x03, 0x19, 0x04, + 0x09, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x19, 0x0a, 0x2d, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x03, 0x12, 0x03, 0x19, 0x30, 0x31, 0x0a, 0x0c, 0x0a, + 0x04, 0x04, 0x01, 0x08, 0x01, 0x12, 0x04, 0x1b, 0x02, 0x1d, 0x03, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x01, 0x08, 0x01, 0x01, 0x12, 0x03, 0x1b, 0x08, 0x13, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, + 0x02, 0x12, 0x03, 0x1c, 0x04, 0x3a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x06, 0x12, + 0x03, 0x1c, 0x04, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x01, 0x12, 0x03, 0x1c, + 0x25, 0x35, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x03, 0x12, 0x03, 0x1c, 0x38, 0x39, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x0a, 0x8d, 0x17, 0x0a, 0x29, 0x6d, 0x6c, 0x73, + 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x73, 0x2f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, + 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x0f, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x56, 0x31, 0x12, 0x58, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x12, 0x72, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x22, 0xdc, 0x04, 0x0a, 0x10, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x4c, 0x0a, 0x04, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, - 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, 0x04, - 0x62, 0x61, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x0d, 0x61, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x64, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x78, 0x6d, - 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, - 0x69, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x64, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x64, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5f, 0x0a, 0x0d, 0x61, 0x6e, 0x79, 0x5f, 0x63, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x78, - 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, - 0x68, 0x69, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x6e, 0x79, 0x43, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x6e, 0x79, 0x43, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x57, 0x0a, 0x0c, 0x41, 0x6e, 0x64, 0x43, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, - 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x1a, - 0x57, 0x0a, 0x0c, 0x41, 0x6e, 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x47, 0x0a, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, - 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x08, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x22, 0x7e, 0x0a, 0x0a, 0x42, 0x61, 0x73, 0x65, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1b, 0x0a, 0x17, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, - 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x4c, 0x49, - 0x43, 0x59, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x42, 0x41, - 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x44, 0x45, 0x4e, 0x59, 0x10, 0x02, - 0x12, 0x26, 0x0a, 0x22, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, - 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x5f, 0x49, 0x46, 0x5f, 0x41, 0x43, 0x54, 0x4f, 0x52, 0x5f, 0x43, - 0x52, 0x45, 0x41, 0x54, 0x4f, 0x52, 0x10, 0x03, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, - 0x2a, 0x6c, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x56, 0x45, - 0x52, 0x53, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x52, 0x4f, - 0x55, 0x50, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x4d, 0x10, 0x02, 0x42, 0xe7, - 0x01, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, - 0x42, 0x12, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x78, 0x6d, 0x74, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, - 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x4d, 0xaa, 0x02, - 0x18, 0x58, 0x6d, 0x74, 0x70, 0x2e, 0x4d, 0x6c, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0xca, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, - 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x73, 0xe2, 0x02, 0x24, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x58, 0x6d, - 0x74, 0x70, 0x3a, 0x3a, 0x4d, 0x6c, 0x73, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x4a, 0xd7, 0x0b, 0x0a, 0x06, 0x12, 0x04, 0x01, - 0x00, 0x35, 0x01, 0x0a, 0x1a, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x01, 0x00, 0x12, 0x1a, 0x10, 0x20, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x0a, 0x0a, - 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x03, 0x00, 0x22, 0x0a, 0x08, 0x0a, 0x01, 0x08, 0x12, 0x03, - 0x05, 0x00, 0x47, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, 0x05, 0x00, 0x47, 0x0a, 0x2f, - 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x09, 0x00, 0x0d, 0x01, 0x1a, 0x23, 0x20, 0x50, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x0a, 0x0a, - 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x09, 0x08, 0x17, 0x0a, 0x0b, 0x0a, 0x04, 0x04, - 0x00, 0x02, 0x00, 0x12, 0x03, 0x0a, 0x02, 0x29, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, - 0x06, 0x12, 0x03, 0x0a, 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, - 0x03, 0x0a, 0x13, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0a, - 0x27, 0x28, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x0b, 0x02, 0x25, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x0b, 0x02, 0x08, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x0b, 0x09, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, - 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x0b, 0x23, 0x24, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, - 0x02, 0x12, 0x03, 0x0c, 0x02, 0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x06, 0x12, - 0x03, 0x0c, 0x02, 0x0b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x0c, - 0x0c, 0x14, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x0c, 0x17, 0x18, - 0x0a, 0x2e, 0x0a, 0x02, 0x05, 0x00, 0x12, 0x04, 0x10, 0x00, 0x14, 0x01, 0x1a, 0x22, 0x20, 0x44, - 0x65, 0x66, 0x69, 0x6e, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, - 0x6f, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, - 0x0a, 0x0a, 0x0a, 0x03, 0x05, 0x00, 0x01, 0x12, 0x03, 0x10, 0x05, 0x15, 0x0a, 0x0b, 0x0a, 0x04, - 0x05, 0x00, 0x02, 0x00, 0x12, 0x03, 0x11, 0x02, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, - 0x00, 0x01, 0x12, 0x03, 0x11, 0x02, 0x1f, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00, 0x02, - 0x12, 0x03, 0x11, 0x22, 0x23, 0x0a, 0x0b, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x01, 0x12, 0x03, 0x12, - 0x02, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x12, 0x02, 0x19, - 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x12, 0x1c, 0x1d, 0x0a, 0x0b, - 0x0a, 0x04, 0x05, 0x00, 0x02, 0x02, 0x12, 0x03, 0x13, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x05, - 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x13, 0x02, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, - 0x02, 0x02, 0x12, 0x03, 0x13, 0x19, 0x1a, 0x0a, 0x37, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x17, - 0x00, 0x1a, 0x01, 0x1a, 0x2b, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66, - 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x67, - 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x0a, - 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x17, 0x08, 0x11, 0x0a, 0x0b, 0x0a, 0x04, - 0x04, 0x01, 0x02, 0x00, 0x12, 0x03, 0x18, 0x02, 0x29, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, - 0x00, 0x06, 0x12, 0x03, 0x18, 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, - 0x12, 0x03, 0x18, 0x13, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, - 0x18, 0x27, 0x28, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x03, 0x19, 0x02, 0x2c, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x06, 0x12, 0x03, 0x19, 0x02, 0x12, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x19, 0x13, 0x27, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x01, 0x02, 0x01, 0x03, 0x12, 0x03, 0x19, 0x2a, 0x2b, 0x0a, 0x4c, 0x0a, 0x02, 0x04, 0x02, - 0x12, 0x04, 0x1d, 0x00, 0x35, 0x01, 0x1a, 0x40, 0x20, 0x41, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x73, 0x20, 0x61, - 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, 0x01, 0x12, - 0x03, 0x1d, 0x08, 0x18, 0x0a, 0x1b, 0x0a, 0x04, 0x04, 0x02, 0x04, 0x00, 0x12, 0x04, 0x1f, 0x02, - 0x24, 0x03, 0x1a, 0x0d, 0x20, 0x42, 0x61, 0x73, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x04, 0x00, 0x01, 0x12, 0x03, 0x1f, 0x07, 0x11, 0x0a, - 0x0d, 0x0a, 0x06, 0x04, 0x02, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x20, 0x04, 0x20, 0x0a, 0x0e, - 0x0a, 0x07, 0x04, 0x02, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x20, 0x04, 0x1b, 0x0a, 0x0e, - 0x0a, 0x07, 0x04, 0x02, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x20, 0x1e, 0x1f, 0x0a, 0x0d, - 0x0a, 0x06, 0x04, 0x02, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x21, 0x04, 0x1a, 0x0a, 0x0e, 0x0a, - 0x07, 0x04, 0x02, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x21, 0x04, 0x15, 0x0a, 0x0e, 0x0a, - 0x07, 0x04, 0x02, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x21, 0x18, 0x19, 0x0a, 0x0d, 0x0a, - 0x06, 0x04, 0x02, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x22, 0x04, 0x19, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x02, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x22, 0x04, 0x14, 0x0a, 0x0e, 0x0a, 0x07, - 0x04, 0x02, 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x03, 0x22, 0x17, 0x18, 0x0a, 0x0d, 0x0a, 0x06, - 0x04, 0x02, 0x04, 0x00, 0x02, 0x03, 0x12, 0x03, 0x23, 0x04, 0x2b, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x02, 0x04, 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, 0x23, 0x04, 0x26, 0x0a, 0x0e, 0x0a, 0x07, 0x04, - 0x02, 0x04, 0x00, 0x02, 0x03, 0x02, 0x12, 0x03, 0x23, 0x29, 0x2a, 0x0a, 0x44, 0x0a, 0x04, 0x04, - 0x02, 0x03, 0x00, 0x12, 0x04, 0x27, 0x02, 0x29, 0x03, 0x1a, 0x36, 0x20, 0x43, 0x6f, 0x6d, 0x62, - 0x69, 0x6e, 0x65, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, - 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x72, 0x75, 0x65, - 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x03, 0x00, 0x01, 0x12, 0x03, 0x27, 0x0a, 0x16, 0x0a, - 0x0d, 0x0a, 0x06, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x28, 0x04, 0x2b, 0x0a, 0x0e, - 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x28, 0x04, 0x0c, 0x0a, 0x0e, - 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x28, 0x0d, 0x1d, 0x0a, 0x0e, - 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x28, 0x1e, 0x26, 0x0a, 0x0e, - 0x0a, 0x07, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x28, 0x29, 0x2a, 0x0a, 0x44, - 0x0a, 0x04, 0x04, 0x02, 0x03, 0x01, 0x12, 0x04, 0x2c, 0x02, 0x2e, 0x03, 0x1a, 0x36, 0x20, 0x43, - 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x20, 0x41, 0x6e, 0x79, 0x20, 0x6d, 0x75, - 0x73, 0x74, 0x20, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, - 0x72, 0x75, 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x03, 0x01, 0x01, 0x12, 0x03, 0x2c, - 0x0a, 0x16, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x02, 0x03, 0x01, 0x02, 0x00, 0x12, 0x03, 0x2d, 0x04, - 0x2b, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x01, 0x02, 0x00, 0x04, 0x12, 0x03, 0x2d, 0x04, - 0x0c, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x01, 0x02, 0x00, 0x06, 0x12, 0x03, 0x2d, 0x0d, - 0x1d, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x2d, 0x1e, - 0x26, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x2d, 0x29, - 0x2a, 0x0a, 0x0c, 0x0a, 0x04, 0x04, 0x02, 0x08, 0x00, 0x12, 0x04, 0x30, 0x02, 0x34, 0x03, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x08, 0x00, 0x01, 0x12, 0x03, 0x30, 0x08, 0x0c, 0x0a, 0x0b, 0x0a, - 0x04, 0x04, 0x02, 0x02, 0x00, 0x12, 0x03, 0x31, 0x04, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, - 0x02, 0x00, 0x06, 0x12, 0x03, 0x31, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, - 0x01, 0x12, 0x03, 0x31, 0x0f, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, - 0x03, 0x31, 0x16, 0x17, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x01, 0x12, 0x03, 0x32, 0x04, - 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x06, 0x12, 0x03, 0x32, 0x04, 0x10, 0x0a, - 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x01, 0x12, 0x03, 0x32, 0x11, 0x1e, 0x0a, 0x0c, 0x0a, - 0x05, 0x04, 0x02, 0x02, 0x01, 0x03, 0x12, 0x03, 0x32, 0x21, 0x22, 0x0a, 0x0b, 0x0a, 0x04, 0x04, - 0x02, 0x02, 0x02, 0x12, 0x03, 0x33, 0x04, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, - 0x06, 0x12, 0x03, 0x33, 0x04, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, 0x01, 0x12, - 0x03, 0x33, 0x11, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, 0x03, 0x12, 0x03, 0x33, - 0x21, 0x22, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x0a, 0xaa, 0x0e, 0x0a, 0x2e, 0x6d, - 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x73, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x78, - 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x10, 0x4d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x29, 0x0a, - 0x10, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, - 0x79, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, - 0x65, 0x64, 0x42, 0x79, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x22, 0x80, 0x03, 0x0a, 0x16, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x50, 0x0a, - 0x0d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x5f, 0x61, 0x64, 0x64, 0x65, 0x64, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, - 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x52, 0x0c, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x65, 0x64, 0x12, - 0x54, 0x0a, 0x0f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, - 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0e, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x12, 0x5c, 0x0a, 0x13, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x61, 0x64, 0x64, 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, + 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x10, 0x63, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x36, 0x0a, 0x17, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x15, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x40, 0x0a, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x6d, 0x74, 0x70, + 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x53, 0x65, 0x74, 0x52, + 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x22, 0xc3, 0x01, 0x0a, 0x09, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x53, 0x65, 0x74, 0x12, 0x57, 0x0a, 0x11, 0x61, 0x64, 0x64, 0x5f, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, - 0x12, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x41, 0x64, - 0x64, 0x65, 0x64, 0x12, 0x60, 0x0a, 0x15, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x03, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, + 0x0f, 0x61, 0x64, 0x64, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x12, 0x5d, 0x0a, 0x14, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, + 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x68, 0x69, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x12, 0x72, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, + 0xdc, 0x04, 0x0a, 0x10, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x12, 0x4c, 0x0a, 0x04, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x42, 0x61, 0x73, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x48, 0x00, 0x52, 0x04, 0x62, 0x61, + 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x0d, 0x61, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x78, 0x6d, 0x74, 0x70, + 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x5f, 0x0a, 0x0d, 0x61, 0x6e, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x78, 0x6d, 0x74, + 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, + 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x6e, 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0c, 0x61, 0x6e, 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x57, 0x0a, 0x0c, 0x41, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, + 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x1a, 0x57, 0x0a, + 0x0c, 0x41, 0x6e, 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x47, 0x0a, + 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x08, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x22, 0x7e, 0x0a, 0x0a, 0x42, 0x61, 0x73, 0x65, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1b, 0x0a, 0x17, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x4c, + 0x49, 0x43, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x15, 0x0a, 0x11, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, + 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x42, 0x41, 0x53, 0x45, + 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x44, 0x45, 0x4e, 0x59, 0x10, 0x02, 0x12, 0x26, + 0x0a, 0x22, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x41, 0x4c, + 0x4c, 0x4f, 0x57, 0x5f, 0x49, 0x46, 0x5f, 0x41, 0x43, 0x54, 0x4f, 0x52, 0x5f, 0x43, 0x52, 0x45, + 0x41, 0x54, 0x4f, 0x52, 0x10, 0x03, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x2a, 0x6c, + 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, + 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x53, 0x41, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x4d, 0x10, 0x02, 0x42, 0xe7, 0x01, 0x0a, + 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x12, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x78, 0x6d, 0x74, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, + 0x6f, 0x2f, 0x6d, 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x4d, 0xaa, 0x02, 0x18, 0x58, + 0x6d, 0x74, 0x70, 0x2e, 0x4d, 0x6c, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0xca, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, + 0x6c, 0x73, 0x5c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x73, 0xe2, 0x02, 0x24, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x58, 0x6d, 0x74, 0x70, + 0x3a, 0x3a, 0x4d, 0x6c, 0x73, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x4a, 0xd7, 0x0b, 0x0a, 0x06, 0x12, 0x04, 0x01, 0x00, 0x35, + 0x01, 0x0a, 0x1a, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x01, 0x00, 0x12, 0x1a, 0x10, 0x20, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x08, 0x0a, + 0x01, 0x02, 0x12, 0x03, 0x03, 0x00, 0x22, 0x0a, 0x08, 0x0a, 0x01, 0x08, 0x12, 0x03, 0x05, 0x00, + 0x47, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, 0x05, 0x00, 0x47, 0x0a, 0x2f, 0x0a, 0x02, + 0x04, 0x00, 0x12, 0x04, 0x09, 0x00, 0x0d, 0x01, 0x1a, 0x23, 0x20, 0x50, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x20, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x0a, 0x0a, 0x0a, 0x0a, + 0x03, 0x04, 0x00, 0x01, 0x12, 0x03, 0x09, 0x08, 0x17, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, + 0x00, 0x12, 0x03, 0x0a, 0x02, 0x29, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x06, 0x12, + 0x03, 0x0a, 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0a, + 0x13, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0a, 0x27, 0x28, + 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x0b, 0x02, 0x25, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x00, 0x02, 0x01, 0x05, 0x12, 0x03, 0x0b, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x0b, 0x09, 0x20, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, + 0x01, 0x03, 0x12, 0x03, 0x0b, 0x23, 0x24, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, + 0x03, 0x0c, 0x02, 0x19, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x06, 0x12, 0x03, 0x0c, + 0x02, 0x0b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x0c, 0x0c, 0x14, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x0c, 0x17, 0x18, 0x0a, 0x2e, + 0x0a, 0x02, 0x05, 0x00, 0x12, 0x04, 0x10, 0x00, 0x14, 0x01, 0x1a, 0x22, 0x20, 0x44, 0x65, 0x66, + 0x69, 0x6e, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, + 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x0a, 0x0a, + 0x0a, 0x03, 0x05, 0x00, 0x01, 0x12, 0x03, 0x10, 0x05, 0x15, 0x0a, 0x0b, 0x0a, 0x04, 0x05, 0x00, + 0x02, 0x00, 0x12, 0x03, 0x11, 0x02, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00, 0x01, + 0x12, 0x03, 0x11, 0x02, 0x1f, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, + 0x11, 0x22, 0x23, 0x0a, 0x0b, 0x0a, 0x04, 0x05, 0x00, 0x02, 0x01, 0x12, 0x03, 0x12, 0x02, 0x1e, + 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x12, 0x02, 0x19, 0x0a, 0x0c, + 0x0a, 0x05, 0x05, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x12, 0x1c, 0x1d, 0x0a, 0x0b, 0x0a, 0x04, + 0x05, 0x00, 0x02, 0x02, 0x12, 0x03, 0x13, 0x02, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, + 0x02, 0x01, 0x12, 0x03, 0x13, 0x02, 0x16, 0x0a, 0x0c, 0x0a, 0x05, 0x05, 0x00, 0x02, 0x02, 0x02, + 0x12, 0x03, 0x13, 0x19, 0x1a, 0x0a, 0x37, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, 0x17, 0x00, 0x1a, + 0x01, 0x1a, 0x2b, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x67, 0x6f, 0x76, + 0x65, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x0a, 0x0a, 0x0a, + 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x17, 0x08, 0x11, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, + 0x02, 0x00, 0x12, 0x03, 0x18, 0x02, 0x29, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x06, + 0x12, 0x03, 0x18, 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, + 0x18, 0x13, 0x24, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x18, 0x27, + 0x28, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x03, 0x19, 0x02, 0x2c, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x06, 0x12, 0x03, 0x19, 0x02, 0x12, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x01, 0x02, 0x01, 0x01, 0x12, 0x03, 0x19, 0x13, 0x27, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, + 0x02, 0x01, 0x03, 0x12, 0x03, 0x19, 0x2a, 0x2b, 0x0a, 0x4c, 0x0a, 0x02, 0x04, 0x02, 0x12, 0x04, + 0x1d, 0x00, 0x35, 0x01, 0x1a, 0x40, 0x20, 0x41, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x20, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x64, 0x64, + 0x69, 0x6e, 0x67, 0x2f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x02, 0x01, 0x12, 0x03, 0x1d, + 0x08, 0x18, 0x0a, 0x1b, 0x0a, 0x04, 0x04, 0x02, 0x04, 0x00, 0x12, 0x04, 0x1f, 0x02, 0x24, 0x03, + 0x1a, 0x0d, 0x20, 0x42, 0x61, 0x73, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x0a, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x04, 0x00, 0x01, 0x12, 0x03, 0x1f, 0x07, 0x11, 0x0a, 0x0d, 0x0a, + 0x06, 0x04, 0x02, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x20, 0x04, 0x20, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x02, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x20, 0x04, 0x1b, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x02, 0x04, 0x00, 0x02, 0x00, 0x02, 0x12, 0x03, 0x20, 0x1e, 0x1f, 0x0a, 0x0d, 0x0a, 0x06, + 0x04, 0x02, 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x21, 0x04, 0x1a, 0x0a, 0x0e, 0x0a, 0x07, 0x04, + 0x02, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, 0x21, 0x04, 0x15, 0x0a, 0x0e, 0x0a, 0x07, 0x04, + 0x02, 0x04, 0x00, 0x02, 0x01, 0x02, 0x12, 0x03, 0x21, 0x18, 0x19, 0x0a, 0x0d, 0x0a, 0x06, 0x04, + 0x02, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x22, 0x04, 0x19, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x02, + 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x22, 0x04, 0x14, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x02, + 0x04, 0x00, 0x02, 0x02, 0x02, 0x12, 0x03, 0x22, 0x17, 0x18, 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x02, + 0x04, 0x00, 0x02, 0x03, 0x12, 0x03, 0x23, 0x04, 0x2b, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x04, + 0x00, 0x02, 0x03, 0x01, 0x12, 0x03, 0x23, 0x04, 0x26, 0x0a, 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x04, + 0x00, 0x02, 0x03, 0x02, 0x12, 0x03, 0x23, 0x29, 0x2a, 0x0a, 0x44, 0x0a, 0x04, 0x04, 0x02, 0x03, + 0x00, 0x12, 0x04, 0x27, 0x02, 0x29, 0x03, 0x1a, 0x36, 0x20, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, + 0x65, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x69, 0x65, 0x73, 0x2e, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x65, 0x76, + 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x03, 0x00, 0x01, 0x12, 0x03, 0x27, 0x0a, 0x16, 0x0a, 0x0d, 0x0a, + 0x06, 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x12, 0x03, 0x28, 0x04, 0x2b, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x28, 0x04, 0x0c, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x06, 0x12, 0x03, 0x28, 0x0d, 0x1d, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x28, 0x1e, 0x26, 0x0a, 0x0e, 0x0a, 0x07, + 0x04, 0x02, 0x03, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x28, 0x29, 0x2a, 0x0a, 0x44, 0x0a, 0x04, + 0x04, 0x02, 0x03, 0x01, 0x12, 0x04, 0x2c, 0x02, 0x2e, 0x03, 0x1a, 0x36, 0x20, 0x43, 0x6f, 0x6d, + 0x62, 0x69, 0x6e, 0x65, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2e, 0x20, 0x41, 0x6e, 0x79, 0x20, 0x6d, 0x75, 0x73, 0x74, + 0x20, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x72, 0x75, + 0x65, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x03, 0x01, 0x01, 0x12, 0x03, 0x2c, 0x0a, 0x16, + 0x0a, 0x0d, 0x0a, 0x06, 0x04, 0x02, 0x03, 0x01, 0x02, 0x00, 0x12, 0x03, 0x2d, 0x04, 0x2b, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x01, 0x02, 0x00, 0x04, 0x12, 0x03, 0x2d, 0x04, 0x0c, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x01, 0x02, 0x00, 0x06, 0x12, 0x03, 0x2d, 0x0d, 0x1d, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x2d, 0x1e, 0x26, 0x0a, + 0x0e, 0x0a, 0x07, 0x04, 0x02, 0x03, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x2d, 0x29, 0x2a, 0x0a, + 0x0c, 0x0a, 0x04, 0x04, 0x02, 0x08, 0x00, 0x12, 0x04, 0x30, 0x02, 0x34, 0x03, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x02, 0x08, 0x00, 0x01, 0x12, 0x03, 0x30, 0x08, 0x0c, 0x0a, 0x0b, 0x0a, 0x04, 0x04, + 0x02, 0x02, 0x00, 0x12, 0x03, 0x31, 0x04, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, + 0x06, 0x12, 0x03, 0x31, 0x04, 0x0e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x01, 0x12, + 0x03, 0x31, 0x0f, 0x13, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x00, 0x03, 0x12, 0x03, 0x31, + 0x16, 0x17, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, 0x01, 0x12, 0x03, 0x32, 0x04, 0x23, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x01, 0x06, 0x12, 0x03, 0x32, 0x04, 0x10, 0x0a, 0x0c, 0x0a, + 0x05, 0x04, 0x02, 0x02, 0x01, 0x01, 0x12, 0x03, 0x32, 0x11, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, + 0x02, 0x02, 0x01, 0x03, 0x12, 0x03, 0x32, 0x21, 0x22, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x02, 0x02, + 0x02, 0x12, 0x03, 0x33, 0x04, 0x23, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, 0x06, 0x12, + 0x03, 0x33, 0x04, 0x10, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, 0x01, 0x12, 0x03, 0x33, + 0x11, 0x1e, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x02, 0x02, 0x02, 0x03, 0x12, 0x03, 0x33, 0x21, 0x22, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x0a, 0xaa, 0x0e, 0x0a, 0x2e, 0x6d, 0x6c, 0x73, + 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x73, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x78, 0x6d, 0x74, + 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x10, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, + 0x3f, 0x0a, 0x1c, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x5f, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x65, 0x64, + 0x42, 0x79, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x22, 0x80, 0x03, 0x0a, 0x16, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x73, 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x0d, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x5f, 0x61, 0x64, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, - 0x14, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x42, 0xec, 0x01, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6d, - 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x17, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, - 0x6d, 0x74, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, 0x6f, 0x2f, - 0x6d, 0x6c, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x73, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x4d, 0xaa, 0x02, 0x18, 0x58, 0x6d, 0x74, - 0x70, 0x2e, 0x4d, 0x6c, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x73, 0xca, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, - 0x5c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, - 0xe2, 0x02, 0x24, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x58, 0x6d, 0x74, 0x70, 0x3a, 0x3a, - 0x4d, 0x6c, 0x73, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x73, 0x4a, 0xb8, 0x07, 0x0a, 0x06, 0x12, 0x04, 0x01, 0x00, 0x1d, 0x01, 0x0a, - 0x2f, 0x0a, 0x01, 0x0c, 0x12, 0x03, 0x01, 0x00, 0x12, 0x1a, 0x25, 0x20, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x65, 0x6e, 0x63, 0x6f, - 0x64, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x73, 0x0a, - 0x0a, 0x08, 0x0a, 0x01, 0x02, 0x12, 0x03, 0x03, 0x00, 0x22, 0x0a, 0x08, 0x0a, 0x01, 0x08, 0x12, - 0x03, 0x05, 0x00, 0x47, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, 0x05, 0x00, 0x47, 0x0a, - 0x3a, 0x0a, 0x02, 0x04, 0x00, 0x12, 0x04, 0x09, 0x00, 0x0d, 0x01, 0x1a, 0x2e, 0x20, 0x41, 0x20, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, - 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x44, 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, - 0x00, 0x01, 0x12, 0x03, 0x09, 0x08, 0x18, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, - 0x03, 0x0a, 0x02, 0x26, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x0a, - 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x0a, 0x0b, 0x10, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0a, 0x11, 0x21, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0a, 0x24, 0x25, 0x0a, 0x0b, 0x0a, 0x04, - 0x04, 0x00, 0x02, 0x01, 0x12, 0x03, 0x0b, 0x02, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, - 0x01, 0x05, 0x12, 0x03, 0x0b, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, - 0x12, 0x03, 0x0b, 0x09, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, - 0x0b, 0x1b, 0x1c, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x0c, 0x02, 0x2a, - 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x05, 0x12, 0x03, 0x0c, 0x02, 0x08, 0x0a, 0x0c, - 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x0c, 0x09, 0x25, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x00, 0x02, 0x02, 0x03, 0x12, 0x03, 0x0c, 0x28, 0x29, 0x0a, 0x64, 0x0a, 0x02, 0x04, 0x01, - 0x12, 0x04, 0x10, 0x00, 0x1d, 0x01, 0x1a, 0x23, 0x20, 0x54, 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, - 0x75, 0x70, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x20, 0x63, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x0a, 0x22, 0x33, 0x20, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x6c, 0x69, 0x6e, 0x74, 0x3a, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x20, - 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x4e, - 0x41, 0x4d, 0x45, 0x53, 0x5f, 0x50, 0x4c, 0x55, 0x52, 0x41, 0x4c, 0x49, 0x5a, 0x45, 0x44, 0x0a, - 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x10, 0x08, 0x1e, 0x0a, 0x39, 0x0a, 0x04, - 0x04, 0x01, 0x02, 0x00, 0x12, 0x03, 0x14, 0x02, 0x2e, 0x1a, 0x2c, 0x20, 0x4d, 0x65, 0x6d, 0x62, - 0x65, 0x72, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, - 0x65, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x04, - 0x12, 0x03, 0x14, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x06, 0x12, 0x03, - 0x14, 0x0b, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x14, 0x1c, - 0x29, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x14, 0x2c, 0x2d, 0x0a, - 0x3b, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x03, 0x16, 0x02, 0x30, 0x1a, 0x2e, 0x20, 0x4d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, - 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x69, 0x6e, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, - 0x04, 0x01, 0x02, 0x01, 0x04, 0x12, 0x03, 0x16, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, - 0x02, 0x01, 0x06, 0x12, 0x03, 0x16, 0x0b, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, - 0x01, 0x12, 0x03, 0x16, 0x1c, 0x2b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x03, 0x12, - 0x03, 0x16, 0x2e, 0x2f, 0x0a, 0x52, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x02, 0x12, 0x03, 0x18, 0x02, - 0x34, 0x1a, 0x45, 0x20, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x0c, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x65, 0x64, 0x12, 0x54, 0x0a, + 0x0f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, + 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x52, 0x0e, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x64, 0x12, 0x5c, 0x0a, 0x13, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x61, 0x64, 0x64, 0x65, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x12, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x41, 0x64, 0x64, 0x65, + 0x64, 0x12, 0x60, 0x0a, 0x15, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x5f, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2b, 0x2e, 0x78, 0x6d, 0x74, 0x70, 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x14, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x64, 0x42, 0xec, 0x01, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x6d, 0x74, 0x70, + 0x2e, 0x6d, 0x6c, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x17, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x6d, 0x74, + 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x33, 0x2f, 0x67, 0x6f, 0x2f, 0x6d, 0x6c, + 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x73, 0xa2, 0x02, 0x03, 0x58, 0x4d, 0x4d, 0xaa, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, 0x2e, + 0x4d, 0x6c, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x73, 0xca, 0x02, 0x18, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0xe2, 0x02, + 0x24, 0x58, 0x6d, 0x74, 0x70, 0x5c, 0x4d, 0x6c, 0x73, 0x5c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x58, 0x6d, 0x74, 0x70, 0x3a, 0x3a, 0x4d, 0x6c, + 0x73, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x73, 0x4a, 0xb8, 0x07, 0x0a, 0x06, 0x12, 0x04, 0x01, 0x00, 0x1d, 0x01, 0x0a, 0x2f, 0x0a, + 0x01, 0x0c, 0x12, 0x03, 0x01, 0x00, 0x12, 0x1a, 0x25, 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, + 0x6e, 0x67, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x73, 0x0a, 0x0a, 0x08, + 0x0a, 0x01, 0x02, 0x12, 0x03, 0x03, 0x00, 0x22, 0x0a, 0x08, 0x0a, 0x01, 0x08, 0x12, 0x03, 0x05, + 0x00, 0x47, 0x0a, 0x09, 0x0a, 0x02, 0x08, 0x0b, 0x12, 0x03, 0x05, 0x00, 0x47, 0x0a, 0x3a, 0x0a, + 0x02, 0x04, 0x00, 0x12, 0x04, 0x09, 0x00, 0x0d, 0x01, 0x1a, 0x2e, 0x20, 0x41, 0x20, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x44, 0x73, 0x0a, 0x0a, 0x0a, 0x0a, 0x03, 0x04, 0x00, 0x01, + 0x12, 0x03, 0x09, 0x08, 0x18, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x00, 0x12, 0x03, 0x0a, + 0x02, 0x26, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x04, 0x12, 0x03, 0x0a, 0x02, 0x0a, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x05, 0x12, 0x03, 0x0a, 0x0b, 0x10, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x00, 0x02, 0x00, 0x01, 0x12, 0x03, 0x0a, 0x11, 0x21, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x00, 0x02, 0x00, 0x03, 0x12, 0x03, 0x0a, 0x24, 0x25, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, + 0x02, 0x01, 0x12, 0x03, 0x0b, 0x02, 0x1d, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x05, + 0x12, 0x03, 0x0b, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x01, 0x12, 0x03, + 0x0b, 0x09, 0x18, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, 0x02, 0x01, 0x03, 0x12, 0x03, 0x0b, 0x1b, + 0x1c, 0x0a, 0x0b, 0x0a, 0x04, 0x04, 0x00, 0x02, 0x02, 0x12, 0x03, 0x0c, 0x02, 0x2a, 0x0a, 0x0c, + 0x0a, 0x05, 0x04, 0x00, 0x02, 0x02, 0x05, 0x12, 0x03, 0x0c, 0x02, 0x08, 0x0a, 0x0c, 0x0a, 0x05, + 0x04, 0x00, 0x02, 0x02, 0x01, 0x12, 0x03, 0x0c, 0x09, 0x25, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x00, + 0x02, 0x02, 0x03, 0x12, 0x03, 0x0c, 0x28, 0x29, 0x0a, 0x64, 0x0a, 0x02, 0x04, 0x01, 0x12, 0x04, + 0x10, 0x00, 0x1d, 0x01, 0x1a, 0x23, 0x20, 0x54, 0x68, 0x65, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x20, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x0a, 0x22, 0x33, 0x20, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x6c, 0x69, 0x6e, 0x74, 0x3a, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x52, 0x45, + 0x50, 0x45, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x4e, 0x41, 0x4d, + 0x45, 0x53, 0x5f, 0x50, 0x4c, 0x55, 0x52, 0x41, 0x4c, 0x49, 0x5a, 0x45, 0x44, 0x0a, 0x0a, 0x0a, + 0x0a, 0x03, 0x04, 0x01, 0x01, 0x12, 0x03, 0x10, 0x08, 0x1e, 0x0a, 0x39, 0x0a, 0x04, 0x04, 0x01, + 0x02, 0x00, 0x12, 0x03, 0x14, 0x02, 0x2e, 0x1a, 0x2c, 0x20, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x2c, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x20, 0x62, 0x79, - 0x20, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, - 0x04, 0x12, 0x03, 0x18, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x06, 0x12, - 0x03, 0x18, 0x0b, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x01, 0x12, 0x03, 0x18, - 0x1c, 0x2f, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x03, 0x12, 0x03, 0x18, 0x32, 0x33, - 0x0a, 0x45, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x03, 0x12, 0x03, 0x1a, 0x02, 0x36, 0x1a, 0x38, 0x20, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x72, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x2c, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, - 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x04, - 0x12, 0x03, 0x1a, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x06, 0x12, 0x03, - 0x1a, 0x0b, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x01, 0x12, 0x03, 0x1a, 0x1c, - 0x31, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x03, 0x12, 0x03, 0x1a, 0x34, 0x35, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6d, 0x6d, 0x69, 0x74, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x04, 0x12, 0x03, + 0x14, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x06, 0x12, 0x03, 0x14, 0x0b, + 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x01, 0x12, 0x03, 0x14, 0x1c, 0x29, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x00, 0x03, 0x12, 0x03, 0x14, 0x2c, 0x2d, 0x0a, 0x3b, 0x0a, + 0x04, 0x04, 0x01, 0x02, 0x01, 0x12, 0x03, 0x16, 0x02, 0x30, 0x1a, 0x2e, 0x20, 0x4d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, + 0x65, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, + 0x02, 0x01, 0x04, 0x12, 0x03, 0x16, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, + 0x06, 0x12, 0x03, 0x16, 0x0b, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x01, 0x12, + 0x03, 0x16, 0x1c, 0x2b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x01, 0x03, 0x12, 0x03, 0x16, + 0x2e, 0x2f, 0x0a, 0x52, 0x0a, 0x04, 0x04, 0x01, 0x02, 0x02, 0x12, 0x03, 0x18, 0x02, 0x34, 0x1a, + 0x45, 0x20, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, + 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x61, + 0x64, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x2c, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6d, + 0x65, 0x6d, 0x62, 0x65, 0x72, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x04, 0x12, + 0x03, 0x18, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x06, 0x12, 0x03, 0x18, + 0x0b, 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x01, 0x12, 0x03, 0x18, 0x1c, 0x2f, + 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x02, 0x03, 0x12, 0x03, 0x18, 0x32, 0x33, 0x0a, 0x45, + 0x0a, 0x04, 0x04, 0x01, 0x02, 0x03, 0x12, 0x03, 0x1a, 0x02, 0x36, 0x1a, 0x38, 0x20, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x72, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x2c, 0x20, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6d, 0x65, + 0x6d, 0x62, 0x65, 0x72, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x04, 0x12, 0x03, + 0x1a, 0x02, 0x0a, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x06, 0x12, 0x03, 0x1a, 0x0b, + 0x1b, 0x0a, 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x01, 0x12, 0x03, 0x1a, 0x1c, 0x31, 0x0a, + 0x0c, 0x0a, 0x05, 0x04, 0x01, 0x02, 0x03, 0x03, 0x12, 0x03, 0x1a, 0x34, 0x35, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, ]; include!("xmtp.mls.message_contents.serde.rs"); // @@protoc_insertion_point(module) \ No newline at end of file diff --git a/xmtp_proto/src/gen/xmtp.mls.message_contents.serde.rs b/xmtp_proto/src/gen/xmtp.mls.message_contents.serde.rs index 05d3224df..e83b950ab 100644 --- a/xmtp_proto/src/gen/xmtp.mls.message_contents.serde.rs +++ b/xmtp_proto/src/gen/xmtp.mls.message_contents.serde.rs @@ -379,20 +379,27 @@ impl serde::Serialize for CredentialRevocation { { use serde::ser::SerializeStruct; let mut len = 0; - if !self.installation_public_key.is_empty() { + if self.public_key.is_some() { len += 1; } if self.association.is_some() { len += 1; } let mut struct_ser = serializer.serialize_struct("xmtp.mls.message_contents.CredentialRevocation", len)?; - if !self.installation_public_key.is_empty() { - struct_ser.serialize_field("installationPublicKey", pbjson::private::base64::encode(&self.installation_public_key).as_str())?; + if let Some(v) = self.public_key.as_ref() { + match v { + credential_revocation::PublicKey::InstallationKey(v) => { + struct_ser.serialize_field("installationKey", pbjson::private::base64::encode(&v).as_str())?; + } + credential_revocation::PublicKey::UnsignedLegacyCreateIdentityKey(v) => { + struct_ser.serialize_field("unsignedLegacyCreateIdentityKey", pbjson::private::base64::encode(&v).as_str())?; + } + } } if let Some(v) = self.association.as_ref() { match v { - credential_revocation::Association::Eip191(v) => { - struct_ser.serialize_field("eip191", v)?; + credential_revocation::Association::MessagingAccess(v) => { + struct_ser.serialize_field("messagingAccess", v)?; } } } @@ -406,16 +413,19 @@ impl<'de> serde::Deserialize<'de> for CredentialRevocation { D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "installation_public_key", - "installationPublicKey", - "eip_191", - "eip191", + "installation_key", + "installationKey", + "unsigned_legacy_create_identity_key", + "unsignedLegacyCreateIdentityKey", + "messaging_access", + "messagingAccess", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - InstallationPublicKey, - Eip191, + InstallationKey, + UnsignedLegacyCreateIdentityKey, + MessagingAccess, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -437,8 +447,9 @@ impl<'de> serde::Deserialize<'de> for CredentialRevocation { E: serde::de::Error, { match value { - "installationPublicKey" | "installation_public_key" => Ok(GeneratedField::InstallationPublicKey), - "eip191" | "eip_191" => Ok(GeneratedField::Eip191), + "installationKey" | "installation_key" => Ok(GeneratedField::InstallationKey), + "unsignedLegacyCreateIdentityKey" | "unsigned_legacy_create_identity_key" => Ok(GeneratedField::UnsignedLegacyCreateIdentityKey), + "messagingAccess" | "messaging_access" => Ok(GeneratedField::MessagingAccess), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -458,29 +469,33 @@ impl<'de> serde::Deserialize<'de> for CredentialRevocation { where V: serde::de::MapAccess<'de>, { - let mut installation_public_key__ = None; + let mut public_key__ = None; let mut association__ = None; while let Some(k) = map.next_key()? { match k { - GeneratedField::InstallationPublicKey => { - if installation_public_key__.is_some() { - return Err(serde::de::Error::duplicate_field("installationPublicKey")); + GeneratedField::InstallationKey => { + if public_key__.is_some() { + return Err(serde::de::Error::duplicate_field("installationKey")); } - installation_public_key__ = - Some(map.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) - ; + public_key__ = map.next_value::<::std::option::Option<::pbjson::private::BytesDeserialize<_>>>()?.map(|x| credential_revocation::PublicKey::InstallationKey(x.0)); + } + GeneratedField::UnsignedLegacyCreateIdentityKey => { + if public_key__.is_some() { + return Err(serde::de::Error::duplicate_field("unsignedLegacyCreateIdentityKey")); + } + public_key__ = map.next_value::<::std::option::Option<::pbjson::private::BytesDeserialize<_>>>()?.map(|x| credential_revocation::PublicKey::UnsignedLegacyCreateIdentityKey(x.0)); } - GeneratedField::Eip191 => { + GeneratedField::MessagingAccess => { if association__.is_some() { - return Err(serde::de::Error::duplicate_field("eip191")); + return Err(serde::de::Error::duplicate_field("messagingAccess")); } - association__ = map.next_value::<::std::option::Option<_>>()?.map(credential_revocation::Association::Eip191) + association__ = map.next_value::<::std::option::Option<_>>()?.map(credential_revocation::Association::MessagingAccess) ; } } } Ok(CredentialRevocation { - installation_public_key: installation_public_key__.unwrap_or_default(), + public_key: public_key__, association: association__, }) } @@ -581,7 +596,7 @@ impl<'de> serde::Deserialize<'de> for EdDsaSignature { deserializer.deserialize_struct("xmtp.mls.message_contents.EdDsaSignature", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for Eip191Association { +impl serde::Serialize for EncodedContent { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -589,58 +604,63 @@ impl serde::Serialize for Eip191Association { { use serde::ser::SerializeStruct; let mut len = 0; - if self.association_text_version != 0 { + if self.r#type.is_some() { len += 1; } - if self.signature.is_some() { + if !self.parameters.is_empty() { len += 1; } - if !self.account_address.is_empty() { + if self.fallback.is_some() { len += 1; } - if !self.iso8601_time.is_empty() { + if self.compression.is_some() { len += 1; } - let mut struct_ser = serializer.serialize_struct("xmtp.mls.message_contents.Eip191Association", len)?; - if self.association_text_version != 0 { - let v = AssociationTextVersion::from_i32(self.association_text_version) - .ok_or_else(|| serde::ser::Error::custom(format!("Invalid variant {}", self.association_text_version)))?; - struct_ser.serialize_field("associationTextVersion", &v)?; + if !self.content.is_empty() { + len += 1; } - if let Some(v) = self.signature.as_ref() { - struct_ser.serialize_field("signature", v)?; + let mut struct_ser = serializer.serialize_struct("xmtp.mls.message_contents.EncodedContent", len)?; + if let Some(v) = self.r#type.as_ref() { + struct_ser.serialize_field("type", v)?; } - if !self.account_address.is_empty() { - struct_ser.serialize_field("accountAddress", &self.account_address)?; + if !self.parameters.is_empty() { + struct_ser.serialize_field("parameters", &self.parameters)?; + } + if let Some(v) = self.fallback.as_ref() { + struct_ser.serialize_field("fallback", v)?; } - if !self.iso8601_time.is_empty() { - struct_ser.serialize_field("iso8601Time", &self.iso8601_time)?; + if let Some(v) = self.compression.as_ref() { + let v = Compression::from_i32(*v) + .ok_or_else(|| serde::ser::Error::custom(format!("Invalid variant {}", *v)))?; + struct_ser.serialize_field("compression", &v)?; + } + if !self.content.is_empty() { + struct_ser.serialize_field("content", pbjson::private::base64::encode(&self.content).as_str())?; } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for Eip191Association { +impl<'de> serde::Deserialize<'de> for EncodedContent { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "association_text_version", - "associationTextVersion", - "signature", - "account_address", - "accountAddress", - "iso8601_time", - "iso8601Time", + "type", + "parameters", + "fallback", + "compression", + "content", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - AssociationTextVersion, - Signature, - AccountAddress, - Iso8601Time, + Type, + Parameters, + Fallback, + Compression, + Content, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -662,10 +682,11 @@ impl<'de> serde::Deserialize<'de> for Eip191Association { E: serde::de::Error, { match value { - "associationTextVersion" | "association_text_version" => Ok(GeneratedField::AssociationTextVersion), - "signature" => Ok(GeneratedField::Signature), - "accountAddress" | "account_address" => Ok(GeneratedField::AccountAddress), - "iso8601Time" | "iso8601_time" => Ok(GeneratedField::Iso8601Time), + "type" => Ok(GeneratedField::Type), + "parameters" => Ok(GeneratedField::Parameters), + "fallback" => Ok(GeneratedField::Fallback), + "compression" => Ok(GeneratedField::Compression), + "content" => Ok(GeneratedField::Content), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -675,60 +696,72 @@ impl<'de> serde::Deserialize<'de> for Eip191Association { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = Eip191Association; + type Value = EncodedContent; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct xmtp.mls.message_contents.Eip191Association") + formatter.write_str("struct xmtp.mls.message_contents.EncodedContent") } - fn visit_map(self, mut map: V) -> std::result::Result + fn visit_map(self, mut map: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - let mut association_text_version__ = None; - let mut signature__ = None; - let mut account_address__ = None; - let mut iso8601_time__ = None; + let mut r#type__ = None; + let mut parameters__ = None; + let mut fallback__ = None; + let mut compression__ = None; + let mut content__ = None; while let Some(k) = map.next_key()? { match k { - GeneratedField::AssociationTextVersion => { - if association_text_version__.is_some() { - return Err(serde::de::Error::duplicate_field("associationTextVersion")); + GeneratedField::Type => { + if r#type__.is_some() { + return Err(serde::de::Error::duplicate_field("type")); } - association_text_version__ = Some(map.next_value::()? as i32); + r#type__ = map.next_value()?; } - GeneratedField::Signature => { - if signature__.is_some() { - return Err(serde::de::Error::duplicate_field("signature")); + GeneratedField::Parameters => { + if parameters__.is_some() { + return Err(serde::de::Error::duplicate_field("parameters")); } - signature__ = map.next_value()?; + parameters__ = Some( + map.next_value::>()? + ); } - GeneratedField::AccountAddress => { - if account_address__.is_some() { - return Err(serde::de::Error::duplicate_field("accountAddress")); + GeneratedField::Fallback => { + if fallback__.is_some() { + return Err(serde::de::Error::duplicate_field("fallback")); } - account_address__ = Some(map.next_value()?); + fallback__ = map.next_value()?; + } + GeneratedField::Compression => { + if compression__.is_some() { + return Err(serde::de::Error::duplicate_field("compression")); + } + compression__ = map.next_value::<::std::option::Option>()?.map(|x| x as i32); } - GeneratedField::Iso8601Time => { - if iso8601_time__.is_some() { - return Err(serde::de::Error::duplicate_field("iso8601Time")); + GeneratedField::Content => { + if content__.is_some() { + return Err(serde::de::Error::duplicate_field("content")); } - iso8601_time__ = Some(map.next_value()?); + content__ = + Some(map.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) + ; } } } - Ok(Eip191Association { - association_text_version: association_text_version__.unwrap_or_default(), - signature: signature__, - account_address: account_address__.unwrap_or_default(), - iso8601_time: iso8601_time__.unwrap_or_default(), + Ok(EncodedContent { + r#type: r#type__, + parameters: parameters__.unwrap_or_default(), + fallback: fallback__, + compression: compression__, + content: content__.unwrap_or_default(), }) } } - deserializer.deserialize_struct("xmtp.mls.message_contents.Eip191Association", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("xmtp.mls.message_contents.EncodedContent", FIELDS, GeneratedVisitor) } } -impl serde::Serialize for EncodedContent { +impl serde::Serialize for GrantMessagingAccessAssociation { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result where @@ -736,63 +769,58 @@ impl serde::Serialize for EncodedContent { { use serde::ser::SerializeStruct; let mut len = 0; - if self.r#type.is_some() { - len += 1; - } - if !self.parameters.is_empty() { + if self.association_text_version != 0 { len += 1; } - if self.fallback.is_some() { + if self.signature.is_some() { len += 1; } - if self.compression.is_some() { + if !self.account_address.is_empty() { len += 1; } - if !self.content.is_empty() { + if self.created_ns != 0 { len += 1; } - let mut struct_ser = serializer.serialize_struct("xmtp.mls.message_contents.EncodedContent", len)?; - if let Some(v) = self.r#type.as_ref() { - struct_ser.serialize_field("type", v)?; - } - if !self.parameters.is_empty() { - struct_ser.serialize_field("parameters", &self.parameters)?; + let mut struct_ser = serializer.serialize_struct("xmtp.mls.message_contents.GrantMessagingAccessAssociation", len)?; + if self.association_text_version != 0 { + let v = AssociationTextVersion::from_i32(self.association_text_version) + .ok_or_else(|| serde::ser::Error::custom(format!("Invalid variant {}", self.association_text_version)))?; + struct_ser.serialize_field("associationTextVersion", &v)?; } - if let Some(v) = self.fallback.as_ref() { - struct_ser.serialize_field("fallback", v)?; + if let Some(v) = self.signature.as_ref() { + struct_ser.serialize_field("signature", v)?; } - if let Some(v) = self.compression.as_ref() { - let v = Compression::from_i32(*v) - .ok_or_else(|| serde::ser::Error::custom(format!("Invalid variant {}", *v)))?; - struct_ser.serialize_field("compression", &v)?; + if !self.account_address.is_empty() { + struct_ser.serialize_field("accountAddress", &self.account_address)?; } - if !self.content.is_empty() { - struct_ser.serialize_field("content", pbjson::private::base64::encode(&self.content).as_str())?; + if self.created_ns != 0 { + struct_ser.serialize_field("createdNs", ToString::to_string(&self.created_ns).as_str())?; } struct_ser.end() } } -impl<'de> serde::Deserialize<'de> for EncodedContent { +impl<'de> serde::Deserialize<'de> for GrantMessagingAccessAssociation { #[allow(deprecated)] fn deserialize(deserializer: D) -> std::result::Result where D: serde::Deserializer<'de>, { const FIELDS: &[&str] = &[ - "type", - "parameters", - "fallback", - "compression", - "content", + "association_text_version", + "associationTextVersion", + "signature", + "account_address", + "accountAddress", + "created_ns", + "createdNs", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { - Type, - Parameters, - Fallback, - Compression, - Content, + AssociationTextVersion, + Signature, + AccountAddress, + CreatedNs, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -814,11 +842,10 @@ impl<'de> serde::Deserialize<'de> for EncodedContent { E: serde::de::Error, { match value { - "type" => Ok(GeneratedField::Type), - "parameters" => Ok(GeneratedField::Parameters), - "fallback" => Ok(GeneratedField::Fallback), - "compression" => Ok(GeneratedField::Compression), - "content" => Ok(GeneratedField::Content), + "associationTextVersion" | "association_text_version" => Ok(GeneratedField::AssociationTextVersion), + "signature" => Ok(GeneratedField::Signature), + "accountAddress" | "account_address" => Ok(GeneratedField::AccountAddress), + "createdNs" | "created_ns" => Ok(GeneratedField::CreatedNs), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -828,69 +855,59 @@ impl<'de> serde::Deserialize<'de> for EncodedContent { } struct GeneratedVisitor; impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { - type Value = EncodedContent; + type Value = GrantMessagingAccessAssociation; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - formatter.write_str("struct xmtp.mls.message_contents.EncodedContent") + formatter.write_str("struct xmtp.mls.message_contents.GrantMessagingAccessAssociation") } - fn visit_map(self, mut map: V) -> std::result::Result + fn visit_map(self, mut map: V) -> std::result::Result where V: serde::de::MapAccess<'de>, { - let mut r#type__ = None; - let mut parameters__ = None; - let mut fallback__ = None; - let mut compression__ = None; - let mut content__ = None; + let mut association_text_version__ = None; + let mut signature__ = None; + let mut account_address__ = None; + let mut created_ns__ = None; while let Some(k) = map.next_key()? { match k { - GeneratedField::Type => { - if r#type__.is_some() { - return Err(serde::de::Error::duplicate_field("type")); - } - r#type__ = map.next_value()?; - } - GeneratedField::Parameters => { - if parameters__.is_some() { - return Err(serde::de::Error::duplicate_field("parameters")); + GeneratedField::AssociationTextVersion => { + if association_text_version__.is_some() { + return Err(serde::de::Error::duplicate_field("associationTextVersion")); } - parameters__ = Some( - map.next_value::>()? - ); + association_text_version__ = Some(map.next_value::()? as i32); } - GeneratedField::Fallback => { - if fallback__.is_some() { - return Err(serde::de::Error::duplicate_field("fallback")); + GeneratedField::Signature => { + if signature__.is_some() { + return Err(serde::de::Error::duplicate_field("signature")); } - fallback__ = map.next_value()?; + signature__ = map.next_value()?; } - GeneratedField::Compression => { - if compression__.is_some() { - return Err(serde::de::Error::duplicate_field("compression")); + GeneratedField::AccountAddress => { + if account_address__.is_some() { + return Err(serde::de::Error::duplicate_field("accountAddress")); } - compression__ = map.next_value::<::std::option::Option>()?.map(|x| x as i32); + account_address__ = Some(map.next_value()?); } - GeneratedField::Content => { - if content__.is_some() { - return Err(serde::de::Error::duplicate_field("content")); + GeneratedField::CreatedNs => { + if created_ns__.is_some() { + return Err(serde::de::Error::duplicate_field("createdNs")); } - content__ = - Some(map.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) + created_ns__ = + Some(map.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) ; } } } - Ok(EncodedContent { - r#type: r#type__, - parameters: parameters__.unwrap_or_default(), - fallback: fallback__, - compression: compression__, - content: content__.unwrap_or_default(), + Ok(GrantMessagingAccessAssociation { + association_text_version: association_text_version__.unwrap_or_default(), + signature: signature__, + account_address: account_address__.unwrap_or_default(), + created_ns: created_ns__.unwrap_or_default(), }) } } - deserializer.deserialize_struct("xmtp.mls.message_contents.EncodedContent", FIELDS, GeneratedVisitor) + deserializer.deserialize_struct("xmtp.mls.message_contents.GrantMessagingAccessAssociation", FIELDS, GeneratedVisitor) } } impl serde::Serialize for GroupMembershipChanges { @@ -1168,6 +1185,115 @@ impl<'de> serde::Deserialize<'de> for GroupMetadataV1 { deserializer.deserialize_struct("xmtp.mls.message_contents.GroupMetadataV1", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for LegacyCreateIdentityAssociation { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.signature.is_some() { + len += 1; + } + if self.signed_legacy_create_identity_key.is_some() { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("xmtp.mls.message_contents.LegacyCreateIdentityAssociation", len)?; + if let Some(v) = self.signature.as_ref() { + struct_ser.serialize_field("signature", v)?; + } + if let Some(v) = self.signed_legacy_create_identity_key.as_ref() { + struct_ser.serialize_field("signedLegacyCreateIdentityKey", v)?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for LegacyCreateIdentityAssociation { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "signature", + "signed_legacy_create_identity_key", + "signedLegacyCreateIdentityKey", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + Signature, + SignedLegacyCreateIdentityKey, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "signature" => Ok(GeneratedField::Signature), + "signedLegacyCreateIdentityKey" | "signed_legacy_create_identity_key" => Ok(GeneratedField::SignedLegacyCreateIdentityKey), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = LegacyCreateIdentityAssociation; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct xmtp.mls.message_contents.LegacyCreateIdentityAssociation") + } + + fn visit_map(self, mut map: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut signature__ = None; + let mut signed_legacy_create_identity_key__ = None; + while let Some(k) = map.next_key()? { + match k { + GeneratedField::Signature => { + if signature__.is_some() { + return Err(serde::de::Error::duplicate_field("signature")); + } + signature__ = map.next_value()?; + } + GeneratedField::SignedLegacyCreateIdentityKey => { + if signed_legacy_create_identity_key__.is_some() { + return Err(serde::de::Error::duplicate_field("signedLegacyCreateIdentityKey")); + } + signed_legacy_create_identity_key__ = map.next_value()?; + } + } + } + Ok(LegacyCreateIdentityAssociation { + signature: signature__, + signed_legacy_create_identity_key: signed_legacy_create_identity_key__, + }) + } + } + deserializer.deserialize_struct("xmtp.mls.message_contents.LegacyCreateIdentityAssociation", FIELDS, GeneratedVisitor) + } +} impl serde::Serialize for MembershipChange { #[allow(deprecated)] fn serialize(&self, serializer: S) -> std::result::Result @@ -1705,8 +1831,11 @@ impl serde::Serialize for MlsCredential { } if let Some(v) = self.association.as_ref() { match v { - mls_credential::Association::Eip191(v) => { - struct_ser.serialize_field("eip191", v)?; + mls_credential::Association::MessagingAccess(v) => { + struct_ser.serialize_field("messagingAccess", v)?; + } + mls_credential::Association::LegacyCreateIdentity(v) => { + struct_ser.serialize_field("legacyCreateIdentity", v)?; } } } @@ -1722,14 +1851,17 @@ impl<'de> serde::Deserialize<'de> for MlsCredential { const FIELDS: &[&str] = &[ "installation_public_key", "installationPublicKey", - "eip_191", - "eip191", + "messaging_access", + "messagingAccess", + "legacy_create_identity", + "legacyCreateIdentity", ]; #[allow(clippy::enum_variant_names)] enum GeneratedField { InstallationPublicKey, - Eip191, + MessagingAccess, + LegacyCreateIdentity, } impl<'de> serde::Deserialize<'de> for GeneratedField { fn deserialize(deserializer: D) -> std::result::Result @@ -1752,7 +1884,8 @@ impl<'de> serde::Deserialize<'de> for MlsCredential { { match value { "installationPublicKey" | "installation_public_key" => Ok(GeneratedField::InstallationPublicKey), - "eip191" | "eip_191" => Ok(GeneratedField::Eip191), + "messagingAccess" | "messaging_access" => Ok(GeneratedField::MessagingAccess), + "legacyCreateIdentity" | "legacy_create_identity" => Ok(GeneratedField::LegacyCreateIdentity), _ => Err(serde::de::Error::unknown_field(value, FIELDS)), } } @@ -1784,11 +1917,18 @@ impl<'de> serde::Deserialize<'de> for MlsCredential { Some(map.next_value::<::pbjson::private::BytesDeserialize<_>>()?.0) ; } - GeneratedField::Eip191 => { + GeneratedField::MessagingAccess => { + if association__.is_some() { + return Err(serde::de::Error::duplicate_field("messagingAccess")); + } + association__ = map.next_value::<::std::option::Option<_>>()?.map(mls_credential::Association::MessagingAccess) +; + } + GeneratedField::LegacyCreateIdentity => { if association__.is_some() { - return Err(serde::de::Error::duplicate_field("eip191")); + return Err(serde::de::Error::duplicate_field("legacyCreateIdentity")); } - association__ = map.next_value::<::std::option::Option<_>>()?.map(mls_credential::Association::Eip191) + association__ = map.next_value::<::std::option::Option<_>>()?.map(mls_credential::Association::LegacyCreateIdentity) ; } } @@ -2005,3 +2145,152 @@ impl<'de> serde::Deserialize<'de> for RecoverableEcdsaSignature { deserializer.deserialize_struct("xmtp.mls.message_contents.RecoverableEcdsaSignature", FIELDS, GeneratedVisitor) } } +impl serde::Serialize for RevokeMessagingAccessAssociation { + #[allow(deprecated)] + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut len = 0; + if self.association_text_version != 0 { + len += 1; + } + if self.signature.is_some() { + len += 1; + } + if !self.account_address.is_empty() { + len += 1; + } + if self.created_ns != 0 { + len += 1; + } + let mut struct_ser = serializer.serialize_struct("xmtp.mls.message_contents.RevokeMessagingAccessAssociation", len)?; + if self.association_text_version != 0 { + let v = AssociationTextVersion::from_i32(self.association_text_version) + .ok_or_else(|| serde::ser::Error::custom(format!("Invalid variant {}", self.association_text_version)))?; + struct_ser.serialize_field("associationTextVersion", &v)?; + } + if let Some(v) = self.signature.as_ref() { + struct_ser.serialize_field("signature", v)?; + } + if !self.account_address.is_empty() { + struct_ser.serialize_field("accountAddress", &self.account_address)?; + } + if self.created_ns != 0 { + struct_ser.serialize_field("createdNs", ToString::to_string(&self.created_ns).as_str())?; + } + struct_ser.end() + } +} +impl<'de> serde::Deserialize<'de> for RevokeMessagingAccessAssociation { + #[allow(deprecated)] + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + const FIELDS: &[&str] = &[ + "association_text_version", + "associationTextVersion", + "signature", + "account_address", + "accountAddress", + "created_ns", + "createdNs", + ]; + + #[allow(clippy::enum_variant_names)] + enum GeneratedField { + AssociationTextVersion, + Signature, + AccountAddress, + CreatedNs, + } + impl<'de> serde::Deserialize<'de> for GeneratedField { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + struct GeneratedVisitor; + + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = GeneratedField; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(formatter, "expected one of: {:?}", &FIELDS) + } + + #[allow(unused_variables)] + fn visit_str(self, value: &str) -> std::result::Result + where + E: serde::de::Error, + { + match value { + "associationTextVersion" | "association_text_version" => Ok(GeneratedField::AssociationTextVersion), + "signature" => Ok(GeneratedField::Signature), + "accountAddress" | "account_address" => Ok(GeneratedField::AccountAddress), + "createdNs" | "created_ns" => Ok(GeneratedField::CreatedNs), + _ => Err(serde::de::Error::unknown_field(value, FIELDS)), + } + } + } + deserializer.deserialize_identifier(GeneratedVisitor) + } + } + struct GeneratedVisitor; + impl<'de> serde::de::Visitor<'de> for GeneratedVisitor { + type Value = RevokeMessagingAccessAssociation; + + fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter.write_str("struct xmtp.mls.message_contents.RevokeMessagingAccessAssociation") + } + + fn visit_map(self, mut map: V) -> std::result::Result + where + V: serde::de::MapAccess<'de>, + { + let mut association_text_version__ = None; + let mut signature__ = None; + let mut account_address__ = None; + let mut created_ns__ = None; + while let Some(k) = map.next_key()? { + match k { + GeneratedField::AssociationTextVersion => { + if association_text_version__.is_some() { + return Err(serde::de::Error::duplicate_field("associationTextVersion")); + } + association_text_version__ = Some(map.next_value::()? as i32); + } + GeneratedField::Signature => { + if signature__.is_some() { + return Err(serde::de::Error::duplicate_field("signature")); + } + signature__ = map.next_value()?; + } + GeneratedField::AccountAddress => { + if account_address__.is_some() { + return Err(serde::de::Error::duplicate_field("accountAddress")); + } + account_address__ = Some(map.next_value()?); + } + GeneratedField::CreatedNs => { + if created_ns__.is_some() { + return Err(serde::de::Error::duplicate_field("createdNs")); + } + created_ns__ = + Some(map.next_value::<::pbjson::private::NumberDeserialize<_>>()?.0) + ; + } + } + } + Ok(RevokeMessagingAccessAssociation { + association_text_version: association_text_version__.unwrap_or_default(), + signature: signature__, + account_address: account_address__.unwrap_or_default(), + created_ns: created_ns__.unwrap_or_default(), + }) + } + } + deserializer.deserialize_struct("xmtp.mls.message_contents.RevokeMessagingAccessAssociation", FIELDS, GeneratedVisitor) + } +} diff --git a/xmtp_v2/src/k256_helper.rs b/xmtp_v2/src/k256_helper.rs index 81fccecd2..1adb80df0 100644 --- a/xmtp_v2/src/k256_helper.rs +++ b/xmtp_v2/src/k256_helper.rs @@ -1,5 +1,5 @@ use k256::{ - ecdsa::{signature::Verifier, RecoveryId, Signature, VerifyingKey}, + ecdsa::{signature::Verifier, RecoveryId, Signature, SigningKey, VerifyingKey}, elliptic_curve::sec1::ToEncodedPoint, PublicKey, SecretKey, }; @@ -32,6 +32,17 @@ pub fn diffie_hellman_byte_params(secret_key: &[u8], public_key: &[u8]) -> Resul diffie_hellman(&secret_key, &public_key) } +/// Produce a recoverable signature for a SHA256 digest of the given message using the secret key +/// Returns signature and recovery_id +pub fn sign_sha256(secret_key: &[u8], message: &[u8]) -> Result<(Vec, u8), String> { + let signing_key = SigningKey::from_bytes(secret_key).map_err(|e| e.to_string())?; + let sha256 = Sha256::new().chain(message); + let (signature, recovery_id) = signing_key + .sign_digest_recoverable(sha256) + .map_err(|e| e.to_string())?; + Ok((signature.to_vec(), recovery_id.to_byte())) +} + /// Verify given a compact signature, recovery_id, digest, and public key in uncompressed format /// NOTE: the recovery_id situation is not necessary, but it is a good sanity check pub fn verify_sha256(