diff --git a/.github/workflows/benches.yml b/.github/workflows/benches.yml index ea41890bf3..1f45e70e76 100644 --- a/.github/workflows/benches.yml +++ b/.github/workflows/benches.yml @@ -1,8 +1,8 @@ name: Benchmarks -concurrency: +concurrency: group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + cancel-in-progress: true on: push: @@ -32,3 +32,8 @@ jobs: - uses: Swatinem/rust-cache@v2 - name: Benchmarks run: cargo bench -p openmls --verbose + + - name: Large groups + run: | + cargo run -p openmls --example large-groups --release -- --write -g 2 3 + cargo run -p openmls --example large-groups --release -- -g 3 diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index 9f876c4e16..10e41d1f14 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -16,4 +16,7 @@ jobs: with: components: clippy - uses: Swatinem/rust-cache@v2 - - run: cargo clippy -p openmls --tests -- -D warnings + - run: | + sudo apt-get -y install protoc-gen-go # Needed to build the interop client + echo $(go env GOPATH)/bin >> $GITHUB_PATH + cargo clippy -p openmls --tests --benches --examples -p openmls_basic_credential -p cli -p interop_client -p mls-ds -p ds-lib -p openmls_libcrux_crypto -p openmls_memory_storage -p openmls_rust_crypto -p openmls_test -p openmls-wasm -p openmls_traits -- -D warnings diff --git a/CHANGELOG.md b/CHANGELOG.md index f939c6bd31..15f3828210 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,31 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## 0.6.0-pre.2 (2024-08-XX) ### Added +- [#1639](https://github.com/openmls/openmls/pull/1639): Introduce `PublicStorageProvider` trait to independently allow for the storage of `PublicGroup` instances. +- [#1641](https://github.com/openmls/openmls/pull/1641): Extend the `PublicGroup` API with `add_proposal()`, `remove_proposal()`, and `queued_proposals()`. + +### Changed + +- [#1637](https://github.com/openmls/openmls/pull/1637): Remove `serde` from `MlsGroup`. +- [#1638](https://github.com/openmls/openmls/pull/1638): Remove `serde` from `PublicGroup`. `PublicGroup::load()` becomes public to load a group from the storage provider. +- [#1642](https://github.com/openmls/openmls/pull/1642): `OpenMlsProvider` is no longer required for the `PublicGroup` API. The `PublicGroup` API now uses the `PublicStorageProvider` trait directly. `ProcessMessageError::InvalidSignature` was removed and replaced with `ValidationError::InvalidSignature`. + +### Removed + + +### Fixed + +- [#1641](https://github.com/openmls/openmls/pull/1641): Fixed missing storage of queued proposals & clearing of the queued proposals. + +## 0.6.0-pre.1 (2024-07-22) + +### Added + +- [#1629](https://github.com/openmls/openmls/pull/1629): Add `add_members_without_update` function to `MlsGroup` to allow the creation of add-only commits - [#1506](https://github.com/openmls/openmls/pull/1506): Add `StagedWelcome` and `StagedCoreWelcome` to make joining a group staged in order to inspect the `Welcome` message. This was followed up with PR [#1533](https://github.com/openmls/openmls/pull/1533) to adjust the API. - [#1516](https://github.com/openmls/openmls/pull/1516): Add `MlsGroup::clear_pending_proposals` to the public API; this allows users to clear a group's internal `ProposalStore` - [#1565](https://github.com/openmls/openmls/pull/1565): Add new `StorageProvider` trait to the `openmls_traits` crate. @@ -29,6 +50,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#1542](https://github.com/openmls/openmls/pull/1542): Add support for custom proposals. ProposalType::Unknown is now called ProposalType::Other. Proposal::Unknown is now called Proposal::Other. - [#1559](https://github.com/openmls/openmls/pull/1559): Remove the `PartialEq` type constraint on the error type of both the `OpenMlsRand` and `OpenMlsKeyStore` traits. Additionally, remove the `Clone` type constraint on the error type of the `OpenMlsRand` trait. - [#1565](https://github.com/openmls/openmls/pull/1565): Removed `OpenMlsKeyStore` and replace it with a new `StorageProvider` trait in the `openmls_traits` crate. +- [#1606](https://github.com/openmls/openmls/pull/1606): Added additional `LeafNodeParameters` argument to `MlsGroup.self_update()` and `MlsGroup.propose_self_update()` to allow for updating the leaf node with custom parameters. `MlsGroup::join_by_external_commit()` now also takes optional parameters to set the capabilities and the extensions of the LeafNode. +- [#1615](https://github.com/openmls/openmls/pull/1615): Changes the AAD handling. The AAD is no longer persisted and needs to be set before every API call that generates an `MlsMessageOut`. The functions `ProccessedMessage` to accees the AAD has been renamed to `aad()`. ### Fixed diff --git a/Cargo.toml b/Cargo.toml index 04e824d33e..d516edc41b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,8 +18,8 @@ resolver = "2" # Central dependency management for some crates [workspace.dependencies] -tls_codec = { version = "0.4.2-pre.1", features = [ +tls_codec = { version = "0.4.1", features = [ "derive", "serde", "mls", -], git = "https://github.com/rustcrypto/formats" } +]} diff --git a/basic_credential/Cargo.toml b/basic_credential/Cargo.toml index c008f3c1cc..84016983ca 100644 --- a/basic_credential/Cargo.toml +++ b/basic_credential/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openmls_basic_credential" -version = "0.2.0" +version = "0.3.0-pre.1" authors = ["OpenMLS Authors"] edition = "2021" description = "A Basic Credential implementation for OpenMLS" @@ -10,7 +10,7 @@ repository = "https://github.com/openmls/openmls/tree/main/basic_credential" readme = "README.md" [dependencies] -openmls_traits = { version = "0.2.0", path = "../traits" } +openmls_traits = { version = "0.3.0-pre.2", path = "../traits" } tls_codec = { workspace = true } serde = "1.0" diff --git a/basic_credential/src/lib.rs b/basic_credential/src/lib.rs index 350ea4fc62..9dda632ba9 100644 --- a/basic_credential/src/lib.rs +++ b/basic_credential/src/lib.rs @@ -137,6 +137,18 @@ impl SignatureKeyPair { .flatten() } + /// Delete a signature key pair from the key store. + pub fn delete>( + store: &T, + public_key: &[u8], + signature_scheme: SignatureScheme, + ) -> Result<(), T::Error> { + let id = StorageId { + value: id(public_key, signature_scheme), + }; + store.delete_signature_key_pair(&id) + } + /// Get the public key as byte slice. pub fn public(&self) -> &[u8] { self.public.as_ref() diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 3763cdf5ab..9b8001efc5 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -8,9 +8,11 @@ - [Group configuration](user_manual/group_config.md) - [Creating groups](user_manual/create_group.md) - [Join a group from a Welcome message](user_manual/join_from_welcome.md) + - [Join a group from an External Commit message](user_manual/join_from_external_commit.md) - [Adding members to a group](user_manual/add_members.md) - [Removing members from a group](user_manual/remove_members.md) - [Updating own key package](user_manual/updates.md) + - [Using Additional Authenticated Data (AAD)](user_manual/aad.md) - [Leaving a group](user_manual/leaving.md) - [Custom proposals](user_manual/custom_proposals.md) - [Creating application messages](user_manual/application_messages.md) diff --git a/book/src/app_validation.md b/book/src/app_validation.md index bcebc5dc40..35017555b2 100644 --- a/book/src/app_validation.md +++ b/book/src/app_validation.md @@ -4,6 +4,64 @@ > > **⚠️** This chapter is work in progress (see [#1504](https://github.com/openmls/openmls/issues/1504)). +## Credential Validation + +### Acceptable Presented Identifiers + +> The application using MLS is responsible for specifying which identifiers +> it finds acceptable for each member in a group. In other words, following +> the model that [[RFC6125]] describes for TLS, the application maintains a list +> of "reference identifiers" for the members of a group, and the credentials +> provide "presented identifiers". A member of a group is authenticated by first +> validating that the member's credential legitimately represents some presented +> identifiers, and then ensuring that the reference identifiers for the member +> are authenticated by those presented identifiers +> +> -- [RFC9420, Section 5.3.1](https://www.rfc-editor.org/rfc/rfc9420.html#section-5.3.1-1) +> +### Validity of Updated Presented Identifiers + +> In cases where a member's credential is being replaced, such as the Update and +> Commit cases above, the AS MUST also verify that the set of presented identifiers +> in the new credential is valid as a successor to the set of presented identifiers +> in the old credential, according to the application's policy. +> +> -- [RFC9420, Section 5.3.1](https://www.rfc-editor.org/rfc/rfc9420.html#section-5.3.1-5) + +### Application ID is Not Authenticed by AS + +> However, applications MUST NOT rely on the data in an application_id extension +> as if it were authenticated by the Authentication Service, and SHOULD gracefully +> handle cases where the identifier presented is not unique. +> +> -- [RFC9420, Section 5.3.3](https://www.rfc-editor.org/rfc/rfc9420.html#section-5.3.3-6) + +## LeafNode Validation + +### Specifying the Maximum Total Acceptable Lifetime + +> Applications MUST define a maximum total lifetime that is acceptable for a +> LeafNode, and reject any LeafNode where the total lifetime is longer than this +> duration. In order to avoid disagreements about whether a LeafNode has a valid +> lifetime, the clients in a group SHOULD maintain time synchronization (e.g., +> using the Network Time Protocol [[RFC5905]]). +> +> -- [RFC9420, Section 7.2](https://www.rfc-editor.org/rfc/rfc9420.html#section-7.2-10) + +## PrivateMessage Validation + +### Structure of AAD is Application-Defined + +> It is up to the application to decide what authenticated_data to provide and +> how much padding to add to a given message (if any). The overall size of the +> AAD and ciphertext MUST fit within the limits established for the group's AEAD +> algorithm in [[CFRG-AEAD-LIMITS]]. +> +> -- [RFC9420, Section 6.3.1](https://www.rfc-editor.org/rfc/rfc9420.html#section-6.3.1-11) + +Therefore, the application must also validate whether the AAD adheres to the +prescribed format. + ## Proposal Validation When processing a commit, the application has to ensure that the application @@ -24,3 +82,7 @@ The RFC requires the following check Since OpenMLS does not know the relevant policies, the application MUST ensure that the credentials are checked according to the policy. + +[RFC6125]: https://www.rfc-editor.org/rfc/rfc6125.html +[RFC5905]: https://www.rfc-editor.org/rfc/rfc5905.html +[CFRG-AEAD-LIMITS]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-aead-limits-08 diff --git a/book/src/performance.md b/book/src/performance.md index 76a437eeb3..1971dcdc88 100644 --- a/book/src/performance.md +++ b/book/src/performance.md @@ -39,9 +39,9 @@ It is the same scenario as the somewhat stable group but with a very small Y and In addition to the three scenarios above extreme and corner cases are interesting. -### Every second leave is blank +### Every second leaf is blank -Only every second leave in the tree is non-blank. +Only every second leaf in the tree is non-blank. ## Use Case Scenarios diff --git a/book/src/traits/traits.md b/book/src/traits/traits.md index deba322fb1..1f1d6b2752 100644 --- a/book/src/traits/traits.md +++ b/book/src/traits/traits.md @@ -35,7 +35,7 @@ It simply needs to implement two functions to generate cryptographically secure randomness and store it in an array or vector. ```rust,no_run,noplayground -{{#include ../../../traits/src/random.rs:8:16}} +{{#include ../../../traits/src/random.rs:openmls_rand}} ``` ### OpenMlsCrypto @@ -48,27 +48,29 @@ This trait defines all cryptographic functions required by OpenMLS. In particula - Signatures - HPKE -```rust,no_run,noplayground -{{#include ../../../traits/src/crypto.rs:10}} -``` - ### StorageProvider This trait defines an API for a storage backend that is used for all OpenMLS persistence. -The store provides functions to `store`, `read`, and `delete` values. -Note that it does not allow updating values. -Instead, entries must be deleted and newly stored. +The store provides functions for reading and updating stored values. +Each sort of value has separate methods for accessing or mutating the state. +In order to decouple the provider from the OpenMLS implementation, while still +having legible types at the provider, there are traits that mirror all the types +stored by OpenMLS. The provider methods use values constrained by these traits as +as arguments. ```rust,no_run,noplayground -{{#include ../../../traits/src/storage.rs:16:25}} +{{#include ../../../traits/src/storage.rs:traits}} ``` -The trait is generic over a `VERSION`, which is used to ensure that the values +The traits are generic over a `VERSION`, which is used to ensure that the values that are persisted can be upgraded when OpenMLS changes the stored structs. -Every function takes `Key` and `Value` arguments. +The traits used as arguments to the storage methods are constrained to implement +the `Key` or `Entity` traits as well, depending on whether they are only used for +addressing (in which case they are a `Key`) or whether they represent a stored +value (in which case they are an `Entity`). ```rust,no_run,noplayground {{#include ../../../traits/src/storage.rs:key_trait}} @@ -78,13 +80,6 @@ Every function takes `Key` and `Value` arguments. {{#include ../../../traits/src/storage.rs:entity_trait}} ``` -To ensure that each function takes the correct input, they use trait bounds. -These are the available traits. - -```rust,no_run,noplayground -{{#include ../../../traits/src/storage.rs:traits}} -``` - An implementation of the storage trait should ensure that it can address and efficiently handle values. @@ -127,20 +122,22 @@ fn write_key_package< This allows the application to iterate over the hash references and delete outdated key packages. -### OpenMlsCryptoProvider +### OpenMlsProvider Additionally, there's a wrapper trait defined that is expected to be passed into the public OpenMLS API. Some OpenMLS APIs require only one of the sub-traits, though. ```rust,no_run,noplayground -{{#include ../../../traits/src/traits.rs:15:28}} +{{#include ../../../traits/src/traits.rs:openmls_provider}} ``` ## Implementation Notes It is not necessary to implement all sub-traits if one functionality is missing. -Suppose you want to use a persisting key store. In that case, it is sufficient to do a new implementation of the key store trait and combine it with one of the provided crypto and randomness trait implementations. +Suppose you want to use a persisting storage provider. In that case, it is +sufficient to do a new implementation of the `StorageProvider` trait and +combine it with one of the provided crypto and randomness trait implementations. [rust crypto]: https://crates.io/crates/openmls_rust_crypto [libcrux crypto]: https://crates.io/crates/openmls_libcrux_crypto diff --git a/book/src/user_manual/README.md b/book/src/user_manual/README.md index abcd6a643c..ba3e006616 100644 --- a/book/src/user_manual/README.md +++ b/book/src/user_manual/README.md @@ -5,7 +5,10 @@ The user manual describes how to use the different parts of the OpenMLS API. ## Prerequisites Most operations in OpenMLS require a `provider` object that provides all required cryptographic algorithms via the [`OpenMlsCryptoProvider`] trait. -Currently, there are two implementations available through the [openmls_rust_crypto] crate. +Currently, there are two implementations available: + +- one through the [openmls_rust_crypto] crate. +- one through the [openmls_libcrux_crypto] crate. Thus, you can create the `provider` object for the following examples using ... @@ -15,3 +18,4 @@ Thus, you can create the `provider` object for the following examples using ... [`openmlscryptoprovider`]: https://docs.rs/openmls/latest/openmls/prelude/trait.OpenMlsCryptoProvider.html [openmls_rust_crypto]: https://crates.io/crates/openmls_rust_crypto +[openmls_libcrux_crypto]: https://crates.io/crates/openmls_libcrux_crypto diff --git a/book/src/user_manual/aad.md b/book/src/user_manual/aad.md new file mode 100644 index 0000000000..dda8b3c50b --- /dev/null +++ b/book/src/user_manual/aad.md @@ -0,0 +1,20 @@ +# Using Additional Authenticated Data (AAD) + +The Additional Authenticated Data (AAD) is a byte sequence that can be included in both private and public messages. By design, it is always authenticated (signed) but never encrypted. Its purpose is to contain data that can be inspected but not changed while a message is in transit. + +## Setting the AAD + +Members can set the AAD by calling the `.set_aad()` function. The AAD will remain set until the next API call that successfully generates an `MlsMessageOut`. Until then, the AAD can be inspected with the `.aad()` function. + +```rust,no_run,noplayground +{{#include ../../../openmls/tests/book_code.rs:set_aad}} +``` + +## Inspecting the AAD + +Members can inspect the AAD of an incoming message once the message has been processed. The AAD can be accessed with the `.aad()` function of a `ProcessedMessage`. + +```rust,no_run,noplayground +{{#include ../../../openmls/tests/book_code.rs:inspect_aad}} +``` + diff --git a/book/src/user_manual/add_members.md b/book/src/user_manual/add_members.md index eabb338625..a817a8c269 100644 --- a/book/src/user_manual/add_members.md +++ b/book/src/user_manual/add_members.md @@ -10,6 +10,12 @@ Members can be added to the group atomically with the `.add_members()` function. The function returns the tuple `(MlsMessageOut, Welcome)`. The `MlsMessageOut` contains a Commit message that needs to be fanned out to existing group members. The `Welcome` message must be sent to the newly added members. +### Adding members without update + +The `.add_members_without_update()` function functions the same as the `.add_members()` function, except that it will only include an update to the sender's key material if the sender's proposal store includes a proposal that requires a path. For a list of proposals and an indication whether they require a `path` (i.e. a key material update) see [Section 17.4 of RFC 9420](https://www.rfc-editor.org/rfc/rfc9420.html#section-17.4). + +Not sending an update means that the sender will not achieve post-compromise security with this particular commit. However, not sending an update saves on performance both in terms of computation and bandwidth. Using `.add_members_without_update()` can thus be a useful option if the ciphersuite of the group features large public keys and/or expensive encryption operations. + ## Proposal Members can also be added as a proposal (without the corresponding Commit message) by using the `.propose_add_member()` function: diff --git a/book/src/user_manual/persistence.md b/book/src/user_manual/persistence.md index a58fcb30db..56b4237542 100644 --- a/book/src/user_manual/persistence.md +++ b/book/src/user_manual/persistence.md @@ -1,13 +1,11 @@ # Persistence of Group Data -The state of a given `MlsGroup` instance can be written or read at any time using the `.save()` or `.load()` functions respectively. The functions take as input a struct implementing either the `Write` (`.save()`) or `Read` (`.load()`) trait. - -Since some group operations might or might not change the `MlsGroup` state depending on the context, the group maintains the `state_changed` flag, which is set to `true` whenever the state is changed by an `MlsGroup` function. The state of the flag can be queried using the `.state_changed()` function. - -## Group Lockout Upon State Loss - -MLS provides strong Post-Compromise Security properties, which means that key material is regularly refreshed and old key material becomes stale very quickly. Consequently, regularly persisting state is important, especially after the client has created a commit or issued an Update proposal, thus introducing new key material into the group. A loss of state in such a situation is only recoverable in specific cases where the commit was rejected by the Delivery Service or if the proposed Update was not committed. A re-join is required in most cases to continue participating in a group after a loss of group state. To avoid a loss of state and the associated re-join, persisting `MlsGroup` state after each state-changing group operation is mandatory. +The state of a given `MlsGroup` instance is continuously written to the configured +`StorageProvider`. Later, the `MlsGroup` can be loaded from the provider using +the `load` constructor, which can be called with the respective storage provider +as well as the `GroupId` of the group to be loaded. For this to work, the group +must have been written to the provider previously. ## Forward-Secrecy Considerations -The `MlsGroup` state that is persisted using the `.save()` function contains private key material. As a consequence, the application needs to delete old group states to achieve Forward-Secrecy w.r.t. that key material. Since, as detailed above, an old group state is stale immediately after most group operations, we recommend deleting old group states as soon as a new one has been written. +OpenMLS uses the `StorageProvider` to store sensitive key material. To achieve forward-secrecy (i.e. to prevent an adversary from decrypting messages sent in the past if a client is compromised), OpenMLS frequently deletes previously used key material through calls to the `StorageProvider`. `StorageProvider` implementations must thus take care to ensure that values deleted through any of the `delete_` functions of the trait are irrevocably deleted and that no copies are kept. diff --git a/book/src/user_manual/updates.md b/book/src/user_manual/updates.md index fea47eb657..408179ab1c 100644 --- a/book/src/user_manual/updates.md +++ b/book/src/user_manual/updates.md @@ -1,20 +1,20 @@ -# Updating own key package +# Updating own leaf node ## Immediate operation -Members can update their own leaf key package atomically with the `.self_update()` function. -The application can optionally provide a `KeyPackage` manually. If not, a key package will be created on the fly with the same extensions as the current one but with a fresh HPKE init key. +Members can update their own leaf node atomically with the `.self_update()` function. +By default, only the HPKE encryption key is updated. The application can however also provide more parameters like a new credential, capabilities and extensions using the `LeafNodeParameters` struct. ```rust,no_run,noplayground {{#include ../../../openmls/tests/book_code.rs:self_update}} ``` The function returns the tuple `(MlsMessageOut, Option)`. The `MlsMessageOut` contains a Commit message that needs to be fanned out to existing group members. -Even though the member updates its own key package only in this operation, the Commit message could potentially also cover Add Proposals that were previously received in the epoch. Therefore the function can also optionally return a `Welcome` message. The `Welcome` message must be sent to the newly added members. +Even though the member updates its own leaf node only in this operation, the Commit message could potentially also cover Add Proposals that were previously received in the epoch. Therefore the function can also optionally return a `Welcome` message. The `Welcome` message must be sent to the newly added members. ## Proposal -Members can also update their key package as a proposal (without the corresponding Commit message) by using the `.propose_self_update()` function. Just like with the `.self_update()` function, an optional key package can be provided: +Members can also update their leaf node as a proposal (without the corresponding Commit message) by using the `.propose_self_update()` function. Just like with the `.self_update()` function, optional parameters can be set through `LeafNodeParameters`: ```rust,no_run,noplayground {{#include ../../../openmls/tests/book_code.rs:propose_self_update}} diff --git a/cli/src/user.rs b/cli/src/user.rs index 25c5ec770d..a0f005d9b7 100644 --- a/cli/src/user.rs +++ b/cli/src/user.rs @@ -29,7 +29,6 @@ impl Contact { } } -#[derive(serde::Serialize, serde::Deserialize)] pub struct Group { group_name: String, conversation: Conversation, @@ -243,7 +242,7 @@ impl User { "Searching for contact {:?}", str::from_utf8(credential.identity()).unwrap() ); - let contact = match self.contacts.get(&credential.identity().to_vec()) { + let contact = match self.contacts.get(credential.identity()) { Some(c) => c.id.clone(), None => panic!("There's a member in the group we don't know."), }; @@ -548,8 +547,6 @@ impl User { pub fn create_group(&mut self, name: String) { log::debug!("{} creates group {}", self.username(), name); let group_id = name.as_bytes(); - let mut group_aad = group_id.to_vec(); - group_aad.extend(b" AAD"); // NOTE: Since the DS currently doesn't distribute copies of the group's ratchet // tree, we need to include the ratchet_tree_extension. @@ -557,7 +554,7 @@ impl User { .use_ratchet_tree_extension(true) .build(); - let mut mls_group = MlsGroup::new_with_group_id( + let mls_group = MlsGroup::new_with_group_id( &self.provider, &self.identity.borrow().signer, &group_config, @@ -565,9 +562,6 @@ impl User { self.identity.borrow().credential_with_key.clone(), ) .expect("Failed to create MlsGroup"); - mls_group - .set_aad(self.provider.storage(), group_aad.as_slice()) - .expect("Failed to write the AAD for the new group to storage"); let group = Group { group_name: name.clone(), @@ -708,7 +702,7 @@ impl User { let group_config = MlsGroupJoinConfig::builder() .use_ratchet_tree_extension(true) .build(); - let mut mls_group = + let mls_group = StagedWelcome::new_from_welcome(&self.provider, &group_config, welcome, None) .expect("Failed to create staged join") .into_group(&self.provider) @@ -717,11 +711,6 @@ impl User { let group_id = mls_group.group_id().to_vec(); // XXX: Use Welcome's encrypted_group_info field to store group_name. let group_name = String::from_utf8(group_id.clone()).unwrap(); - let group_aad = group_name.clone() + " AAD"; - - mls_group - .set_aad(self.provider.storage(), group_aad.as_bytes()) - .expect("Failed to update the AAD in the storage"); let group = Group { group_name: group_name.clone(), diff --git a/interop_client/Cargo.toml b/interop_client/Cargo.toml index f365441552..74844d3a69 100644 --- a/interop_client/Cargo.toml +++ b/interop_client/Cargo.toml @@ -24,6 +24,6 @@ clap_derive = "4.1" serde = { version = "^1.0", features = ["derive"] } serde_json = "^1.0" tls_codec = { workspace = true } -openmls_basic_credential = { version = "0.2.0", path = "../basic_credential" } +openmls_basic_credential = { path = "../basic_credential" } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/interop_client/src/main.rs b/interop_client/src/main.rs index 4304a7113e..9ef69f8db3 100644 --- a/interop_client/src/main.rs +++ b/interop_client/src/main.rs @@ -6,6 +6,7 @@ use std::{collections::HashMap, fmt::Display, fs::File, io::Write, sync::Mutex}; use clap::Parser; +#[allow(unused_imports)] use clap_derive::*; use mls_client::{ mls_client_server::{MlsClient, MlsClientServer}, @@ -22,7 +23,7 @@ use openmls::{ key_packages::{KeyPackage, KeyPackageBundle}, prelude::{Capabilities, ExtensionType, SenderRatchetConfiguration}, schedule::{psk::ResumptionPskUsage, ExternalPsk, PreSharedKeyId, Psk}, - treesync::RatchetTreeIn, + treesync::{LeafNodeParameters, RatchetTreeIn}, versions::ProtocolVersion, }; use openmls_basic_credential::SignatureKeyPair; @@ -494,6 +495,8 @@ impl MlsClient for MlsClientImpl { ratchet_tree, verifiable_group_info, &mls_group_config, + None, + None, b"", credential_with_key, ) @@ -604,11 +607,7 @@ impl MlsClient for MlsClientImpl { interop_group .group - .set_aad( - interop_group.crypto_provider.storage(), - &request.authenticated_data, - ) - .map_err(|err| tonic::Status::internal(format!("error setting aad: {err}")))?; + .set_aad(request.authenticated_data.clone()); let ciphertext = interop_group .group @@ -657,7 +656,7 @@ impl MlsClient for MlsClientImpl { debug!("Processed."); trace!(?processed_message); - let authenticated_data = processed_message.authenticated_data().to_vec(); + let authenticated_data = processed_message.aad().to_vec(); let plaintext = match processed_message.into_content() { ProcessedMessageContent::ApplicationMessage(application_message) => { application_message.into_bytes() @@ -833,7 +832,7 @@ impl MlsClient for MlsClientImpl { .propose_self_update( &interop_group.crypto_provider, &interop_group.signature_keys, - None, + LeafNodeParameters::default(), ) .map_err(into_status)?; @@ -979,7 +978,7 @@ impl MlsClient for MlsClientImpl { let (proposal, _proposal_ref) = match proposal_type.as_ref() { "add" => { let key_package = - MlsMessageIn::tls_deserialize_exact(&mut proposal.key_package.clone()) + MlsMessageIn::tls_deserialize_exact(proposal.key_package.clone()) .map_err(|_| Status::invalid_argument("Invalid key package"))?; let key_package = key_package .into_keypackage() diff --git a/libcrux_crypto/Cargo.toml b/libcrux_crypto/Cargo.toml index 4fd77b8101..a2cb168113 100644 --- a/libcrux_crypto/Cargo.toml +++ b/libcrux_crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openmls_libcrux_crypto" -version = "0.1.0" +version = "0.1.0-pre.2" edition = "2021" authors = ["OpenMLS Authors"] description = "A crypto backend for OpenMLS based on libcrux implementing openmls_traits." @@ -11,8 +11,8 @@ readme = "../README.md" [dependencies] getrandom = "0.2.12" -libcrux = { git = "https://github.com/cryspen/libcrux", features = ["rand"] } -openmls_traits = { path = "../traits" } -openmls_rust_crypto = { path = "../openmls_rust_crypto" } +libcrux = { version = "=0.0.2-alpha.3", features = ["rand"] } +openmls_traits = { version = "0.3.0-pre.2", path = "../traits" } +openmls_memory_storage = { version = "0.3.0-pre.2", path = "../memory_storage" } rand = "0.8.5" tls_codec.workspace = true diff --git a/libcrux_crypto/src/lib.rs b/libcrux_crypto/src/lib.rs index c61a437588..5deeb0e93f 100644 --- a/libcrux_crypto/src/lib.rs +++ b/libcrux_crypto/src/lib.rs @@ -12,16 +12,16 @@ pub use rand::RandProvider; pub struct Provider { crypto: crypto::CryptoProvider, rand: rand::RandProvider, - key_store: openmls_rust_crypto::MemoryStorage, + storage: openmls_memory_storage::MemoryStorage, } impl OpenMlsProvider for Provider { type CryptoProvider = CryptoProvider; type RandProvider = RandProvider; - type StorageProvider = openmls_rust_crypto::MemoryStorage; + type StorageProvider = openmls_memory_storage::MemoryStorage; fn storage(&self) -> &Self::StorageProvider { - &self.key_store + &self.storage } fn crypto(&self) -> &Self::CryptoProvider { diff --git a/memory_storage/Cargo.toml b/memory_storage/Cargo.toml index d6387d9d7e..4b4c1dc694 100644 --- a/memory_storage/Cargo.toml +++ b/memory_storage/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "openmls_memory_storage" authors = ["OpenMLS Authors"] -version = "0.2.0" +version = "0.3.0-pre.2" edition = "2021" description = "A very basic storage for OpenMLS implementing openmls_traits." license = "MIT" @@ -10,7 +10,7 @@ repository = "https://github.com/openmls/openmls/tree/main/memory_storage" readme = "README.md" [dependencies] -openmls_traits = { version = "0.2.0", path = "../traits" } +openmls_traits = { version = "0.3.0-pre.2", path = "../traits" } thiserror = "1.0" serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } diff --git a/memory_storage/src/lib.rs b/memory_storage/src/lib.rs index 1e1a86739c..9635be2282 100644 --- a/memory_storage/src/lib.rs +++ b/memory_storage/src/lib.rs @@ -1,8 +1,10 @@ use openmls_traits::storage::*; - -use serde::{Deserialize, Serialize}; +use serde::Serialize; use std::{collections::HashMap, sync::RwLock}; +#[cfg(feature = "test-utils")] +use std::io::Write as _; + /// A storage for the V_TEST version. #[cfg(any(test, feature = "test-utils"))] mod test_store; @@ -10,9 +12,76 @@ mod test_store; #[cfg(feature = "persistence")] pub mod persistence; -#[derive(Debug, Default, Serialize, Deserialize)] +#[derive(Debug, Default)] pub struct MemoryStorage { - values: RwLock, Vec>>, + pub values: RwLock, Vec>>, +} + +// For testing we want to clone. +#[cfg(feature = "test-utils")] +impl Clone for MemoryStorage { + fn clone(&self) -> Self { + let values = self.values.read().unwrap(); + Self { + values: RwLock::new(values.clone()), + } + } +} + +// For testing (KATs in particular) we want to serialize and deserialize the storage +#[cfg(feature = "test-utils")] +impl MemoryStorage { + pub fn serialize(&self, w: &mut Vec) -> std::io::Result { + let values = self.values.read().unwrap(); + + let mut written = 8; + let count = (values.len() as u64).to_be_bytes(); + w.write_all(&count)?; + + for (k, v) in values.iter() { + let rec_len = 8 + 8 + k.len() + v.len(); + let k_len = (k.len() as u64).to_be_bytes(); + let v_len = (v.len() as u64).to_be_bytes(); + + w.write_all(&k_len)?; + w.write_all(&v_len)?; + w.write_all(k)?; + w.write_all(v)?; + + written += rec_len; + } + + Ok(written) + } + + pub fn deserialize(r: &mut R) -> std::io::Result { + let read_u64 = |r: &mut R| { + let mut buf8 = [0u8; 8]; + r.read_exact(&mut buf8).map(|_| u64::from_be_bytes(buf8)) + }; + + let read_bytes = |r: &mut R, len: usize| { + let mut buf = vec![0u8; len]; + r.read_exact(&mut buf).map(|_| buf) + }; + + let mut count = read_u64(r)? as usize; + let mut map = HashMap::new(); + + while count > 0 { + let k_len = read_u64(r)? as usize; + let v_len = read_u64(r)? as usize; + let k = read_bytes(r, k_len)?; + let v = read_bytes(r, v_len)?; + + map.insert(k, v); + count -= 1; + } + + Ok(Self { + values: RwLock::new(map), + }) + } } impl MemoryStorage { @@ -134,10 +203,7 @@ impl MemoryStorage { log::trace!("{}", std::backtrace::Backtrace::capture()); let value: Vec> = match values.get(&storage_key) { - Some(list_bytes) => { - println!("{}", String::from_utf8(list_bytes.to_vec()).unwrap()); - serde_json::from_slice(list_bytes).unwrap() - } + Some(list_bytes) => serde_json::from_slice(list_bytes).unwrap(), None => vec![], }; @@ -201,12 +267,10 @@ const OWN_LEAF_NODE_INDEX_LABEL: &[u8] = b"OwnLeafNodeIndex"; const EPOCH_SECRETS_LABEL: &[u8] = b"EpochSecrets"; const RESUMPTION_PSK_STORE_LABEL: &[u8] = b"ResumptionPsk"; const MESSAGE_SECRETS_LABEL: &[u8] = b"MessageSecrets"; -const USE_RATCHET_TREE_LABEL: &[u8] = b"UseRatchetTree"; // related to MlsGroup const JOIN_CONFIG_LABEL: &[u8] = b"MlsGroupJoinConfig"; const OWN_LEAF_NODES_LABEL: &[u8] = b"OwnLeafNodes"; -const AAD_LABEL: &[u8] = b"AAD"; const GROUP_STATE_LABEL: &[u8] = b"GroupState"; const QUEUED_PROPOSAL_LABEL: &[u8] = b"QueuedProposal"; const PROPOSAL_QUEUE_REFS_LABEL: &[u8] = b"ProposalQueueRefs"; @@ -349,7 +413,7 @@ impl StorageProvider for MemoryStorage { .collect::, _>>() } - fn treesync< + fn tree< GroupId: traits::GroupId, TreeSync: traits::TreeSync, >( @@ -359,7 +423,9 @@ impl StorageProvider for MemoryStorage { let values = self.values.read().unwrap(); let key = build_key::(TREE_LABEL, group_id); - let value = values.get(&key).unwrap(); + let Some(value) = values.get(&key) else { + return Ok(None); + }; let value = serde_json::from_slice(value).unwrap(); Ok(value) @@ -375,7 +441,9 @@ impl StorageProvider for MemoryStorage { let values = self.values.read().unwrap(); let key = build_key::(GROUP_CONTEXT_LABEL, group_id); - let value = values.get(&key).unwrap(); + let Some(value) = values.get(&key) else { + return Ok(None); + }; let value = serde_json::from_slice(value).unwrap(); Ok(value) @@ -391,7 +459,9 @@ impl StorageProvider for MemoryStorage { let values = self.values.read().unwrap(); let key = build_key::(INTERIM_TRANSCRIPT_HASH_LABEL, group_id); - let value = values.get(&key).unwrap(); + let Some(value) = values.get(&key) else { + return Ok(None); + }; let value = serde_json::from_slice(value).unwrap(); Ok(value) @@ -407,7 +477,9 @@ impl StorageProvider for MemoryStorage { let values = self.values.read().unwrap(); let key = build_key::(CONFIRMATION_TAG_LABEL, group_id); - let value = values.get(&key).unwrap(); + let Some(value) = values.get(&key) else { + return Ok(None); + }; let value = serde_json::from_slice(value).unwrap(); Ok(value) @@ -425,7 +497,9 @@ impl StorageProvider for MemoryStorage { let key = build_key::(SIGNATURE_KEY_PAIR_LABEL, public_key); - let value = values.get(&key).unwrap(); + let Some(value) = values.get(&key) else { + return Ok(None); + }; let value = serde_json::from_slice(value).unwrap(); Ok(value) @@ -673,32 +747,6 @@ impl StorageProvider for MemoryStorage { self.delete::(OWN_LEAF_NODE_INDEX_LABEL, &serde_json::to_vec(group_id)?) } - fn use_ratchet_tree_extension>( - &self, - group_id: &GroupId, - ) -> Result, Self::Error> { - self.read(USE_RATCHET_TREE_LABEL, &serde_json::to_vec(group_id)?) - } - - fn set_use_ratchet_tree_extension>( - &self, - group_id: &GroupId, - value: bool, - ) -> Result<(), Self::Error> { - self.write::( - USE_RATCHET_TREE_LABEL, - &serde_json::to_vec(group_id)?, - serde_json::to_vec(&value)?, - ) - } - - fn delete_use_ratchet_tree_extension>( - &self, - group_id: &GroupId, - ) -> Result<(), Self::Error> { - self.delete::(USE_RATCHET_TREE_LABEL, &serde_json::to_vec(group_id)?) - } - fn group_epoch_secrets< GroupId: traits::GroupId, GroupEpochSecrets: traits::GroupEpochSecrets, @@ -867,35 +915,6 @@ impl StorageProvider for MemoryStorage { self.append::(OWN_LEAF_NODES_LABEL, &key, value) } - fn aad>( - &self, - group_id: &GroupId, - ) -> Result, Self::Error> { - let key = serde_json::to_vec(group_id)?; - self.read::>(AAD_LABEL, &key) - .map(|v| { - // When we didn't find the value, we return an empty vector as - // required by the trait. - v.unwrap_or_default() - }) - } - - fn write_aad>( - &self, - group_id: &GroupId, - aad: &[u8], - ) -> Result<(), Self::Error> { - let key = serde_json::to_vec(group_id)?; - self.write::(AAD_LABEL, &key, serde_json::to_vec(aad).unwrap()) - } - - fn delete_aad>( - &self, - group_id: &GroupId, - ) -> Result<(), Self::Error> { - self.delete::(AAD_LABEL, &serde_json::to_vec(group_id).unwrap()) - } - fn delete_own_leaf_nodes>( &self, group_id: &GroupId, diff --git a/memory_storage/src/persistence.rs b/memory_storage/src/persistence.rs index b746aba51d..3f94031191 100644 --- a/memory_storage/src/persistence.rs +++ b/memory_storage/src/persistence.rs @@ -23,7 +23,7 @@ impl super::MemoryStorage { get_file_path(&("openmls_cli_".to_owned() + user_name + "_ks.json")) } - fn save_to_file(&self, output_file: &File) -> Result<(), String> { + pub fn save_to_file(&self, output_file: &File) -> Result<(), String> { let writer = BufWriter::new(output_file); let mut ser_ks = SerializableKeyStore::default(); @@ -48,7 +48,7 @@ impl super::MemoryStorage { } } - fn load_from_file(&mut self, input_file: &File) -> Result<(), String> { + pub fn load_from_file(&mut self, input_file: &File) -> Result<(), String> { // Prepare file reader. let reader = BufReader::new(input_file); diff --git a/memory_storage/src/test_store.rs b/memory_storage/src/test_store.rs index c17d76fee2..949f42d680 100644 --- a/memory_storage/src/test_store.rs +++ b/memory_storage/src/test_store.rs @@ -175,7 +175,7 @@ impl StorageProvider for MemoryStorage { todo!() } - fn treesync, TreeSync: traits::TreeSync>( + fn tree, TreeSync: traits::TreeSync>( &self, _group_id: &GroupId, ) -> Result, Self::Error> { @@ -388,28 +388,6 @@ impl StorageProvider for MemoryStorage { todo!() } - fn use_ratchet_tree_extension>( - &self, - _group_id: &GroupId, - ) -> Result, Self::Error> { - todo!() - } - - fn set_use_ratchet_tree_extension>( - &self, - _group_id: &GroupId, - _value: bool, - ) -> Result<(), Self::Error> { - todo!() - } - - fn delete_use_ratchet_tree_extension>( - &self, - _group_id: &GroupId, - ) -> Result<(), Self::Error> { - todo!() - } - fn group_epoch_secrets< GroupId: traits::GroupId, GroupEpochSecrets: traits::GroupEpochSecrets, @@ -487,21 +465,6 @@ impl StorageProvider for MemoryStorage { todo!() } - fn aad>( - &self, - _group_id: &GroupId, - ) -> Result, Self::Error> { - todo!() - } - - fn write_aad>( - &self, - _group_id: &GroupId, - _aad: &[u8], - ) -> Result<(), Self::Error> { - todo!() - } - fn queued_proposals< GroupId: traits::GroupId, ProposalRef: traits::ProposalRef, @@ -524,13 +487,6 @@ impl StorageProvider for MemoryStorage { todo!() } - fn delete_aad>( - &self, - _group_id: &GroupId, - ) -> Result<(), Self::Error> { - todo!() - } - fn delete_own_leaf_nodes>( &self, _group_id: &GroupId, diff --git a/memory_storage/tests/proposals.rs b/memory_storage/tests/proposals.rs index f0d888be05..ae973ffc07 100644 --- a/memory_storage/tests/proposals.rs +++ b/memory_storage/tests/proposals.rs @@ -41,31 +41,27 @@ fn read_write_delete() { // Read proposal refs let proposal_refs_read: Vec = storage.queued_proposal_refs(&group_id).unwrap(); assert_eq!( - (0..10).map(|i| ProposalRef(i)).collect::>(), + (0..10).map(ProposalRef).collect::>(), proposal_refs_read ); // Read proposals let proposals_read: Vec<(ProposalRef, Proposal)> = storage.queued_proposals(&group_id).unwrap(); - let proposals_expected: Vec<(ProposalRef, Proposal)> = (0..10) - .map(|i| ProposalRef(i)) - .zip(proposals.clone().into_iter()) - .collect(); + let proposals_expected: Vec<(ProposalRef, Proposal)> = + (0..10).map(ProposalRef).zip(proposals.clone()).collect(); assert_eq!(proposals_expected, proposals_read); // Remove proposal 5 storage.remove_proposal(&group_id, &ProposalRef(5)).unwrap(); let proposal_refs_read: Vec = storage.queued_proposal_refs(&group_id).unwrap(); - let mut expected = (0..10).map(|i| ProposalRef(i)).collect::>(); + let mut expected = (0..10).map(ProposalRef).collect::>(); expected.remove(5); assert_eq!(expected, proposal_refs_read); let proposals_read: Vec<(ProposalRef, Proposal)> = storage.queued_proposals(&group_id).unwrap(); - let mut proposals_expected: Vec<(ProposalRef, Proposal)> = (0..10) - .map(|i| ProposalRef(i)) - .zip(proposals.clone().into_iter()) - .collect(); + let mut proposals_expected: Vec<(ProposalRef, Proposal)> = + (0..10).map(ProposalRef).zip(proposals.clone()).collect(); proposals_expected.remove(5); assert_eq!(proposals_expected, proposals_read); diff --git a/openmls/Cargo.toml b/openmls/Cargo.toml index 0137d32be0..c96b8cf552 100644 --- a/openmls/Cargo.toml +++ b/openmls/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openmls" -version = "0.5.0" +version = "0.6.0-pre.2" authors = ["OpenMLS Authors"] edition = "2021" description = "A Rust implementation of the Messaging Layer Security (MLS) protocol, as defined in RFC 9420." @@ -9,9 +9,20 @@ documentation = "https://openmls.github.io/openmls/" repository = "https://github.com/openmls/openmls/" readme = "../README.md" keywords = ["MLS", "IETF", "RFC9420", "Encryption", "E2EE"] +exclude = ["/test_vectors"] [dependencies] -openmls_traits = { version = "0.2.0", path = "../traits" } +openmls_traits = { version = "0.3.0-pre.2", path = "../traits" } +openmls_rust_crypto = { version = "0.3.0-pre.1", path = "../openmls_rust_crypto", optional = true } +openmls_basic_credential = { version = "0.3.0-pre.1", path = "../basic_credential", optional = true, features = [ + "clonable", + "test-utils", +] } +openmls_memory_storage = { version = "0.3.0-pre.2", path = "../memory_storage", features = [ + "test-utils", +], optional = true } +openmls_test = { version = "0.1.0-pre.1", path = "../openmls_test", optional = true } +openmls_libcrux_crypto = { version = "0.1.0-pre.2", path = "../libcrux_crypto", optional = true } serde = { version = "^1.0", features = ["derive"] } log = { version = "0.4", features = ["std"] } tls_codec = { workspace = true } @@ -23,59 +34,53 @@ rand = { version = "0.8", optional = true } serde_json = { version = "1.0", optional = true } # Crypto providers required for KAT and testing - "test-utils" feature itertools = { version = "0.10", optional = true } -openmls_rust_crypto = { version = "0.2.0", path = "../openmls_rust_crypto", optional = true } -openmls_basic_credential = { version = "0.2.0", path = "../basic_credential", optional = true, features = [ - "clonable", - "test-utils", -] } wasm-bindgen-test = { version = "0.3.40", optional = true } getrandom = { version = "0.2.12", optional = true, features = ["js"] } fluvio-wasm-timer = { version = "0.2.5", optional = true } -openmls_memory_storage = { path = "../memory_storage", features = [ - "test-utils", -], optional = true } -openmls_test = { path = "../openmls_test", optional = true } -openmls_libcrux_crypto = { path = "../libcrux_crypto", optional = true } once_cell = { version = "1.19.0", optional = true } [features] -default = ["backtrace"] crypto-subtle = [] # Enable subtle crypto APIs that have to be used with care. test-utils = [ - "dep:serde_json", - "dep:itertools", - "dep:openmls_rust_crypto", - "dep:rand", - "dep:wasm-bindgen-test", - "dep:openmls_basic_credential", - "dep:openmls_memory_storage", - "dep:openmls_test", - "dep:once_cell", + "dep:serde_json", + "dep:itertools", + "openmls_rust_crypto/test-utils", + "dep:rand", + "dep:wasm-bindgen-test", + "dep:openmls_basic_credential", + "dep:openmls_memory_storage", + "dep:openmls_test", + "dep:once_cell", + "backtrace", ] +backtrace = ["dep:backtrace"] libcrux-provider = [ - "dep:openmls_libcrux_crypto", - "openmls_test?/libcrux-provider", + "dep:openmls_libcrux_crypto", + "openmls_test?/libcrux-provider", ] crypto-debug = [] # ☣️ Enable logging of sensitive cryptographic information content-debug = [] # ☣️ Enable logging of sensitive message content js = [ - "dep:getrandom", - "dep:fluvio-wasm-timer", + "dep:getrandom", + "dep:fluvio-wasm-timer", ] # enable js randomness source for provider [dev-dependencies] -backtrace = "0.3" criterion = { version = "^0.5", default-features = false } # need to disable default features for wasm hex = { version = "0.4", features = ["serde"] } itertools = "0.10" lazy_static = "1.4" -openmls_traits = { version = "0.2.0", path = "../traits", features = [ - "test-utils", +openmls_traits = { version = "0.3.0-pre.2", path = "../traits", features = [ + "test-utils", ] } pretty_env_logger = "0.5" tempfile = "3" wasm-bindgen = "0.2.90" wasm-bindgen-test = "0.3.40" +clap = { version = "4", features = ["derive"] } +base64 = "0.22.1" +flate2 = "1.0" +indicatif = "0.17.8" # Disable for wasm32 and Win32 [target.'cfg(not(any(target_arch = "wasm32", all(target_arch = "x86", target_os = "windows"))))'.dev-dependencies] diff --git a/openmls/benches/benchmark.rs b/openmls/benches/benchmark.rs index 1516f846f1..346076d412 100644 --- a/openmls/benches/benchmark.rs +++ b/openmls/benches/benchmark.rs @@ -255,8 +255,9 @@ fn create_commit(c: &mut Criterion, provider: &impl OpenMlsProvider) { (bob_group, bob_signer) }, |(mut bob_group, bob_signer)| { - let (queued_message, welcome_option, _group_info) = - bob_group.self_update(provider, &bob_signer).unwrap(); + let (_queued_message, _welcome_option, _group_info) = bob_group + .self_update(provider, &bob_signer, LeafNodeParameters::default()) + .unwrap(); bob_group .merge_pending_commit(provider) diff --git a/openmls/examples/large-groups.rs b/openmls/examples/large-groups.rs new file mode 100644 index 0000000000..c255dfaae5 --- /dev/null +++ b/openmls/examples/large-groups.rs @@ -0,0 +1,623 @@ +//! This benchmarks tests the performance of group operations in a large group +//! when the tree is fully populated. +//! +//! In particular do we assume that each member commits after joining the group. + +use std::{ + collections::HashMap, + fs::File, + time::{Duration, Instant}, +}; + +use base64::prelude::*; +use clap::Parser; +use openmls::{ + credentials::{BasicCredential, CredentialWithKey}, + framing::{MlsMessageIn, MlsMessageOut, ProcessedMessageContent}, + group::{ + GroupId, MlsGroup, MlsGroupCreateConfig, StagedWelcome, PURE_PLAINTEXT_WIRE_FORMAT_POLICY, + }, + prelude::LeafNodeIndex, + prelude_test::*, + treesync::LeafNodeParameters, +}; +use openmls_basic_credential::SignatureKeyPair; +use openmls_rust_crypto::OpenMlsRustCrypto; +use openmls_traits::{types::Ciphersuite, OpenMlsProvider as _}; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone)] +#[allow(dead_code)] +struct Member { + provider: OpenMlsRustCrypto, + credential_with_key: CredentialWithKey, + signer: SignatureKeyPair, + group_id: GroupId, +} + +#[derive(Debug, Default, Serialize, Deserialize)] +struct SerializableStore { + values: HashMap, +} + +impl Member { + fn serialize(&self) -> (Vec, Vec, Vec, Vec) { + let storage = self.provider.storage(); + + let mut serializable_storage = SerializableStore::default(); + for (key, value) in &*storage.values.read().unwrap() { + serializable_storage + .values + .insert(BASE64_STANDARD.encode(key), BASE64_STANDARD.encode(value)); + } + + ( + serde_json::to_vec(&serializable_storage).unwrap(), + serde_json::to_vec(&self.credential_with_key).unwrap(), + serde_json::to_vec(&self.signer).unwrap(), + serde_json::to_vec(&self.group_id).unwrap(), + ) + } + + fn load(storage: &[u8], ckey: &[u8], signer: &[u8], group_id: &[u8]) -> Self { + let serializable_storage: SerializableStore = serde_json::from_slice(storage).unwrap(); + let credential_with_key: CredentialWithKey = serde_json::from_slice(ckey).unwrap(); + let signer: SignatureKeyPair = serde_json::from_slice(signer).unwrap(); + let group_id: GroupId = serde_json::from_slice(group_id).unwrap(); + + let provider = OpenMlsRustCrypto::default(); + let mut ks_map = provider.storage().values.write().unwrap(); + for (key, value) in serializable_storage.values { + ks_map.insert( + BASE64_STANDARD.decode(key).unwrap(), + BASE64_STANDARD.decode(value).unwrap(), + ); + } + drop(ks_map); + + Self { + provider, + credential_with_key, + signer, + group_id, + } + } + + fn group(&self) -> Option { + MlsGroup::load(self.provider.storage(), &self.group_id) + .ok() + .flatten() + } +} + +#[inline(always)] +fn process_commit( + group: &mut MlsGroup, + provider: &OpenMlsRustCrypto, + commit: openmls::prelude::MlsMessageOut, +) { + let processed_message = group + .process_message(provider, commit.into_protocol_message().unwrap()) + .unwrap(); + + if let ProcessedMessageContent::StagedCommitMessage(staged_commit) = + processed_message.into_content() + { + group.merge_staged_commit(provider, *staged_commit).unwrap(); + } else { + unreachable!("Expected a StagedCommit."); + } +} + +#[inline(always)] +fn self_update( + group: &mut MlsGroup, + provider: &OpenMlsRustCrypto, + signer: &SignatureKeyPair, +) -> MlsMessageOut { + let (commit, _, _group_info) = group + .self_update(provider, signer, LeafNodeParameters::default()) + .unwrap(); + + group.merge_pending_commit(provider).unwrap(); + + commit +} + +/// Remove member 1 +#[inline(always)] +fn remove_member( + group: &mut MlsGroup, + provider: &OpenMlsRustCrypto, + signer: &SignatureKeyPair, +) -> MlsMessageOut { + let (commit, _, _group_info) = group + .remove_members(provider, signer, &[LeafNodeIndex::new(1)]) + .unwrap(); + + group.merge_pending_commit(provider).unwrap(); + + commit +} + +/// Create a new member +fn new_member( + name: &str, +) -> ( + OpenMlsRustCrypto, + SignatureKeyPair, + CredentialWithKey, + openmls::prelude::KeyPackageBundle, +) { + let member_provider = OpenMlsRustCrypto::default(); + let credential = BasicCredential::new(name.into()); + let signer = SignatureKeyPair::new(CIPHERSUITE.signature_algorithm()).unwrap(); + let credential_with_key = CredentialWithKey { + credential: credential.into(), + signature_key: signer.to_public_vec().into(), + }; + let key_package = KeyPackage::builder() + .build( + CIPHERSUITE, + &member_provider, + &signer, + credential_with_key.clone(), + ) + .expect("An unexpected error occurred."); + (member_provider, signer, credential_with_key, key_package) +} + +#[inline(always)] +fn add_member( + group: &mut MlsGroup, + provider: &OpenMlsRustCrypto, + signer: &SignatureKeyPair, + key_package: KeyPackage, +) -> MlsMessageOut { + let (commit, _welcome, _) = group.add_members(provider, signer, &[key_package]).unwrap(); + + group.merge_pending_commit(provider).unwrap(); + + commit +} + +use generate::CIPHERSUITE; + +mod generate { + use indicatif::ProgressBar; + + use super::*; + + pub const GROUP_SIZES: &[usize] = &[2, 3, 4, 5, 10, 25, 50, 100]; + pub const CIPHERSUITE: Ciphersuite = + Ciphersuite::MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519; + + /// Create a group of `num` clients. + /// All of them committed after joining. + pub fn setup( + num: usize, + variant: Option, + members: Option<(Vec, Vec)>, + ) -> Vec<(MlsGroup, Member)> { + // We default to a bare group unless variant wants something else. + let variant = variant.unwrap_or(SetupVariants::Bare); + + let mls_group_create_config = MlsGroupCreateConfig::builder() + .wire_format_policy(PURE_PLAINTEXT_WIRE_FORMAT_POLICY) + .ciphersuite(CIPHERSUITE) + .build(); + + // If we have a previous group/member setup, let's use it. + // The creator is always at 0. + let mut members = if let Some(members) = members { + members.0.into_iter().zip(members.1).collect() + } else { + // Create a new setup. + let creator_provider = OpenMlsRustCrypto::default(); + let creator_credential = BasicCredential::new("Creator".to_string().into()); + let creator_signer = SignatureKeyPair::new(CIPHERSUITE.signature_algorithm()).unwrap(); + let creator_credential_with_key = CredentialWithKey { + credential: creator_credential.into(), + signature_key: creator_signer.to_public_vec().into(), + }; + + // Create the group + let creator_group = MlsGroup::new( + &creator_provider, + &creator_signer, + &mls_group_create_config, + creator_credential_with_key.clone(), + ) + .expect("An unexpected error occurred."); + + let group_id = creator_group.group_id().clone(); + + vec![( + creator_group, + Member { + provider: creator_provider, + credential_with_key: creator_credential_with_key, + signer: creator_signer, + group_id, + }, + )] + }; + + let pb = ProgressBar::new((num - members.len()) as u64); + for member_i in members.len()..num { + let (member_provider, signer, credential_with_key, key_package) = + new_member(&format!("Member {member_i}")); + + let creator = &mut members[0]; + let creator_group = &mut creator.0; + let creator_provider = &creator.1.provider; + let creator_signer = &creator.1.signer; + let (commit, welcome, _) = creator_group + .add_members( + creator_provider, + creator_signer, + &[key_package.key_package().clone()], + ) + .unwrap(); + + creator_group + .merge_pending_commit(creator_provider) + .expect("error merging pending commit"); + + let welcome: MlsMessageIn = welcome.into(); + let welcome = welcome + .into_welcome() + .expect("expected the message to be a welcome message"); + let mut member_i_group = StagedWelcome::new_from_welcome( + &member_provider, + mls_group_create_config.join_config(), + welcome, + Some(creator_group.export_ratchet_tree().into()), + ) + .unwrap() + .into_group(&member_provider) + .unwrap(); + + // Merge commit on all other members + for (group, member) in members.iter_mut().skip(1) { + process_commit(group, &member.provider, commit.clone()); + } + + // Depending on the variant we do something here. + match variant { + SetupVariants::Bare => (), // Nothing to do in this case. + SetupVariants::CommitAfterJoin => { + // The new member commits and everyone else processes it. + let update_commit = self_update(&mut member_i_group, &member_provider, &signer); + for (group, member) in members.iter_mut() { + process_commit(group, &member.provider, update_commit.clone()); + } + } + SetupVariants::CommitToFullGroup => (), // Commit after everyone was added. + } + + let group_id = member_i_group.group_id().clone(); + + // Add new member to list + members.push(( + member_i_group, + Member { + provider: member_provider, + credential_with_key, + signer, + group_id, + }, + )); + pb.inc(1); + } + pb.finish(); + + // Depending on the variant we do something once everyone was added. + match variant { + SetupVariants::Bare => (), // Nothing to do in this case. + SetupVariants::CommitAfterJoin => (), // Noting to do in this case. + SetupVariants::CommitToFullGroup => { + println!("Commit to the full group."); + let pb = ProgressBar::new((num - members.len()) as u64); + // Every member commits and everyone else processes it. + for i in 0..members.len() { + let (member_i_group, member_i) = &mut members[i]; + let update_commit = + self_update(member_i_group, &member_i.provider, &member_i.signer); + for (j, (group, member)) in members.iter_mut().enumerate() { + if i != j { + process_commit(group, &member.provider, update_commit.clone()); + } + } + } + pb.finish(); + } + } + + members + } +} + +const ITERATIONS: usize = 1000; +const WARMUP_ITERATIONS: usize = 5; + +/// A custom benchmarking function. +/// +/// DO NOT USE THIS WITH LARGE INPUTS +#[inline(always)] +#[allow(dead_code)] +fn bench(si: &SI, mut setup: S, mut routine: R) -> Duration +where + SI: Clone, + S: FnMut(&SI) -> I, + R: FnMut(I) -> O, +{ + let mut time = Duration::ZERO; + + // Warmup + for _ in 0..WARMUP_ITERATIONS { + let input = setup(si); + routine(input); + } + + // Benchmark + for _ in 0..ITERATIONS { + let input = setup(si); + + let start = Instant::now(); + core::hint::black_box(routine(input)); + let end = Instant::now(); + + time += end.duration_since(start); + } + + time +} + +// A benchmarking macro to avoid copying memory and skewing the results. +macro_rules! bench { + ($groups:expr, $setup:expr, $routine:expr) => {{ + let mut time = Duration::ZERO; + + // Warmup + for _ in 0..WARMUP_ITERATIONS { + let input = $setup($groups); + $routine(input); + } + + // Benchmark + for _ in 0..ITERATIONS { + let input = $setup($groups); + + let start = Instant::now(); + core::hint::black_box($routine(input)); + let end = Instant::now(); + + time += end.duration_since(start); + } + + time + }}; +} + +/// The different group setups for the benchmarks. +#[derive(clap::ValueEnum, Clone, Copy, Debug)] +enum SetupVariants { + /// No messages are sent after the setup. + Bare, + + /// Every member sends a commit directly after joining the group. + CommitAfterJoin, + + /// Every member sends a commit after everyone was added to the group. + CommitToFullGroup, +} + +/// A tool to benchmark openmls (large) groups. +/// +/// The benchmarks need to write a setup first that is then read to run the benchmarks. +#[derive(Parser)] +struct Args { + /// Write out the setup (groups and states) + #[clap(short, long, action)] + write: bool, + + /// The file to read or write. + #[clap(short, long)] + data: Option, + + /// The group sizes to run or generate. + /// This has to be a list of values, separated by spaces, e.g. 2 3 5 10 + #[clap(short, long, value_delimiter = ' ', num_args = 1..)] + groups: Option>, + + /// The group setup to use. + #[clap(short, long)] + setup: Option, +} +mod util { + use std::path::Path; + + use itertools::Itertools; + + use super::{generate, *}; + + const MEMBERS_PATH: &str = "large-balanced-group-members.json.gzip"; + + type Members = Vec<(Vec, Vec, Vec, Vec)>; + + /// Read benchmark setups from the fiels previously written. + pub fn read(path: Option) -> Vec> { + let file = File::open(members_file(&path)).unwrap(); + let mut reader = flate2::read::GzDecoder::new(file); + let members: Vec = serde_json::from_reader(&mut reader).unwrap(); + + let members: Vec> = members + .into_iter() + .map(|members| { + members + .into_iter() + .map(|m| { + let m = Member::load(&m.0, &m.1, &m.2, &m.3); + + (m.group().unwrap(), m) + }) + .collect() + }) + .collect(); + + members + } + + fn members_file(path: &Option) -> std::path::PathBuf { + let path = path.clone().unwrap_or_default(); + let path = Path::new(&path); + path.join(MEMBERS_PATH) + } + + /// Generate benchmark setups and write them out. + pub fn write( + path: Option, + group_sizes: Option>, + variant: Option, + ) { + let mut members = vec![]; + + let group_sizes = group_sizes.unwrap_or(generate::GROUP_SIZES.to_vec()); + println!("Generating groups for benchmarks {group_sizes:?}..."); + let mut smaller_groups = None; + for num in group_sizes.into_iter().sorted() { + println!("Generating group of size {num} ..."); + // Generate and write out groups. + let new_groups = generate::setup(num, variant, smaller_groups); + let (new_groups, new_members): (Vec, Vec) = + new_groups.into_iter().unzip(); + smaller_groups = Some((new_groups.clone(), new_members.clone())); + let new_members: Members = new_members.into_iter().map(|m| m.serialize()).collect(); + members.push(new_members); + } + + println!("Writing out files."); + let file = File::create(members_file(&path)).unwrap(); + let mut writer = flate2::write::GzEncoder::new(file, flate2::Compression::default()); + serde_json::to_writer(&mut writer, &members).unwrap(); + + println!("Wrote new test groups to file."); + } +} +use util::*; + +fn print_time(label: &str, d: Duration) { + let micros = d.as_micros(); + let time = if micros < (1_000 * ITERATIONS as u128) { + format!("{} μs", micros / ITERATIONS as u128) + } else if micros < (1_000_000 * ITERATIONS as u128) { + format!( + "{:.2} ms", + (micros as f64 / (1_000_f64 * ITERATIONS as f64)) + ) + } else { + format!( + "{:.2}s", + (micros as f64 / (1_000_000_f64 * ITERATIONS as f64)) + ) + }; + let space = if label.len() < 6 { + "\t\t".to_string() + } else { + "\t".to_string() + }; + + println!("{label}:{space}{time}"); +} + +fn main() { + let args = Args::parse(); + + if args.write { + // Only generate groups and write them out. + write(args.data, args.groups, args.setup); + + return; + } + + let all_groups = read(args.data); + for groups in all_groups.iter() { + if let Some(group_sizes) = &args.groups { + // Only run the groups of the sizes from the cli + if !group_sizes.contains(&groups.len()) { + continue; + } + } + println!("{} Members", groups.len()); + + // Add + let time = bench!( + groups, + |groups: &Vec<(MlsGroup, Member)>| { + let (_member_provider, _signer, _credential_with_key, key_package) = + new_member("New Member"); + let key_package = key_package.key_package().clone(); + + (groups[1].clone(), key_package) + }, + |(group1, key_package): ((MlsGroup, Member), KeyPackage)| { + let (mut updater_group, updater) = group1; + let provider = &updater.provider; + let signer = &updater.signer; + let _ = add_member(&mut updater_group, provider, signer, key_package); + } + ); + print_time("Adder", time); + + // Update + let time = bench!( + groups, + |groups: &Vec<(MlsGroup, Member)>| groups[1].clone(), + |group1: (MlsGroup, Member)| { + // Let group 1 update and merge the commit. + let (mut updater_group, updater) = group1; + let provider = &updater.provider; + let signer = &updater.signer; + let _ = self_update(&mut updater_group, provider, signer); + } + ); + print_time("Updater", time); + + // Remove + let time = bench!( + groups, + |groups: &Vec<(MlsGroup, Member)>| groups[0].clone(), + |group0: (MlsGroup, Member)| { + // Let group 1 update and merge the commit. + let (mut updater_group, updater) = group0; + let provider = &updater.provider; + let signer = &updater.signer; + let _ = remove_member(&mut updater_group, provider, signer); + } + ); + print_time("Remover", time); + + // Process an update + let time = bench!( + groups, + |groups: &Vec<(MlsGroup, Member)>| { + // Let group 1 update and merge the commit. + let (updater_group, updater) = &groups[1]; + let provider = &updater.provider; + let signer = &updater.signer; + let commit = self_update(&mut updater_group.clone(), provider, signer); + + (groups[0].clone(), commit) + }, + |(group0, commit): ((MlsGroup, Member), MlsMessageOut)| { + // Apply the commit at member 0 + let (mut member_group, member) = group0; + let provider = &member.provider; + + process_commit(&mut member_group, provider, commit); + } + ); + print_time("Process update", time); + } +} diff --git a/openmls/src/binary_tree/array_representation/diff.rs b/openmls/src/binary_tree/array_representation/diff.rs index 36e69d6140..4f38fe6e65 100644 --- a/openmls/src/binary_tree/array_representation/diff.rs +++ b/openmls/src/binary_tree/array_representation/diff.rs @@ -42,6 +42,7 @@ use super::{ /// was created from. However, the lack of the internal reference means that its /// lifetime is not tied to that of the original tree. #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone, PartialEq))] pub(crate) struct StagedAbDiff { leaf_diff: BTreeMap, parent_diff: BTreeMap, @@ -334,30 +335,6 @@ impl<'a, L: Clone + Debug + Default, P: Clone + Debug + Default> AbDiff<'a, L, P self.original_tree.parent_by_index(parent_index) } - /// Returns a mutable reference to the leaf node in the diff at index - /// `leaf_index`. If the diff doesn't have a node at that index, it clones - /// the node to the diff and returns a mutable reference to that node. - pub(crate) fn leaf_mut(&mut self, leaf_index: LeafNodeIndex) -> &mut L { - debug_assert!(leaf_index.u32() < self.leaf_count()); - // We then check if the node is already in the diff. (Not using `if let - // ...` here, because the borrow checker doesn't like that). - if self.leaf_diff.contains_key(&leaf_index) { - return self - .leaf_diff - .get_mut(&leaf_index) - // We just checked that this index exists, so this must be Some. - .unwrap_or(&mut self.default_leaf); - // If not, we take a copy from the original tree and put it in the - // diff before returning a mutable reference to it. - } - let tree_node = self.original_tree.leaf_by_index(leaf_index); - self.replace_leaf(leaf_index, tree_node.clone()); - self.leaf_diff - .get_mut(&leaf_index) - // We just inserted this into the diff, so this should be Some. - .unwrap_or(&mut self.default_leaf) - } - /// Returns a mutable reference to the parent node in the diff at index /// `parent_index`. If the diff doesn't have a node at that index, it clones /// the node to the diff and returns a mutable reference to that node. diff --git a/openmls/src/binary_tree/array_representation/tree.rs b/openmls/src/binary_tree/array_representation/tree.rs index c0cb943d6e..79dcf5d59c 100644 --- a/openmls/src/binary_tree/array_representation/tree.rs +++ b/openmls/src/binary_tree/array_representation/tree.rs @@ -27,7 +27,7 @@ where Parent(P), } -#[cfg_attr(test, derive(PartialEq))] +#[cfg_attr(any(test, feature = "test-utils"), derive(PartialEq))] #[derive(Clone, Debug, Serialize, Deserialize)] /// A representation of a full, left-balanced binary tree that uses a simple /// vector to store nodes. Each tree has to consist of at least one node. diff --git a/openmls/src/binary_tree/mod.rs b/openmls/src/binary_tree/mod.rs index 2d21396147..4ae7342131 100644 --- a/openmls/src/binary_tree/mod.rs +++ b/openmls/src/binary_tree/mod.rs @@ -14,7 +14,7 @@ pub(crate) mod array_representation; // Tests #[cfg(test)] -mod test_binary_tree; +mod tests; // Crate types diff --git a/openmls/src/binary_tree/test_binary_tree.rs b/openmls/src/binary_tree/tests.rs similarity index 100% rename from openmls/src/binary_tree/test_binary_tree.rs rename to openmls/src/binary_tree/tests.rs diff --git a/openmls/src/ciphersuite/mod.rs b/openmls/src/ciphersuite/mod.rs index 99656f23b4..72373ea2e0 100644 --- a/openmls/src/ciphersuite/mod.rs +++ b/openmls/src/ciphersuite/mod.rs @@ -36,7 +36,7 @@ pub(crate) use signature::*; pub(crate) use serde::{Deserialize, Serialize}; #[cfg(test)] -mod tests; +mod tests_and_kats; const LABEL_PREFIX: &str = "MLS 1.0 "; diff --git a/openmls/src/ciphersuite/tests.rs b/openmls/src/ciphersuite/tests_and_kats.rs similarity index 83% rename from openmls/src/ciphersuite/tests.rs rename to openmls/src/ciphersuite/tests_and_kats.rs index a1c700565a..e60de6d020 100644 --- a/openmls/src/ciphersuite/tests.rs +++ b/openmls/src/ciphersuite/tests_and_kats.rs @@ -1,6 +1,6 @@ //! Unit tests for the ciphersuites. -mod test_ciphersuite; +mod tests; // Test vector for basic crypto functionality mod kat_crypto_basics; diff --git a/openmls/src/ciphersuite/tests/kat_crypto_basics.rs b/openmls/src/ciphersuite/tests_and_kats/kat_crypto_basics.rs similarity index 100% rename from openmls/src/ciphersuite/tests/kat_crypto_basics.rs rename to openmls/src/ciphersuite/tests_and_kats/kat_crypto_basics.rs diff --git a/openmls/src/ciphersuite/tests/test_ciphersuite.rs b/openmls/src/ciphersuite/tests_and_kats/tests.rs similarity index 100% rename from openmls/src/ciphersuite/tests/test_ciphersuite.rs rename to openmls/src/ciphersuite/tests_and_kats/tests.rs diff --git a/openmls/src/credentials/mod.rs b/openmls/src/credentials/mod.rs index d00294affc..94a8a6f10f 100644 --- a/openmls/src/credentials/mod.rs +++ b/openmls/src/credentials/mod.rs @@ -288,7 +288,7 @@ impl TryFrom for BasicCredential { } } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] /// A wrapper around a credential with a corresponding public key. pub struct CredentialWithKey { /// The [`Credential`]. diff --git a/openmls/src/extensions/mod.rs b/openmls/src/extensions/mod.rs index df9d2414dc..3c5cb4ebef 100644 --- a/openmls/src/extensions/mod.rs +++ b/openmls/src/extensions/mod.rs @@ -57,7 +57,7 @@ use tls_codec::{ pub use metadata::Metadata; #[cfg(test)] -mod test_extensions; +mod tests; /// MLS Extension Types /// diff --git a/openmls/src/extensions/test_extensions.rs b/openmls/src/extensions/tests.rs similarity index 73% rename from openmls/src/extensions/test_extensions.rs rename to openmls/src/extensions/tests.rs index 492c5bbc6b..ab878a7780 100644 --- a/openmls/src/extensions/test_extensions.rs +++ b/openmls/src/extensions/tests.rs @@ -8,12 +8,11 @@ use super::*; use crate::{ credentials::*, framing::*, - group::{errors::*, *}, + group::{errors::*, tests_and_kats::utils::generate_credential_with_key, *}, key_packages::*, messages::proposals::ProposalType, prelude::{Capabilities, RatchetTreeIn}, prelude_test::HpkePublicKey, - schedule::psk::store::ResumptionPskStore, versions::ProtocolVersion, }; use openmls_traits::prelude::*; @@ -39,8 +38,6 @@ fn application_id() { #[openmls_test::openmls_test] fn ratchet_tree_extension() { // Basic group setup. - let group_aad = b"Alice's test group"; - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); // Create credentials and keys let (alice_credential_with_key, alice_signature_keys) = @@ -57,63 +54,37 @@ fn ratchet_tree_extension() { ); let bob_key_package = bob_key_package_bundle.key_package(); - let config = CoreGroupConfig { - add_ratchet_tree_extension: true, - }; - // === Alice creates a group with the ratchet tree extension === - let mut alice_group = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential_with_key.clone(), - ) - .with_config(config) - .build(provider, &alice_signature_keys) - .expect("Error creating group."); - - // === Alice adds Bob === - let bob_add_proposal = alice_group - .create_add_proposal( - framing_parameters, - bob_key_package.clone(), + let mut alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .use_ratchet_tree_extension(true) + .build( + provider, &alice_signature_keys, + alice_credential_with_key.clone(), ) - .expect("Could not create proposal."); + .expect("Error creating group."); - let proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - bob_add_proposal, - ) - .expect("Could not create QueuedProposal."), - ); + // === Alice adds Bob === + let (_commit, welcome, _group_info_option) = alice_group + .add_members(provider, &alice_signature_keys, &[bob_key_package.clone()]) + .expect("An unexpected error occurred."); + + alice_group.merge_pending_commit(provider).unwrap(); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) + let config = MlsGroupJoinConfig::builder() + .use_ratchet_tree_extension(true) .build(); - let create_commit_result = alice_group - .create_commit(params, provider, &alice_signature_keys) - .expect("Error creating commit"); - - alice_group - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging commit"); - - let bob_group = StagedCoreWelcome::new_from_welcome( - create_commit_result - .welcome_option - .expect("An unexpected error occurred."), - None, - bob_key_package_bundle, + + let bob_group = StagedWelcome::new_from_welcome( provider, - ResumptionPskStore::new(1024), + &config, + welcome.into_welcome().unwrap(), + Some(alice_group.export_ratchet_tree().into()), ) - .expect("Could not stage group join with ratchet tree extension") - .into_core_group(provider) - .expect("Could not join group with ratchet tree extension"); + .expect("Error staging welcome") + .into_group(provider) + .expect("Error creating group from welcome"); // Make sure the group state is the same assert_eq!( @@ -122,8 +93,8 @@ fn ratchet_tree_extension() { ); // Make sure both groups have set the flag correctly - assert!(alice_group.use_ratchet_tree_extension()); - assert!(bob_group.use_ratchet_tree_extension()); + assert!(alice_group.configuration().use_ratchet_tree_extension); + assert!(bob_group.configuration().use_ratchet_tree_extension); // === Alice creates a group without the ratchet tree extension === @@ -136,61 +107,25 @@ fn ratchet_tree_extension() { ); let bob_key_package = bob_key_package_bundle.key_package(); - let config = CoreGroupConfig { - add_ratchet_tree_extension: false, - }; - - let mut alice_group = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential_with_key, - ) - .with_config(config) - .build(provider, &alice_signature_keys) - .expect("Error creating group."); + let mut alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .use_ratchet_tree_extension(false) + .build(provider, &alice_signature_keys, alice_credential_with_key) + .expect("Error creating group."); // === Alice adds Bob === - let bob_add_proposal = alice_group - .create_add_proposal( - framing_parameters, - bob_key_package.clone(), - &alice_signature_keys, - ) - .expect("Could not create proposal."); - - let proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - bob_add_proposal, - ) - .expect("Could not create staged proposal."), - ); + let (_commit, welcome, _group_info_option) = alice_group + .add_members(provider, &alice_signature_keys, &[bob_key_package.clone()]) + .expect("An unexpected error occurred."); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) + let config = MlsGroupJoinConfig::builder() + .use_ratchet_tree_extension(false) .build(); - let create_commit_result = alice_group - .create_commit(params, provider, &alice_signature_keys) - .expect("Error creating commit"); - - alice_group - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging commit"); - - let error = StagedCoreWelcome::new_from_welcome( - create_commit_result - .welcome_option - .expect("An unexpected error occurred."), - None, - bob_key_package_bundle, - provider, - ResumptionPskStore::new(1024), - ) - .and_then(|staged_join| staged_join.into_core_group(provider)) - .err(); + + let error = + StagedWelcome::new_from_welcome(provider, &config, welcome.into_welcome().unwrap(), None) + .and_then(|staged_join| staged_join.into_group(provider)) + .err(); // We expect an error because the ratchet tree is missing assert!(matches!( @@ -246,11 +181,8 @@ fn with_group_context_extensions() { let test_extension = Extension::Unknown(0xf023, UnknownExtension(vec![0xca, 0xfe])); let extensions = Extensions::single(test_extension.clone()); - let alice_credential_with_key_and_signer = tests::utils::generate_credential_with_key( - "Alice".into(), - ciphersuite.signature_algorithm(), - provider, - ); + let alice_credential_with_key_and_signer = + generate_credential_with_key("Alice".into(), ciphersuite.signature_algorithm(), provider); let mls_group_create_config = MlsGroupCreateConfig::builder() .with_group_context_extensions(extensions) @@ -283,11 +215,8 @@ fn wrong_extension_with_group_context_extensions() { // - external pub // - ratchet tree - let alice_credential_with_key_and_signer = tests::utils::generate_credential_with_key( - "Alice".into(), - ciphersuite.signature_algorithm(), - provider, - ); + let alice_credential_with_key_and_signer = + generate_credential_with_key("Alice".into(), ciphersuite.signature_algorithm(), provider); // create an extension that we can check for later let test_extension = Extension::ApplicationId(ApplicationIdExtension::new(&[0xca, 0xfe])); @@ -398,11 +327,8 @@ fn last_resort_extension() { // If we join a group using a last resort KP, it shouldn't be deleted from the // provider. - let alice_credential_with_key_and_signer = tests::utils::generate_credential_with_key( - "Alice".into(), - ciphersuite.signature_algorithm(), - provider, - ); + let alice_credential_with_key_and_signer = + generate_credential_with_key("Alice".into(), ciphersuite.signature_algorithm(), provider); let mls_group_create_config = MlsGroupCreateConfig::builder() .ciphersuite(ciphersuite) diff --git a/openmls/src/framing/mls_auth_content.rs b/openmls/src/framing/mls_auth_content.rs index 3d7eae0b3a..92607e339d 100644 --- a/openmls/src/framing/mls_auth_content.rs +++ b/openmls/src/framing/mls_auth_content.rs @@ -290,10 +290,6 @@ impl AuthenticatedContent { pub fn test_signature(&self) -> &Signature { &self.auth.signature } - - pub(super) fn unset_confirmation_tag(&mut self) { - self.auth.confirmation_tag = None; - } } impl SignedStruct for AuthenticatedContent { diff --git a/openmls/src/framing/mod.rs b/openmls/src/framing/mod.rs index 41fa1feb0f..33c8609977 100644 --- a/openmls/src/framing/mod.rs +++ b/openmls/src/framing/mod.rs @@ -94,7 +94,7 @@ pub use validation::*; // Tests #[cfg(test)] -pub(crate) mod test_framing; +pub(crate) mod tests; /// Wire format of MLS messages. /// diff --git a/openmls/src/framing/test_framing.rs b/openmls/src/framing/tests.rs similarity index 57% rename from openmls/src/framing/test_framing.rs rename to openmls/src/framing/tests.rs index 124e215686..d04a5b658b 100644 --- a/openmls/src/framing/test_framing.rs +++ b/openmls/src/framing/tests.rs @@ -2,6 +2,7 @@ use openmls_basic_credential::SignatureKeyPair; use openmls_traits::prelude::*; use openmls_traits::types::Ciphersuite; +use mls_group::tests_and_kats::utils::{setup_alice_bob_group, setup_client}; use signable::Verifiable; use tls_codec::{Deserialize, Serialize}; @@ -10,13 +11,10 @@ use crate::{ ciphersuite::signable::{Signable, SignatureError}, extensions::Extensions, framing::*, - group::{ - core_group::proposals::{ProposalStore, QueuedProposal}, - errors::*, - CreateCommitParams, - }, - key_packages::{test_key_packages::key_package, KeyPackageBundle}, - schedule::psk::{store::ResumptionPskStore, PskSecret}, + group::errors::*, + key_packages::tests::key_package, + prelude::LeafNodeParameters, + schedule::psk::PskSecret, storage::OpenMlsProvider, test_utils::frankenstein::*, tree::{secret_tree::SecretTree, sender_ratchet::SenderRatchetConfiguration}, @@ -383,185 +381,65 @@ fn membership_tag() { fn unknown_sender(ciphersuite: Ciphersuite, provider: &Provider) { let _ = pretty_env_logger::try_init(); - let alice_provider = provider; - let bob_provider = provider; - let charlie_provider = provider; - - let group_aad = b"Alice's test group"; - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); - let configuration = &SenderRatchetConfiguration::default(); - // Define credentials with keys - let (alice_credential, alice_signature_keys) = - test_utils::new_credential(alice_provider, b"Alice", ciphersuite.signature_algorithm()); - let (bob_credential, bob_signature_keys) = - test_utils::new_credential(bob_provider, b"Bob", ciphersuite.signature_algorithm()); - let (charlie_credential, charlie_signature_keys) = test_utils::new_credential( - charlie_provider, - b"Charlie", - ciphersuite.signature_algorithm(), - ); - - // Generate KeyPackages - let bob_key_package_bundle = KeyPackageBundle::generate( - bob_provider, - &bob_signature_keys, - ciphersuite, - bob_credential, - ); - let bob_key_package = bob_key_package_bundle.key_package(); - - let charlie_key_package_bundle = KeyPackageBundle::generate( - charlie_provider, - &charlie_signature_keys, - ciphersuite, - charlie_credential, - ); - let charlie_key_package = charlie_key_package_bundle.key_package(); - - // Alice creates a group - let mut group_alice = CoreGroup::builder( - GroupId::random(alice_provider.rand()), - ciphersuite, - alice_credential, - ) - .build(alice_provider, &alice_signature_keys) - .expect("Error creating group."); - - // Alice adds Bob - let bob_add_proposal = group_alice - .create_add_proposal( - framing_parameters, - bob_key_package.clone(), - &alice_signature_keys, - ) - .expect("Could not create proposal."); - - let mut proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - alice_provider.crypto(), - bob_add_proposal, - ) - .expect("Could not create QueuedProposal."), - ); + let ( + _charlie_credential, + charlie_key_package_bundle, + _charlie_signature_keys, + _charlie_public_signature_key, + ) = setup_client("Charlie", ciphersuite, provider); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = group_alice - .create_commit(params, alice_provider, &alice_signature_keys) - .expect("Error creating Commit"); - - group_alice - .merge_commit(alice_provider, create_commit_result.staged_commit) - .expect("error merging pending commit"); - - let _group_bob = StagedCoreWelcome::new_from_welcome( - create_commit_result - .welcome_option - .expect("An unexpected error occurred."), - Some(group_alice.public_group().export_ratchet_tree().into()), - bob_key_package_bundle, - bob_provider, - ResumptionPskStore::new(1024), - ) - .and_then(|staged_join| staged_join.into_core_group(bob_provider)) - .expect("Bob: Error creating group from Welcome"); + let (mut alice_group, alice_signature_keys, _bob_group, _bob_signature_keys, _bob_credential) = + setup_alice_bob_group(ciphersuite, provider); // Alice adds Charlie - - let charlie_add_proposal = group_alice - .create_add_proposal( - framing_parameters, - charlie_key_package.clone(), + let (_commit, welcome, _group_info_option) = alice_group + .add_members( + provider, &alice_signature_keys, + &[charlie_key_package_bundle.key_package().clone()], ) - .expect("Could not create proposal."); + .expect("Could not add members."); - proposal_store.empty(); - proposal_store.add( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - alice_provider.crypto(), - charlie_add_proposal, - ) - .expect("Could not create staged proposal."), - ); + alice_group + .merge_pending_commit(provider) + .expect("Could not merge commit."); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) + let config = MlsGroupJoinConfig::builder() + .wire_format_policy(PURE_PLAINTEXT_WIRE_FORMAT_POLICY) .build(); - let create_commit_result = group_alice - .create_commit(params, alice_provider, &alice_signature_keys) - .expect("Error creating Commit"); - - group_alice - .merge_commit(alice_provider, create_commit_result.staged_commit) - .expect("error merging pending commit"); - - let mut group_charlie = StagedCoreWelcome::new_from_welcome( - create_commit_result - .welcome_option - .expect("An unexpected error occurred."), - Some(group_alice.public_group().export_ratchet_tree().into()), - charlie_key_package_bundle, - charlie_provider, - ResumptionPskStore::new(1024), + + let mut charlie_group = StagedWelcome::new_from_welcome( + provider, + &config, + welcome.into_welcome().unwrap(), + Some(alice_group.export_ratchet_tree().into()), ) - .and_then(|staged_join| staged_join.into_core_group(charlie_provider)) - .expect("Charlie: Error creating group from Welcome"); + .expect("Could not create group from Welcome") + .into_group(provider) + .expect("Could not create group from Welcome"); // Alice removes Bob - let bob_remove_proposal = group_alice - .create_remove_proposal( - framing_parameters, - LeafNodeIndex::new(1), - &alice_signature_keys, - ) - .expect("Could not create proposal."); + let (commit, _welcome_option, _group_info_option) = alice_group + .remove_members(provider, &alice_signature_keys, &[LeafNodeIndex::new(1)]) + .expect("Could not remove members."); - proposal_store.empty(); - proposal_store.add( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - alice_provider.crypto(), - bob_remove_proposal, - ) - .expect("Could not create staged proposal."), - ); + alice_group + .merge_pending_commit(provider) + .expect("Could not merge commit."); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = group_alice - .create_commit(params, alice_provider, &alice_signature_keys) - .expect("Error creating Commit"); - - let staged_commit = group_charlie - .read_keys_and_stage_commit( - &create_commit_result.commit, - &proposal_store, - &[], - alice_provider, - ) - .expect("Charlie: Could not stage Commit"); - group_charlie - .merge_commit(charlie_provider, staged_commit) - .expect("error merging commit"); + let processed_message = charlie_group + .process_message(provider, commit.into_protocol_message().unwrap()) + .expect("Could not process message."); - group_alice - .merge_commit(alice_provider, create_commit_result.staged_commit) - .expect("error merging pending commit"); + let staged_commit = match processed_message.into_content() { + ProcessedMessageContent::StagedCommitMessage(staged_commit) => *staged_commit, + _ => panic!("Wrong message type."), + }; - group_alice.print_ratchet_tree("Alice tree"); - group_charlie.print_ratchet_tree("Charlie tree"); + charlie_group + .merge_staged_commit(provider, staged_commit) + .expect("Could not merge commit."); // Alice sends a message with a sender that is outside of the group // Expected result: SenderError::UnknownSender @@ -569,164 +447,91 @@ fn unknown_sender(ciphersuite: Ciphersuite, provider: LeafNodeIndex::new(0), &[], &[1, 2, 3], - group_alice.context(), + alice_group.export_group_context(), &alice_signature_keys, ) - .expect("Could not create new PublicMessage."); + .expect("Could not create new ApplicationMessage."); let enc_message = PrivateMessage::encrypt_with_different_header( &bogus_sender_message, ciphersuite, - alice_provider, + provider, MlsMessageHeader { - group_id: group_alice.group_id().clone(), - epoch: group_alice.context().epoch(), + group_id: alice_group.group_id().clone(), + epoch: alice_group.epoch(), sender: LeafNodeIndex::new(987543210u32), }, - group_alice.message_secrets_test_mut(), + alice_group.message_secrets_test_mut(), 0, ) .expect("Encryption error"); - let received_message = group_charlie.decrypt_message( - charlie_provider.crypto(), + let received_message = charlie_group.process_message( + provider, ProtocolMessage::from(PrivateMessageIn::from(enc_message)), - configuration, ); + assert_eq!( received_message.unwrap_err(), - ValidationError::UnableToDecrypt(MessageDecryptionError::SecretTreeError( - SecretTreeError::IndexOutOfBounds + ProcessMessageError::ValidationError(ValidationError::UnableToDecrypt( + MessageDecryptionError::SecretTreeError(SecretTreeError::IndexOutOfBounds) )) ); } #[openmls_test::openmls_test] fn confirmation_tag_presence() { - let (framing_parameters, group_alice, alice_signature_keys, group_bob, _, _) = - setup_alice_bob_group(ciphersuite, provider); + let ( + mut alice_group, + alice_signature_keys, + mut bob_group, + _bob_signature_keys, + _bob_credential, + ) = setup_alice_bob_group(ciphersuite, provider); // Alice does an update - let proposal_store = ProposalStore::default(); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(true) - .build(); - let mut create_commit_result = group_alice - .create_commit(params, provider, &alice_signature_keys) - .expect("Error creating Commit"); - - create_commit_result.commit.unset_confirmation_tag(); - - let err = group_bob - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect_err("No error despite missing confirmation tag."); - - assert_eq!(err, StageCommitError::ConfirmationTagMissing); -} - -pub(crate) fn setup_alice_bob_group( - ciphersuite: Ciphersuite, - provider: &Provider, -) -> ( - FramingParameters, - CoreGroup, - SignatureKeyPair, - CoreGroup, - SignatureKeyPair, - CredentialWithKey, -) { - let group_aad = b"Alice's test group"; - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); - - // Create credentials and keys - let (alice_credential, alice_signature_keys) = - test_utils::new_credential(provider, b"Alice", ciphersuite.signature_algorithm()); - let (bob_credential, bob_signature_keys) = - test_utils::new_credential(provider, b"Bob", ciphersuite.signature_algorithm()); - - // Generate KeyPackages - let bob_key_package_bundle = KeyPackageBundle::generate( - provider, - &bob_signature_keys, - ciphersuite, - bob_credential.clone(), - ); - let bob_key_package = bob_key_package_bundle.key_package(); - - // Alice creates a group - let mut group_alice = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential, - ) - .build(provider, &alice_signature_keys) - .expect("Error creating group."); - - // Alice adds Bob - let bob_add_proposal = group_alice - .create_add_proposal( - framing_parameters, - bob_key_package.clone(), + let (commit, _welcome_option, _group_info_option) = alice_group + .self_update( + provider, &alice_signature_keys, + LeafNodeParameters::default(), ) - .expect("Could not create proposal."); + .expect("Could not update group."); - let proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - bob_add_proposal, - ) - .expect("Could not create QueuedProposal."), - ); + let commit = match commit.body { + MlsMessageBodyOut::PublicMessage(pm) => pm, + _ => panic!("Wrong message type."), + }; - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); + let mut franken_pm = FrankenPublicMessage::from(commit); - let create_commit_result = group_alice - .create_commit(params, provider, &alice_signature_keys) - .expect("Error creating Commit"); + franken_pm.auth.confirmation_tag = None; - let commit = match create_commit_result.commit.content() { - FramedContentBody::Commit(commit) => commit, - _ => panic!("Wrong content type"), + let serialized_pm = franken_pm + .tls_serialize_detached() + .expect("Could not serialize message."); + + let pm = match PublicMessageIn::tls_deserialize(&mut serialized_pm.as_slice()) { + Ok(pm) => pm, + Err(err) => { + assert!(matches!(err, tls_codec::Error::InvalidVectorLength)); + return; + } }; - assert!(!commit.has_path()); - // Check that the function returned a Welcome message - assert!(create_commit_result.welcome_option.is_some()); - - group_alice - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging pending commit"); - - // We have to create Bob's group so he can process the commit with the - // broken confirmation tag, because Alice can't process her own commit. - let group_bob = StagedCoreWelcome::new_from_welcome( - create_commit_result - .welcome_option - .expect("commit didn't return a welcome as expected"), - Some(group_alice.public_group().export_ratchet_tree().into()), - bob_key_package_bundle, - provider, - ResumptionPskStore::new(1024), - ) - .and_then(|staged_join| staged_join.into_core_group(provider)) - .expect("error creating group from welcome"); - ( - framing_parameters, - group_alice, - alice_signature_keys, - group_bob, - bob_signature_keys, - bob_credential, - ) + // Just in case the decoding succeeds, we need to make sure that the + // missing confirmation tag is detected when processing the message. + + let protocol_message: ProtocolMessage = pm.into(); + + let err = bob_group + .process_message(provider, protocol_message) + .expect_err("Could not process message."); + + assert_eq!( + err, + ProcessMessageError::InvalidCommit(StageCommitError::ConfirmationTagMissing) + ); } /// Test divergent protocol versions in KeyPackages diff --git a/openmls/src/framing/validation.rs b/openmls/src/framing/validation.rs index 6e27b814fb..914e75d05e 100644 --- a/openmls/src/framing/validation.rs +++ b/openmls/src/framing/validation.rs @@ -34,14 +34,11 @@ use crate::{ core_group::{proposals::QueuedProposal, staged_commit::StagedCommit}, errors::ValidationError, }, - storage::OpenMlsProvider, tree::sender_ratchet::SenderRatchetConfiguration, treesync::TreeSync, versions::ProtocolVersion, }; -use self::mls_group::errors::ProcessMessageError; - use super::{ mls_auth_content::AuthenticatedContent, mls_auth_content_in::{AuthenticatedContentIn, VerifiableAuthenticatedContentIn}, @@ -271,23 +268,18 @@ impl UnverifiedMessage { /// Verify the [`UnverifiedMessage`]. Returns the [`AuthenticatedContent`] /// and the internal [`Credential`]. - pub(crate) fn verify( + pub(crate) fn verify( self, ciphersuite: Ciphersuite, - provider: &Provider, + crypto: &impl OpenMlsCrypto, protocol_version: ProtocolVersion, - ) -> Result<(AuthenticatedContent, Credential), ProcessMessageError> - { + ) -> Result<(AuthenticatedContent, Credential), ValidationError> { let content: AuthenticatedContentIn = self .verifiable_content - .verify(provider.crypto(), &self.sender_pk) - .map_err(|_| ProcessMessageError::InvalidSignature)?; - let content = content.validate( - ciphersuite, - provider.crypto(), - self.sender_context, - protocol_version, - )?; + .verify(crypto, &self.sender_pk) + .map_err(|_| ValidationError::InvalidSignature)?; + let content = + content.validate(ciphersuite, crypto, self.sender_context, protocol_version)?; Ok((content, self.credential)) } @@ -343,8 +335,8 @@ impl ProcessedMessage { &self.sender } - /// Returns the authenticated data of the message. - pub fn authenticated_data(&self) -> &[u8] { + /// Returns the additional authenticated data (AAD) of the message. + pub fn aad(&self) -> &[u8] { &self.authenticated_data } diff --git a/openmls/src/group/core_group/create_commit_params.rs b/openmls/src/group/core_group/create_commit_params.rs index d30a52a8b5..c5fbf46469 100644 --- a/openmls/src/group/core_group/create_commit_params.rs +++ b/openmls/src/group/core_group/create_commit_params.rs @@ -3,35 +3,30 @@ use serde::{Deserialize, Serialize}; use crate::{ - credentials::CredentialWithKey, framing::FramingParameters, group::ProposalStore, - messages::proposals::Proposal, + credentials::CredentialWithKey, framing::FramingParameters, messages::proposals::Proposal, }; #[cfg(doc)] use super::CoreGroup; +use super::LeafNodeParameters; /// Can be used to denote the type of a commit. -#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub(crate) enum CommitType { - External, + External(CredentialWithKey), Member, } pub(crate) struct CreateCommitParams<'a> { - framing_parameters: FramingParameters<'a>, // Mandatory - proposal_store: &'a ProposalStore, // Mandatory - inline_proposals: Vec, // Optional - force_self_update: bool, // Optional - commit_type: CommitType, // Optional (default is `Member`) - credential_with_key: Option, // Mandatory for external commits + framing_parameters: FramingParameters<'a>, // Mandatory + inline_proposals: Vec, // Optional + force_self_update: bool, // Optional + commit_type: CommitType, // Optional (default is `Member`) + leaf_node_parameters: LeafNodeParameters, // Optional } pub(crate) struct TempBuilderCCPM0 {} -pub(crate) struct TempBuilderCCPM1<'a> { - framing_parameters: FramingParameters<'a>, -} - pub(crate) struct CreateCommitParamsBuilder<'a> { ccp: CreateCommitParams<'a>, } @@ -39,25 +34,15 @@ pub(crate) struct CreateCommitParamsBuilder<'a> { impl TempBuilderCCPM0 { pub(crate) fn framing_parameters( self, - framing_parameters: FramingParameters<'_>, - ) -> TempBuilderCCPM1<'_> { - TempBuilderCCPM1 { framing_parameters } - } -} - -impl<'a> TempBuilderCCPM1<'a> { - pub(crate) fn proposal_store( - self, - proposal_store: &'a ProposalStore, - ) -> CreateCommitParamsBuilder<'a> { + framing_parameters: FramingParameters, + ) -> CreateCommitParamsBuilder { CreateCommitParamsBuilder { ccp: CreateCommitParams { - framing_parameters: self.framing_parameters, - proposal_store, + framing_parameters, inline_proposals: vec![], force_self_update: true, commit_type: CommitType::Member, - credential_with_key: None, + leaf_node_parameters: LeafNodeParameters::default(), }, } } @@ -68,7 +53,6 @@ impl<'a> CreateCommitParamsBuilder<'a> { self.ccp.inline_proposals = inline_proposals; self } - #[cfg(test)] pub(crate) fn force_self_update(mut self, force_self_update: bool) -> Self { self.ccp.force_self_update = force_self_update; self @@ -77,8 +61,8 @@ impl<'a> CreateCommitParamsBuilder<'a> { self.ccp.commit_type = commit_type; self } - pub(crate) fn credential_with_key(mut self, credential_with_key: CredentialWithKey) -> Self { - self.ccp.credential_with_key = Some(credential_with_key); + pub(crate) fn leaf_node_parameters(mut self, leaf_node_parameters: LeafNodeParameters) -> Self { + self.ccp.leaf_node_parameters = leaf_node_parameters; self } pub(crate) fn build(self) -> CreateCommitParams<'a> { @@ -93,19 +77,19 @@ impl<'a> CreateCommitParams<'a> { pub(crate) fn framing_parameters(&self) -> &FramingParameters { &self.framing_parameters } - pub(crate) fn proposal_store(&self) -> &ProposalStore { - self.proposal_store - } pub(crate) fn inline_proposals(&self) -> &[Proposal] { &self.inline_proposals } + pub(crate) fn set_inline_proposals(&mut self, inline_proposals: Vec) { + self.inline_proposals = inline_proposals; + } pub(crate) fn force_self_update(&self) -> bool { self.force_self_update } - pub(crate) fn commit_type(&self) -> CommitType { - self.commit_type + pub(crate) fn commit_type(&self) -> &CommitType { + &self.commit_type } - pub(crate) fn take_credential_with_key(&mut self) -> Option { - self.credential_with_key.take() + pub(crate) fn leaf_node_parameters(&self) -> &LeafNodeParameters { + &self.leaf_node_parameters } } diff --git a/openmls/src/group/core_group/mod.rs b/openmls/src/group/core_group/mod.rs index 28d4c5d3aa..d3f7f08ecd 100644 --- a/openmls/src/group/core_group/mod.rs +++ b/openmls/src/group/core_group/mod.rs @@ -16,22 +16,6 @@ pub(crate) mod process; pub(crate) mod proposals; pub(crate) mod staged_commit; -// Tests -#[cfg(test)] -pub(crate) mod kat_passive_client; -#[cfg(test)] -pub(crate) mod kat_welcome; -#[cfg(test)] -pub(crate) mod test_core_group; -#[cfg(test)] -mod test_create_commit_params; -#[cfg(test)] -mod test_external_init; -#[cfg(test)] -mod test_past_secrets; -#[cfg(test)] -mod test_proposals; - use log::{debug, trace}; use openmls_traits::{ crypto::OpenMlsCrypto, signatures::Signer, storage::StorageProvider as _, types::Ciphersuite, @@ -158,8 +142,8 @@ pub(crate) struct StagedCoreWelcome { path_keypairs: Option>, } -#[derive(Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq, Clone))] +#[derive(Debug)] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone, PartialEq))] pub(crate) struct CoreGroup { public_group: PublicGroup, group_epoch_secrets: GroupEpochSecrets, @@ -209,13 +193,6 @@ impl CoreGroupBuilder { self } - /// Set the [`Vec`] of the [`CoreGroup`]. - #[cfg(test)] - pub(crate) fn with_psk(mut self, psk_ids: Vec) -> Self { - self.psk_ids = psk_ids; - self - } - /// Set the [`Capabilities`] of the group's creator. pub(crate) fn with_capabilities(mut self, capabilities: Capabilities) -> Self { self.public_group_builder = self.public_group_builder.with_capabilities(capabilities); @@ -621,6 +598,16 @@ impl CoreGroup { &self.public_group } + /// Returns a reference to the proposal store. + pub(crate) fn proposal_store(&self) -> &ProposalStore { + self.public_group.proposal_store() + } + + /// Returns a mutable reference to the proposal store. + pub(crate) fn proposal_store_mut(&mut self) -> &mut ProposalStore { + self.public_group.proposal_store_mut() + } + /// Get the ciphersuite implementation used in this group. pub(crate) fn ciphersuite(&self) -> Ciphersuite { self.public_group.ciphersuite() @@ -735,7 +722,6 @@ impl CoreGroup { self.public_group.store(storage)?; storage.write_own_leaf_index(group_id, &self.own_leaf_index())?; storage.write_group_epoch_secrets(group_id, &self.group_epoch_secrets)?; - storage.set_use_ratchet_tree_extension(group_id, self.use_ratchet_tree_extension)?; storage.write_message_secrets(group_id, &self.message_secrets_store)?; storage.write_resumption_psk_store(group_id, &self.resumption_psk_store)?; @@ -746,11 +732,11 @@ impl CoreGroup { pub(super) fn load( storage: &Storage, group_id: &GroupId, + use_ratchet_tree_extension: Option, ) -> Result, Storage::Error> { let public_group = PublicGroup::load(storage, group_id)?; let group_epoch_secrets = storage.group_epoch_secrets(group_id)?; let own_leaf_index = storage.own_leaf_index(group_id)?; - let use_ratchet_tree_extension = storage.use_ratchet_tree_extension(group_id)?; let message_secrets_store = storage.message_secrets(group_id)?; let resumption_psk_store = storage.resumption_psk_store(group_id)?; @@ -775,7 +761,6 @@ impl CoreGroup { self.public_group.delete(storage)?; storage.delete_own_leaf_index(self.group_id())?; storage.delete_group_epoch_secrets(self.group_id())?; - storage.delete_use_ratchet_tree_extension(self.group_id())?; storage.delete_message_secrets(self.group_id())?; storage.delete_all_resumption_psk_secrets(self.group_id())?; @@ -834,14 +819,14 @@ impl CoreGroup { pub(crate) fn create_commit( &self, - mut params: CreateCommitParams, + params: CreateCommitParams, provider: &Provider, signer: &impl Signer, ) -> Result> { let ciphersuite = self.ciphersuite(); let sender = match params.commit_type() { - CommitType::External => Sender::NewMemberCommit, + CommitType::External(_) => Sender::NewMemberCommit, CommitType::Member => Sender::build_member(self.own_leaf_index()), }; @@ -850,7 +835,7 @@ impl CoreGroup { ciphersuite, provider.crypto(), sender.clone(), - params.proposal_store(), + self.proposal_store(), params.inline_proposals(), self.own_leaf_index(), ) @@ -914,7 +899,7 @@ impl CoreGroup { // Apply proposals to tree let apply_proposals_values = diff.apply_proposals(&proposal_queue, self.own_leaf_index())?; - if apply_proposals_values.self_removed && params.commit_type() != CommitType::External { + if apply_proposals_values.self_removed && params.commit_type() == &CommitType::Member { return Err(CreateCommitError::CannotRemoveSelf); } @@ -923,6 +908,7 @@ impl CoreGroup { if apply_proposals_values.path_required || contains_own_updates || params.force_self_update() + || !params.leaf_node_parameters().is_empty() { // Process the path. This includes updating the provisional // group context by updating the epoch and computing the new @@ -932,8 +918,8 @@ impl CoreGroup { self.own_leaf_index(), apply_proposals_values.exclusion_list(), params.commit_type(), + params.leaf_node_parameters(), signer, - params.take_credential_with_key(), apply_proposals_values.extensions.clone() )? } else { @@ -1174,10 +1160,6 @@ impl CoreGroup { // Test functions #[cfg(test)] impl CoreGroup { - pub(crate) fn use_ratchet_tree_extension(&self) -> bool { - self.use_ratchet_tree_extension - } - pub(crate) fn set_own_leaf_index(&mut self, own_leaf_index: LeafNodeIndex) { self.own_leaf_index = own_leaf_index; } @@ -1196,6 +1178,7 @@ impl CoreGroup { } // Test and test-utils functions +#[cfg_attr(all(not(test), feature = "test-utils"), allow(dead_code))] #[cfg(any(feature = "test-utils", test))] impl CoreGroup { pub(crate) fn context_mut(&mut self) -> &mut GroupContext { @@ -1209,6 +1192,10 @@ impl CoreGroup { pub(crate) fn print_ratchet_tree(&self, message: &str) { println!("{}: {}", message, self.public_group().export_ratchet_tree()); } + + pub(crate) fn resumption_psk_store(&self) -> &ResumptionPskStore { + &self.resumption_psk_store + } } /// Configuration for core group. diff --git a/openmls/src/group/core_group/new_from_external_init.rs b/openmls/src/group/core_group/new_from_external_init.rs index 29a708405f..e8c387416b 100644 --- a/openmls/src/group/core_group/new_from_external_init.rs +++ b/openmls/src/group/core_group/new_from_external_init.rs @@ -48,7 +48,8 @@ impl CoreGroup { }; let (public_group, group_info) = PublicGroup::from_external( - provider, + provider.crypto(), + provider.storage(), ratchet_tree, verifiable_group_info, // Existing proposals are discarded when joining by external commit. @@ -97,17 +98,22 @@ impl CoreGroup { // If there is a group member in the group with the same identity as us, // commit a remove proposal. - let params_credential_with_key = params - .take_credential_with_key() - .ok_or(ExternalCommitError::MissingCredential)?; - if let Some(us) = public_group.members().find(|member| { - member.signature_key == params_credential_with_key.signature_key.as_slice() - }) { + let signature_key = match params.commit_type() { + CommitType::External(credential_with_key) => { + credential_with_key.signature_key.as_slice() + } + _ => return Err(ExternalCommitError::MissingCredential), + }; + if let Some(us) = public_group + .members() + .find(|member| member.signature_key == signature_key) + { let remove_proposal = Proposal::Remove(RemoveProposal { removed: us.index }); inline_proposals.push(remove_proposal); }; let own_leaf_index = public_group.leftmost_free_index(inline_proposals.iter().map(Some))?; + params.set_inline_proposals(inline_proposals); let group = CoreGroup { public_group, @@ -119,14 +125,6 @@ impl CoreGroup { resumption_psk_store: ResumptionPskStore::new(32), }; - let params = CreateCommitParams::builder() - .framing_parameters(*params.framing_parameters()) - .proposal_store(params.proposal_store()) - .inline_proposals(inline_proposals) - .commit_type(CommitType::External) - .credential_with_key(params_credential_with_key) - .build(); - // Immediately create the commit to add ourselves to the group. let create_commit_result = group.create_commit(params, provider, signer); debug_assert!( diff --git a/openmls/src/group/core_group/new_from_welcome.rs b/openmls/src/group/core_group/new_from_welcome.rs index 3a50c17588..ae653b6a02 100644 --- a/openmls/src/group/core_group/new_from_welcome.rs +++ b/openmls/src/group/core_group/new_from_welcome.rs @@ -1,7 +1,6 @@ use log::debug; use crate::{ - ciphersuite::hash_ref::HashReference, group::{core_group::*, errors::WelcomeError}, schedule::psk::store::ResumptionPskStore, storage::OpenMlsProvider, @@ -120,7 +119,8 @@ pub(in crate::group) fn build_staged_welcome( // Since there is currently only the external pub extension, there is no // group info extension of interest here. let (public_group, _group_info_extensions) = PublicGroup::from_external( - provider, + provider.crypto(), + provider.storage(), ratchet_tree, verifiable_group_info.clone(), ProposalStore::new(), @@ -244,14 +244,11 @@ pub(in crate::group) fn process_welcome( WelcomeError, > { let ciphersuite = welcome.ciphersuite(); - let egs = if let Some(egs) = CoreGroup::find_key_package_from_welcome_secrets( + let Some(egs) = welcome.find_encrypted_group_secret( key_package_bundle .key_package() .hash_ref(provider.crypto())?, - welcome.secrets(), - ) { - egs - } else { + ) else { return Err(WelcomeError::JoinerSecretNotFound); }; if ciphersuite != key_package_bundle.key_package().ciphersuite() { @@ -310,19 +307,3 @@ pub(in crate::group) fn process_welcome( verifiable_group_info, )) } - -impl CoreGroup { - // Helper functions - - pub(crate) fn find_key_package_from_welcome_secrets( - hash_ref: HashReference, - welcome_secrets: &[EncryptedGroupSecrets], - ) -> Option { - for egs in welcome_secrets { - if hash_ref == egs.new_member() { - return Some(egs.clone()); - } - } - None - } -} diff --git a/openmls/src/group/core_group/past_secrets.rs b/openmls/src/group/core_group/past_secrets.rs index 88a794eb45..e3e878717b 100644 --- a/openmls/src/group/core_group/past_secrets.rs +++ b/openmls/src/group/core_group/past_secrets.rs @@ -6,7 +6,7 @@ use super::*; // Internal helper struct #[derive(Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq, Clone))] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone, PartialEq))] #[cfg_attr(feature = "crypto-debug", derive(Debug))] struct EpochTree { epoch: u64, @@ -17,7 +17,7 @@ struct EpochTree { /// Can store message secrets for up to `max_epochs`. The trees are added with [`self::add()`] and can be queried /// with [`Self::get_epoch()`]. #[derive(Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq, Clone))] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone, PartialEq))] #[cfg_attr(feature = "crypto-debug", derive(Debug))] pub(crate) struct MessageSecretsStore { // Maximum size of the `past_epoch_trees` list. diff --git a/openmls/src/group/core_group/process.rs b/openmls/src/group/core_group/process.rs index e203643af5..e9b6cac054 100644 --- a/openmls/src/group/core_group/process.rs +++ b/openmls/src/group/core_group/process.rs @@ -8,7 +8,7 @@ use crate::{ }, }; -use super::{proposals::ProposalStore, *}; +use super::*; impl CoreGroup { /// This processing function does most of the semantic verifications. @@ -43,15 +43,14 @@ impl CoreGroup { &self, provider: &Provider, unverified_message: UnverifiedMessage, - proposal_store: &ProposalStore, old_epoch_keypairs: Vec, leaf_node_keypairs: Vec, - ) -> Result> { + ) -> Result { // Checks the following semantic validation: // - ValSem010 // - ValSem246 (as part of ValSem010) let (content, credential) = - unverified_message.verify(self.ciphersuite(), provider, self.version())?; + unverified_message.verify(self.ciphersuite(), provider.crypto(), self.version())?; match content.sender() { Sender::Member(_) | Sender::NewMemberCommit | Sender::NewMemberProposal => { @@ -80,7 +79,6 @@ impl CoreGroup { FramedContentBody::Commit(_) => { let staged_commit = self.stage_commit( &content, - proposal_store, old_epoch_keypairs, leaf_node_keypairs, provider, @@ -174,9 +172,8 @@ impl CoreGroup { provider: &Provider, message: impl Into, sender_ratchet_configuration: &SenderRatchetConfiguration, - proposal_store: &ProposalStore, own_leaf_nodes: &[LeafNode], - ) -> Result> { + ) -> Result { let message: ProtocolMessage = message.into(); // Checks the following semantic validation: @@ -203,7 +200,6 @@ impl CoreGroup { self.process_unverified_message( provider, unverified_message, - proposal_store, old_epoch_keypairs, leaf_node_keypairs, ) @@ -294,7 +290,6 @@ impl CoreGroup { &mut self, provider: &Provider, staged_commit: StagedCommit, - proposal_store: &mut ProposalStore, ) -> Result<(), MergeCommitError> { // Save the past epoch let past_epoch = self.context().epoch(); @@ -306,8 +301,6 @@ impl CoreGroup { self.message_secrets_store .add(past_epoch, message_secrets, leaves); } - // Empty the proposal store - proposal_store.empty(); Ok(()) } } diff --git a/openmls/src/group/core_group/proposals.rs b/openmls/src/group/core_group/proposals.rs index f08695864c..714408e863 100644 --- a/openmls/src/group/core_group/proposals.rs +++ b/openmls/src/group/core_group/proposals.rs @@ -20,7 +20,7 @@ use crate::{ /// A [ProposalStore] can store the standalone proposals that are received from /// the DS in between two commit messages. #[derive(Debug, Default, Serialize, Deserialize, PartialEq)] -#[cfg_attr(test, derive(Clone))] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone))] pub struct ProposalStore { queued_proposals: Vec, } @@ -53,11 +53,11 @@ impl ProposalStore { /// Removes a proposal from the store using its reference. It will return /// None if it wasn't found in the store. - pub(crate) fn remove(&mut self, proposal_ref: ProposalRef) -> Option<()> { + pub(crate) fn remove(&mut self, proposal_ref: &ProposalRef) -> Option<()> { let index = self .queued_proposals .iter() - .position(|p| p.proposal_reference() == proposal_ref)?; + .position(|p| &p.proposal_reference() == proposal_ref)?; self.queued_proposals.remove(index); Some(()) } @@ -88,20 +88,6 @@ impl QueuedProposal { ) } - /// Creates a new [QueuedProposal] from an [PublicMessage] - pub(crate) fn from_authenticated_content_by_value( - ciphersuite: Ciphersuite, - crypto: &impl OpenMlsCrypto, - public_message: AuthenticatedContent, - ) -> Result { - Self::from_authenticated_content( - ciphersuite, - crypto, - public_message, - ProposalOrRefType::Proposal, - ) - } - /// Creates a new [QueuedProposal] from an [PublicMessage] pub(crate) fn from_authenticated_content( ciphersuite: Ciphersuite, @@ -204,6 +190,7 @@ impl OrderedProposalRefs { /// accessed efficiently. To enable iteration over the queue in order, the /// `ProposalQueue` also contains a vector of `ProposalRef`s. #[derive(Default, Debug, Serialize, Deserialize)] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone, PartialEq))] pub(crate) struct ProposalQueue { /// `proposal_references` holds references to the proposals in the queue and /// determines the order of the queue. diff --git a/openmls/src/group/core_group/staged_commit.rs b/openmls/src/group/core_group/staged_commit.rs index 440c9c0be6..b5d3f5d568 100644 --- a/openmls/src/group/core_group/staged_commit.rs +++ b/openmls/src/group/core_group/staged_commit.rs @@ -5,9 +5,10 @@ use public_group::diff::{apply_proposals::ApplyProposalsValues, StagedPublicGrou use self::public_group::staged_commit::PublicStagedCommitState; -use super::{super::errors::*, proposals::ProposalStore, *}; +use super::{super::errors::*, *}; use crate::{ - ciphersuite::Secret, framing::mls_auth_content::AuthenticatedContent, + ciphersuite::{hash_ref::ProposalRef, Secret}, + framing::mls_auth_content::AuthenticatedContent, treesync::node::encryption_keys::EncryptionKeyPair, }; @@ -120,11 +121,10 @@ impl CoreGroup { /// - ValSem241 /// - ValSem242 /// - ValSem244 Returns an error if the given commit was sent by the owner - /// of this group. + /// of this group. pub(crate) fn stage_commit( &self, mls_content: &AuthenticatedContent, - proposal_store: &ProposalStore, old_epoch_keypairs: Vec, leaf_node_keypairs: Vec, provider: &impl OpenMlsProvider, @@ -138,9 +138,9 @@ impl CoreGroup { let ciphersuite = self.ciphersuite(); - let (commit, proposal_queue, sender_index) = - self.public_group - .validate_commit(mls_content, proposal_store, provider.crypto())?; + let (commit, proposal_queue, sender_index) = self + .public_group + .validate_commit(mls_content, provider.crypto())?; // Create the provisional public group state (including the tree and // group context) and apply proposals. @@ -149,19 +149,6 @@ impl CoreGroup { let apply_proposals_values = diff.apply_proposals(&proposal_queue, self.own_leaf_index())?; - // Check if we were removed from the group - if apply_proposals_values.self_removed { - let staged_diff = diff.into_staged_diff(provider.crypto(), ciphersuite)?; - let staged_state = PublicStagedCommitState::new( - staged_diff, - commit.path.as_ref().map(|path| path.leaf_node().clone()), - ); - return Ok(StagedCommit::new( - proposal_queue, - StagedCommitState::PublicState(Box::new(staged_state)), - )); - } - // Determine if Commit has a path let (commit_secret, new_keypairs, new_leaf_keypair_option, update_path_leaf_node) = if let Some(path) = commit.path.clone() { @@ -180,6 +167,20 @@ impl CoreGroup { apply_proposals_values.extensions.clone(), )?; + // Check if we were removed from the group + if apply_proposals_values.self_removed { + // If so, we return here, because we can't decrypt the path + let staged_diff = diff.into_staged_diff(provider.crypto(), ciphersuite)?; + let staged_state = PublicStagedCommitState::new( + staged_diff, + commit.path.as_ref().map(|path| path.leaf_node().clone()), + ); + return Ok(StagedCommit::new( + proposal_queue, + StagedCommitState::PublicState(Box::new(staged_state)), + )); + } + let decryption_keypairs: Vec<&EncryptionKeyPair> = old_epoch_keypairs .iter() .chain(leaf_node_keypairs.iter()) @@ -373,7 +374,7 @@ impl CoreGroup { .into()); } - // store the updated group state + // Store the updated group state let storage = provider.storage(); let group_id = self.group_id(); @@ -400,35 +401,20 @@ impl CoreGroup { .map_err(MergeCommitError::StorageError)?; } + // Empty the proposal store + storage + .clear_proposal_queue::(group_id) + .map_err(MergeCommitError::StorageError)?; + self.proposal_store_mut().empty(); + Ok(Some(message_secrets)) } } } - - #[cfg(test)] - /// Helper function that reads the decryption keys from the key store - /// (unwrapping the result) and stages the given commit. - pub(crate) fn read_keys_and_stage_commit( - &self, - mls_content: &AuthenticatedContent, - proposal_store: &ProposalStore, - own_leaf_nodes: &[LeafNode], - provider: &impl OpenMlsProvider, - ) -> Result { - let (old_epoch_keypairs, leaf_node_keypairs) = - self.read_decryption_keypairs(provider, own_leaf_nodes)?; - - self.stage_commit( - mls_content, - proposal_store, - old_epoch_keypairs, - leaf_node_keypairs, - provider, - ) - } } #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone, PartialEq))] pub(crate) enum StagedCommitState { PublicState(Box), GroupMember(Box), @@ -436,6 +422,7 @@ pub(crate) enum StagedCommitState { /// Contains the changes from a commit to the group state. #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone, PartialEq))] pub struct StagedCommit { staged_proposal_queue: ProposalQueue, state: StagedCommitState, @@ -568,6 +555,7 @@ impl StagedCommit { /// This struct is used internally by [StagedCommit] to encapsulate all the modified group state. #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone, PartialEq))] pub(crate) struct MemberStagedCommitState { group_epoch_secrets: GroupEpochSecrets, message_secrets: MessageSecrets, diff --git a/openmls/src/group/core_group/test_core_group.rs b/openmls/src/group/core_group/test_core_group.rs deleted file mode 100644 index 796c292616..0000000000 --- a/openmls/src/group/core_group/test_core_group.rs +++ /dev/null @@ -1,763 +0,0 @@ -use openmls_basic_credential::SignatureKeyPair; -use openmls_traits::types::HpkeCiphertext; -use tls_codec::Serialize; - -use crate::{ - binary_tree::*, - ciphersuite::{signable::Signable, AeadNonce}, - credentials::*, - framing::*, - group::{errors::*, *}, - key_packages::*, - messages::{group_info::GroupInfoTBS, *}, - schedule::psk::{store::ResumptionPskStore, ExternalPsk, PreSharedKeyId, Psk}, - test_utils::*, - treesync::{errors::ApplyUpdatePathError, node::leaf_node::TreeInfoTbs}, -}; - -pub(crate) fn setup_alice_group( - ciphersuite: Ciphersuite, - provider: &impl crate::storage::OpenMlsProvider, -) -> ( - CoreGroup, - CredentialWithKey, - SignatureKeyPair, - OpenMlsSignaturePublicKey, -) { - // Create credentials and keys - let (alice_credential_with_key, alice_signature_keys) = - test_utils::new_credential(provider, b"Alice", ciphersuite.signature_algorithm()); - let pk = OpenMlsSignaturePublicKey::new( - alice_signature_keys.to_public_vec().into(), - ciphersuite.signature_algorithm(), - ) - .unwrap(); - - // Alice creates a group - let group = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential_with_key.clone(), - ) - .build(provider, &alice_signature_keys) - .expect("Error creating group."); - (group, alice_credential_with_key, alice_signature_keys, pk) -} - -/// This function flips the last byte of the ciphertext. -pub fn flip_last_byte(ctxt: &mut HpkeCiphertext) { - let mut last_bits = ctxt - .ciphertext - .pop() - .expect("An unexpected error occurred."); - last_bits ^= 0xff; - ctxt.ciphertext.push(last_bits); -} - -#[openmls_test::openmls_test] -fn test_failed_groupinfo_decryption( - ciphersuite: Ciphersuite, - provider: &impl crate::storage::OpenMlsProvider, -) { - let epoch = 123; - let group_id = GroupId::random(provider.rand()); - let tree_hash = vec![1, 2, 3, 4, 5, 6, 7, 8, 9]; - let confirmed_transcript_hash = vec![1, 1, 1]; - let extensions = Extensions::empty(); - let confirmation_tag = ConfirmationTag(Mac { - mac_value: vec![1, 2, 3, 4, 5, 6, 7, 8, 9].into(), - }); - - // Create credentials and keys - let (alice_credential_with_key, alice_signature_keys) = - test_utils::new_credential(provider, b"Alice", ciphersuite.signature_algorithm()); - - let key_package_bundle = KeyPackageBundle::generate( - provider, - &alice_signature_keys, - ciphersuite, - alice_credential_with_key, - ); - - let group_info_tbs = { - let group_context = GroupContext::new( - ciphersuite, - group_id, - epoch, - tree_hash, - confirmed_transcript_hash, - Extensions::empty(), - ); - - GroupInfoTBS::new( - group_context, - extensions, - confirmation_tag, - LeafNodeIndex::new(0), - ) - }; - - // Generate key and nonce for the symmetric cipher. - let welcome_key = AeadKey::random(ciphersuite, provider.rand()); - let welcome_nonce = AeadNonce::random(provider.rand()); - - // Generate receiver key pair. - let receiver_key_pair = provider - .crypto() - .derive_hpke_keypair( - ciphersuite.hpke_config(), - Secret::random(ciphersuite, provider.rand()) - .expect("Not enough randomness.") - .as_slice(), - ) - .expect("error deriving receiver hpke key pair"); - let hpke_context = b"group info welcome test info"; - let group_secrets = b"these should be the group secrets"; - let mut encrypted_group_secrets = hpke::encrypt_with_label( - receiver_key_pair.public.as_slice(), - "Welcome", - hpke_context, - group_secrets, - ciphersuite, - provider.crypto(), - ) - .unwrap(); - - let group_info = group_info_tbs - .sign(&alice_signature_keys) - .expect("Error signing group info"); - - // Mess with the ciphertext by flipping the last byte. - flip_last_byte(&mut encrypted_group_secrets); - - let broken_secrets = vec![EncryptedGroupSecrets::new( - key_package_bundle - .key_package - .hash_ref(provider.crypto()) - .expect("Could not hash KeyPackage."), - encrypted_group_secrets, - )]; - - // Encrypt the group info. - let encrypted_group_info = welcome_key - .aead_seal( - provider.crypto(), - &group_info - .tls_serialize_detached() - .expect("An unexpected error occurred."), - &[], - &welcome_nonce, - ) - .expect("An unexpected error occurred."); - - // Now build the welcome message. - let broken_welcome = Welcome::new(ciphersuite, broken_secrets, encrypted_group_info); - - let error = StagedCoreWelcome::new_from_welcome( - broken_welcome, - None, - key_package_bundle, - provider, - ResumptionPskStore::new(1024), - ) - .and_then(|staged_join| staged_join.into_core_group(provider)) - .expect_err("Creation of core group from a broken Welcome was successful."); - - assert!(matches!( - error, - WelcomeError::GroupSecrets(GroupSecretsError::DecryptionFailed) - )) -} - -/// Test what happens if the KEM ciphertext for the receiver in the UpdatePath -/// is broken. -#[openmls_test::openmls_test] -fn test_update_path() { - // === Alice creates a group with her and Bob === - let ( - framing_parameters, - group_alice, - _alice_signature_keys, - group_bob, - bob_signature_keys, - _bob_credential_with_key, - ) = test_framing::setup_alice_bob_group(ciphersuite, provider); - - // === Bob updates and commits === - let bob_old_leaf = group_bob.own_leaf_node().unwrap(); - let bob_update_leaf_node = bob_old_leaf - .updated( - ciphersuite, - TreeInfoTbs::Update(group_bob.own_tree_position()), - provider, - &bob_signature_keys, - ) - .unwrap(); - - let update_proposal_bob = group_bob - .create_update_proposal( - framing_parameters, - bob_update_leaf_node, - &bob_signature_keys, - ) - .expect("Could not create proposal."); - let proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - update_proposal_bob, - ) - .expect("Could not create QueuedProposal."), - ); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = group_bob - .create_commit(params, provider, &bob_signature_keys) - .expect("An unexpected error occurred."); - - // Now we break Alice's HPKE ciphertext in Bob's commit by breaking - // apart the commit, manipulating the ciphertexts and the piecing it - // back together. - let commit = match create_commit_result.commit.content() { - FramedContentBody::Commit(commit) => commit, - _ => panic!("Bob created a commit, which does not contain an actual commit."), - }; - - let commit = commit.clone(); - - let path = commit.path.expect("An unexpected error occurred."); - - let mut broken_path = path; - // For simplicity, let's just break all the ciphertexts. - broken_path.flip_eps_bytes(); - - // Now let's create a new commit from out broken update path. - let broken_commit = Commit { - proposals: commit.proposals, - path: Some(broken_path), - }; - - let mut broken_plaintext = AuthenticatedContent::commit( - framing_parameters, - create_commit_result.commit.sender().clone(), - broken_commit, - group_bob.context(), - &bob_signature_keys, - ) - .expect("Could not create plaintext."); - - broken_plaintext.set_confirmation_tag( - create_commit_result - .commit - .confirmation_tag() - .cloned() - .expect("An unexpected error occurred."), - ); - - println!( - "Confirmation tag: {:?}", - broken_plaintext.confirmation_tag() - ); - - let staged_commit_res = - group_alice.read_keys_and_stage_commit(&broken_plaintext, &proposal_store, &[], provider); - assert_eq!( - staged_commit_res.expect_err("Successful processing of a broken commit."), - StageCommitError::UpdatePathError(ApplyUpdatePathError::UnableToDecrypt) - ); -} - -fn setup_alice_bob( - ciphersuite: Ciphersuite, - provider: &impl crate::storage::OpenMlsProvider, -) -> ( - CredentialWithKey, - SignatureKeyPair, - KeyPackageBundle, - SignatureKeyPair, -) { - // Create credentials and keys - let (alice_credential_with_key, alice_signer) = - test_utils::new_credential(provider, b"Alice", ciphersuite.signature_algorithm()); - let (bob_credential_with_key, bob_signer) = - test_utils::new_credential(provider, b"Bob", ciphersuite.signature_algorithm()); - - // Generate Bob's KeyPackage - let bob_key_package_bundle = - KeyPackageBundle::generate(provider, &bob_signer, ciphersuite, bob_credential_with_key); - - ( - alice_credential_with_key, - alice_signer, - bob_key_package_bundle, - bob_signer, - ) -} - -// Test several scenarios when PSKs are used in a group -#[openmls_test::openmls_test] -fn test_psks() { - // Basic group setup. - let group_aad = b"Alice's test group"; - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); - - let ( - alice_credential_with_key, - alice_signature_keys, - bob_key_package_bundle, - bob_signature_keys, - ) = setup_alice_bob(ciphersuite, provider); - - // === Alice creates a group with a PSK === - let psk_id = vec![1u8, 2, 3]; - - let secret = Secret::random(ciphersuite, provider.rand()).expect("Not enough randomness."); - let external_psk = ExternalPsk::new(psk_id); - let preshared_key_id = - PreSharedKeyId::new(ciphersuite, provider.rand(), Psk::External(external_psk)) - .expect("An unexpected error occured."); - preshared_key_id.store(provider, secret.as_slice()).unwrap(); - let mut alice_group = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential_with_key, - ) - .with_psk(vec![preshared_key_id.clone()]) - .build(provider, &alice_signature_keys) - .expect("Error creating group."); - - // === Alice creates a PSK proposal === - log::info!(" >>> Creating psk proposal ..."); - let psk_proposal = alice_group - .create_presharedkey_proposal(framing_parameters, preshared_key_id, &alice_signature_keys) - .expect("Could not create PSK proposal"); - - // === Alice adds Bob === - let bob_add_proposal = alice_group - .create_add_proposal( - framing_parameters, - bob_key_package_bundle.key_package().clone(), - &alice_signature_keys, - ) - .expect("Could not create proposal"); - - let mut proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - bob_add_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - proposal_store.add( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - psk_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - log::info!(" >>> Creating commit ..."); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = alice_group - .create_commit(params, provider, &alice_signature_keys) - .expect("Error creating commit"); - - log::info!(" >>> Staging & merging commit ..."); - - alice_group - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging pending commit"); - let ratchet_tree = alice_group.public_group().export_ratchet_tree(); - - let group_bob = StagedCoreWelcome::new_from_welcome( - create_commit_result - .welcome_option - .expect("An unexpected error occurred."), - Some(ratchet_tree.into()), - bob_key_package_bundle, - provider, - ResumptionPskStore::new(1024), - ) - .and_then(|staged_join| staged_join.into_core_group(provider)) - .expect("Could not create new group from Welcome"); - - // === Bob updates and commits === - let bob_old_leaf = group_bob.own_leaf_node().unwrap(); - let bob_update_leaf_node = bob_old_leaf - .updated( - ciphersuite, - TreeInfoTbs::Update(group_bob.own_tree_position()), - provider, - &bob_signature_keys, - ) - .unwrap(); - - let update_proposal_bob = group_bob - .create_update_proposal( - framing_parameters, - bob_update_leaf_node, - &bob_signature_keys, - ) - .expect("Could not create proposal."); - let proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - update_proposal_bob, - ) - .expect("Could not create QueuedProposal."), - ); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let _create_commit_result = group_bob - .create_commit(params, provider, &bob_signature_keys) - .expect("An unexpected error occurred."); -} - -// Test several scenarios when PSKs are used in a group -#[openmls_test::openmls_test] -fn test_staged_commit_creation( - ciphersuite: Ciphersuite, - provider: &impl crate::storage::OpenMlsProvider, -) { - // Basic group setup. - let group_aad = b"Alice's test group"; - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); - - let (alice_credential_with_key, alice_signature_keys, bob_key_package_bundle, _) = - setup_alice_bob(ciphersuite, provider); - - // === Alice creates a group === - let mut alice_group = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential_with_key, - ) - .build(provider, &alice_signature_keys) - .expect("Error creating group."); - - // === Alice adds Bob === - let bob_add_proposal = alice_group - .create_add_proposal( - framing_parameters, - bob_key_package_bundle.key_package().clone(), - &alice_signature_keys, - ) - .expect("Could not create proposal."); - let proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - bob_add_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = alice_group - .create_commit(params, provider, &alice_signature_keys) - .expect("Error creating commit"); - - // === Alice merges her own commit === - alice_group - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error processing own staged commit"); - - // === Bob joins the group using Alice's tree === - let group_bob = StagedCoreWelcome::new_from_welcome( - create_commit_result - .welcome_option - .expect("An unexpected error occurred."), - Some(alice_group.public_group().export_ratchet_tree().into()), - bob_key_package_bundle, - provider, - ResumptionPskStore::new(1024), - ) - .and_then(|staged_join| staged_join.into_core_group(provider)) - .expect("An unexpected error occurred."); - - // Let's make sure we end up in the same group state. - assert_eq!( - group_bob.export_secret(provider.crypto(), "", b"test", ciphersuite.hash_length()), - alice_group.export_secret(provider.crypto(), "", b"test", ciphersuite.hash_length()) - ); - assert_eq!( - group_bob.public_group().export_ratchet_tree(), - alice_group.public_group().export_ratchet_tree() - ) -} - -// Test processing of own commits -#[openmls_test::openmls_test] -fn test_own_commit_processing( - ciphersuite: Ciphersuite, - provider: &impl crate::storage::OpenMlsProvider, -) { - // Basic group setup. - let group_aad = b"Alice's test group"; - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); - - // Create credentials and keys - let (alice_credential_with_key, alice_signature_keys) = - test_utils::new_credential(provider, b"Alice", ciphersuite.signature_algorithm()); - - // === Alice creates a group === - let alice_group = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential_with_key, - ) - .build(provider, &alice_signature_keys) - .expect("Error creating group."); - - let proposal_store = ProposalStore::default(); - // Alice creates a commit - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(true) - .build(); - let create_commit_result = alice_group - .create_commit(params, provider, &alice_signature_keys) - .expect("error creating commit"); - - // Alice attempts to process her own commit - let error = alice_group - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect_err("no error while processing own commit"); - assert_eq!(error, StageCommitError::OwnCommit); -} - -pub(crate) fn setup_client( - id: &str, - ciphersuite: Ciphersuite, - provider: &impl crate::storage::OpenMlsProvider, -) -> ( - CredentialWithKey, - KeyPackageBundle, - SignatureKeyPair, - OpenMlsSignaturePublicKey, -) { - let (credential_with_key, signature_keys) = - test_utils::new_credential(provider, id.as_bytes(), ciphersuite.signature_algorithm()); - let pk = OpenMlsSignaturePublicKey::new( - signature_keys.to_public_vec().into(), - ciphersuite.signature_algorithm(), - ) - .unwrap(); - - // Generate the KeyPackage - let key_package_bundle = KeyPackageBundle::generate( - provider, - &signature_keys, - ciphersuite, - credential_with_key.clone(), - ); - (credential_with_key, key_package_bundle, signature_keys, pk) -} - -#[openmls_test::openmls_test] -fn test_proposal_application_after_self_was_removed( - ciphersuite: Ciphersuite, - provider: &impl crate::storage::OpenMlsProvider, -) { - // We're going to test if proposals are still applied, even after a client - // notices that it was removed from a group. We do so by having Alice - // create a group, add Bob and then create a commit where Bob is removed and - // Charlie is added in a single commit (by Alice). We then check if - // everyone's membership list is as expected. - - // Basic group setup. - let group_aad = b"Alice's test group"; - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); - - let (alice_credential_with_key, _, alice_signature_keys, _pk) = - setup_client("Alice", ciphersuite, provider); - let (_, bob_kpb, _, _) = setup_client("Bob", ciphersuite, provider); - let (_, charlie_kpb, _, _) = setup_client("Charlie", ciphersuite, provider); - - let mut alice_group = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential_with_key, - ) - .build(provider, &alice_signature_keys) - .expect("Error creating CoreGroup."); - - // Adding Bob - let bob_add_proposal = alice_group - .create_add_proposal( - framing_parameters, - bob_kpb.key_package().clone(), - &alice_signature_keys, - ) - .expect("Could not create proposal"); - - let bob_add_proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - bob_add_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&bob_add_proposal_store) - .force_self_update(false) - .build(); - let add_commit_result = alice_group - .create_commit(params, provider, &alice_signature_keys) - .expect("Error creating commit"); - - alice_group - .merge_commit(provider, add_commit_result.staged_commit) - .expect("error merging pending commit"); - - let ratchet_tree = alice_group.public_group().export_ratchet_tree(); - - let mut bob_group = StagedCoreWelcome::new_from_welcome( - add_commit_result - .welcome_option - .expect("An unexpected error occurred."), - Some(ratchet_tree.into()), - bob_kpb, - provider, - ResumptionPskStore::new(1024), - ) - .and_then(|staged_join| staged_join.into_core_group(provider)) - .expect("Error joining group."); - - // Alice adds Charlie and removes Bob in the same commit. - let bob_index = alice_group - .public_group() - .members() - .find( - |Member { - index: _, - credential, - .. - }| { credential.serialized_content() == b"Bob" }, - ) - .expect("Couldn't find Bob in tree.") - .index; - let bob_remove_proposal = alice_group - .create_remove_proposal(framing_parameters, bob_index, &alice_signature_keys) - .expect("Could not create proposal"); - - let charlie_add_proposal = alice_group - .create_add_proposal( - framing_parameters, - charlie_kpb.key_package().clone(), - &alice_signature_keys, - ) - .expect("Could not create proposal"); - - let mut remove_add_proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - bob_remove_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - - remove_add_proposal_store.add( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - charlie_add_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&remove_add_proposal_store) - .build(); - let remove_add_commit_result = alice_group - .create_commit(params, provider, &alice_signature_keys) - .expect("Error creating commit"); - - let staged_commit = bob_group - .read_keys_and_stage_commit( - &remove_add_commit_result.commit, - &remove_add_proposal_store, - &[], - provider, - ) - .expect("error staging commit"); - bob_group - .merge_commit(provider, staged_commit) - .expect("Error merging commit."); - - alice_group - .merge_commit(provider, remove_add_commit_result.staged_commit) - .expect("Error merging commit."); - - let ratchet_tree = alice_group.public_group().export_ratchet_tree(); - - let charlie_group = StagedCoreWelcome::new_from_welcome( - remove_add_commit_result - .welcome_option - .expect("An unexpected error occurred."), - Some(ratchet_tree.into()), - charlie_kpb, - provider, - ResumptionPskStore::new(1024), - ) - .and_then(|staged_join| staged_join.into_core_group(provider)) - .expect("Error joining group."); - - // We can now check that Bob correctly processed his and applied the changes - // to his tree after he was removed by comparing membership lists. In - // particular, Bob's list should show that he was removed and Charlie was - // added. - let alice_members = alice_group.public_group().members(); - - let bob_members = bob_group.public_group().members(); - - let charlie_members = charlie_group.public_group().members(); - - for (alice_member, (bob_member, charlie_member)) in - alice_members.zip(bob_members.zip(charlie_members)) - { - // Note that we can't compare encryption keys for Bob because they - // didn't get updated. - assert_eq!(alice_member.index, bob_member.index); - - let alice_id = alice_member.credential.serialized_content(); - let bob_id = bob_member.credential.serialized_content(); - let charlie_id = charlie_member.credential.serialized_content(); - assert_eq!(alice_id, bob_id); - assert_eq!(alice_member.signature_key, bob_member.signature_key); - assert_eq!(charlie_member.index, bob_member.index); - assert_eq!(charlie_id, bob_id); - assert_eq!(charlie_member.signature_key, bob_member.signature_key); - assert_eq!(charlie_member.encryption_key, alice_member.encryption_key); - } - - let mut bob_members = bob_group.public_group().members(); - - let member = bob_members.next().unwrap(); - let bob_next_id = member.credential.serialized_content(); - assert_eq!(bob_next_id, b"Alice"); - let member = bob_members.next().unwrap(); - let bob_next_id = member.credential.serialized_content(); - assert_eq!(bob_next_id, b"Charlie"); -} diff --git a/openmls/src/group/core_group/test_external_init.rs b/openmls/src/group/core_group/test_external_init.rs deleted file mode 100644 index 4aa36d8375..0000000000 --- a/openmls/src/group/core_group/test_external_init.rs +++ /dev/null @@ -1,284 +0,0 @@ -use crate::{ - framing::{ - test_framing::setup_alice_bob_group, FramedContentBody, FramingParameters, WireFormat, - }, - group::{ - errors::ExternalCommitError, - public_group::errors::CreationFromExternalError, - test_core_group::{setup_alice_group, setup_client}, - CreateCommitParams, - }, - messages::proposals::{ProposalOrRef, ProposalType}, - storage::OpenMlsProvider, -}; -use openmls_traits::prelude::*; - -use super::{proposals::ProposalStore, CoreGroup}; - -#[openmls_test::openmls_test] -fn test_external_init() { - let ( - framing_parameters, - mut group_alice, - alice_signer, - mut group_bob, - bob_signer, - bob_credential_with_key, - ) = setup_alice_bob_group(ciphersuite, provider); - - // Now set up Charlie and try to init externally. - let (charlie_credential, _charlie_kpb, charlie_signer, _charlie_pk) = - setup_client("Charlie", ciphersuite, provider); - - // Have Alice export everything that Charly needs. - let verifiable_group_info = group_alice - .export_group_info(provider.crypto(), &alice_signer, true) - .unwrap() - .into_verifiable_group_info(); - - let proposal_store = ProposalStore::new(); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .credential_with_key(charlie_credential) - .build(); - let (mut group_charly, create_commit_result) = CoreGroup::join_by_external_commit( - provider, - &charlie_signer, - params, - None, - verifiable_group_info, - ) - .expect("Error initializing group externally."); - - // Have alice and bob process the commit resulting from external init. - let proposal_store = ProposalStore::default(); - - let staged_commit = group_alice - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect("error staging commit"); - group_alice - .merge_commit(provider, staged_commit) - .expect("error merging commit"); - - let staged_commit = group_bob - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect("error staging commit"); - group_bob - .merge_commit(provider, staged_commit) - .expect("error merging commit"); - - // Have charly process their own staged commit - group_charly - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging own external commit"); - - assert_eq!( - group_charly.export_secret(provider.crypto(), "", &[], ciphersuite.hash_length()), - group_bob.export_secret(provider.crypto(), "", &[], ciphersuite.hash_length()) - ); - - assert_eq!( - group_charly.public_group().export_ratchet_tree(), - group_bob.public_group().export_ratchet_tree() - ); - - // Check if charly can create valid commits - let proposal_store = ProposalStore::default(); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .build(); - let create_commit_result = group_charly - .create_commit(params, provider, &charlie_signer) - .expect("Error creating commit"); - - let staged_commit = group_alice - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect("error staging commit"); - group_alice - .merge_commit(provider, staged_commit) - .expect("error merging commit"); - - group_charly - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging commit"); - - // Now we assume that Bob somehow lost his group state and wants to add - // themselves back through an external commit. - - // Have Alice export everything that Bob needs. - let verifiable_group_info = group_alice - .export_group_info(provider.crypto(), &alice_signer, false) - .unwrap() - .into_verifiable_group_info(); - let ratchet_tree = group_alice.public_group().export_ratchet_tree(); - - let proposal_store = ProposalStore::new(); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .credential_with_key(bob_credential_with_key) - .build(); - let (mut new_group_bob, create_commit_result) = CoreGroup::join_by_external_commit( - provider, - &bob_signer, - params, - Some(ratchet_tree.into()), - verifiable_group_info, - ) - .expect("Error initializing group externally."); - - // Let's make sure there's a remove in the commit. - let contains_remove = match create_commit_result.commit.content() { - FramedContentBody::Commit(commit) => { - commit - .proposals - .as_slice() - .iter() - .find(|&proposal| match proposal { - ProposalOrRef::Proposal(proposal) => proposal.is_type(ProposalType::Remove), - _ => false, - }) - } - _ => panic!("Wrong content type."), - } - .is_some(); - assert!(contains_remove); - - // Have alice and charly process the commit resulting from external init. - let proposal_store = ProposalStore::default(); - let staged_commit = group_alice - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect("error staging commit"); - group_alice - .merge_commit(provider, staged_commit) - .expect("error merging commit"); - - let staged_commit = group_charly - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect("error staging commit"); - group_charly - .merge_commit(provider, staged_commit) - .expect("error merging commit"); - - // Have Bob process his own staged commit - new_group_bob - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging own external commit"); - - assert_eq!( - group_charly.export_secret(provider.crypto(), "", &[], ciphersuite.hash_length()), - new_group_bob.export_secret(provider.crypto(), "", &[], ciphersuite.hash_length()) - ); - - assert_eq!( - group_charly.public_group().export_ratchet_tree(), - new_group_bob.public_group().export_ratchet_tree() - ); -} - -#[openmls_test::openmls_test] -fn test_external_init_single_member_group() { - let (mut group_alice, _alice_credential_with_key, alice_signer, _alice_pk) = - setup_alice_group(ciphersuite, provider); - - // Framing parameters - let group_aad = b"Alice's test group"; - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); - - // Now set up charly and try to init externally. - let (charly_credential, _charly_kpb, charly_signer, _charly_pk) = - setup_client("Charly", ciphersuite, provider); - - // Have Alice export everything that Charly needs. - let verifiable_group_info = group_alice - .export_group_info(provider.crypto(), &alice_signer, false) - .unwrap() - .into_verifiable_group_info(); - let ratchet_tree = group_alice.public_group().export_ratchet_tree(); - - let proposal_store = ProposalStore::new(); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .credential_with_key(charly_credential) - .build(); - let (mut group_charly, create_commit_result) = CoreGroup::join_by_external_commit( - provider, - &charly_signer, - params, - Some(ratchet_tree.into()), - verifiable_group_info, - ) - .expect("Error initializing group externally."); - - // Have alice and bob process the commit resulting from external init. - let proposal_store = ProposalStore::default(); - let staged_commit = group_alice - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect("error staging commit"); - group_alice - .merge_commit(provider, staged_commit) - .expect("error merging commit"); - - group_charly - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging own external commit"); - - assert_eq!( - group_charly.export_secret(provider.crypto(), "", &[], ciphersuite.hash_length()), - group_alice.export_secret(provider.crypto(), "", &[], ciphersuite.hash_length()) - ); - - assert_eq!( - group_charly.public_group().export_ratchet_tree(), - group_alice.public_group().export_ratchet_tree() - ); -} - -#[openmls_test::openmls_test] -fn test_external_init_broken_signature() { - let ( - framing_parameters, - group_alice, - alice_signer, - _group_bob, - _bob_signer, - _bob_credential_with_key, - ) = setup_alice_bob_group(ciphersuite, provider); - - // Now set up charly and try to init externally. - let (_charlie_credential, _charlie_kpb, charlie_signer, _charlie_pk) = - setup_client("Charlie", ciphersuite, provider); - - let verifiable_group_info = { - let mut verifiable_group_info = group_alice - .export_group_info(provider.crypto(), &alice_signer, true) - .unwrap() - .into_verifiable_group_info(); - verifiable_group_info.break_signature(); - verifiable_group_info - }; - - let proposal_store = ProposalStore::new(); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .build(); - - let result = CoreGroup::join_by_external_commit( - provider, - &charlie_signer, - params, - None, - verifiable_group_info, - ) - .expect_err("Signature was corrupted. This should have failed."); - assert!(matches!( - result, - ExternalCommitError::<::StorageError>::PublicGroupError( - CreationFromExternalError::InvalidGroupInfoSignature - ) - )); -} diff --git a/openmls/src/group/errors.rs b/openmls/src/group/errors.rs index 8dc1332e5e..9d242d2ed2 100644 --- a/openmls/src/group/errors.rs +++ b/openmls/src/group/errors.rs @@ -11,11 +11,10 @@ use crate::{ error::LibraryError, extensions::errors::{ExtensionError, InvalidExtensionError}, framing::errors::MessageDecryptionError, - key_packages::errors::KeyPackageVerifyError, - key_packages::errors::{KeyPackageExtensionSupportError, KeyPackageNewError}, + key_packages::errors::{KeyPackageExtensionSupportError, KeyPackageVerifyError}, messages::{group_info::GroupInfoError, GroupSecretsError}, schedule::errors::PskError, - treesync::errors::*, + treesync::{errors::*, node::leaf_node::LeafNodeUpdateError}, }; /// Welcome error @@ -229,9 +228,6 @@ pub enum CreateCommitError { /// Error interacting with storage. #[error("Error interacting with storage.")] KeyStoreError(StorageError), - /// See [`KeyPackageNewError`] for more details. - #[error(transparent)] - KeyPackageGenerationError(#[from] KeyPackageNewError), /// See [`SignatureError`] for more details. #[error(transparent)] SignatureError(#[from] SignatureError), @@ -249,6 +245,12 @@ pub enum CreateCommitError { GroupContextExtensionsProposalValidationError( #[from] GroupContextExtensionsProposalValidationError, ), + /// See [`LeafNodeUpdateError`] for more details. + #[error(transparent)] + LeafNodeUpdateError(#[from] LeafNodeUpdateError), + /// See [`TreeSyncAddLeaf`] for more details. + #[error(transparent)] + TreeSyncAddLeaf(#[from] TreeSyncAddLeaf), } /// Validation error @@ -515,7 +517,7 @@ pub enum CreateGroupContextExtProposalError { LeafNodeValidation(#[from] LeafNodeValidationError), /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - MlsGroupStateError(#[from] MlsGroupStateError), + MlsGroupStateError(#[from] MlsGroupStateError), /// See [`CreateCommitError`] for more details. #[error(transparent)] CreateCommitError(#[from] CreateCommitError), diff --git a/openmls/src/group/mls_group/application.rs b/openmls/src/group/mls_group/application.rs index 52601ff4a1..1811973a51 100644 --- a/openmls/src/group/mls_group/application.rs +++ b/openmls/src/group/mls_group/application.rs @@ -18,13 +18,13 @@ impl MlsGroup { provider: &Provider, signer: &impl Signer, message: &[u8], - ) -> Result> { + ) -> Result { if !self.is_active() { return Err(CreateMessageError::GroupStateError( MlsGroupStateError::UseAfterEviction, )); } - if !self.proposal_store.is_empty() { + if !self.proposal_store().is_empty() { return Err(CreateMessageError::GroupStateError( MlsGroupStateError::PendingProposal, )); @@ -42,6 +42,7 @@ impl MlsGroup { // We know the application message is wellformed and we have the key material of the current epoch .map_err(|_| LibraryError::custom("Malformed plaintext"))?; + self.reset_aad(); Ok(MlsMessageOut::from_private_message( ciphertext, self.group.version(), diff --git a/openmls/src/group/mls_group/builder.rs b/openmls/src/group/mls_group/builder.rs index 59fe151b02..5644620dea 100644 --- a/openmls/src/group/mls_group/builder.rs +++ b/openmls/src/group/mls_group/builder.rs @@ -7,7 +7,7 @@ use crate::{ group::{ public_group::errors::PublicGroupBuildError, CoreGroup, CoreGroupBuildError, CoreGroupConfig, GroupId, MlsGroupCreateConfig, MlsGroupCreateConfigBuilder, NewGroupError, - ProposalStore, WireFormatPolicy, + WireFormatPolicy, }, key_packages::Lifetime, storage::OpenMlsProvider, @@ -103,7 +103,6 @@ impl MlsGroupBuilder { let mls_group = MlsGroup { mls_group_config: mls_group_create_config.join_config.clone(), group, - proposal_store: ProposalStore::new(), own_leaf_nodes: vec![], aad: vec![], group_state: MlsGroupState::Operational, diff --git a/openmls/src/group/mls_group/creation.rs b/openmls/src/group/mls_group/creation.rs index a61a9eae7c..d473f3e315 100644 --- a/openmls/src/group/mls_group/creation.rs +++ b/openmls/src/group/mls_group/creation.rs @@ -4,7 +4,7 @@ use super::{builder::MlsGroupBuilder, *}; use crate::{ credentials::CredentialWithKey, group::{ - core_group::create_commit_params::CreateCommitParams, + core_group::create_commit_params::{CommitType, CreateCommitParams}, errors::{ExternalCommitError, WelcomeError}, }, messages::{ @@ -13,7 +13,10 @@ use crate::{ }, schedule::psk::{store::ResumptionPskStore, PreSharedKeyId}, storage::OpenMlsProvider, - treesync::RatchetTreeIn, + treesync::{ + node::leaf_node::{Capabilities, LeafNodeParameters}, + RatchetTreeIn, + }, }; impl MlsGroup { @@ -77,12 +80,15 @@ impl MlsGroup { /// /// Note: If there is a group member in the group with the same identity as /// us, this will create a remove proposal. + #[allow(clippy::too_many_arguments)] pub fn join_by_external_commit( provider: &Provider, signer: &impl Signer, ratchet_tree: Option, verifiable_group_info: VerifiableGroupInfo, mls_group_config: &MlsGroupJoinConfig, + capabilities: Option, + extensions: Option, aad: &[u8], credential_with_key: CredentialWithKey, ) -> Result<(Self, MlsMessageOut, Option), ExternalCommitError> @@ -90,11 +96,14 @@ impl MlsGroup { // Prepare the commit parameters let framing_parameters = FramingParameters::new(aad, WireFormat::PublicMessage); - let proposal_store = ProposalStore::new(); + let leaf_node_parameters = LeafNodeParameters::builder() + .with_capabilities(capabilities.unwrap_or_default()) + .with_extensions(extensions.unwrap_or_default()) + .build(); let params = CreateCommitParams::builder() .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .credential_with_key(credential_with_key) + .commit_type(CommitType::External(credential_with_key)) + .leaf_node_parameters(leaf_node_parameters) .build(); let (mut group, create_commit_result) = CoreGroup::join_by_external_commit( provider, @@ -108,7 +117,6 @@ impl MlsGroup { let mls_group = MlsGroup { mls_group_config: mls_group_config.clone(), group, - proposal_store: ProposalStore::new(), own_leaf_nodes: vec![], aad: vec![], group_state: MlsGroupState::PendingCommit(Box::new(PendingCommitState::External( @@ -280,7 +288,6 @@ impl StagedWelcome { let mls_group = MlsGroup { mls_group_config: self.mls_group_config, group, - proposal_store: ProposalStore::new(), own_leaf_nodes: vec![], aad: vec![], group_state: MlsGroupState::Operational, diff --git a/openmls/src/group/mls_group/errors.rs b/openmls/src/group/mls_group/errors.rs index 888f57b2ae..3a8986ce8c 100644 --- a/openmls/src/group/mls_group/errors.rs +++ b/openmls/src/group/mls_group/errors.rs @@ -18,7 +18,10 @@ use crate::{ CreateGroupContextExtProposalError, }, schedule::errors::PskError, - treesync::errors::{LeafNodeValidationError, PublicTreeError}, + treesync::{ + errors::{LeafNodeValidationError, PublicTreeError}, + node::leaf_node::LeafNodeUpdateError, + }, }; /// New group error @@ -57,7 +60,7 @@ pub enum EmptyInputError { /// Group state error #[derive(Error, Debug, PartialEq, Clone)] -pub enum MlsGroupStateError { +pub enum MlsGroupStateError { /// See [`LibraryError`] for more details. #[error(transparent)] LibraryError(#[from] LibraryError), @@ -76,9 +79,6 @@ pub enum MlsGroupStateError { /// Requested pending proposal hasn't been found in local pending proposals #[error("Requested pending proposal hasn't been found in local pending proposals.")] PendingProposalNotFound, - /// An error ocurred while writing to storage - #[error("An error ocurred while writing to storage")] - StorageError(StorageError), } /// Error merging pending commit @@ -86,7 +86,7 @@ pub enum MlsGroupStateError { pub enum MergePendingCommitError { /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - MlsGroupStateError(#[from] MlsGroupStateError), + MlsGroupStateError(#[from] MlsGroupStateError), /// See [`MergeCommitError`] for more details. #[error(transparent)] MergeCommitError(#[from] MergeCommitError), @@ -94,7 +94,7 @@ pub enum MergePendingCommitError { /// Process message error #[derive(Error, Debug, PartialEq, Clone)] -pub enum ProcessMessageError { +pub enum ProcessMessageError { /// See [`LibraryError`] for more details. #[error(transparent)] LibraryError(#[from] LibraryError), @@ -106,10 +106,7 @@ pub enum ProcessMessageError { ValidationError(#[from] ValidationError), /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - GroupStateError(#[from] MlsGroupStateError), - /// The message's signature is invalid. - #[error("The message's signature is invalid.")] - InvalidSignature, + GroupStateError(#[from] MlsGroupStateError), /// See [`StageCommitError`] for more details. #[error(transparent)] InvalidCommit(#[from] StageCommitError), @@ -123,13 +120,13 @@ pub enum ProcessMessageError { /// Create message error #[derive(Error, Debug, PartialEq, Clone)] -pub enum CreateMessageError { +pub enum CreateMessageError { /// See [`LibraryError`] for more details. #[error(transparent)] LibraryError(#[from] LibraryError), /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - GroupStateError(#[from] MlsGroupStateError), + GroupStateError(#[from] MlsGroupStateError), } /// Add members error @@ -146,7 +143,7 @@ pub enum AddMembersError { CreateCommitError(#[from] CreateCommitError), /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - GroupStateError(#[from] MlsGroupStateError), + GroupStateError(#[from] MlsGroupStateError), /// Error writing to storage. #[error("Error writing to storage")] StorageError(StorageError), @@ -163,7 +160,7 @@ pub enum ProposeAddMemberError { UnsupportedExtensions, /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - GroupStateError(#[from] MlsGroupStateError), + GroupStateError(#[from] MlsGroupStateError), /// See [`LeafNodeValidationError`] for more details. #[error(transparent)] LeafNodeValidation(#[from] LeafNodeValidationError), @@ -180,7 +177,7 @@ pub enum ProposeRemoveMemberError { LibraryError(#[from] LibraryError), /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - GroupStateError(#[from] MlsGroupStateError), + GroupStateError(#[from] MlsGroupStateError), /// The member that should be removed can not be found. #[error("The member that should be removed can not be found.")] UnknownMember, @@ -203,7 +200,7 @@ pub enum RemoveMembersError { CreateCommitError(#[from] CreateCommitError), /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - GroupStateError(#[from] MlsGroupStateError), + GroupStateError(#[from] MlsGroupStateError), /// The member that should be removed can not be found. #[error("The member that should be removed can not be found.")] UnknownMember, @@ -240,7 +237,10 @@ pub enum LeaveGroupError { LibraryError(#[from] LibraryError), /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - GroupStateError(#[from] MlsGroupStateError), + GroupStateError(#[from] MlsGroupStateError), + /// An error ocurred while writing to storage + #[error("An error ocurred while writing to storage")] + StorageError(StorageError), } /// Self update error @@ -254,7 +254,7 @@ pub enum SelfUpdateError { CreateCommitError(#[from] CreateCommitError), /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - GroupStateError(#[from] MlsGroupStateError), + GroupStateError(#[from] MlsGroupStateError), /// Error accessing the storage. #[error("Error accessing the storage.")] StorageError(StorageError), @@ -269,13 +269,16 @@ pub enum ProposeSelfUpdateError { /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - GroupStateError(#[from] MlsGroupStateError), + GroupStateError(#[from] MlsGroupStateError), /// Error accessing storage. #[error("Error accessing storage.")] StorageError(StorageError), /// See [`PublicTreeError`] for more details. #[error(transparent)] PublicTreeError(#[from] PublicTreeError), + /// See [`LeafNodeUpdateError`] for more details. + #[error(transparent)] + LeafNodeUpdateError(#[from] LeafNodeUpdateError), } /// Commit to pending proposals error @@ -289,7 +292,7 @@ pub enum CommitToPendingProposalsError { CreateCommitError(#[from] CreateCommitError), /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - GroupStateError(#[from] MlsGroupStateError), + GroupStateError(#[from] MlsGroupStateError), /// Error writing to storage #[error("Error writing to storage: {0}")] StorageError(StorageError), @@ -297,18 +300,18 @@ pub enum CommitToPendingProposalsError { /// Errors that can happen when exporting a group info object. #[derive(Error, Debug, PartialEq, Clone)] -pub enum ExportGroupInfoError { +pub enum ExportGroupInfoError { /// See [`LibraryError`] for more details. #[error(transparent)] LibraryError(#[from] LibraryError), /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - GroupStateError(#[from] MlsGroupStateError), + GroupStateError(#[from] MlsGroupStateError), } /// Export secret error #[derive(Error, Debug, PartialEq, Clone)] -pub enum ExportSecretError { +pub enum ExportSecretError { /// See [`LibraryError`] for more details. #[error(transparent)] LibraryError(#[from] LibraryError), @@ -317,24 +320,24 @@ pub enum ExportSecretError { KeyLengthTooLong, /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - GroupStateError(#[from] MlsGroupStateError), + GroupStateError(#[from] MlsGroupStateError), } /// Propose PSK error #[derive(Error, Debug, PartialEq, Clone)] -pub enum ProposePskError { +pub enum ProposePskError { /// See [`PskError`] for more details. #[error(transparent)] Psk(#[from] PskError), /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - GroupStateError(#[from] MlsGroupStateError), + GroupStateError(#[from] MlsGroupStateError), /// See [`LibraryError`] for more details. #[error(transparent)] LibraryError(#[from] LibraryError), } -/// Export secret error +/// Proposal error #[derive(Error, Debug, PartialEq, Clone)] pub enum ProposalError { /// See [`LibraryError`] for more details. @@ -354,7 +357,7 @@ pub enum ProposalError { ProposeRemoveMemberError(#[from] ProposeRemoveMemberError), /// See [`MlsGroupStateError`] for more details. #[error(transparent)] - GroupStateError(#[from] MlsGroupStateError), + GroupStateError(#[from] MlsGroupStateError), /// See [`ValidationError`] for more details. #[error(transparent)] ValidationError(#[from] ValidationError), @@ -365,3 +368,14 @@ pub enum ProposalError { #[error("error writing proposal to storage")] StorageError(StorageError), } + +/// Remove proposal error +#[derive(Error, Debug, PartialEq, Clone)] +pub enum RemoveProposalError { + /// Couldn't find the proposal for the given `ProposalRef`. + #[error("Couldn't find the proposal for the given `ProposalRef`")] + ProposalNotFound, + /// Error erasing proposal from storage. + #[error("error writing proposal to storage")] + Storage(StorageError), +} diff --git a/openmls/src/group/mls_group/exporting.rs b/openmls/src/group/mls_group/exporting.rs index 36da09ea8d..09fa39effd 100644 --- a/openmls/src/group/mls_group/exporting.rs +++ b/openmls/src/group/mls_group/exporting.rs @@ -18,7 +18,7 @@ impl MlsGroup { label: &str, context: &[u8], key_length: usize, - ) -> Result, ExportSecretError> { + ) -> Result, ExportSecretError> { let crypto = provider.crypto(); if self.is_active() { @@ -58,7 +58,7 @@ impl MlsGroup { provider: &Provider, signer: &impl Signer, with_ratchet_tree: bool, - ) -> Result> { + ) -> Result { Ok(self .group .export_group_info(provider.crypto(), signer, with_ratchet_tree)? diff --git a/openmls/src/group/mls_group/membership.rs b/openmls/src/group/mls_group/membership.rs index c1bf84b180..efa0ae0598 100644 --- a/openmls/src/group/mls_group/membership.rs +++ b/openmls/src/group/mls_group/membership.rs @@ -90,7 +90,9 @@ impl MlsGroup { /// New members are added by providing a `KeyPackage` for each member. /// /// This operation results in a Commit with a `path`, i.e. it includes an - /// update of the committer's leaf [KeyPackage]. + /// update of the committer's leaf [KeyPackage]. To add members without + /// forcing an update of the committer's leaf [KeyPackage], use + /// [`Self::add_members_without_update()`]. /// /// If successful, it returns a triple of [`MlsMessageOut`]s, where the first /// contains the commit, the second one the [`Welcome`] and the third an optional [GroupInfo] that @@ -109,6 +111,53 @@ impl MlsGroup { ) -> Result< (MlsMessageOut, MlsMessageOut, Option), AddMembersError, + > { + self.add_members_internal(provider, signer, key_packages, true) + } + + /// Adds members to the group. + /// + /// New members are added by providing a `KeyPackage` for each member. + /// + /// This operation results in a Commit that does not necessarily include a + /// `path`, i.e. an update of the committer's leaf [KeyPackage]. In + /// particular, it will only include a path if the group's proposal store + /// includes one or more proposals that require a path (see [Section 17.4 of + /// RFC 9420](https://www.rfc-editor.org/rfc/rfc9420.html#section-17.4) for + /// a list of proposals and whether they require a path). + /// + /// If successful, it returns a triple of [`MlsMessageOut`]s, where the + /// first contains the commit, the second one the [`Welcome`] and the third + /// an optional [GroupInfo] that will be [Some] if the group has the + /// `use_ratchet_tree_extension` flag set. + /// + /// Returns an error if there is a pending commit. + /// + /// [`Welcome`]: crate::messages::Welcome + // FIXME: #1217 + #[allow(clippy::type_complexity)] + pub fn add_members_without_update( + &mut self, + provider: &Provider, + signer: &impl Signer, + key_packages: &[KeyPackage], + ) -> Result< + (MlsMessageOut, MlsMessageOut, Option), + AddMembersError, + > { + self.add_members_internal(provider, signer, key_packages, false) + } + + #[allow(clippy::type_complexity)] + fn add_members_internal( + &mut self, + provider: &Provider, + signer: &impl Signer, + key_packages: &[KeyPackage], + force_self_update: bool, + ) -> Result< + (MlsMessageOut, MlsMessageOut, Option), + AddMembersError, > { self.is_operational()?; @@ -130,8 +179,8 @@ impl MlsGroup { // TODO #751 let params = CreateCommitParams::builder() .framing_parameters(self.framing_parameters()) - .proposal_store(&self.proposal_store) .inline_proposals(inline_proposals) + .force_self_update(force_self_update) .build(); let create_commit_result = self.group.create_commit(params, provider, signer)?; @@ -157,6 +206,7 @@ impl MlsGroup { .write_group_state(self.group_id(), &self.group_state) .map_err(AddMembersError::StorageError)?; + self.reset_aad(); Ok(( mls_messages, MlsMessageOut::from_welcome(welcome, self.group.version()), @@ -212,7 +262,6 @@ impl MlsGroup { // TODO #751 let params = CreateCommitParams::builder() .framing_parameters(self.framing_parameters()) - .proposal_store(&self.proposal_store) .inline_proposals(inline_proposals) .build(); let create_commit_result = self.group.create_commit(params, provider, signer)?; @@ -232,6 +281,7 @@ impl MlsGroup { .write_group_state(self.group_id(), &self.group_state) .map_err(RemoveMembersError::StorageError)?; + self.reset_aad(); Ok(( mls_message, create_commit_result @@ -260,13 +310,25 @@ impl MlsGroup { .create_remove_proposal(self.framing_parameters(), removed, signer) .map_err(|_| LibraryError::custom("Creating a self removal should not fail"))?; - self.proposal_store - .add(QueuedProposal::from_authenticated_content_by_ref( - self.ciphersuite(), - provider.crypto(), - remove_proposal.clone(), - )?); + let ciphersuite = self.ciphersuite(); + let queued_remove_proposal = QueuedProposal::from_authenticated_content_by_ref( + ciphersuite, + provider.crypto(), + remove_proposal.clone(), + )?; + + provider + .storage() + .queue_proposal( + self.group_id(), + &queued_remove_proposal.proposal_reference(), + &queued_remove_proposal, + ) + .map_err(LeaveGroupError::StorageError)?; + + self.proposal_store_mut().add(queued_remove_proposal); + self.reset_aad(); Ok(self.content_to_mls_message(remove_proposal, provider)?) } diff --git a/openmls/src/group/mls_group/mod.rs b/openmls/src/group/mls_group/mod.rs index 4c7360f5ab..1538f20211 100644 --- a/openmls/src/group/mls_group/mod.rs +++ b/openmls/src/group/mls_group/mod.rs @@ -1,6 +1,16 @@ //! MLS Group //! //! This module contains [`MlsGroup`] and its submodules. +//! + +#[cfg(any(feature = "test-utils", test))] +use crate::schedule::message_secrets::MessageSecrets; + +#[cfg(test)] +use openmls_traits::crypto::OpenMlsCrypto; + +#[cfg(test)] +use crate::prelude::SenderRatchetConfiguration; use super::proposals::{ProposalStore, QueuedProposal}; use crate::{ @@ -33,15 +43,15 @@ pub(crate) mod errors; pub(crate) mod membership; pub(crate) mod processing; pub(crate) mod proposal; -pub(crate) mod ser; // Tests #[cfg(test)] -mod test_mls_group; +pub(crate) mod tests_and_kats; /// Pending Commit state. Differentiates between Commits issued by group members /// and External Commits. #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone, PartialEq))] pub enum PendingCommitState { /// Commit from a group member Member(StagedCommit), @@ -73,47 +83,48 @@ impl From for StagedCommit { /// states and their transitions are as follows: /// /// * [`MlsGroupState::Operational`]: This is the main state of the group, which -/// allows access to all of its functionality, (except merging pending commits, -/// see the [`MlsGroupState::PendingCommit`] for more information) and it's the -/// state the group starts in (except when created via -/// [`MlsGroup::join_by_external_commit()`], see the functions documentation for -/// more information). From this `Operational`, the group state can either -/// transition to [`MlsGroupState::Inactive`], when it processes a commit that -/// removes this client from the group, or to [`MlsGroupState::PendingCommit`], -/// when this client creates a commit. +/// allows access to all of its functionality, (except merging pending commits, +/// see the [`MlsGroupState::PendingCommit`] for more information) and it's the +/// state the group starts in (except when created via +/// [`MlsGroup::join_by_external_commit()`], see the functions documentation for +/// more information). From this `Operational`, the group state can either +/// transition to [`MlsGroupState::Inactive`], when it processes a commit that +/// removes this client from the group, or to [`MlsGroupState::PendingCommit`], +/// when this client creates a commit. /// /// * [`MlsGroupState::Inactive`]: A group can enter this state from any other -/// state when it processes a commit that removes this client from the group. -/// This is a terminal state that the group can not exit from. If the clients -/// wants to re-join the group, it can either be added by a group member or it -/// can join via external commit. +/// state when it processes a commit that removes this client from the group. +/// This is a terminal state that the group can not exit from. If the clients +/// wants to re-join the group, it can either be added by a group member or it +/// can join via external commit. /// /// * [`MlsGroupState::PendingCommit`]: This state is split into two possible -/// sub-states, one for each Commit type: -/// [`PendingCommitState::Member`] and [`PendingCommitState::External`]: +/// sub-states, one for each Commit type: +/// [`PendingCommitState::Member`] and [`PendingCommitState::External`]: /// /// * If the client creates a commit for this group, the `PendingCommit` state -/// is entered with [`PendingCommitState::Member`] and with the [`StagedCommit`] as -/// additional state variable. In this state, it can perform the same -/// operations as in the [`MlsGroupState::Operational`], except that it cannot -/// create proposals or commits. However, it can merge or clear the stored -/// [`StagedCommit`], where both actions result in a transition to the -/// [`MlsGroupState::Operational`]. Additionally, if a commit from another -/// group member is processed, the own pending commit is also cleared and -/// either the `Inactive` state is entered (if this client was removed from -/// the group as part of the processed commit), or the `Operational` state is -/// entered. +/// is entered with [`PendingCommitState::Member`] and with the [`StagedCommit`] as +/// additional state variable. In this state, it can perform the same +/// operations as in the [`MlsGroupState::Operational`], except that it cannot +/// create proposals or commits. However, it can merge or clear the stored +/// [`StagedCommit`], where both actions result in a transition to the +/// [`MlsGroupState::Operational`]. Additionally, if a commit from another +/// group member is processed, the own pending commit is also cleared and +/// either the `Inactive` state is entered (if this client was removed from +/// the group as part of the processed commit), or the `Operational` state is +/// entered. /// /// * A group can enter the [`PendingCommitState::External`] sub-state only as -/// the initial state when the group is created via -/// [`MlsGroup::join_by_external_commit()`]. In contrast to the -/// [`PendingCommitState::Member`] `PendingCommit` state, the only possible -/// functionality that can be used is the [`MlsGroup::merge_pending_commit()`] -/// function, which merges the pending external commit and transitions the -/// state to [`MlsGroupState::PendingCommit`]. For more information on the -/// external commit process, see [`MlsGroup::join_by_external_commit()`] or -/// Section 11.2.1 of the MLS specification. +/// the initial state when the group is created via +/// [`MlsGroup::join_by_external_commit()`]. In contrast to the +/// [`PendingCommitState::Member`] `PendingCommit` state, the only possible +/// functionality that can be used is the [`MlsGroup::merge_pending_commit()`] +/// function, which merges the pending external commit and transitions the +/// state to [`MlsGroupState::PendingCommit`]. For more information on the +/// external commit process, see [`MlsGroup::join_by_external_commit()`] or +/// Section 11.2.1 of the MLS specification. #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone, PartialEq))] pub enum MlsGroupState { /// There is currently a pending Commit that hasn't been merged yet. PendingCommit(Box), @@ -148,21 +159,20 @@ pub enum MlsGroupState { /// inactive, as well as if it has a pending commit. See [`MlsGroupState`] for /// more information. #[derive(Debug)] +#[cfg_attr(feature = "test-utils", derive(Clone, PartialEq))] pub struct MlsGroup { // The group configuration. See [`MlsGroupJoinConfig`] for more information. mls_group_config: MlsGroupJoinConfig, // the internal `CoreGroup` used for lower level operations. See `CoreGroup` for more // information. group: CoreGroup, - // A [ProposalStore] that stores incoming proposals from the DS within one epoch. - // The store is emptied after every epoch change. - pub(crate) proposal_store: ProposalStore, // Own [`LeafNode`]s that were created for update proposals and that // are needed in case an update proposal is committed by another group // member. The vector is emptied after every epoch change. own_leaf_nodes: Vec, - // The AAD that is used for all outgoing handshake messages. The AAD can be set through - // `set_aad()`. + // Additional authenticated data (AAD) for the next outgoing message. This + // is ephemeral and will be reset by every API call that successfully + // returns an [`MlsMessageOut`]. aad: Vec, // A variable that indicates the state of the group. See [`MlsGroupState`] // for more information. @@ -187,19 +197,17 @@ impl MlsGroup { storage.write_mls_join_config(self.group_id(), mls_group_config) } - /// Returns the AAD used in the framing. - pub fn aad(&self) -> &[u8] { - &self.aad + /// Sets the additional authenticated data (AAD) for the next outgoing + /// message. This is ephemeral and will be reset by every API call that + /// successfully returns an [`MlsMessageOut`]. + pub fn set_aad(&mut self, aad: Vec) { + self.aad = aad; } - /// Sets the AAD used in the framing. - pub fn set_aad( - &mut self, - storage: &Storage, - aad: &[u8], - ) -> Result<(), Storage::Error> { - self.aad = aad.to_vec(); - storage.write_aad(self.group_id(), aad) + /// Returns the additional authenticated data (AAD) for the next outgoing + /// message. + pub fn aad(&self) -> &[u8] { + &self.aad } // === Advanced functions === @@ -217,9 +225,7 @@ impl MlsGroup { /// Returns own credential. If the group is inactive, it returns a /// `UseAfterEviction` error. - pub fn credential( - &self, - ) -> Result<&Credential, MlsGroupStateError> { + pub fn credential(&self) -> Result<&Credential, MlsGroupStateError> { if !self.is_active() { return Err(MlsGroupStateError::UseAfterEviction); } @@ -252,7 +258,7 @@ impl MlsGroup { /// Returns an `Iterator` over pending proposals. pub fn pending_proposals(&self) -> impl Iterator { - self.proposal_store.proposals() + self.proposal_store().proposals() } /// Returns a reference to the [`StagedCommit`] of the most recently created @@ -307,9 +313,9 @@ impl MlsGroup { storage: &Storage, ) -> Result<(), Storage::Error> { // If the proposal store is not empty... - if !self.proposal_store.is_empty() { + if !self.proposal_store().is_empty() { // Empty the proposal store - self.proposal_store.empty(); + self.proposal_store_mut().empty(); // Clear proposals in storage storage.clear_proposal_queue::(self.group_id())?; @@ -339,22 +345,21 @@ impl MlsGroup { group_id: &GroupId, ) -> Result, Storage::Error> { let group_config = storage.mls_group_join_config(group_id)?; - let core_group = CoreGroup::load(storage, group_id)?; - let proposals: Vec<(ProposalRef, QueuedProposal)> = storage.queued_proposals(group_id)?; + let core_group = CoreGroup::load( + storage, + group_id, + group_config + .as_ref() + .map(|config: &MlsGroupJoinConfig| config.use_ratchet_tree_extension), + )?; let own_leaf_nodes = storage.own_leaf_nodes(group_id)?; - let aad = storage.aad(group_id)?; + let aad = Vec::new(); let group_state = storage.group_state(group_id)?; - let mut proposal_store = ProposalStore::new(); - - for (_ref, proposal) in proposals { - proposal_store.add(proposal); - } let build = || -> Option { Some(Self { mls_group_config: group_config?, group: core_group?, - proposal_store, own_leaf_nodes, aad, group_state: group_state?, @@ -364,17 +369,25 @@ impl MlsGroup { Ok(build()) } - /// Remove the persisted state from storage - pub fn delete( + /// Remove the persisted state of this group from storage. Note that + /// signature key material is not managed by OpenMLS and has to be removed + /// from the storage provider separately (if desired). + pub fn delete( &mut self, - storage: &StorageProvider, - ) -> Result<(), StorageProvider::Error> { + storage: &Storage, + ) -> Result<(), Storage::Error> { self.group.delete(storage)?; storage.delete_group_config(self.group_id())?; storage.clear_proposal_queue::(self.group_id())?; storage.delete_own_leaf_nodes(self.group_id())?; - storage.delete_aad(self.group_id())?; storage.delete_group_state(self.group_id())?; + storage.delete_encryption_epoch_key_pairs( + self.group_id(), + &self.epoch(), + self.own_leaf_index().u32(), + )?; + + self.proposal_store_mut().empty(); Ok(()) } @@ -437,13 +450,29 @@ impl MlsGroup { /// Check if the group is operational. Throws an error if the group is /// inactive or if there is a pending commit. - fn is_operational(&self) -> Result<(), MlsGroupStateError> { + fn is_operational(&self) -> Result<(), MlsGroupStateError> { match self.group_state { MlsGroupState::PendingCommit(_) => Err(MlsGroupStateError::PendingCommit), MlsGroupState::Inactive => Err(MlsGroupStateError::UseAfterEviction), MlsGroupState::Operational => Ok(()), } } + + /// Returns a reference to the proposal store. + pub(crate) fn proposal_store(&self) -> &ProposalStore { + self.group.proposal_store() + } + + /// Returns a mutable reference to the proposal store. + pub(crate) fn proposal_store_mut(&mut self) -> &mut ProposalStore { + self.group.proposal_store_mut() + } + + /// Resets the AAD. + #[inline] + pub(crate) fn reset_aad(&mut self) { + self.aad.clear(); + } } // Methods used in tests @@ -458,29 +487,59 @@ impl MlsGroup { self.group.public_group().group_context().tree_hash() } + #[cfg(any(feature = "test-utils", test))] + pub(crate) fn message_secrets_test_mut(&mut self) -> &mut MessageSecrets { + self.group.message_secrets_test_mut() + } + #[cfg(any(feature = "test-utils", test))] pub fn print_ratchet_tree(&self, message: &str) { self.group.print_ratchet_tree(message) } - /// Returns the underlying [CoreGroup]. + #[cfg(any(feature = "test-utils", test))] + pub(crate) fn context_mut(&mut self) -> &mut GroupContext { + self.group.context_mut() + } + + // Encrypt an AuthenticatedContent into a PrivateMessage. Only needed for + // the message protection KAT. #[cfg(test)] - pub(crate) fn group(&self) -> &CoreGroup { - &self.group + pub(crate) fn encrypt( + &mut self, + public_message: AuthenticatedContent, + padding_size: usize, + provider: &Provider, + ) -> Result> { + self.group.encrypt(public_message, padding_size, provider) } - /// Removes a specific proposal from the store. - pub fn remove_pending_proposal( + #[cfg(test)] + // Decrypt a ProtocolMessage. Only needed for the message protection KAT. + pub(crate) fn decrypt_message( &mut self, - storage: &Storage, - proposal_ref: ProposalRef, - ) -> Result<(), MlsGroupStateError> { - storage - .remove_proposal(self.group_id(), &proposal_ref) - .map_err(MlsGroupStateError::StorageError)?; - self.proposal_store - .remove(proposal_ref) - .ok_or(MlsGroupStateError::PendingProposalNotFound) + crypto: &impl OpenMlsCrypto, + message: ProtocolMessage, + sender_ratchet_configuration: &SenderRatchetConfiguration, + ) -> Result { + self.group + .decrypt_message(crypto, message, sender_ratchet_configuration) + } + + #[cfg(test)] + pub(crate) fn set_group_context(&mut self, group_context: GroupContext) { + self.group.set_group_context(group_context) + } + + #[cfg(test)] + pub(crate) fn set_own_leaf_index(&mut self, own_leaf_index: LeafNodeIndex) { + self.group.set_own_leaf_index(own_leaf_index) + } + + /// Returns the underlying [CoreGroup]. + #[cfg(test)] + pub(crate) fn group(&self) -> &CoreGroup { + &self.group } } diff --git a/openmls/src/group/mls_group/processing.rs b/openmls/src/group/mls_group/processing.rs index ba78d64bc7..1a22eb683a 100644 --- a/openmls/src/group/mls_group/processing.rs +++ b/openmls/src/group/mls_group/processing.rs @@ -28,7 +28,7 @@ impl MlsGroup { &mut self, provider: &Provider, message: impl Into, - ) -> Result> { + ) -> Result { // Make sure we are still a member of the group if !self.is_active() { return Err(ProcessMessageError::GroupStateError( @@ -56,7 +56,6 @@ impl MlsGroup { provider, message, &sender_ratchet_configuration, - &self.proposal_store, &self.own_leaf_nodes, ) } @@ -69,7 +68,7 @@ impl MlsGroup { ) -> Result<(), Storage::Error> { storage.queue_proposal(self.group_id(), &proposal.proposal_reference(), &proposal)?; // Store the proposal in in the internal ProposalStore - self.proposal_store.add(proposal); + self.proposal_store_mut().add(proposal); Ok(()) } @@ -99,7 +98,6 @@ impl MlsGroup { // TODO #751 let params = CreateCommitParams::builder() .framing_parameters(self.framing_parameters()) - .proposal_store(&self.proposal_store) .build(); let create_commit_result = self.group.create_commit(params, provider, signer)?; @@ -117,6 +115,7 @@ impl MlsGroup { .write_group_state(self.group_id(), &self.group_state) .map_err(CommitToPendingProposalsError::StorageError)?; + self.reset_aad(); Ok(( mls_message, create_commit_result @@ -143,14 +142,17 @@ impl MlsGroup { .map_err(MergeCommitError::StorageError)?; // Merge staged commit - self.group - .merge_staged_commit(provider, staged_commit, &mut self.proposal_store)?; + self.group.merge_staged_commit(provider, staged_commit)?; // Extract and store the resumption psk for the current epoch let resumption_psk = self.group.group_epoch_secrets().resumption_psk(); self.group .resumption_psk_store .add(self.group.context().epoch(), resumption_psk.clone()); + provider + .storage() + .write_resumption_psk_store(self.group_id(), &self.group.resumption_psk_store) + .map_err(MergeCommitError::StorageError)?; // Delete own KeyPackageBundles self.own_leaf_nodes.clear(); diff --git a/openmls/src/group/mls_group/proposal.rs b/openmls/src/group/mls_group/proposal.rs index 46cd8ee643..bf1fdb3de6 100644 --- a/openmls/src/group/mls_group/proposal.rs +++ b/openmls/src/group/mls_group/proposal.rs @@ -1,10 +1,10 @@ -use openmls_traits::{signatures::Signer, storage::StorageProvider, types::Ciphersuite}; +use openmls_traits::{signatures::Signer, storage::StorageProvider as _, types::Ciphersuite}; use super::{ core_group::create_commit_params::CreateCommitParams, errors::{ProposalError, ProposeAddMemberError, ProposeRemoveMemberError}, CreateGroupContextExtProposalError, CustomProposal, GroupContextExtensionProposal, MlsGroup, - MlsGroupState, PendingCommitState, Proposal, + MlsGroupState, PendingCommitState, Proposal, RemoveProposalError, }; use crate::{ binary_tree::LeafNodeIndex, @@ -17,8 +17,8 @@ use crate::{ messages::{group_info::GroupInfo, proposals::ProposalOrRefType}, prelude::LibraryError, schedule::PreSharedKeyId, - storage::OpenMlsProvider, - treesync::LeafNode, + storage::{OpenMlsProvider, StorageProvider}, + treesync::LeafNodeParameters, versions::ProtocolVersion, }; @@ -29,7 +29,7 @@ pub enum Propose { Add(KeyPackage), /// An update proposal requires a new leaf node. - Update(Option), + Update(LeafNodeParameters), /// A remove proposal consists of the leaf index of the leaf to be removed. Remove(u32), @@ -89,10 +89,11 @@ macro_rules! impl_propose_fun { .storage() .queue_proposal(self.group.group_id(), &proposal_ref, &queued_proposal) .map_err(ProposalError::StorageError)?; - self.proposal_store.add(queued_proposal); + self.proposal_store_mut().add(queued_proposal); let mls_message = self.content_to_mls_message(proposal, provider)?; + self.reset_aad(); Ok((mls_message, proposal_ref)) } }; @@ -159,12 +160,12 @@ impl MlsGroup { .map_err(|e| e.into()), }, - Propose::Update(leaf_node) => match ref_or_value { + Propose::Update(leaf_node_parameters) => match ref_or_value { ProposalOrRefType::Proposal => self - .propose_self_update_by_value(provider, signer, leaf_node) + .propose_self_update(provider, signer, leaf_node_parameters) .map_err(|e| e.into()), ProposalOrRefType::Reference => self - .propose_self_update(provider, signer, leaf_node) + .propose_self_update(provider, signer, leaf_node_parameters) .map_err(|e| e.into()), }, @@ -256,10 +257,11 @@ impl MlsGroup { .storage() .queue_proposal(self.group_id(), &proposal_ref, &proposal) .map_err(ProposeAddMemberError::StorageError)?; - self.proposal_store.add(proposal); + self.proposal_store_mut().add(proposal); let mls_message = self.content_to_mls_message(add_proposal, provider)?; + self.reset_aad(); Ok((mls_message, proposal_ref)) } @@ -291,10 +293,11 @@ impl MlsGroup { .storage() .queue_proposal(self.group_id(), &proposal_ref, &proposal) .map_err(ProposeRemoveMemberError::StorageError)?; - self.proposal_store.add(proposal); + self.proposal_store_mut().add(proposal); let mls_message = self.content_to_mls_message(remove_proposal, provider)?; + self.reset_aad(); Ok((mls_message, proposal_ref)) } @@ -380,10 +383,11 @@ impl MlsGroup { .storage() .queue_proposal(self.group_id(), &proposal_ref, &queued_proposal) .map_err(ProposalError::StorageError)?; - self.proposal_store.add(queued_proposal); + self.proposal_store_mut().add(queued_proposal); let mls_message = self.content_to_mls_message(proposal, provider)?; + self.reset_aad(); Ok((mls_message, proposal_ref)) } @@ -414,7 +418,6 @@ impl MlsGroup { // Create Commit over all proposals let params = CreateCommitParams::builder() .framing_parameters(self.framing_parameters()) - .proposal_store(&self.proposal_store) .inline_proposals(inline_proposals) .build(); let create_commit_result = self.group.create_commit(params, provider, signer)?; @@ -432,6 +435,7 @@ impl MlsGroup { .write_group_state(self.group_id(), &self.group_state) .map_err(CreateGroupContextExtProposalError::StorageError)?; + self.reset_aad(); Ok(( mls_messages, create_commit_result @@ -440,4 +444,18 @@ impl MlsGroup { create_commit_result.group_info, )) } + + /// Removes a specific proposal from the store. + pub fn remove_pending_proposal( + &mut self, + storage: &Storage, + proposal_ref: &ProposalRef, + ) -> Result<(), RemoveProposalError> { + storage + .remove_proposal(self.group_id(), proposal_ref) + .map_err(RemoveProposalError::Storage)?; + self.proposal_store_mut() + .remove(proposal_ref) + .ok_or(RemoveProposalError::ProposalNotFound) + } } diff --git a/openmls/src/group/mls_group/ser.rs b/openmls/src/group/mls_group/ser.rs deleted file mode 100644 index 4449b3a0bb..0000000000 --- a/openmls/src/group/mls_group/ser.rs +++ /dev/null @@ -1,67 +0,0 @@ -// TODO #245: Remove this once we have a proper serialization format -#![allow(deprecated)] - -use super::*; -use crate::schedule::psk::store::ResumptionPskStore; - -use serde::{ - ser::{SerializeStruct, Serializer}, - Deserialize, Serialize, -}; - -/// Helper struct that contains the serializable values of an `MlsGroup. -#[deprecated( - since = "0.4.1", - note = "It is temporarily exposed, it will be private again after #245" -)] -#[derive(Serialize, Deserialize)] -pub struct SerializedMlsGroup { - mls_group_config: MlsGroupJoinConfig, - group: CoreGroup, - proposal_store: ProposalStore, - own_leaf_nodes: Vec, - aad: Vec, - resumption_psk_store: ResumptionPskStore, - group_state: MlsGroupState, -} - -#[allow(clippy::from_over_into)] -impl Into for SerializedMlsGroup { - fn into(self) -> MlsGroup { - MlsGroup { - mls_group_config: self.mls_group_config, - group: self.group, - proposal_store: self.proposal_store, - own_leaf_nodes: self.own_leaf_nodes, - aad: self.aad, - group_state: self.group_state, - } - } -} - -impl Serialize for MlsGroup { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let mut state = serializer.serialize_struct("SerializedMlsGroup", 6)?; - state.serialize_field("mls_group_config", &self.mls_group_config)?; - state.serialize_field("group", &self.group)?; - state.serialize_field("proposal_store", &self.proposal_store)?; - state.serialize_field("own_leaf_nodes", &self.own_leaf_nodes)?; - state.serialize_field("aad", &self.aad)?; - state.serialize_field("resumption_psk_store", &self.group.resumption_psk_store)?; - state.serialize_field("group_state", &self.group_state)?; - state.end() - } -} - -impl<'de> Deserialize<'de> for MlsGroup { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let sgroup = SerializedMlsGroup::deserialize(deserializer)?; - Ok(sgroup.into()) - } -} diff --git a/openmls/src/group/mls_group/tests_and_kats/kats/mod.rs b/openmls/src/group/mls_group/tests_and_kats/kats/mod.rs new file mode 100644 index 0000000000..813d47fe3d --- /dev/null +++ b/openmls/src/group/mls_group/tests_and_kats/kats/mod.rs @@ -0,0 +1,2 @@ +mod passive_client; +mod welcome; diff --git a/openmls/src/group/core_group/kat_passive_client.rs b/openmls/src/group/mls_group/tests_and_kats/kats/passive_client.rs similarity index 97% rename from openmls/src/group/core_group/kat_passive_client.rs rename to openmls/src/group/mls_group/tests_and_kats/kats/passive_client.rs index 37566545ec..1184739ee9 100644 --- a/openmls/src/group/core_group/kat_passive_client.rs +++ b/openmls/src/group/mls_group/tests_and_kats/kats/passive_client.rs @@ -5,8 +5,12 @@ use tls_codec::{Deserialize as TlsDeserialize, Serialize as TlsSerialize}; use crate::{ framing::{MlsMessageBodyIn, MlsMessageIn, MlsMessageOut, ProcessedMessageContent}, - group::*, + group::{ + HpkePrivateKey, IncomingWireFormatPolicy, Member, MlsGroup, MlsGroupCreateConfig, + MlsGroupJoinConfig, OutgoingWireFormatPolicy, StagedWelcome, WireFormatPolicy, + }, key_packages::*, + prelude::LeafNodeParameters, schedule::psk::PreSharedKeyId, test_utils::*, treesync::{ @@ -559,7 +563,11 @@ fn update_inline( group: &mut MlsGroup, ) -> TestEpoch { let (mls_message_out_commit, _, _) = group - .self_update(provider, &candidate.signature_keypair) + .self_update( + provider, + &candidate.signature_keypair, + LeafNodeParameters::default(), + ) .unwrap(); group.merge_pending_commit(provider).unwrap(); diff --git a/openmls/src/group/core_group/kat_welcome.rs b/openmls/src/group/mls_group/tests_and_kats/kats/welcome.rs similarity index 95% rename from openmls/src/group/core_group/kat_welcome.rs rename to openmls/src/group/mls_group/tests_and_kats/kats/welcome.rs index 4ed16f194e..5691bbf1c2 100644 --- a/openmls/src/group/core_group/kat_welcome.rs +++ b/openmls/src/group/mls_group/tests_and_kats/kats/welcome.rs @@ -19,8 +19,7 @@ //! from the key schedule epoch and the `confirmed_transcript_hash` from the //! decrypted GroupContext -use crate::test_utils::OpenMlsRustCrypto; -use kat_welcome::core_group::node::encryption_keys::EncryptionPrivateKey; +use crate::{test_utils::OpenMlsRustCrypto, treesync::node::encryption_keys::EncryptionPrivateKey}; use openmls_traits::{crypto::OpenMlsCrypto, storage::StorageProvider, OpenMlsProvider}; use serde::{self, Deserialize, Serialize}; use tls_codec::{Deserialize as TlsDeserialize, Serialize as TlsSerialize}; @@ -29,7 +28,7 @@ use crate::{ binary_tree::{array_representation::TreeSize, LeafNodeIndex}, ciphersuite::signable::Verifiable, framing::{MlsMessageBodyIn, MlsMessageIn}, - group::*, + group::{GroupContext, HpkePrivateKey, OpenMlsSignaturePublicKey, SignaturePublicKey}, key_packages::*, messages::*, prelude::group_info::{GroupInfo, VerifiableGroupInfo}, @@ -177,14 +176,14 @@ pub fn run_test_vector(test_vector: WelcomeTestVector) -> Result<(), &'static st // Verification: // * Decrypt the Welcome message: // * Identify the entry in `welcome.secrets` corresponding to `key_package` - let encrypted_group_secrets = CoreGroup::find_key_package_from_welcome_secrets( - key_package_bundle - .key_package() - .hash_ref(provider.crypto()) - .unwrap(), - welcome.secrets(), - ) - .unwrap(); + let encrypted_group_secrets = welcome + .find_encrypted_group_secret( + key_package_bundle + .key_package() + .hash_ref(provider.crypto()) + .unwrap(), + ) + .unwrap(); println!("{encrypted_group_secrets:?}"); // // // * Decrypt the encrypted group secrets using `init_priv` diff --git a/openmls/src/group/mls_group/tests_and_kats/mod.rs b/openmls/src/group/mls_group/tests_and_kats/mod.rs new file mode 100644 index 0000000000..acbbd9ff6c --- /dev/null +++ b/openmls/src/group/mls_group/tests_and_kats/mod.rs @@ -0,0 +1,3 @@ +mod kats; +mod tests; +pub(crate) mod utils; diff --git a/openmls/src/group/mls_group/tests_and_kats/tests/core_group.rs b/openmls/src/group/mls_group/tests_and_kats/tests/core_group.rs new file mode 100644 index 0000000000..4054536156 --- /dev/null +++ b/openmls/src/group/mls_group/tests_and_kats/tests/core_group.rs @@ -0,0 +1,737 @@ +use core::panic; + +use frankenstein::{FrankenFramedContentBody, FrankenPublicMessage}; +use mls_group::tests_and_kats::utils::{ + flip_last_byte, setup_alice_bob, setup_alice_bob_group, setup_client, +}; +use tls_codec::Serialize; + +use crate::{ + binary_tree::*, + ciphersuite::{signable::Signable, AeadNonce}, + credentials::*, + framing::*, + group::{errors::*, *}, + key_packages::*, + messages::{group_info::GroupInfoTBS, *}, + prelude::LeafNodeParameters, + schedule::psk::{ExternalPsk, PreSharedKeyId, Psk}, + test_utils::*, + treesync::errors::ApplyUpdatePathError, +}; + +#[openmls_test::openmls_test] +fn failed_groupinfo_decryption( + ciphersuite: Ciphersuite, + provider: &impl crate::storage::OpenMlsProvider, +) { + let epoch = 123; + let group_id = GroupId::random(provider.rand()); + let tree_hash = vec![1, 2, 3, 4, 5, 6, 7, 8, 9]; + let confirmed_transcript_hash = vec![1, 1, 1]; + let extensions = Extensions::empty(); + let confirmation_tag = ConfirmationTag(Mac { + mac_value: vec![1, 2, 3, 4, 5, 6, 7, 8, 9].into(), + }); + + // Create credentials and keys + let (alice_credential_with_key, alice_signature_keys) = + test_utils::new_credential(provider, b"Alice", ciphersuite.signature_algorithm()); + + let key_package_bundle = KeyPackageBundle::generate( + provider, + &alice_signature_keys, + ciphersuite, + alice_credential_with_key, + ); + + let group_info_tbs = { + let group_context = GroupContext::new( + ciphersuite, + group_id, + epoch, + tree_hash, + confirmed_transcript_hash, + Extensions::empty(), + ); + + GroupInfoTBS::new( + group_context, + extensions, + confirmation_tag, + LeafNodeIndex::new(0), + ) + }; + + // Generate key and nonce for the symmetric cipher. + let welcome_key = AeadKey::random(ciphersuite, provider.rand()); + let welcome_nonce = AeadNonce::random(provider.rand()); + + // Generate receiver key pair. + let receiver_key_pair = provider + .crypto() + .derive_hpke_keypair( + ciphersuite.hpke_config(), + Secret::random(ciphersuite, provider.rand()) + .expect("Not enough randomness.") + .as_slice(), + ) + .expect("error deriving receiver hpke key pair"); + let hpke_context = b"group info welcome test info"; + let group_secrets = b"these should be the group secrets"; + let mut encrypted_group_secrets = hpke::encrypt_with_label( + receiver_key_pair.public.as_slice(), + "Welcome", + hpke_context, + group_secrets, + ciphersuite, + provider.crypto(), + ) + .unwrap(); + + let group_info = group_info_tbs + .sign(&alice_signature_keys) + .expect("Error signing group info"); + + // Mess with the ciphertext by flipping the last byte. + flip_last_byte(&mut encrypted_group_secrets); + + let broken_secrets = vec![EncryptedGroupSecrets::new( + key_package_bundle + .key_package + .hash_ref(provider.crypto()) + .expect("Could not hash KeyPackage."), + encrypted_group_secrets, + )]; + + // Encrypt the group info. + let encrypted_group_info = welcome_key + .aead_seal( + provider.crypto(), + &group_info + .tls_serialize_detached() + .expect("An unexpected error occurred."), + &[], + &welcome_nonce, + ) + .expect("An unexpected error occurred."); + + // Now build the welcome message. + let broken_welcome = Welcome::new(ciphersuite, broken_secrets, encrypted_group_info); + + let error = StagedWelcome::new_from_welcome( + provider, + &MlsGroupJoinConfig::default(), + broken_welcome, + None, + ) + .and_then(|staged_join| staged_join.into_group(provider)) + .expect_err("Creation of mls group from a broken Welcome was successful."); + + assert!(matches!( + error, + WelcomeError::GroupSecrets(GroupSecretsError::DecryptionFailed) + )) +} + +/// Test what happens if the KEM ciphertext for the receiver in the UpdatePath +/// is broken. +#[openmls_test::openmls_test] +fn update_path() { + // === Alice creates a group with her and Bob === + let ( + mut group_alice, + _alice_signature_keys, + mut group_bob, + bob_signature_keys, + _bob_credential_with_key, + ) = setup_alice_bob_group(ciphersuite, provider); + + // === Bob updates and commits === + let mut bob_new_leaf_node = group_bob.own_leaf_node().unwrap().clone(); + bob_new_leaf_node + .update( + ciphersuite, + provider, + &bob_signature_keys, + group_bob.group_id().clone(), + group_bob.own_leaf_index(), + LeafNodeParameters::default(), + ) + .unwrap(); + + let (update_bob, _welcome_option, _group_info_option) = group_bob + .self_update(provider, &bob_signature_keys, LeafNodeParameters::default()) + .expect("Could not create proposal."); + + // Now we break Alice's HPKE ciphertext in Bob's commit by breaking + // apart the commit, manipulating the ciphertexts and the piecing it + // back together. + let pm = match update_bob.body { + mls_group::MlsMessageBodyOut::PublicMessage(pm) => pm, + _ => panic!("Wrong message type"), + }; + + let franken_pm = FrankenPublicMessage::from(pm.clone()); + let mut content = franken_pm.content.clone(); + let FrankenFramedContentBody::Commit(ref mut commit) = content.body else { + panic!("Unexpected content type"); + }; + let Some(ref mut path) = commit.path else { + panic!("No path in commit."); + }; + + for node in &mut path.nodes { + for eps in &mut node.encrypted_path_secrets { + let mut eps_ctxt_vec = Vec::::from(eps.ciphertext.clone()); + eps_ctxt_vec[0] ^= 0xff; + eps.ciphertext = eps_ctxt_vec.into(); + } + } + + // Rebuild the PublicMessage with the new content + let group_context = group_bob.export_group_context().clone(); + let membership_key = group_bob + .group() + .message_secrets() + .membership_key() + .as_slice(); + + let broken_message = FrankenPublicMessage::auth( + provider, + ciphersuite, + &bob_signature_keys, + content, + Some(&group_context.into()), + Some(membership_key), + Some(pm.confirmation_tag().unwrap().0.mac_value.clone()), + ); + + let protocol_message = + ProtocolMessage::PublicMessage(PublicMessage::from(broken_message).into()); + + let result = group_alice.process_message(provider, protocol_message); + assert_eq!( + result.expect_err("Successful processing of a broken commit."), + ProcessMessageError::InvalidCommit(StageCommitError::UpdatePathError( + ApplyUpdatePathError::UnableToDecrypt + )) + ); +} + +// Test several scenarios when PSKs are used in a group +#[openmls_test::openmls_test] +fn psks() { + // Basic group setup. + let ( + alice_credential_with_key, + alice_signature_keys, + bob_key_package_bundle, + bob_signature_keys, + ) = setup_alice_bob(ciphersuite, provider); + + // === Alice creates a group with a PSK === + let psk_id = vec![1u8, 2, 3]; + + let secret = Secret::random(ciphersuite, provider.rand()).expect("Not enough randomness."); + let external_psk = ExternalPsk::new(psk_id); + let preshared_key_id = + PreSharedKeyId::new(ciphersuite, provider.rand(), Psk::External(external_psk)) + .expect("An unexpected error occured."); + preshared_key_id.store(provider, secret.as_slice()).unwrap(); + let mut alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .with_wire_format_policy(PURE_PLAINTEXT_WIRE_FORMAT_POLICY) + .build(provider, &alice_signature_keys, alice_credential_with_key) + .expect("Error creating group."); + + // === Alice creates a PSK proposal === + log::info!(" >>> Creating psk proposal ..."); + let (_psk_proposal, _proposal_ref) = alice_group + .propose_external_psk(provider, &alice_signature_keys, preshared_key_id) + .expect("Could not create PSK proposal"); + + // === Alice adds Bob (and commits to PSK proposal) === + let (_commit, welcome, _group_info_option) = alice_group + .add_members( + provider, + &alice_signature_keys, + &[bob_key_package_bundle.key_package().clone()], + ) + .expect("Could not create commit"); + + log::info!(" >>> Merging commit ..."); + + alice_group + .merge_pending_commit(provider) + .expect("Could not merge commit"); + + let ratchet_tree = alice_group.export_ratchet_tree(); + + let mut bob_group = StagedWelcome::new_from_welcome( + provider, + &MlsGroupJoinConfig::default(), + welcome.into_welcome().unwrap(), + Some(ratchet_tree.into()), + ) + .expect("Could not stage welcome") + .into_group(provider) + .expect("Could not create group from welcome"); + + // === Bob updates and commits === + let (_commit, _welcome_option, _group_info_option) = bob_group + .self_update(provider, &bob_signature_keys, LeafNodeParameters::default()) + .expect("An unexpected error occurred."); +} + +// Test several scenarios when PSKs are used in a group +#[openmls_test::openmls_test] +fn staged_commit_creation( + ciphersuite: Ciphersuite, + provider: &impl crate::storage::OpenMlsProvider, +) { + // Basic group setup. + let (alice_credential_with_key, alice_signature_keys, bob_key_package_bundle, _) = + setup_alice_bob(ciphersuite, provider); + + // === Alice creates a group === + let mut alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .with_wire_format_policy(PURE_PLAINTEXT_WIRE_FORMAT_POLICY) + .build(provider, &alice_signature_keys, alice_credential_with_key) + .expect("Error creating group."); + + // === Alice adds Bob === + let (_commit, welcome, _group_info_option) = alice_group + .add_members( + provider, + &alice_signature_keys, + &[bob_key_package_bundle.key_package().clone()], + ) + .expect("Could not create commit"); + + alice_group + .merge_pending_commit(provider) + .expect("Could not merge commit"); + + let ratchet_tree = alice_group.export_ratchet_tree(); + + let bob_group = StagedWelcome::new_from_welcome( + provider, + &MlsGroupJoinConfig::default(), + welcome.into_welcome().unwrap(), + Some(ratchet_tree.into()), + ) + .expect("Could not stage welcome") + .into_group(provider) + .expect("Could not create group from welcome"); + + // Let's make sure we end up in the same group state. + assert_eq!( + bob_group.epoch_authenticator(), + alice_group.epoch_authenticator() + ); + assert_eq!( + bob_group.export_ratchet_tree(), + alice_group.export_ratchet_tree() + ) +} + +// Test processing of own commits +#[openmls_test::openmls_test] +fn own_commit_processing( + ciphersuite: Ciphersuite, + provider: &impl crate::storage::OpenMlsProvider, +) { + // Basic group setup. + let (alice_credential_with_key, alice_signature_keys) = + test_utils::new_credential(provider, b"Alice", ciphersuite.signature_algorithm()); + + // === Alice creates a group === + let mut alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .with_wire_format_policy(PURE_PLAINTEXT_WIRE_FORMAT_POLICY) + .build(provider, &alice_signature_keys, alice_credential_with_key) + .expect("Error creating group."); + + // Alice creates a commit + let (commit_out, _welcome_option, _group_info_option) = alice_group + .self_update( + provider, + &alice_signature_keys, + LeafNodeParameters::default(), + ) + .expect("Could not create commit"); + + let commit_in = MlsMessageIn::from(commit_out); + + // Alice attempts to process her own commit + let error = alice_group + .process_message(provider, commit_in.into_protocol_message().unwrap()) + .expect_err("no error while processing own commit"); + assert_eq!( + error, + ProcessMessageError::InvalidCommit(StageCommitError::OwnCommit) + ); +} + +#[openmls_test::openmls_test] +fn proposal_application_after_self_was_removed( + ciphersuite: Ciphersuite, + provider: &impl crate::storage::OpenMlsProvider, +) { + // We're going to test if proposals are still applied, even after a client + // notices that it was removed from a group. We do so by having Alice + // create a group, add Bob and then create a commit where Bob is removed and + // Charlie is added in a single commit (by Alice). We then check if + // everyone's membership list is as expected. + + // Basic group setup. + let (alice_credential_with_key, _, alice_signature_keys, _pk) = + setup_client("Alice", ciphersuite, provider); + let (_, bob_kpb, _, _) = setup_client("Bob", ciphersuite, provider); + let (_, charlie_kpb, _, _) = setup_client("Charlie", ciphersuite, provider); + + let join_group_config = MlsGroupJoinConfig::builder() + .wire_format_policy(PURE_PLAINTEXT_WIRE_FORMAT_POLICY) + .build(); + + let mut alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .with_wire_format_policy(PURE_PLAINTEXT_WIRE_FORMAT_POLICY) + .build(provider, &alice_signature_keys, alice_credential_with_key) + .expect("Error creating group."); + + let (_commit, welcome, _group_info_option) = alice_group + .add_members( + provider, + &alice_signature_keys, + &[bob_kpb.key_package().clone()], + ) + .expect("Could not create commit"); + + alice_group + .merge_pending_commit(provider) + .expect("Could not merge commit"); + + let ratchet_tree = alice_group.export_ratchet_tree(); + + let mut bob_group = StagedWelcome::new_from_welcome( + provider, + &join_group_config, + welcome.into_welcome().unwrap(), + Some(ratchet_tree.into()), + ) + .expect("Could not stage welcome") + .into_group(provider) + .expect("Could not create group from welcome"); + + // Alice adds Charlie and removes Bob in the same commit. + // She first creates a proposal to remove Bob + let bob_index = alice_group + .members() + .find( + |Member { + index: _, + credential, + .. + }| { credential.serialized_content() == b"Bob" }, + ) + .expect("Couldn't find Bob in tree.") + .index; + + assert_eq!(bob_index.u32(), 1); + + let (bob_remove_proposal, _bob_remove_proposal_ref) = alice_group + .propose_remove_member(provider, &alice_signature_keys, bob_index) + .expect("Could not create proposal"); + + // Bob processes the proposal + let processed_message = bob_group + .process_message( + provider, + bob_remove_proposal.into_protocol_message().unwrap(), + ) + .unwrap(); + + let staged_proposal = match processed_message.into_content() { + ProcessedMessageContent::ProposalMessage(proposal) => *proposal, + _ => panic!("Wrong message type"), + }; + + bob_group + .store_pending_proposal(provider.storage(), staged_proposal) + .expect("Error storing proposal"); + + // Alice then commit to the proposal and at the same time adds Charlie + let (commit, welcome, _group_info_option) = alice_group + .add_members( + provider, + &alice_signature_keys, + &[charlie_kpb.key_package().clone()], + ) + .expect("Could not create commit"); + + // Alice merges her own commit + alice_group + .merge_pending_commit(provider) + .expect("Could not merge commit"); + + // Bob processes the commit + println!("Bob processes the commit"); + let processed_message = bob_group + .process_message(provider, commit.into_protocol_message().unwrap()) + .unwrap(); + + let staged_commit = match processed_message.into_content() { + ProcessedMessageContent::StagedCommitMessage(commit) => *commit, + _ => panic!("Wrong message type"), + }; + + bob_group + .merge_staged_commit(provider, staged_commit) + .expect("Error merging commit."); + + // Charlie processes the welcome + println!("Charlie processes the commit"); + let ratchet_tree = alice_group.export_ratchet_tree(); + + let charlie_group = StagedWelcome::new_from_welcome( + provider, + &join_group_config, + welcome.into_welcome().unwrap(), + Some(ratchet_tree.into()), + ) + .expect("Error staging welcome.") + .into_group(provider) + .expect("Error creating group from welcome."); + + // We can now check that Bob correctly processed his commit and applied the changes + // to his tree after he was removed by comparing membership lists. In + // particular, Bob's list should show that he was removed and Charlie was + // added. + let alice_members = alice_group.members(); + + let bob_members = bob_group.members(); + + let charlie_members = charlie_group.members(); + + for (alice_member, (bob_member, charlie_member)) in + alice_members.zip(bob_members.zip(charlie_members)) + { + // Note that we can't compare encryption keys for Bob because they + // didn't get updated. + assert_eq!(alice_member.index, bob_member.index); + + let alice_id = alice_member.credential.serialized_content(); + let bob_id = bob_member.credential.serialized_content(); + let charlie_id = charlie_member.credential.serialized_content(); + assert_eq!(alice_id, bob_id); + assert_eq!(alice_member.signature_key, bob_member.signature_key); + assert_eq!(charlie_member.index, bob_member.index); + assert_eq!(charlie_id, bob_id); + assert_eq!(charlie_member.signature_key, bob_member.signature_key); + assert_eq!(charlie_member.encryption_key, alice_member.encryption_key); + } + + let mut bob_members = bob_group.members(); + + let member = bob_members.next().unwrap(); + let bob_next_id = member.credential.serialized_content(); + assert_eq!(bob_next_id, b"Alice"); + let member = bob_members.next().unwrap(); + let bob_next_id = member.credential.serialized_content(); + assert_eq!(bob_next_id, b"Charlie"); +} + +#[openmls_test::openmls_test] +fn proposal_application_after_self_was_removed_ref( + ciphersuite: Ciphersuite, + provider: &impl crate::storage::OpenMlsProvider, +) { + // We're going to test if proposals are still applied, even after a client + // notices that it was removed from a group. We do so by having Alice + // create a group, add Bob and then create a commit where Bob is removed and + // Charlie is added in a single commit (by Alice). We then check if + // everyone's membership list is as expected. + + // Basic group setup. + let (alice_credential_with_key, _, alice_signature_keys, _pk) = + setup_client("Alice", ciphersuite, provider); + let (_, bob_kpb, _, _) = setup_client("Bob", ciphersuite, provider); + let (_, charlie_kpb, _, _) = setup_client("Charlie", ciphersuite, provider); + + let join_group_config = MlsGroupJoinConfig::builder() + .wire_format_policy(PURE_PLAINTEXT_WIRE_FORMAT_POLICY) + .build(); + + let mut alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .with_wire_format_policy(PURE_PLAINTEXT_WIRE_FORMAT_POLICY) + .build(provider, &alice_signature_keys, alice_credential_with_key) + .expect("Error creating group."); + + let (_commit, welcome, _group_info_option) = alice_group + .add_members( + provider, + &alice_signature_keys, + &[bob_kpb.key_package().clone()], + ) + .expect("Could not create commit"); + + alice_group + .merge_pending_commit(provider) + .expect("Could not merge commit"); + + let ratchet_tree = alice_group.export_ratchet_tree(); + + let mut bob_group = StagedWelcome::new_from_welcome( + provider, + &join_group_config, + welcome.into_welcome().unwrap(), + Some(ratchet_tree.into()), + ) + .expect("Could not stage welcome") + .into_group(provider) + .expect("Could not create group from welcome"); + + // Alice adds Charlie and removes Bob in the same commit. + // She first creates a proposal to remove Bob + let bob_index = alice_group + .members() + .find( + |Member { + index: _, + credential, + .. + }| { credential.serialized_content() == b"Bob" }, + ) + .expect("Couldn't find Bob in tree.") + .index; + + assert_eq!(bob_index.u32(), 1); + + let (bob_remove_proposal, _bob_remove_proposal_ref) = alice_group + .propose_remove_member(provider, &alice_signature_keys, bob_index) + .expect("Could not create proposal"); + + let (charlie_add_proposal, _charlie_add_proposal_ref) = alice_group + .propose_add_member(provider, &alice_signature_keys, charlie_kpb.key_package()) + .expect("Could not create proposal"); + + // Bob processes the proposals + let processed_message = bob_group + .process_message( + provider, + bob_remove_proposal.into_protocol_message().unwrap(), + ) + .unwrap(); + + let staged_proposal = match processed_message.into_content() { + ProcessedMessageContent::ProposalMessage(proposal) => *proposal, + _ => panic!("Wrong message type"), + }; + + bob_group + .store_pending_proposal(provider.storage(), staged_proposal) + .expect("Error storing proposal"); + + let processed_message = bob_group + .process_message( + provider, + charlie_add_proposal.into_protocol_message().unwrap(), + ) + .unwrap(); + + let staged_proposal = match processed_message.into_content() { + ProcessedMessageContent::ProposalMessage(proposal) => *proposal, + _ => panic!("Wrong message type"), + }; + + bob_group + .store_pending_proposal(provider.storage(), staged_proposal) + .expect("Error storing proposal"); + + // Alice then commits to the proposal and at the same time adds Charlie + alice_group.print_ratchet_tree("Alice's tree before commit\n"); + let alice_rt_before = alice_group.export_ratchet_tree(); + let (commit, welcome, _group_info_option) = alice_group + .commit_to_pending_proposals(provider, &alice_signature_keys) + .expect("Could not create commit"); + + // Alice merges her own commit + alice_group + .merge_pending_commit(provider) + .expect("Could not merge commit"); + alice_group.print_ratchet_tree("Alice's tree after commit\n"); + + // Bob processes the commit + println!("Bob processes the commit"); + bob_group.print_ratchet_tree("Bob's tree before processing the commit\n"); + let bob_rt_before = bob_group.export_ratchet_tree(); + assert_eq!(alice_rt_before, bob_rt_before); + let processed_message = bob_group + .process_message(provider, commit.into_protocol_message().unwrap()) + .unwrap(); + println!("Bob finished processesing the commit"); + + let staged_commit = match processed_message.into_content() { + ProcessedMessageContent::StagedCommitMessage(commit) => *commit, + _ => panic!("Wrong message type"), + }; + + bob_group + .merge_staged_commit(provider, staged_commit) + .expect("Error merging commit."); + + // Charlie processes the welcome + println!("Charlie processes the commit"); + let ratchet_tree = alice_group.export_ratchet_tree(); + + let charlie_group = StagedWelcome::new_from_welcome( + provider, + &join_group_config, + welcome.unwrap().into_welcome().unwrap(), + Some(ratchet_tree.into()), + ) + .expect("Error staging welcome.") + .into_group(provider) + .expect("Error creating group from welcome."); + + // We can now check that Bob correctly processed his and applied the changes + // to his tree after he was removed by comparing membership lists. In + // particular, Bob's list should show that he was removed and Charlie was + // added. + let alice_members = alice_group.members(); + + let bob_members = bob_group.members(); + + let charlie_members = charlie_group.members(); + + for (alice_member, (bob_member, charlie_member)) in + alice_members.zip(bob_members.zip(charlie_members)) + { + // Note that we can't compare encryption keys for Bob because they + // didn't get updated. + assert_eq!(alice_member.index, bob_member.index); + + let alice_id = alice_member.credential.serialized_content(); + let bob_id = bob_member.credential.serialized_content(); + let charlie_id = charlie_member.credential.serialized_content(); + assert_eq!(alice_id, bob_id); + assert_eq!(alice_member.signature_key, bob_member.signature_key); + assert_eq!(charlie_member.index, bob_member.index); + assert_eq!(charlie_id, bob_id); + assert_eq!(charlie_member.signature_key, bob_member.signature_key); + assert_eq!(charlie_member.encryption_key, alice_member.encryption_key); + } + + let mut bob_members = bob_group.members(); + + let member = bob_members.next().unwrap(); + let bob_next_id = member.credential.serialized_content(); + assert_eq!(bob_next_id, b"Alice"); + let member = bob_members.next().unwrap(); + let bob_next_id = member.credential.serialized_content(); + assert_eq!(bob_next_id, b"Charlie"); +} diff --git a/openmls/src/group/core_group/test_create_commit_params.rs b/openmls/src/group/mls_group/tests_and_kats/tests/create_commit_params.rs similarity index 82% rename from openmls/src/group/core_group/test_create_commit_params.rs rename to openmls/src/group/mls_group/tests_and_kats/tests/create_commit_params.rs index 3ec1ba1425..876b8b94ca 100644 --- a/openmls/src/group/core_group/test_create_commit_params.rs +++ b/openmls/src/group/mls_group/tests_and_kats/tests/create_commit_params.rs @@ -1,4 +1,7 @@ -use super::*; +use crate::group::{ + mls_group::{FramingParameters, Proposal, WireFormat}, + CreateCommitParams, +}; // Tests that the builder for CreateCommitParams works as expected #[openmls_test::openmls_test] @@ -6,19 +9,16 @@ fn build_create_commit_params(provider: &Provider) { let _ = provider; let framing_parameters: FramingParameters = FramingParameters::new(&[1, 2, 3], WireFormat::PrivateMessage); - let proposal_store: &ProposalStore = &ProposalStore::new(); let inline_proposals: Vec = vec![]; let force_self_update: bool = true; let params = CreateCommitParams::builder() .framing_parameters(framing_parameters) - .proposal_store(proposal_store) .inline_proposals(inline_proposals.clone()) .force_self_update(force_self_update) .build(); assert_eq!(params.framing_parameters(), &framing_parameters); - assert_eq!(params.proposal_store(), proposal_store); assert_eq!(params.inline_proposals(), inline_proposals); assert_eq!(params.force_self_update(), force_self_update); } diff --git a/openmls/src/group/mls_group/tests_and_kats/tests/external_init.rs b/openmls/src/group/mls_group/tests_and_kats/tests/external_init.rs new file mode 100644 index 0000000000..5b634f57b2 --- /dev/null +++ b/openmls/src/group/mls_group/tests_and_kats/tests/external_init.rs @@ -0,0 +1,48 @@ +use crate::{ + group::{ + errors::ExternalCommitError, + mls_group::tests_and_kats::utils::{setup_alice_bob_group, setup_client}, + public_group::errors::CreationFromExternalError, + MlsGroup, MlsGroupJoinConfig, + }, + storage::OpenMlsProvider, +}; + +#[openmls_test::openmls_test] +fn test_external_init_broken_signature() { + let (group_alice, alice_signer, _group_bob, _bob_signer, _bob_credential_with_key) = + setup_alice_bob_group(ciphersuite, provider); + + // Now set up charly and try to init externally. + let (charlie_credential, _charlie_kpb, charlie_signer, _charlie_pk) = + setup_client("Charlie", ciphersuite, provider); + + let verifiable_group_info = { + let mut verifiable_group_info = group_alice + .export_group_info(provider, &alice_signer, true) + .unwrap() + .into_verifiable_group_info() + .unwrap(); + verifiable_group_info.break_signature(); + verifiable_group_info + }; + + let result = MlsGroup::join_by_external_commit( + provider, + &charlie_signer, + None, + verifiable_group_info, + &MlsGroupJoinConfig::default(), + None, + None, + &[], + charlie_credential, + ) + .expect_err("Signature was corrupted. This should have failed."); + assert!(matches!( + result, + ExternalCommitError::<::StorageError>::PublicGroupError( + CreationFromExternalError::InvalidGroupInfoSignature + ) + )); +} diff --git a/openmls/src/group/mls_group/test_mls_group.rs b/openmls/src/group/mls_group/tests_and_kats/tests/mls_group.rs similarity index 88% rename from openmls/src/group/mls_group/test_mls_group.rs rename to openmls/src/group/mls_group/tests_and_kats/tests/mls_group.rs index 0e9b3bc51a..849885fb36 100644 --- a/openmls/src/group/mls_group/test_mls_group.rs +++ b/openmls/src/group/mls_group/tests_and_kats/tests/mls_group.rs @@ -1,6 +1,8 @@ -use core_group::test_core_group::setup_client; +use mls_group::tests_and_kats::utils::setup_client; +use openmls_basic_credential::SignatureKeyPair; +use openmls_rust_crypto::MemoryStorage; use openmls_test::openmls_test; -use openmls_traits::OpenMlsProvider as _; +use openmls_traits::{storage::CURRENT_VERSION, OpenMlsProvider as _}; use tls_codec::{Deserialize, Serialize}; use crate::{ @@ -10,15 +12,12 @@ use crate::{ group::{errors::*, *}, key_packages::*, messages::proposals::*, - prelude::Capabilities, - test_utils::{ - frankenstein::{self, FrankenMlsMessage}, - test_framework::{ - errors::ClientError, noop_authentication_service, ActionType::Commit, CodecUse, - MlsGroupTestSetup, - }, + test_utils::test_framework::{ + errors::ClientError, noop_authentication_service, ActionType::Commit, CodecUse, + MlsGroupTestSetup, }, tree::sender_ratchet::SenderRatchetConfiguration, + treesync::{node::leaf_node::Capabilities, LeafNodeParameters}, }; #[openmls_test] @@ -353,7 +352,7 @@ fn test_invalid_plaintext() { .expect("An unexpected error occurred."); let (mls_message, _welcome_option, _group_info) = client - .self_update(Commit, &group_id, None) + .self_update(Commit, &group_id, LeafNodeParameters::default()) .expect("error creating self update"); // Store the context and membership key so that we can re-compute the membership tag later. @@ -479,7 +478,7 @@ fn test_verify_staged_commit_credentials( } let (_msg, welcome_option, _group_info) = alice_group - .self_update(provider, &alice_signer) + .self_update(provider, &alice_signer, LeafNodeParameters::default()) .expect("error creating self-update commit"); // Merging the pending commit should clear the pending commit and we should @@ -521,7 +520,7 @@ fn test_verify_staged_commit_credentials( // === Make a new, empty commit and check that the leaf node credentials match === let (commit_msg, _welcome_option, _group_info) = alice_group - .self_update(provider, &alice_signer) + .self_update(provider, &alice_signer, LeafNodeParameters::default()) .expect("error creating self-update commit"); // empty commits should only produce a single message @@ -659,7 +658,7 @@ fn test_commit_with_update_path_leaf_node( println!("\nCreating commit with add proposal."); let (_msg, welcome_option, _group_info) = alice_group - .self_update(provider, &alice_signer) + .self_update(provider, &alice_signer, LeafNodeParameters::default()) .expect("error creating self-update commit"); println!("Done creating commit."); @@ -704,7 +703,7 @@ fn test_commit_with_update_path_leaf_node( println!("\nCreating self-update commit."); let (commit_msg, _welcome_option, _group_info) = alice_group - .self_update(provider, &alice_signer) + .self_update(provider, &alice_signer, LeafNodeParameters::default()) .expect("error creating self-update commit"); println!("Done creating commit."); @@ -855,7 +854,7 @@ fn test_pending_commit_logic( println!("\nCreating commit with add proposal."); let (_msg, _welcome_option, _group_info) = alice_group - .self_update(provider, &alice_signer) + .self_update(provider, &alice_signer, LeafNodeParameters::default()) .expect("error creating self-update commit"); println!("Done creating commit."); @@ -900,14 +899,14 @@ fn test_pending_commit_logic( CommitToPendingProposalsError::GroupStateError(MlsGroupStateError::PendingCommit) )); let error = alice_group - .self_update(provider, &alice_signer) + .self_update(provider, &alice_signer, LeafNodeParameters::default()) .expect_err("no error committing while a commit is pending"); assert!(matches!( error, SelfUpdateError::GroupStateError(MlsGroupStateError::PendingCommit) )); let error = alice_group - .propose_self_update(provider, &alice_signer, None) + .propose_self_update(provider, &alice_signer, LeafNodeParameters::default()) .expect_err("no error creating a proposal while a commit is pending"); assert!(matches!( error, @@ -922,7 +921,7 @@ fn test_pending_commit_logic( // Creating a new commit should commit the same proposals. let (_msg, welcome_option, _group_info) = alice_group - .self_update(provider, &alice_signer) + .self_update(provider, &alice_signer, LeafNodeParameters::default()) .expect("error creating self-update commit"); // Merging the pending commit should clear the pending commit and we should @@ -962,11 +961,11 @@ fn test_pending_commit_logic( // While a commit is pending, merging Bob's commit should clear the pending commit. let (_msg, _welcome_option, _group_info) = alice_group - .self_update(provider, &alice_signer) + .self_update(provider, &alice_signer, LeafNodeParameters::default()) .expect("error creating self-update commit"); let (msg, _welcome_option, _group_info) = bob_group - .self_update(provider, &bob_signer) + .self_update(provider, &bob_signer, LeafNodeParameters::default()) .expect("error creating self-update commit"); let alice_processed_message = alice_group @@ -1105,18 +1104,18 @@ fn remove_prosposal_by_ref( .propose_add_member(provider, &alice_signer, charlie_key_package) .unwrap(); - assert_eq!(alice_group.proposal_store.proposals().count(), 1); + assert_eq!(alice_group.proposal_store().proposals().count(), 1); // clearing the proposal by reference alice_group - .remove_pending_proposal(provider.storage(), reference.clone()) + .remove_pending_proposal(provider.storage(), &reference) .unwrap(); - assert!(alice_group.proposal_store.is_empty()); + assert!(alice_group.proposal_store().is_empty()); // the proposal should not be stored anymore let err = alice_group - .remove_pending_proposal(provider.storage(), reference) + .remove_pending_proposal(provider.storage(), &reference) .unwrap_err(); - assert!(matches!(err, MlsGroupStateError::PendingProposalNotFound)); + assert!(matches!(err, RemoveProposalError::ProposalNotFound)); // the commit should have no proposal let (commit, _, _) = alice_group @@ -1143,216 +1142,6 @@ fn remove_prosposal_by_ref( } } -// Test that the builder pattern accurately configures the new group. -#[openmls_test] -fn group_context_extensions_proposal() { - let alice_provider = &mut Provider::default(); - let bob_provider = &mut Provider::default(); - let (alice_credential_with_key, _alice_kpb, alice_signer, _alice_pk) = - setup_client("Alice", ciphersuite, alice_provider); - let (bob_credential_with_key, _bob_kpb, bob_signer, _bob_pk) = - setup_client("bob", ciphersuite, bob_provider); - - // === Alice creates a group === - let mut alice_group = MlsGroup::builder() - .ciphersuite(ciphersuite) - .with_wire_format_policy(WireFormatPolicy::new( - OutgoingWireFormatPolicy::AlwaysPlaintext, - IncomingWireFormatPolicy::Mixed, - )) - .build(alice_provider, &alice_signer, alice_credential_with_key) - .expect("error creating group using builder"); - - // === Alice adds Bob === - let bob_key_package = KeyPackage::builder() - .build( - ciphersuite, - bob_provider, - &bob_signer, - bob_credential_with_key, - ) - .expect("error building key package"); - - let (_, welcome, _) = alice_group - .add_members( - alice_provider, - &alice_signer, - &[bob_key_package.key_package().clone()], - ) - .unwrap(); - alice_group.merge_pending_commit(alice_provider).unwrap(); - - let welcome: MlsMessageIn = welcome.into(); - let welcome = welcome - .into_welcome() - .expect("expected message to be a welcome"); - - let mut bob_group = StagedWelcome::new_from_welcome( - bob_provider, - alice_group.configuration(), - welcome, - Some(alice_group.export_ratchet_tree().into()), - ) - .expect("Error creating staged join from Welcome") - .into_group(bob_provider) - .expect("Error creating group from staged join"); - - // No required capabilities, so no specifically required extensions. - assert!(alice_group - .group() - .context() - .extensions() - .required_capabilities() - .is_none()); - - let new_extensions = Extensions::single(Extension::RequiredCapabilities( - RequiredCapabilitiesExtension::new(&[ExtensionType::RequiredCapabilities], &[], &[]), - )); - - let new_extensions_2 = Extensions::single(Extension::RequiredCapabilities( - RequiredCapabilitiesExtension::new(&[ExtensionType::RatchetTree], &[], &[]), - )); - - let (proposal, _) = alice_group - .propose_group_context_extensions(alice_provider, new_extensions.clone(), &alice_signer) - .expect("failed to build group context extensions proposal"); - - let proc_msg = bob_group - .process_message(bob_provider, proposal.into_protocol_message().unwrap()) - .unwrap(); - match proc_msg.into_content() { - ProcessedMessageContent::ProposalMessage(proposal) => bob_group - .store_pending_proposal(bob_provider.storage(), *proposal) - .unwrap(), - _ => unreachable!(), - }; - - assert_eq!(alice_group.pending_proposals().count(), 1); - - let (commit, _, _) = alice_group - .commit_to_pending_proposals(alice_provider, &alice_signer) - .expect("failed to commit to pending proposals"); - - // we'll change the commit we feed to bob to include two GCE proposals - let mut franken_commit = FrankenMlsMessage::tls_deserialize( - &mut commit.tls_serialize_detached().unwrap().as_slice(), - ) - .unwrap(); - - // Craft a commit that has two GroupContextExtension proposals. This is forbidden by the RFC. - // Change the commit before alice commits, so alice's state is still in the old epoch and we can - // use her state to forge the macs and signatures - match &mut franken_commit.body { - frankenstein::FrankenMlsMessageBody::PublicMessage(msg) => { - match &mut msg.content.body { - frankenstein::FrankenFramedContentBody::Commit(commit) => { - let second_gces = frankenstein::FrankenProposalOrRef::Proposal( - frankenstein::FrankenProposal::GroupContextExtensions(vec![ - frankenstein::FrankenExtension::LastResort, - ]), - ); - - commit.proposals.push(second_gces); - } - _ => unreachable!(), - } - - let group_context = alice_group.export_group_context().clone(); - - let bob_group_context = bob_group.export_group_context(); - assert_eq!( - bob_group_context.confirmed_transcript_hash(), - group_context.confirmed_transcript_hash() - ); - - let secrets = alice_group.group.message_secrets(); - let membership_key = secrets.membership_key().as_slice(); - - *msg = frankenstein::FrankenPublicMessage::auth( - alice_provider, - group_context.ciphersuite(), - &alice_signer, - msg.content.clone(), - Some(&group_context.into()), - Some(membership_key), - // this is a dummy confirmation_tag: - Some(vec![0u8; 32].into()), - ); - } - _ => unreachable!(), - } - - // alice merges the unmodified commit - alice_group - .merge_pending_commit(alice_provider) - .expect("error merging pending commit"); - - let fake_commit = MlsMessageIn::tls_deserialize( - &mut franken_commit.tls_serialize_detached().unwrap().as_slice(), - ) - .unwrap(); - - let fake_commit_protocol_msg = fake_commit.into_protocol_message().unwrap(); - - let err = { - let validation_skip_handle = crate::skip_validation::checks::confirmation_tag::handle(); - validation_skip_handle.with_disabled(|| { - bob_group.process_message(bob_provider, fake_commit_protocol_msg.clone()) - }) - } - .expect_err("expected an error"); - - assert!(matches!( - err, - ProcessMessageError::InvalidCommit( - StageCommitError::GroupContextExtensionsProposalValidationError( - GroupContextExtensionsProposalValidationError::TooManyGCEProposals - ) - ) - )); - - let required_capabilities = alice_group - .group() - .context() - .extensions() - .required_capabilities() - .expect("couldn't get required_capabilities"); - - // has required_capabilities as required capability - assert!(required_capabilities.extension_types() == [ExtensionType::RequiredCapabilities]); - - // === committing to two group context extensions should fail - - alice_group - .propose_group_context_extensions(alice_provider, new_extensions, &alice_signer) - .expect("failed to build group context extensions proposal"); - - // the proposals need to be different or they will be deduplicated - alice_group - .propose_group_context_extensions(alice_provider, new_extensions_2, &alice_signer) - .expect("failed to build group context extensions proposal"); - - assert_eq!(alice_group.pending_proposals().count(), 2); - - alice_group - .commit_to_pending_proposals(alice_provider, &alice_signer) - .expect_err( - "expected error when committing to multiple group context extensions proposals", - ); - - // === can't update required required_capabilities to extensions that existing group members - // are not capable of - - // contains unsupported extension - let new_extensions = Extensions::single(Extension::RequiredCapabilities( - RequiredCapabilitiesExtension::new(&[ExtensionType::Unknown(0xf042)], &[], &[]), - )); - - alice_group - .propose_group_context_extensions(alice_provider, new_extensions, &alice_signer) - .expect_err("expected an error building GCE proposal with bad required_capabilities"); -} - // Test that the builder pattern accurately configures the new group. #[openmls_test] fn builder_pattern() { @@ -1473,7 +1262,7 @@ fn builder_pattern() { fn update_group_context_with_unknown_extension() { let alice_provider = Provider::default(); let (alice_credential_with_key, _alice_kpb, alice_signer, _alice_pk) = - setup_client("Alice", ciphersuite, &alice_provider); + setup_client("Alice", ciphersuite, provider); // === Define the unknown group context extension and initial data === const UNKNOWN_EXTENSION_TYPE: u16 = 0xff11; @@ -1501,7 +1290,7 @@ fn update_group_context_with_unknown_extension>:: + delete_key_package(alice_provider.storage(),&alice_kpb.key_package().hash_ref(provider.crypto()).unwrap()) + .unwrap(); + >:: + delete_encryption_key_pair(alice_provider.storage(),alice_kpb.key_package().leaf_node().encryption_key()).unwrap(); + + // alice creates MlsGroup + let mut alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .use_ratchet_tree_extension(true) + .build(provider, &alice_signer, alice_credential_with_key) + .expect("error creating group for alice using builder"); + + SignatureKeyPair::delete( + alice_provider.storage(), + alice_pk.as_slice(), + ciphersuite.signature_algorithm(), + ) + .unwrap(); + + // alice deletes the group + alice_group.delete(alice_provider.storage()).unwrap(); + + assert!(alice_provider.storage().values.read().unwrap().is_empty()); +} diff --git a/openmls/src/group/mls_group/tests_and_kats/tests/mod.rs b/openmls/src/group/mls_group/tests_and_kats/tests/mod.rs new file mode 100644 index 0000000000..6281969e6a --- /dev/null +++ b/openmls/src/group/mls_group/tests_and_kats/tests/mod.rs @@ -0,0 +1,8 @@ +//! Test and Known Answer Test (KAT) modules for the MLS group. + +mod core_group; +mod create_commit_params; +mod external_init; +mod mls_group; +mod past_secrets; +mod proposals; diff --git a/openmls/src/group/core_group/test_past_secrets.rs b/openmls/src/group/mls_group/tests_and_kats/tests/past_secrets.rs similarity index 100% rename from openmls/src/group/core_group/test_past_secrets.rs rename to openmls/src/group/mls_group/tests_and_kats/tests/past_secrets.rs diff --git a/openmls/src/group/core_group/test_proposals.rs b/openmls/src/group/mls_group/tests_and_kats/tests/proposals.rs similarity index 58% rename from openmls/src/group/core_group/test_proposals.rs rename to openmls/src/group/mls_group/tests_and_kats/tests/proposals.rs index 240c990bde..6b28abad56 100644 --- a/openmls/src/group/core_group/test_proposals.rs +++ b/openmls/src/group/mls_group/tests_and_kats/tests/proposals.rs @@ -1,4 +1,3 @@ -use super::CoreGroup; use crate::{ binary_tree::LeafNodeIndex, ciphersuite::hash_ref::ProposalRef, @@ -9,13 +8,15 @@ use crate::{ }, group::{ errors::*, + mls_group::{ + tests_and_kats::utils::{setup_alice_bob_group, setup_client}, + ProcessedMessageContent, + }, proposals::{ProposalQueue, ProposalStore, QueuedProposal}, - test_core_group::setup_client, - CreateCommitParams, GroupContext, GroupId, StagedCoreWelcome, + GroupContext, GroupId, MlsGroup, MlsGroupJoinConfig, StagedWelcome, }, key_packages::{KeyPackageBundle, KeyPackageIn}, messages::proposals::{AddProposal, Proposal, ProposalOrRef, ProposalType}, - schedule::psk::store::ResumptionPskStore, test_utils::*, versions::ProtocolVersion, }; @@ -279,14 +280,11 @@ fn proposal_queue_order() { } #[openmls_test::openmls_test] -fn test_required_extension_key_package_mismatch( +fn required_extension_key_package_mismatch( ciphersuite: Ciphersuite, provider: &impl crate::storage::OpenMlsProvider, ) { // Basic group setup. - let group_aad = b"Alice's test group"; - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); - let (alice_credential, _, alice_signer, _alice_pk) = setup_client("Alice", ciphersuite, provider); let (_bob_credential_with_key, bob_key_package_bundle, _, _) = @@ -301,42 +299,32 @@ fn test_required_extension_key_package_mismatch( let required_capabilities = RequiredCapabilitiesExtension::new(extensions, proposals, credentials); - let alice_group = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential, - ) - .with_group_context_extensions(Extensions::single(Extension::RequiredCapabilities( - required_capabilities, - ))) - .expect("error adding group context extensions") - .build(provider, &alice_signer) - .expect("Error creating CoreGroup."); - - let e = alice_group - .create_add_proposal( - framing_parameters, - bob_key_package.clone(), - &alice_signer, - ) + let mut alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .with_group_context_extensions(Extensions::single(Extension::RequiredCapabilities( + required_capabilities, + ))) + .unwrap() + .build(provider, &alice_signer, alice_credential) + .expect("Error creating CoreGroup."); + + let e = alice_group.propose_add_member(provider, &alice_signer, bob_key_package) .expect_err("Proposal was created even though the key package didn't support the required extensions."); + assert_eq!( e, - CreateAddProposalError::LeafNodeValidation( + ProposeAddMemberError::LeafNodeValidation( crate::treesync::errors::LeafNodeValidationError::UnsupportedExtensions ) ); } #[openmls_test::openmls_test] -fn test_group_context_extensions( +fn group_context_extensions( ciphersuite: Ciphersuite, provider: &impl crate::storage::OpenMlsProvider, ) { // Basic group setup. - let group_aad = b"Alice's test group"; - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); - let (alice_credential, _, alice_signer, _alice_pk) = setup_client("Alice", ciphersuite, provider); let (_bob_credential_with_key, bob_key_package_bundle, _, _) = @@ -356,74 +344,43 @@ fn test_group_context_extensions( let required_capabilities = RequiredCapabilitiesExtension::new(extensions, proposals, credentials); - let mut alice_group = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential, - ) - .with_group_context_extensions(Extensions::single(Extension::RequiredCapabilities( - required_capabilities, - ))) - .unwrap() - .build(provider, &alice_signer) - .expect("Error creating CoreGroup."); - - let bob_add_proposal = alice_group - .create_add_proposal(framing_parameters, bob_key_package.clone(), &alice_signer) - .expect("Could not create proposal"); - - let proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - bob_add_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - log::info!(" >>> Creating commit ..."); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = alice_group - .create_commit(params, provider, &alice_signer) - .expect("Error creating commit"); - - log::info!(" >>> Staging & merging commit ..."); - - alice_group - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging own staged commit"); - let ratchet_tree = alice_group.public_group().export_ratchet_tree(); + let mut alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .with_group_context_extensions(Extensions::single(Extension::RequiredCapabilities( + required_capabilities, + ))) + .unwrap() + .build(provider, &alice_signer, alice_credential) + .expect("Error creating MlsGroup."); + + let (_commit, welcome, _group_info_option) = alice_group + .add_members(provider, &alice_signer, &[bob_key_package.clone()]) + .expect("Error adding members."); + + alice_group.merge_pending_commit(provider).unwrap(); + + let ratchet_tree = alice_group.export_ratchet_tree(); // Make sure that Bob can join the group with the required extension in place // and Bob's key package supporting them. - let _bob_group = StagedCoreWelcome::new_from_welcome( - create_commit_result - .welcome_option - .expect("An unexpected error occurred."), - Some(ratchet_tree.into()), - bob_key_package_bundle, + let _bob_group = StagedWelcome::new_from_welcome( provider, - ResumptionPskStore::new(1024), + &MlsGroupJoinConfig::default(), + welcome.into_welcome().unwrap(), + Some(ratchet_tree.into()), ) - .and_then(|staged_join| staged_join.into_core_group(provider)) .expect("Error joining group."); } #[openmls_test::openmls_test] -fn test_group_context_extension_proposal_fails( +fn group_context_extension_proposal_fails( ciphersuite: Ciphersuite, provider: &impl crate::storage::OpenMlsProvider, ) { // Basic group setup. - let group_aad = b"Alice's test group"; - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); - let (alice_credential, _, alice_signer, _alice_pk) = setup_client("Alice", ciphersuite, provider); - let (_bob_credential_with_key, bob_key_package_bundle, _, _) = + let (_bob_credential_with_key, bob_key_package_bundle, _bob_signer, _) = setup_client("Bob", ciphersuite, provider); let bob_key_package = bob_key_package_bundle.key_package(); @@ -438,142 +395,62 @@ fn test_group_context_extension_proposal_fails( let credentials = &[CredentialType::Basic]; let required_capabilities = RequiredCapabilitiesExtension::new(&[], proposals, credentials); - let mut alice_group = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential, - ) - .with_group_context_extensions(Extensions::single(Extension::RequiredCapabilities( - required_capabilities, - ))) - .unwrap() - .build(provider, &alice_signer) - .expect("Error creating CoreGroup."); + let mut alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .with_group_context_extensions(Extensions::single(Extension::RequiredCapabilities( + required_capabilities, + ))) + .unwrap() + .build(provider, &alice_signer, alice_credential) + .expect("Error creating CoreGroup."); // Adding Bob - let bob_add_proposal = alice_group - .create_add_proposal(framing_parameters, bob_key_package.clone(), &alice_signer) - .expect("Could not create proposal"); + let (_commit, welcome, _group_info_option) = alice_group + .add_members(provider, &alice_signer, &[bob_key_package.clone()]) + .expect("Error adding members."); - let proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - bob_add_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - log::info!(" >>> Creating commit ..."); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = alice_group - .create_commit(params, provider, &alice_signer) - .expect("Error creating commit"); - - log::info!(" >>> Staging & merging commit ..."); - - alice_group - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging pending commit"); - let ratchet_tree = alice_group.public_group().export_ratchet_tree(); - - let _bob_group = StagedCoreWelcome::new_from_welcome( - create_commit_result - .welcome_option - .expect("An unexpected error occurred."), - Some(ratchet_tree.into()), - bob_key_package_bundle, + alice_group.merge_pending_commit(provider).unwrap(); + + let ratchet_tree = alice_group.export_ratchet_tree(); + + let _bob_group = StagedWelcome::new_from_welcome( provider, - ResumptionPskStore::new(1024), + &MlsGroupJoinConfig::default(), + welcome.into_welcome().unwrap(), + Some(ratchet_tree.into()), ) - .and_then(|staged_join| staged_join.into_core_group(provider)) + .and_then(|staged_join| staged_join.into_group(provider)) .expect("Error joining group."); // TODO: openmls/openmls#1130 re-enable // // Now Bob wants the ApplicationId extension to be required. // // This should fail because Alice doesn't support it. - // let e = bob_group - // .create_group_context_ext_proposal( - // framing_parameters, - // &alice_credential_bundle, - // &[required_application_id], - // provider, - // ) - // .expect_err("Bob was able to create a gce proposal for an extension not supported by all other parties."); - // assert_eq!( - // e, - // CreateGroupContextExtProposalError::TreeSyncError( - // crate::treesync::errors::TreeSyncError::UnsupportedExtension - // ) - // ); + //let unsupported_extensions = Extensions::single(Extension::Unknown( + // 0xff00, + // UnknownExtension(vec![0, 1, 2, 3]), + //)); + //let e = bob_group + // .propose_group_context_extensions(provider, unsupported_extensions, &bob_signer) + // .expect_err("Bob was able to propose an extension not supported by all other parties."); + // + //assert_eq!( + // e, + // ProposalError::CreateGroupContextExtProposalError( + // CreateGroupContextExtProposalError::KeyPackageExtensionSupport( + // KeyPackageExtensionSupportError::UnsupportedExtension + // ) + // ) + //); } #[openmls_test::openmls_test] -fn test_group_context_extension_proposal(ciphersuite: Ciphersuite, provider: &Provider) { +fn group_context_extension_proposal( + ciphersuite: Ciphersuite, + provider: &impl crate::storage::OpenMlsProvider, +) { // Basic group setup. - let group_aad = b"Alice's test group"; - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); - - let (alice_credential, _, alice_signer, _alice_pk) = - setup_client("Alice", ciphersuite, provider); - let (_bob_credential_with_key, bob_key_package_bundle, _, _) = - setup_client("Bob", ciphersuite, provider); - - let bob_key_package = bob_key_package_bundle.key_package(); - - let mut alice_group = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential, - ) - .build(provider, &alice_signer) - .expect("Error creating CoreGroup."); - - // Adding Bob - let bob_add_proposal = alice_group - .create_add_proposal(framing_parameters, bob_key_package.clone(), &alice_signer) - .expect("Could not create proposal"); - - let proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - bob_add_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - log::info!(" >>> Creating commit ..."); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_results = alice_group - .create_commit(params, provider, &alice_signer) - .expect("Error creating commit"); - - log::info!(" >>> Staging & merging commit ..."); - - alice_group - .merge_commit(provider, create_commit_results.staged_commit) - .expect("error merging pending commit"); - - let ratchet_tree = alice_group.public_group().export_ratchet_tree(); - - let mut bob_group = StagedCoreWelcome::new_from_welcome( - create_commit_results - .welcome_option - .expect("An unexpected error occurred."), - Some(ratchet_tree.into()), - bob_key_package_bundle, - provider, - ResumptionPskStore::new(1024), - ) - .and_then(|staged_join| staged_join.into_core_group(provider)) - .expect("Error joining group."); + let (mut alice_group, alice_signer, mut bob_group, bob_signer, _bob_credential) = + setup_alice_bob_group(ciphersuite, provider); // Alice adds a required capability. let required_application_id = @@ -582,51 +459,47 @@ fn test_group_context_extension_proposal(ciphersuite: Ciphersuite, provider: &Pr &[], &[CredentialType::Basic], )); - let gce_proposal = alice_group - .create_group_context_ext_proposal::( - framing_parameters, + let (gce_proposal, _) = alice_group + .propose_group_context_extensions( + provider, Extensions::single(required_application_id), &alice_signer, ) - .expect("Error creating gce proposal."); + .expect("Error proposing gce."); + + let processed_message = bob_group + .process_message(provider, gce_proposal.into_protocol_message().unwrap()) + .expect("Error processing gce proposal."); + + match processed_message.into_content() { + ProcessedMessageContent::ProposalMessage(queued_proposal) => { + bob_group + .store_pending_proposal(provider.storage(), *queued_proposal) + .unwrap(); + } + _ => panic!("Expected a StagedCommitMessage."), + }; - let proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - gce_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - log::info!(" >>> Creating commit ..."); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = alice_group - .create_commit(params, provider, &alice_signer) - .expect("Error creating commit"); - - log::info!(" >>> Staging & merging commit ..."); - - let staged_commit = bob_group - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect("error staging commit"); - bob_group - .merge_commit(provider, staged_commit) - .expect("error merging commit"); - - alice_group - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging pending commit"); + // Bob commits the proposal. + let (commit, _, _) = bob_group + .commit_to_pending_proposals(provider, &bob_signer) + .unwrap(); + + bob_group.merge_pending_commit(provider).unwrap(); + + let processed_message = alice_group + .process_message(provider, commit.into_protocol_message().unwrap()) + .expect("Error processing commit."); + + match processed_message.into_content() { + ProcessedMessageContent::StagedCommitMessage(commit) => { + alice_group.merge_staged_commit(provider, *commit).unwrap(); + } + _ => panic!("Expected a StagedCommitMessage."), + }; assert_eq!( - alice_group - .export_secret(provider.crypto(), "label", b"gce test", 32) - .expect("Error exporting secret."), - bob_group - .export_secret(provider.crypto(), "label", b"gce test", 32) - .expect("Error exporting secret.") + alice_group.epoch_authenticator(), + bob_group.epoch_authenticator() ) } diff --git a/openmls/src/group/mls_group/tests_and_kats/utils.rs b/openmls/src/group/mls_group/tests_and_kats/utils.rs new file mode 100644 index 0000000000..cf824f2be0 --- /dev/null +++ b/openmls/src/group/mls_group/tests_and_kats/utils.rs @@ -0,0 +1,162 @@ +//! Test utilities for (MLS group) tests. + +use openmls_basic_credential::SignatureKeyPair; +use openmls_traits::types::HpkeCiphertext; + +use crate::{credentials::*, group::*, key_packages::*, test_utils::*}; + +pub(crate) fn setup_alice_group( + ciphersuite: Ciphersuite, + provider: &impl crate::storage::OpenMlsProvider, +) -> ( + MlsGroup, + CredentialWithKey, + SignatureKeyPair, + OpenMlsSignaturePublicKey, +) { + // Create credentials and keys + let (alice_credential_with_key, alice_signature_keys) = + test_utils::new_credential(provider, b"Alice", ciphersuite.signature_algorithm()); + let pk = OpenMlsSignaturePublicKey::new( + alice_signature_keys.to_public_vec().into(), + ciphersuite.signature_algorithm(), + ) + .unwrap(); + + // Alice creates a group + let group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .build( + provider, + &alice_signature_keys, + alice_credential_with_key.clone(), + ) + .expect("Error creating group."); + (group, alice_credential_with_key, alice_signature_keys, pk) +} + +/// This function flips the last byte of the ciphertext. +pub fn flip_last_byte(ctxt: &mut HpkeCiphertext) { + let mut last_bits = ctxt + .ciphertext + .pop() + .expect("An unexpected error occurred."); + last_bits ^= 0xff; + ctxt.ciphertext.push(last_bits); +} + +pub(crate) fn setup_alice_bob( + ciphersuite: Ciphersuite, + provider: &impl crate::storage::OpenMlsProvider, +) -> ( + CredentialWithKey, + SignatureKeyPair, + KeyPackageBundle, + SignatureKeyPair, +) { + // Create credentials and keys + let (alice_credential_with_key, alice_signer) = + test_utils::new_credential(provider, b"Alice", ciphersuite.signature_algorithm()); + let (bob_credential_with_key, bob_signer) = + test_utils::new_credential(provider, b"Bob", ciphersuite.signature_algorithm()); + + // Generate Bob's KeyPackage + let bob_key_package_bundle = + KeyPackageBundle::generate(provider, &bob_signer, ciphersuite, bob_credential_with_key); + + ( + alice_credential_with_key, + alice_signer, + bob_key_package_bundle, + bob_signer, + ) +} + +pub(crate) fn setup_client( + id: &str, + ciphersuite: Ciphersuite, + provider: &impl crate::storage::OpenMlsProvider, +) -> ( + CredentialWithKey, + KeyPackageBundle, + SignatureKeyPair, + OpenMlsSignaturePublicKey, +) { + let (credential_with_key, signature_keys) = + test_utils::new_credential(provider, id.as_bytes(), ciphersuite.signature_algorithm()); + let pk = OpenMlsSignaturePublicKey::new( + signature_keys.to_public_vec().into(), + ciphersuite.signature_algorithm(), + ) + .unwrap(); + + // Generate the KeyPackage + let key_package_bundle = KeyPackageBundle::generate( + provider, + &signature_keys, + ciphersuite, + credential_with_key.clone(), + ); + (credential_with_key, key_package_bundle, signature_keys, pk) +} + +pub(crate) fn setup_alice_bob_group( + ciphersuite: Ciphersuite, + provider: &Provider, +) -> ( + MlsGroup, + SignatureKeyPair, + MlsGroup, + SignatureKeyPair, + CredentialWithKey, +) { + // Create credentials and keys + let (alice_credential, alice_signature_keys) = + test_utils::new_credential(provider, b"Alice", ciphersuite.signature_algorithm()); + let (bob_credential, bob_signature_keys) = + test_utils::new_credential(provider, b"Bob", ciphersuite.signature_algorithm()); + + // Generate KeyPackages + let bob_key_package_bundle = KeyPackageBundle::generate( + provider, + &bob_signature_keys, + ciphersuite, + bob_credential.clone(), + ); + let bob_key_package = bob_key_package_bundle.key_package(); + + // Alice creates a group + let mut group_alice = MlsGroup::builder() + .ciphersuite(ciphersuite) + .with_wire_format_policy(PURE_PLAINTEXT_WIRE_FORMAT_POLICY) + .build(provider, &alice_signature_keys, alice_credential.clone()) + .expect("Error creating group."); + + // Alice adds Bob + let (_commit, welcome, _group_info_option) = group_alice + .add_members(provider, &alice_signature_keys, &[bob_key_package.clone()]) + .expect("Could not create proposal."); + + group_alice + .merge_pending_commit(provider) + .expect("error merging pending commit"); + + let group_bob = StagedWelcome::new_from_welcome( + provider, + &MlsGroupJoinConfig::builder() + .wire_format_policy(PURE_PLAINTEXT_WIRE_FORMAT_POLICY) + .build(), + welcome.into_welcome().unwrap(), + Some(group_alice.export_ratchet_tree().into()), + ) + .and_then(|staged_join| staged_join.into_group(provider)) + .expect("error creating group from welcome"); + + ( + group_alice, + alice_signature_keys, + group_bob, + bob_signature_keys, + bob_credential, + ) +} diff --git a/openmls/src/group/mls_group/updates.rs b/openmls/src/group/mls_group/updates.rs index 93508f984d..10bc74e08e 100644 --- a/openmls/src/group/mls_group/updates.rs +++ b/openmls/src/group/mls_group/updates.rs @@ -1,25 +1,25 @@ use core_group::create_commit_params::CreateCommitParams; use openmls_traits::{signatures::Signer, storage::StorageProvider as _}; -use crate::{messages::group_info::GroupInfo, storage::OpenMlsProvider, treesync::LeafNode}; +use crate::{ + messages::group_info::GroupInfo, storage::OpenMlsProvider, treesync::LeafNodeParameters, +}; use super::*; impl MlsGroup { - /// Updates the own leaf node. + /// Updates the own leaf node. The application can choose to update the + /// credential, the capabilities, and the extensions by buliding the + /// [`LeafNodeParameters`]. /// /// If successful, it returns a tuple of [`MlsMessageOut`] (containing the - /// commit), an optional [`MlsMessageOut`] (containing the [`Welcome`]) and the [GroupInfo]. - /// The [`Welcome`] is [Some] when the queue of pending proposals contained - /// add proposals - /// The [GroupInfo] is [Some] if the group has the `use_ratchet_tree_extension` flag set. + /// commit), an optional [`MlsMessageOut`] (containing the [`Welcome`]) and + /// the [GroupInfo]. The [`Welcome`] is [Some] when the queue of pending + /// proposals contained add proposals The [GroupInfo] is [Some] if the group + /// has the `use_ratchet_tree_extension` flag set. /// /// Returns an error if there is a pending commit. /// - /// TODO #1208 : The caller should be able to optionally provide a - /// [`LeafNode`] here, so that things like extensions can be changed via - /// commit. - /// /// [`Welcome`]: crate::messages::Welcome // FIXME: #1217 #[allow(clippy::type_complexity)] @@ -27,6 +27,7 @@ impl MlsGroup { &mut self, provider: &Provider, signer: &impl Signer, + leaf_node_parameters: LeafNodeParameters, ) -> Result< (MlsMessageOut, Option, Option), SelfUpdateError, @@ -35,7 +36,7 @@ impl MlsGroup { let params = CreateCommitParams::builder() .framing_parameters(self.framing_parameters()) - .proposal_store(&self.proposal_store) + .leaf_node_parameters(leaf_node_parameters) .build(); // Create Commit over all proposals. // TODO #751 @@ -59,6 +60,7 @@ impl MlsGroup { .store(provider.storage()) .map_err(SelfUpdateError::StorageError)?; + self.reset_aad(); Ok(( mls_message, create_commit_result @@ -75,7 +77,7 @@ impl MlsGroup { &mut self, provider: &Provider, signer: &impl Signer, - leaf_node: Option, + leaf_node_parmeters: LeafNodeParameters, ) -> Result> { self.is_operational()?; @@ -89,27 +91,15 @@ impl MlsGroup { .leaf(self.own_leaf_index()) .ok_or_else(|| LibraryError::custom("The tree is broken. Couldn't find own leaf."))? .clone(); - if let Some(leaf) = leaf_node { - own_leaf.update_and_re_sign( - None, - leaf, - self.group_id().clone(), - self.own_leaf_index(), - signer, - )? - } else { - let keypair = own_leaf.rekey( - self.group_id(), - self.own_leaf_index(), - self.ciphersuite(), - provider, - signer, - )?; - // TODO #1207: Move to the top of the function. - keypair - .write(provider.storage()) - .map_err(ProposeSelfUpdateError::StorageError)?; - }; + + own_leaf.update( + self.ciphersuite(), + provider, + signer, + self.group_id().clone(), + self.own_leaf_index(), + leaf_node_parmeters, + )?; let update_proposal = self.group.create_update_proposal( self.framing_parameters(), @@ -126,14 +116,16 @@ impl MlsGroup { Ok(update_proposal) } - /// Creates a proposal to update the own leaf node. + /// Creates a proposal to update the own leaf node. The application can + /// choose to update the credential, the capabilities, and the extensions by + /// building the [`LeafNodeParameters`]. pub fn propose_self_update( &mut self, provider: &Provider, signer: &impl Signer, - leaf_node: Option, + leaf_node_parameters: LeafNodeParameters, ) -> Result<(MlsMessageOut, ProposalRef), ProposeSelfUpdateError> { - let update_proposal = self._propose_self_update(provider, signer, leaf_node)?; + let update_proposal = self._propose_self_update(provider, signer, leaf_node_parameters)?; let proposal = QueuedProposal::from_authenticated_content_by_ref( self.ciphersuite(), provider.crypto(), @@ -144,35 +136,11 @@ impl MlsGroup { .storage() .queue_proposal(self.group_id(), &proposal_ref, &proposal) .map_err(ProposeSelfUpdateError::StorageError)?; - self.proposal_store.add(proposal); - - let mls_message = self.content_to_mls_message(update_proposal, provider)?; - - Ok((mls_message, proposal_ref)) - } - - /// Creates a proposal to update the own leaf node. - pub fn propose_self_update_by_value( - &mut self, - provider: &Provider, - signer: &impl Signer, - leaf_node: Option, - ) -> Result<(MlsMessageOut, ProposalRef), ProposeSelfUpdateError> { - let update_proposal = self._propose_self_update(provider, signer, leaf_node)?; - let proposal = QueuedProposal::from_authenticated_content_by_value( - self.ciphersuite(), - provider.crypto(), - update_proposal.clone(), - )?; - let proposal_ref = proposal.proposal_reference(); - provider - .storage() - .queue_proposal(self.group_id(), &proposal_ref, &proposal) - .map_err(ProposeSelfUpdateError::StorageError)?; - self.proposal_store.add(proposal); + self.proposal_store_mut().add(proposal); let mls_message = self.content_to_mls_message(update_proposal, provider)?; + self.reset_aad(); Ok((mls_message, proposal_ref)) } } diff --git a/openmls/src/group/mod.rs b/openmls/src/group/mod.rs index c905da9818..ac1ec61279 100644 --- a/openmls/src/group/mod.rs +++ b/openmls/src/group/mod.rs @@ -2,19 +2,19 @@ //! //! This module contains the API to interact with groups. -mod group_context; - use std::fmt::Display; +use serde::{Deserialize, Serialize}; +use tls_codec::*; + +use crate::extensions::*; +use openmls_traits::random::OpenMlsRand; + #[cfg(test)] use crate::ciphersuite::*; -use crate::extensions::*; #[cfg(test)] use crate::utils::*; -use serde::{Deserialize, Serialize}; -use tls_codec::*; - // Crate pub(crate) mod core_group; pub(crate) mod public_group; @@ -32,12 +32,14 @@ pub use mls_group::membership::*; pub use mls_group::*; pub use public_group::*; +// Private +mod group_context; + // Tests #[cfg(test)] pub(crate) use core_group::create_commit_params::*; #[cfg(any(feature = "test-utils", test))] -pub(crate) mod tests; -use openmls_traits::random::OpenMlsRand; +pub(crate) mod tests_and_kats; /// A group ID. The group ID is chosen by the creator of the group and should be globally unique. #[derive( diff --git a/openmls/src/group/public_group/builder.rs b/openmls/src/group/public_group/builder.rs index ea0269c536..529872672f 100644 --- a/openmls/src/group/public_group/builder.rs +++ b/openmls/src/group/public_group/builder.rs @@ -1,6 +1,4 @@ -use openmls_traits::{ - crypto::OpenMlsCrypto, signatures::Signer, types::Ciphersuite, OpenMlsProvider, -}; +use openmls_traits::{crypto::OpenMlsCrypto, signatures::Signer, types::Ciphersuite}; use super::{errors::PublicGroupBuildError, PublicGroup}; use crate::{ @@ -11,6 +9,7 @@ use crate::{ key_packages::Lifetime, messages::ConfirmationTag, schedule::CommitSecret, + storage::OpenMlsProvider, treesync::{ node::{encryption_keys::EncryptionKeyPair, leaf_node::Capabilities}, TreeSync, diff --git a/openmls/src/group/public_group/diff.rs b/openmls/src/group/public_group/diff.rs index 685b7760c1..a6e5e42fa3 100644 --- a/openmls/src/group/public_group/diff.rs +++ b/openmls/src/group/public_group/diff.rs @@ -238,6 +238,7 @@ impl<'a> PublicGroupDiff<'a> { /// The staged version of a [`PublicGroupDiff`], which means it can no longer be /// modified. Its only use is to merge it into the original [`PublicGroup`]. #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone, PartialEq))] pub(crate) struct StagedPublicGroupDiff { pub(super) staged_diff: StagedTreeSyncDiff, pub(super) group_context: GroupContext, diff --git a/openmls/src/group/public_group/diff/compute_path.rs b/openmls/src/group/public_group/diff/compute_path.rs index 6caa719c2a..fcb608f4d0 100644 --- a/openmls/src/group/public_group/diff/compute_path.rs +++ b/openmls/src/group/public_group/diff/compute_path.rs @@ -9,12 +9,12 @@ use crate::{ error::LibraryError, extensions::Extensions, group::{core_group::create_commit_params::CommitType, errors::CreateCommitError}, - key_packages::{KeyPackage, KeyPackageCreationResult}, schedule::CommitSecret, storage::OpenMlsProvider, treesync::{ node::{ - encryption_keys::EncryptionKeyPair, leaf_node::LeafNode, + encryption_keys::EncryptionKeyPair, + leaf_node::{Capabilities, LeafNodeParameters, UpdateLeafNodeParams}, parent_node::PlainUpdatePathNode, }, treekem::UpdatePath, @@ -40,59 +40,76 @@ impl<'a> PublicGroupDiff<'a> { provider: &Provider, leaf_index: LeafNodeIndex, exclusion_list: HashSet<&LeafNodeIndex>, - commit_type: CommitType, + commit_type: &CommitType, + leaf_node_params: &LeafNodeParameters, signer: &impl Signer, - credential_with_key: Option, - extensions: Option, + gc_extensions: Option, ) -> Result> { let ciphersuite = self.group_context().ciphersuite(); - let group_id = self.group_context().group_id().clone(); - - let mut new_keypairs = if commit_type == CommitType::External { - // If this is an external commit we add a fresh leaf to the diff. - // Generate a KeyPackageBundle to generate a payload from for later - // path generation. - let KeyPackageCreationResult { - key_package, - encryption_keypair, - // The KeyPackage is immediately put into the group. No need for - // the init key. - init_private_key: _, - } = KeyPackage::builder().build_without_storage( - ciphersuite, - provider, - signer, - credential_with_key.ok_or(CreateCommitError::MissingCredential)?, - )?; - - let leaf_node: LeafNode = key_package.into(); - self.diff - .add_leaf(leaf_node) - .map_err(|_| LibraryError::custom("Tree full: cannot add more members"))?; - vec![encryption_keypair] + + let leaf_node_params = if let CommitType::External(credential_with_key) = commit_type { + let capabilities = match leaf_node_params.capabilities() { + Some(c) => c.to_owned(), + None => Capabilities::default(), + }; + + let extensions = match leaf_node_params.extensions() { + Some(e) => e.to_owned(), + None => Extensions::default(), + }; + + UpdateLeafNodeParams { + credential_with_key: credential_with_key.clone(), + capabilities, + extensions, + } } else { - // If we're already in the tree, we rekey our existing leaf. - let own_diff_leaf = self + let leaf = self .diff - .leaf_mut(leaf_index) - .ok_or_else(|| LibraryError::custom("Unable to get own leaf from diff"))?; - let encryption_keypair = - own_diff_leaf.rekey(&group_id, leaf_index, ciphersuite, provider, signer)?; - vec![encryption_keypair] + .leaf(leaf_index) + .ok_or_else(|| LibraryError::custom("Couldn't find own leaf"))?; + + let credential_with_key = match leaf_node_params.credential_with_key() { + Some(cwk) => cwk.to_owned(), + None => CredentialWithKey { + credential: leaf.credential().clone(), + signature_key: leaf.signature_key().clone(), + }, + }; + + let capabilities = match leaf_node_params.capabilities() { + Some(c) => c.to_owned(), + None => leaf.capabilities().clone(), + }; + + let extensions = match leaf_node_params.extensions() { + Some(e) => e.to_owned(), + None => leaf.extensions().clone(), + }; + + UpdateLeafNodeParams { + credential_with_key, + capabilities, + extensions, + } }; // Derive and apply an update path based on the previously // generated new leaf. - let (plain_path, mut new_parent_keypairs, commit_secret) = self - .diff - .apply_own_update_path(provider, signer, ciphersuite, group_id, leaf_index)?; - - new_keypairs.append(&mut new_parent_keypairs); + let (plain_path, new_keypairs, commit_secret) = self.diff.apply_own_update_path( + provider, + signer, + ciphersuite, + commit_type, + self.group_context().group_id().clone(), + leaf_index, + leaf_node_params, + )?; // After we've processed the path, we can update the group context s.t. // the updated group context is used for path secret encryption. Note // that we have not yet updated the confirmed transcript hash. - self.update_group_context(provider.crypto(), extensions)?; + self.update_group_context(provider.crypto(), gc_extensions)?; let serialized_group_context = self .group_context() diff --git a/openmls/src/group/public_group/mod.rs b/openmls/src/group/public_group/mod.rs index b4ffff0810..32dffa7397 100644 --- a/openmls/src/group/public_group/mod.rs +++ b/openmls/src/group/public_group/mod.rs @@ -26,7 +26,7 @@ use super::{GroupContext, GroupId, Member, ProposalStore, QueuedProposal, Staged use crate::treesync::{node::parent_node::PlainUpdatePathNode, treekem::UpdatePathNode}; use crate::{ binary_tree::{array_representation::TreeSize, LeafNodeIndex}, - ciphersuite::signable::Verifiable, + ciphersuite::{hash_ref::ProposalRef, signable::Verifiable}, error::LibraryError, extensions::RequiredCapabilitiesExtension, framing::InterimTranscriptHashInput, @@ -36,7 +36,7 @@ use crate::{ ConfirmationTag, PathSecret, }, schedule::CommitSecret, - storage::{OpenMlsProvider, StorageProvider}, + storage::PublicStorageProvider, treesync::{ errors::{DerivePathError, TreeSyncFromNodesError}, node::{ @@ -60,8 +60,8 @@ mod tests; mod validation; /// This struct holds all public values of an MLS group. -#[derive(Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq, Clone))] +#[derive(Debug)] +#[cfg_attr(any(test, feature = "test-utils"), derive(PartialEq, Clone))] pub struct PublicGroup { treesync: TreeSync, proposal_store: ProposalStore, @@ -108,14 +108,14 @@ impl PublicGroup { /// This function performs basic validation checks and returns an error if /// one of the checks fails. See [`CreationFromExternalError`] for more /// details. - pub fn from_external( - provider: &Provider, + pub fn from_external( + crypto: &impl OpenMlsCrypto, + storage: &StorageProvider, ratchet_tree: RatchetTreeIn, verifiable_group_info: VerifiableGroupInfo, proposal_store: ProposalStore, - ) -> Result<(Self, GroupInfo), CreationFromExternalError> { + ) -> Result<(Self, GroupInfo), CreationFromExternalError> { let ciphersuite = verifiable_group_info.ciphersuite(); - let crypto = provider.crypto(); let group_id = verifiable_group_info.group_id(); let ratchet_tree = ratchet_tree @@ -173,7 +173,7 @@ impl PublicGroup { }; public_group - .store(provider.storage()) + .store(storage) .map_err(CreationFromExternalError::WriteToStorageError)?; Ok((public_group, group_info)) @@ -288,8 +288,33 @@ impl PublicGroup { } /// Add the [`QueuedProposal`] to the [`PublicGroup`]s internal [`ProposalStore`]. - pub fn add_proposal(&mut self, proposal: QueuedProposal) { - self.proposal_store.add(proposal) + pub fn add_proposal( + &mut self, + storage: &Storage, + proposal: QueuedProposal, + ) -> Result<(), Storage::PublicError> { + storage.queue_proposal(self.group_id(), &proposal.proposal_reference(), &proposal)?; + self.proposal_store.add(proposal); + Ok(()) + } + + /// Remove the Proposal with the given [`ProposalRef`] from the [`PublicGroup`]s internal [`ProposalStore`]. + pub fn remove_proposal( + &mut self, + storage: &Storage, + proposal_ref: &ProposalRef, + ) -> Result<(), Storage::PublicError> { + storage.remove_proposal(self.group_id(), proposal_ref)?; + self.proposal_store.remove(proposal_ref); + Ok(()) + } + + /// Return all queued proposals + pub fn queued_proposals( + &self, + storage: &Storage, + ) -> Result, Storage::PublicError> { + storage.queued_proposals(self.group_id()) } } @@ -355,10 +380,10 @@ impl PublicGroup { /// existing group, both inside [`PublicGroup`] and in [`CoreGroup`]. /// /// [`CoreGroup`]: crate::group::core_group::CoreGroup - pub(crate) fn store( + pub(crate) fn store( &self, storage: &Storage, - ) -> Result<(), Storage::Error> { + ) -> Result<(), Storage::PublicError> { let group_id = self.group_context.group_id(); storage.write_tree(group_id, self.treesync())?; storage.write_confirmation_tag(group_id, self.confirmation_tag())?; @@ -371,10 +396,10 @@ impl PublicGroup { } /// Deletes the [`PublicGroup`] from storage. - pub(crate) fn delete( + pub(crate) fn delete( &self, storage: &Storage, - ) -> Result<(), Storage::Error> { + ) -> Result<(), Storage::PublicError> { storage.delete_tree(self.group_id())?; storage.delete_confirmation_tag(self.group_id())?; storage.delete_context(self.group_id())?; @@ -383,23 +408,27 @@ impl PublicGroup { Ok(()) } - /// Loads the [`PublicGroup`] from storage. Called from [`CoreGroup::load`]. - /// - /// [`CoreGroup::load`]: crate::group::core_group::CoreGroup::load - pub(crate) fn load( + /// Loads the [`PublicGroup`] corresponding to a [`GroupId`] from storage. + pub fn load( storage: &Storage, group_id: &GroupId, - ) -> Result, Storage::Error> { + ) -> Result, Storage::PublicError> { let treesync = storage.treesync(group_id)?; + let proposals: Vec<(ProposalRef, QueuedProposal)> = storage.queued_proposals(group_id)?; let group_context = storage.group_context(group_id)?; let interim_transcript_hash: Option = storage.interim_transcript_hash(group_id)?; let confirmation_tag = storage.confirmation_tag(group_id)?; + let mut proposal_store = ProposalStore::new(); + + for (_ref, proposal) in proposals { + proposal_store.add(proposal); + } let build = || -> Option { Some(Self { treesync: treesync?, - proposal_store: ProposalStore::new(), + proposal_store, group_context: group_context?, interim_transcript_hash: interim_transcript_hash?.0, confirmation_tag: confirmation_tag?, @@ -408,6 +437,16 @@ impl PublicGroup { Ok(build()) } + + /// Returns a reference to the [`ProposalStore`]. + pub(crate) fn proposal_store(&self) -> &ProposalStore { + &self.proposal_store + } + + /// Returns a mutable reference to the [`ProposalStore`]. + pub(crate) fn proposal_store_mut(&mut self) -> &mut ProposalStore { + &mut self.proposal_store + } } // Test functions @@ -425,7 +464,7 @@ impl PublicGroup { #[cfg(test)] pub(crate) fn encrypt_path( &self, - provider: &impl OpenMlsProvider, + provider: &impl crate::storage::OpenMlsProvider, ciphersuite: Ciphersuite, path: &[PlainUpdatePathNode], group_context: &[u8], diff --git a/openmls/src/group/public_group/process.rs b/openmls/src/group/public_group/process.rs index fe6daade9c..a689ec367d 100644 --- a/openmls/src/group/public_group/process.rs +++ b/openmls/src/group/public_group/process.rs @@ -1,3 +1,4 @@ +use openmls_traits::crypto::OpenMlsCrypto; use tls_codec::Serialize; use crate::{ @@ -9,13 +10,10 @@ use crate::{ ProcessedMessageContent, ProtocolMessage, Sender, SenderContext, UnverifiedMessage, }, group::{ - core_group::proposals::{ProposalStore, QueuedProposal}, - errors::ValidationError, - mls_group::errors::ProcessMessageError, - past_secrets::MessageSecretsStore, + core_group::proposals::QueuedProposal, errors::ValidationError, + mls_group::errors::ProcessMessageError, past_secrets::MessageSecretsStore, }, messages::proposals::Proposal, - storage::OpenMlsProvider, }; use super::PublicGroup; @@ -129,12 +127,11 @@ impl PublicGroup { /// - ValSem244 /// - ValSem245 /// - ValSem246 (as part of ValSem010) - pub fn process_message( + pub fn process_message( &self, - provider: &Provider, + crypto: &impl OpenMlsCrypto, message: impl Into, - ) -> Result> { - let crypto = provider.crypto(); + ) -> Result { let protocol_message = message.into(); // Checks the following semantic validation: // - ValSem002 @@ -161,7 +158,7 @@ impl PublicGroup { let unverified_message = self .parse_message(decrypted_message, None) .map_err(ProcessMessageError::from)?; - self.process_unverified_message(provider, unverified_message, &self.proposal_store) + self.process_unverified_message(crypto, unverified_message) } } @@ -192,18 +189,16 @@ impl PublicGroup { /// - ValSem242 /// - ValSem244 /// - ValSem246 (as part of ValSem010) - pub(crate) fn process_unverified_message( + pub(crate) fn process_unverified_message( &self, - provider: &Provider, + crypto: &impl OpenMlsCrypto, unverified_message: UnverifiedMessage, - proposal_store: &ProposalStore, - ) -> Result> { - let crypto = provider.crypto(); + ) -> Result { // Checks the following semantic validation: // - ValSem010 // - ValSem246 (as part of ValSem010) let (content, credential) = - unverified_message.verify(self.ciphersuite(), provider, self.version())?; + unverified_message.verify(self.ciphersuite(), crypto, self.version())?; match content.sender() { Sender::Member(_) | Sender::NewMemberCommit | Sender::NewMemberProposal => { @@ -229,7 +224,7 @@ impl PublicGroup { } } FramedContentBody::Commit(_) => { - let staged_commit = self.stage_commit(&content, proposal_store, crypto)?; + let staged_commit = self.stage_commit(&content, crypto)?; ProcessedMessageContent::StagedCommitMessage(Box::new(staged_commit)) } }; diff --git a/openmls/src/group/public_group/staged_commit.rs b/openmls/src/group/public_group/staged_commit.rs index 342dbcf77f..187fc45e34 100644 --- a/openmls/src/group/public_group/staged_commit.rs +++ b/openmls/src/group/public_group/staged_commit.rs @@ -2,17 +2,14 @@ use super::{super::errors::*, *}; use crate::{ framing::{mls_auth_content::AuthenticatedContent, mls_content::FramedContentBody, Sender}, group::{ - core_group::{ - proposals::{ProposalQueue, ProposalStore}, - staged_commit::StagedCommitState, - }, + core_group::{proposals::ProposalQueue, staged_commit::StagedCommitState}, StagedCommit, }, messages::{proposals::ProposalOrRef, Commit}, - storage::StorageProvider, }; #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone, PartialEq))] pub struct PublicStagedCommitState { pub(super) staged_diff: StagedPublicGroupDiff, pub(super) update_path_leaf_node: Option, @@ -46,7 +43,6 @@ impl PublicGroup { pub(crate) fn validate_commit<'a>( &self, mls_content: &'a AuthenticatedContent, - proposal_store: &ProposalStore, crypto: &impl OpenMlsCrypto, ) -> Result<(&'a Commit, ProposalQueue, LeafNodeIndex), StageCommitError> { let ciphersuite = self.ciphersuite(); @@ -87,7 +83,7 @@ impl PublicGroup { ciphersuite, crypto, commit.proposals.as_slice().to_vec(), - proposal_store, + self.proposal_store(), sender, ) .map_err(|e| { @@ -205,16 +201,15 @@ impl PublicGroup { /// - ValSem241 /// - ValSem242 /// - ValSem244 + /// /// Returns an error if the given commit was sent by the owner of this /// group. pub(crate) fn stage_commit( &self, mls_content: &AuthenticatedContent, - proposal_store: &ProposalStore, crypto: &impl OpenMlsCrypto, ) -> Result { - let (commit, proposal_queue, sender_index) = - self.validate_commit(mls_content, proposal_store, crypto)?; + let (commit, proposal_queue, sender_index) = self.validate_commit(mls_content, crypto)?; let staged_diff = self.stage_diff(mls_content, &proposal_queue, sender_index, crypto)?; let staged_state = PublicStagedCommitState { @@ -278,11 +273,11 @@ impl PublicGroup { } /// Merges a [StagedCommit] into the public group state. - pub fn merge_commit( + pub fn merge_commit( &mut self, storage: &Storage, staged_commit: StagedCommit, - ) -> Result<(), MergeCommitError> { + ) -> Result<(), MergeCommitError> { match staged_commit.into_state() { StagedCommitState::PublicState(staged_state) => { self.merge_diff(staged_state.staged_diff); @@ -291,6 +286,9 @@ impl PublicGroup { } self.proposal_store.empty(); + storage + .clear_proposal_queue::(self.group_id()) + .map_err(MergeCommitError::StorageError)?; self.store(storage).map_err(MergeCommitError::StorageError) } } diff --git a/openmls/src/group/public_group/tests.rs b/openmls/src/group/public_group/tests.rs index 6f39076b33..5cf00bcfe2 100644 --- a/openmls/src/group/public_group/tests.rs +++ b/openmls/src/group/public_group/tests.rs @@ -7,8 +7,8 @@ use crate::{ ProcessedMessageContent, ProtocolMessage, Sender, }, group::{ - test_core_group::setup_client, GroupId, MlsGroup, MlsGroupCreateConfig, ProposalStore, - StagedCommit, PURE_PLAINTEXT_WIRE_FORMAT_POLICY, + mls_group::tests_and_kats::utils::setup_client, GroupId, MlsGroup, MlsGroupCreateConfig, + ProposalStore, StagedCommit, PURE_PLAINTEXT_WIRE_FORMAT_POLICY, }, messages::proposals::Proposal, }; @@ -51,7 +51,8 @@ fn public_group(ciphersuite: Ciphersuite, provider: & .unwrap(); let ratchet_tree = alice_group.export_ratchet_tree(); let (mut public_group, _extensions) = PublicGroup::from_external( - provider, + provider.crypto(), + provider.storage(), ratchet_tree.into(), verifiable_group_info, ProposalStore::new(), @@ -72,7 +73,7 @@ fn public_group(ciphersuite: Ciphersuite, provider: & ProtocolMessage::PublicMessage(public_message) => public_message, }; let processed_message = public_group - .process_message(provider, public_message) + .process_message(provider.crypto(), public_message) .unwrap(); // Further inspection of the message can take place here ... @@ -134,7 +135,7 @@ fn public_group(ciphersuite: Ciphersuite, provider: & // The public group processes let ppm = public_group - .process_message(provider, into_public_message(queued_messages)) + .process_message(provider.crypto(), into_public_message(queued_messages)) .unwrap(); public_group .merge_commit(provider.storage(), extract_staged_commit(ppm)) @@ -178,7 +179,7 @@ fn public_group(ciphersuite: Ciphersuite, provider: & // The public group processes let ppm = public_group - .process_message(provider, into_public_message(queued_messages)) + .process_message(provider.crypto(), into_public_message(queued_messages)) .unwrap(); // We have to add the proposal to the public group's proposal store. match ppm.into_content() { @@ -190,7 +191,7 @@ fn public_group(ciphersuite: Ciphersuite, provider: & Proposal::Remove(r) => assert_eq!(r.removed(), LeafNodeIndex::new(1)), _ => panic!("Unexpected proposal type"), } - public_group.add_proposal(*p); + public_group.add_proposal(provider.storage(), *p).unwrap(); } } @@ -225,7 +226,10 @@ fn public_group(ciphersuite: Ciphersuite, provider: & // The public group processes let ppm = public_group - .process_message(provider, into_public_message(queued_messages.clone())) + .process_message( + provider.crypto(), + into_public_message(queued_messages.clone()), + ) .unwrap(); public_group .merge_commit(provider.storage(), extract_staged_commit(ppm)) diff --git a/openmls/src/group/public_group/validation.rs b/openmls/src/group/public_group/validation.rs index b7969e0f42..abfc52597d 100644 --- a/openmls/src/group/public_group/validation.rs +++ b/openmls/src/group/public_group/validation.rs @@ -431,6 +431,7 @@ impl PublicGroup { /// Validate Update proposals. This function implements the following checks: /// - ValSem111: Update Proposal: The sender of a full Commit must not include own update proposals /// - ValSem112: Update Proposal: The sender of a standalone update proposal must be of type member + /// /// TODO: #133 This validation must be updated according to Sec. 13.2 pub(crate) fn validate_update_proposals( &self, diff --git a/openmls/src/group/tests/mod.rs b/openmls/src/group/tests/mod.rs deleted file mode 100644 index c78c16e778..0000000000 --- a/openmls/src/group/tests/mod.rs +++ /dev/null @@ -1,34 +0,0 @@ -//! Unit tests for the core group - -#[cfg(test)] -mod external_add_proposal; -#[cfg(test)] -mod external_remove_proposal; -#[cfg(test)] -pub mod kat_messages; -#[cfg(test)] -pub mod kat_transcript_hashes; -#[cfg(test)] -mod test_commit_validation; -#[cfg(test)] -mod test_encoding; -#[cfg(test)] -mod test_external_commit_validation; -#[cfg(test)] -mod test_framing; -#[cfg(test)] -mod test_framing_validation; -#[cfg(test)] -mod test_group; -#[cfg(test)] -mod test_past_secrets; -#[cfg(test)] -mod test_proposal_validation; -#[cfg(test)] -mod test_remove_operation; -#[cfg(test)] -mod test_wire_format_policy; -#[cfg(test)] -pub(crate) mod utils; - -pub(crate) mod tree_printing; diff --git a/openmls/src/group/tests/test_group.rs b/openmls/src/group/tests/test_group.rs deleted file mode 100644 index 61984eb7bd..0000000000 --- a/openmls/src/group/tests/test_group.rs +++ /dev/null @@ -1,918 +0,0 @@ -use framing::mls_content_in::FramedContentBodyIn; -use tests::utils::{generate_credential_with_key, generate_key_package}; - -use crate::{ - ciphersuite::signable::Verifiable, framing::*, group::*, key_packages::*, - schedule::psk::store::ResumptionPskStore, test_utils::*, - tree::sender_ratchet::SenderRatchetConfiguration, treesync::node::leaf_node::TreeInfoTbs, *, -}; - -#[openmls_test::openmls_test] -fn create_commit_optional_path( - ciphersuite: Ciphersuite, - provider: &impl crate::storage::OpenMlsProvider, -) { - let group_aad = b"Alice's test group"; - // Framing parameters - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); - - // Define identities - let alice_credential_with_keys = generate_credential_with_key( - b"Alice".to_vec(), - ciphersuite.signature_algorithm(), - provider, - ); - let bob_credential_with_keys = - generate_credential_with_key(b"Bob".to_vec(), ciphersuite.signature_algorithm(), provider); - - // Generate Bob's KeyPackage - let bob_key_package = generate_key_package( - ciphersuite, - Extensions::empty(), - provider, - bob_credential_with_keys, - ); - - // Alice creates a group - let mut group_alice = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential_with_keys.credential_with_key, - ) - .build(provider, &alice_credential_with_keys.signer) - .expect("Error creating CoreGroup."); - - // Alice proposes to add Bob with forced self-update - // Even though there are only Add Proposals, this should generated a path field - // on the Commit - let bob_add_proposal = group_alice - .create_add_proposal( - framing_parameters, - bob_key_package.key_package().clone(), - &alice_credential_with_keys.signer, - ) - .expect("Could not create proposal."); - - let mut proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - bob_add_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .build(); - let create_commit_result = match group_alice.create_commit( - params, /* No PSK fetcher */ - provider, - &alice_credential_with_keys.signer, - ) { - Ok(c) => c, - Err(e) => panic!("Error creating commit: {e:?}"), - }; - let commit = match create_commit_result.commit.content() { - FramedContentBody::Commit(commit) => commit, - _ => panic!(), - }; - assert!(commit.has_path()); - - // Alice adds Bob without forced self-update - // Since there are only Add Proposals, this does not generate a path field on - // the Commit Creating a second proposal to add the same member should - // not fail, only committing that proposal should fail - let bob_add_proposal = group_alice - .create_add_proposal( - framing_parameters, - bob_key_package.key_package().clone(), - &alice_credential_with_keys.signer, - ) - .expect("Could not create proposal."); - - proposal_store.empty(); - proposal_store.add( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - bob_add_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = - match group_alice.create_commit(params, provider, &alice_credential_with_keys.signer) { - Ok(c) => c, - Err(e) => panic!("Error creating commit: {e:?}"), - }; - let commit = match create_commit_result.commit.content() { - FramedContentBody::Commit(commit) => commit, - _ => panic!(), - }; - assert!(!commit.has_path()); - - // Alice applies the Commit without the forced self-update - group_alice - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging pending commit"); - let ratchet_tree = group_alice.public_group().export_ratchet_tree(); - - // Bob creates group from Welcome - let group_bob = StagedCoreWelcome::new_from_welcome( - create_commit_result - .welcome_option - .expect("An unexpected error occurred."), - Some(ratchet_tree.into()), - bob_key_package, - provider, - ResumptionPskStore::new(1024), - ) - .and_then(|staged_join| staged_join.into_core_group(provider)) - .unwrap_or_else(|e| panic!("Error creating group from Welcome: {e:?}")); - - assert_eq!( - group_alice.public_group().export_ratchet_tree(), - group_bob.public_group().export_ratchet_tree() - ); - - // Alice updates - let alice_new_leaf_node = group_alice - .own_leaf_node() - .unwrap() - .updated( - ciphersuite, - TreeInfoTbs::Update(group_alice.own_tree_position()), - provider, - &alice_credential_with_keys.signer, - ) - .unwrap(); - let alice_update_proposal = group_alice - .create_update_proposal( - framing_parameters, - alice_new_leaf_node, - &alice_credential_with_keys.signer, - ) - .expect("Could not create proposal."); - - proposal_store.empty(); - proposal_store.add( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - alice_update_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - - // Only UpdateProposal - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = - match group_alice.create_commit(params, provider, &alice_credential_with_keys.signer) { - Ok(c) => c, - Err(e) => panic!("Error creating commit: {e:?}"), - }; - let commit = match create_commit_result.commit.content() { - FramedContentBody::Commit(commit) => commit, - _ => panic!(), - }; - assert!(commit.has_path()); - - // Apply UpdateProposal - group_alice - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging pending commit"); -} - -#[openmls_test::openmls_test] -fn basic_group_setup() { - let group_aad = b"Alice's test group"; - // Framing parameters - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); - - // Define credentials with keys - let alice_credential_with_keys = generate_credential_with_key( - b"Alice".to_vec(), - ciphersuite.signature_algorithm(), - provider, - ); - let bob_credential_with_keys = - generate_credential_with_key(b"Bob".to_vec(), ciphersuite.signature_algorithm(), provider); - - // Generate KeyPackages - let bob_key_package = generate_key_package( - ciphersuite, - Extensions::empty(), - provider, - bob_credential_with_keys, - ); - - // Alice creates a group - let group_alice = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential_with_keys.credential_with_key, - ) - .build(provider, &alice_credential_with_keys.signer) - .expect("Error creating CoreGroup."); - - // Alice adds Bob - let bob_add_proposal = group_alice - .create_add_proposal( - framing_parameters, - bob_key_package.key_package().clone(), - &alice_credential_with_keys.signer, - ) - .expect("Could not create proposal."); - - let proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - bob_add_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .build(); - let _commit = match group_alice.create_commit( - params, /* PSK fetcher */ - provider, - &alice_credential_with_keys.signer, - ) { - Ok(c) => c, - Err(e) => panic!("Error creating commit: {e:?}"), - }; -} - -/// This test simulates various group operations like Add, Update, Remove in a -/// small group -/// - Alice creates a group -/// - Alice adds Bob -/// - Alice sends a message to Bob -/// - Bob updates and commits -/// - Alice updates and commits -/// - Bob updates and Alice commits -/// - Bob adds Charlie -/// - Charlie sends a message to the group -/// - Charlie updates and commits -/// - Charlie removes Bob -#[openmls_test::openmls_test] -fn group_operations() { - let group_aad = b"Alice's test group"; - // Framing parameters - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); - let sender_ratchet_configuration = SenderRatchetConfiguration::default(); - - // Define credentials with keys - let alice_credential_with_keys = generate_credential_with_key( - b"Alice".to_vec(), - ciphersuite.signature_algorithm(), - provider, - ); - let bob_credential_with_keys = - generate_credential_with_key(b"Bob".to_vec(), ciphersuite.signature_algorithm(), provider); - - // Generate KeyPackages - let bob_key_package_bundle = KeyPackageBundle::generate( - provider, - &bob_credential_with_keys.signer, - ciphersuite, - bob_credential_with_keys.credential_with_key.clone(), - ); - let bob_key_package = bob_key_package_bundle.key_package(); - - // === Alice creates a group === - let mut group_alice = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential_with_keys.credential_with_key.clone(), - ) - .build(provider, &alice_credential_with_keys.signer) - .expect("Error creating CoreGroup."); - - // === Alice adds Bob === - let bob_add_proposal = group_alice - .create_add_proposal( - framing_parameters, - bob_key_package.clone(), - &alice_credential_with_keys.signer, - ) - .expect("Could not create proposal."); - - let mut proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - bob_add_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = group_alice - .create_commit(params, provider, &alice_credential_with_keys.signer) - .expect("Error creating commit"); - let commit = match create_commit_result.commit.content() { - FramedContentBody::Commit(commit) => commit, - _ => panic!("Wrong content type"), - }; - assert!(!commit.has_path()); - // Check that the function returned a Welcome message - assert!(create_commit_result.welcome_option.is_some()); - - group_alice - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging own commits"); - let ratchet_tree = group_alice.public_group().export_ratchet_tree(); - - let mut group_bob = match StagedCoreWelcome::new_from_welcome( - create_commit_result - .welcome_option - .expect("An unexpected error occurred."), - Some(ratchet_tree.into()), - bob_key_package_bundle, - provider, - ResumptionPskStore::new(1024), - ) - .and_then(|staged_join| staged_join.into_core_group(provider)) - { - Ok(group) => group, - Err(e) => panic!("Error creating group from Welcome: {e:?}"), - }; - - // Make sure that both groups have the same public tree - assert_eq!( - group_alice.public_group().export_ratchet_tree(), - group_bob.public_group().export_ratchet_tree() - ); - - // Make sure that both groups have the same group context - if group_alice.context() != group_bob.context() { - panic!("Different group contexts"); - } - - // === Alice sends a message to Bob === - let message_alice = [1, 2, 3]; - let mls_ciphertext_alice: PrivateMessageIn = group_alice - .create_application_message( - &[], - &message_alice, - 0, - provider, - &alice_credential_with_keys.signer, - ) - .expect("An unexpected error occurred.") - .into(); - - let verifiable_plaintext = group_bob - .decrypt_message( - provider.crypto(), - mls_ciphertext_alice.into(), - &sender_ratchet_configuration, - ) - .expect("An unexpected error occurred.") - .verifiable_content() - .to_owned(); - - let mls_plaintext_bob: AuthenticatedContentIn = verifiable_plaintext - .verify( - provider.crypto(), - &OpenMlsSignaturePublicKey::new( - alice_credential_with_keys.signer.to_public_vec().into(), - ciphersuite.signature_algorithm(), - ) - .unwrap(), - ) - .expect("An unexpected error occurred."); - - assert!(matches!( - mls_plaintext_bob.content(), - FramedContentBodyIn::Application(message) if message.as_slice() == &message_alice[..])); - - // === Bob updates and commits === - let bob_new_leaf_node = group_bob - .own_leaf_node() - .unwrap() - .updated( - ciphersuite, - TreeInfoTbs::Update(group_bob.own_tree_position()), - provider, - &alice_credential_with_keys.signer, - ) - .unwrap(); - - let update_proposal_bob = group_bob - .create_update_proposal( - framing_parameters, - bob_new_leaf_node, - &alice_credential_with_keys.signer, - ) - .expect("Could not create proposal."); - - proposal_store.empty(); - proposal_store.add( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - update_proposal_bob, - ) - .expect("Could not create QueuedProposal."), - ); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = - match group_bob.create_commit(params, provider, &bob_credential_with_keys.signer) { - Ok(c) => c, - Err(e) => panic!("Error creating commit: {e:?}"), - }; - - // Check that there is a path - let commit = match create_commit_result.commit.content() { - FramedContentBody::Commit(commit) => commit, - _ => panic!("Wrong content type"), - }; - assert!(commit.has_path()); - // Check there is no Welcome message - assert!(create_commit_result.welcome_option.is_none()); - - let staged_commit = group_alice - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect("Error applying commit (Alice)"); - group_alice - .merge_commit(provider, staged_commit) - .expect("error merging commit"); - - group_bob - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging own commits"); - - // Make sure that both groups have the same public tree - assert_eq!( - group_alice.public_group().export_ratchet_tree(), - group_bob.public_group().export_ratchet_tree() - ); - - // === Alice updates and commits === - let alice_new_leaf_node = group_alice - .own_leaf_node() - .unwrap() - .updated( - ciphersuite, - TreeInfoTbs::Update(group_alice.own_tree_position()), - provider, - &alice_credential_with_keys.signer, - ) - .unwrap(); - - let update_proposal_alice = group_alice - .create_update_proposal( - framing_parameters, - alice_new_leaf_node, - &alice_credential_with_keys.signer, - ) - .expect("Could not create proposal."); - - proposal_store.empty(); - proposal_store.add( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - update_proposal_alice, - ) - .expect("Could not create QueuedProposal."), - ); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = match group_alice.create_commit( - params, /* PSK fetcher */ - provider, - &alice_credential_with_keys.signer, - ) { - Ok(c) => c, - Err(e) => panic!("Error creating commit: {e:?}"), - }; - - // Check that there is a path - assert!(commit.has_path()); - - group_alice - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging own commits"); - let staged_commit = group_bob - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect("Error applying commit (Bob)"); - group_bob - .merge_commit(provider, staged_commit) - .expect("error merging commit"); - - // Make sure that both groups have the same public tree - assert_eq!( - group_alice.public_group().export_ratchet_tree(), - group_bob.public_group().export_ratchet_tree() - ); - - // === Bob updates and Alice commits === - let bob_new_leaf_node = group_bob - .own_leaf_node() - .unwrap() - .updated( - ciphersuite, - TreeInfoTbs::Update(group_bob.own_tree_position()), - provider, - &bob_credential_with_keys.signer, - ) - .unwrap(); - - let update_proposal_bob = group_bob - .create_update_proposal( - framing_parameters, - bob_new_leaf_node.clone(), - &bob_credential_with_keys.signer, - ) - .expect("Could not create proposal."); - - proposal_store.empty(); - proposal_store.add( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - update_proposal_bob.clone(), - ) - .expect("Could not create QueuedProposal."), - ); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = - match group_alice.create_commit(params, provider, &alice_credential_with_keys.signer) { - Ok(c) => c, - Err(e) => panic!("Error creating commit: {e:?}"), - }; - - // Check that there is a path - assert!(commit.has_path()); - - group_alice - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging own commits"); - - proposal_store.add( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - update_proposal_bob, - ) - .expect("Could not create StagedProposal."), - ); - - let staged_commit = group_bob - .read_keys_and_stage_commit( - &create_commit_result.commit, - &proposal_store, - &[bob_new_leaf_node], - provider, - ) - .expect("Error applying commit (Bob)"); - group_bob - .merge_commit(provider, staged_commit) - .expect("error merging commit"); - - // Make sure that both groups have the same public tree - assert_eq!( - group_alice.public_group().export_ratchet_tree(), - group_bob.public_group().export_ratchet_tree() - ); - - // === Bob adds Charlie === - let charlie_credential_with_keys = generate_credential_with_key( - b"Charlie".to_vec(), - ciphersuite.signature_algorithm(), - provider, - ); - - let charlie_key_package_bundle = KeyPackageBundle::generate( - provider, - &charlie_credential_with_keys.signer, - ciphersuite, - charlie_credential_with_keys.credential_with_key.clone(), - ); - let charlie_key_package = charlie_key_package_bundle.key_package().clone(); - - let add_charlie_proposal_bob = group_bob - .create_add_proposal( - framing_parameters, - charlie_key_package, - &bob_credential_with_keys.signer, - ) - .expect("Could not create proposal."); - - proposal_store.empty(); - proposal_store.add( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - add_charlie_proposal_bob, - ) - .expect("Could not create QueuedProposal."), - ); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = - match group_bob.create_commit(params, provider, &bob_credential_with_keys.signer) { - Ok(c) => c, - Err(e) => panic!("Error creating commit: {e:?}"), - }; - - // Check there is no path since there are only Add Proposals and no forced - // self-update - let commit = match create_commit_result.commit.content() { - FramedContentBody::Commit(commit) => commit, - _ => panic!("Wrong content type"), - }; - assert!(!commit.has_path()); - // Make sure this is a Welcome message for Charlie - assert!(create_commit_result.welcome_option.is_some()); - - let staged_commit = group_alice - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect("Error applying commit (Alice)"); - group_alice - .merge_commit(provider, staged_commit) - .expect("error merging commit"); - group_bob - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging own commits"); - - let ratchet_tree = group_alice.public_group().export_ratchet_tree(); - let mut group_charlie = match StagedCoreWelcome::new_from_welcome( - create_commit_result - .welcome_option - .expect("An unexpected error occurred."), - Some(ratchet_tree.into()), - charlie_key_package_bundle, - provider, - ResumptionPskStore::new(1024), - ) - .and_then(|staged_join| staged_join.into_core_group(provider)) - { - Ok(group) => group, - Err(e) => panic!("Error creating group from Welcome: {e:?}"), - }; - - // Make sure that all groups have the same public tree - assert_eq!( - group_alice.public_group().export_ratchet_tree(), - group_bob.public_group().export_ratchet_tree() - ); - assert_eq!( - group_alice.public_group().export_ratchet_tree(), - group_charlie.public_group().export_ratchet_tree() - ); - - // === Charlie sends a message to the group === - let message_charlie = [1, 2, 3]; - let mls_ciphertext_charlie: PrivateMessageIn = group_charlie - .create_application_message( - &[], - &message_charlie, - 0, - provider, - &charlie_credential_with_keys.signer, - ) - .expect("An unexpected error occurred.") - .into(); - - // Alice decrypts and verifies - let verifiable_plaintext = group_alice - .decrypt_message( - provider.crypto(), - mls_ciphertext_charlie.clone().into(), - &sender_ratchet_configuration, - ) - .expect("An unexpected error occurred.") - .verifiable_content() - .to_owned(); - - let mls_plaintext_alice: AuthenticatedContentIn = verifiable_plaintext - .verify( - provider.crypto(), - &OpenMlsSignaturePublicKey::new( - charlie_credential_with_keys.signer.to_public_vec().into(), - ciphersuite.signature_algorithm(), - ) - .unwrap(), - ) - .expect("An unexpected error occurred."); - - assert!(matches!( - mls_plaintext_alice.content(), - FramedContentBodyIn::Application(message) if message.as_slice() == &message_charlie[..])); - - // Bob decrypts and verifies - let verifiable_plaintext = group_bob - .decrypt_message( - provider.crypto(), - mls_ciphertext_charlie.into(), - &sender_ratchet_configuration, - ) - .expect("An unexpected error occurred.") - .verifiable_content() - .to_owned(); - - let mls_plaintext_bob: AuthenticatedContentIn = verifiable_plaintext - .verify( - provider.crypto(), - &OpenMlsSignaturePublicKey::new( - charlie_credential_with_keys.signer.to_public_vec().into(), - ciphersuite.signature_algorithm(), - ) - .unwrap(), - ) - .expect("An unexpected error occurred."); - - assert!(matches!( - mls_plaintext_bob.content(), - FramedContentBodyIn::Application(message) if message.as_slice() == &message_charlie[..])); - - // === Charlie updates and commits === - let charlie_new_leaf_node = group_charlie - .own_leaf_node() - .unwrap() - .updated( - ciphersuite, - TreeInfoTbs::Update(group_charlie.own_tree_position()), - provider, - &charlie_credential_with_keys.signer, - ) - .unwrap(); - - let update_proposal_charlie = group_charlie - .create_update_proposal( - framing_parameters, - charlie_new_leaf_node, - &charlie_credential_with_keys.signer, - ) - .expect("Could not create proposal."); - - proposal_store.empty(); - proposal_store.add( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - update_proposal_charlie, - ) - .expect("Could not create QueuedProposal."), - ); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = - match group_charlie.create_commit(params, provider, &charlie_credential_with_keys.signer) { - Ok(c) => c, - Err(e) => panic!("Error creating commit: {e:?}"), - }; - - // Check that there is a new KeyPackageBundle - let commit = match create_commit_result.commit.content() { - FramedContentBody::Commit(commit) => commit, - _ => panic!("Wrong content type"), - }; - assert!(commit.has_path()); - - let staged_commit = group_alice - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect("Error applying commit (Alice)"); - group_alice - .merge_commit(provider, staged_commit) - .expect("error merging commit"); - let staged_commit = group_bob - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect("Error applying commit (Bob)"); - group_bob - .merge_commit(provider, staged_commit) - .expect("error merging commit"); - group_charlie - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging own commits"); - - // Make sure that all groups have the same public tree - assert_eq!( - group_alice.public_group().export_ratchet_tree(), - group_bob.public_group().export_ratchet_tree() - ); - assert_eq!( - group_alice.public_group().export_ratchet_tree(), - group_charlie.public_group().export_ratchet_tree() - ); - - // === Charlie removes Bob === - let remove_bob_proposal_charlie = group_charlie - .create_remove_proposal( - framing_parameters, - group_bob.own_leaf_index(), - &charlie_credential_with_keys.signer, - ) - .expect("Could not create proposal."); - - proposal_store.empty(); - proposal_store.add( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - remove_bob_proposal_charlie, - ) - .expect("Could not create QueuedProposal."), - ); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - let create_commit_result = match group_charlie.create_commit( - params, /* PSK fetcher */ - provider, - &charlie_credential_with_keys.signer, - ) { - Ok(c) => c, - Err(e) => panic!("Error creating commit: {e:?}"), - }; - - // Check that there is a new KeyPackageBundle - assert!(commit.has_path()); - - let staged_commit = group_alice - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect("Error applying commit (Alice)"); - group_alice - .merge_commit(provider, staged_commit) - .expect("error merging commit"); - assert!(group_bob - .read_keys_and_stage_commit(&create_commit_result.commit, &proposal_store, &[], provider) - .expect("Could not stage commit.") - .self_removed()); - group_charlie - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging own commits"); - - assert_ne!( - group_alice.public_group().export_ratchet_tree(), - group_bob.public_group().export_ratchet_tree() - ); - assert_eq!( - group_alice.public_group().export_ratchet_tree(), - group_charlie.public_group().export_ratchet_tree() - ); - - // Make sure all groups export the same key - let alice_exporter = group_alice - .export_secret(provider.crypto(), "export test", &[], 32) - .expect("An unexpected error occurred."); - let charlie_exporter = group_charlie - .export_secret(provider.crypto(), "export test", &[], 32) - .expect("An unexpected error occurred."); - assert_eq!(alice_exporter, charlie_exporter); - - // Now alice tries to derive an exporter with too large of a key length. - let exporter_length: usize = u16::MAX.into(); - let exporter_length = exporter_length + 1; - let alice_exporter = - group_alice.export_secret(provider.crypto(), "export test", &[], exporter_length); - assert!(alice_exporter.is_err()) -} diff --git a/openmls/src/group/tests/kat_messages.rs b/openmls/src/group/tests_and_kats/kats/messages.rs similarity index 79% rename from openmls/src/group/tests/kat_messages.rs rename to openmls/src/group/tests_and_kats/kats/messages.rs index 19aee1a73a..fcf2074379 100644 --- a/openmls/src/group/tests/kat_messages.rs +++ b/openmls/src/group/tests_and_kats/kats/messages.rs @@ -4,18 +4,17 @@ //! See //! for more description on the test vectors. +use frankenstein::{FrankenFramedContentBody, FrankenPublicMessage}; use openmls_traits::{random::OpenMlsRand, types::SignatureScheme, OpenMlsProvider}; -use rand::{rngs::OsRng, RngCore}; use serde::{self, Deserialize, Serialize}; use thiserror::Error; use tls_codec::{Deserialize as TlsDeserialize, Serialize as TlsSerialize}; use crate::{ binary_tree::array_representation::LeafNodeIndex, - ciphersuite::Mac, framing::*, group::{ - tests::utils::{generate_credential_with_key, generate_key_package, randombytes}, + tests_and_kats::utils::{generate_credential_with_key, generate_key_package, randombytes}, *, }, key_packages::*, @@ -25,11 +24,10 @@ use crate::{ *, }, prelude::{CredentialType, LeafNode}, - schedule::psk::{store::ResumptionPskStore, *}, + schedule::psk::*, test_utils::*, - tree::sender_ratchet::*, treesync::node::{ - leaf_node::{Capabilities, TreeInfoTbs}, + leaf_node::{Capabilities, TreeInfoTbs, TreePosition}, NodeIn, }, versions::ProtocolVersion, @@ -135,22 +133,24 @@ pub fn generate_test_vector(ciphersuite: Ciphersuite) -> MessagesTestVector { ); // Let's create a group - let mut alice_group = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - alice_credential_with_key_and_signer - .credential_with_key - .clone(), - ) - .with_max_past_epoch_secrets(2) - .build(&provider, &alice_credential_with_key_and_signer.signer) - .unwrap(); + let mut alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .max_past_epochs(2) + .with_wire_format_policy(PURE_PLAINTEXT_WIRE_FORMAT_POLICY) + .build( + &provider, + &alice_credential_with_key_and_signer.signer, + alice_credential_with_key_and_signer + .credential_with_key + .clone(), + ) + .unwrap(); - let alice_ratchet_tree = alice_group.public_group().export_ratchet_tree(); + let alice_ratchet_tree = alice_group.export_ratchet_tree(); let alice_group_info = alice_group .export_group_info( - provider.rand(), + &provider, &alice_credential_with_key_and_signer.signer, true, ) @@ -176,7 +176,10 @@ pub fn generate_test_vector(ciphersuite: Ciphersuite) -> MessagesTestVector { .clone(), capabilities, Extensions::default(), - TreeInfoTbs::Update(alice_group.own_tree_position()), + TreeInfoTbs::Update(TreePosition::new( + alice_group.group_id().clone(), + alice_group.own_leaf_index(), + )), &provider, &alice_credential_with_key_and_signer.signer.clone(), ) @@ -241,117 +244,51 @@ pub fn generate_test_vector(ciphersuite: Ciphersuite) -> MessagesTestVector { let group_context_extensions_proposal = GroupContextExtensionProposal::new(Extensions::default()); - let framing_parameters = FramingParameters::new(b"aad", WireFormat::PrivateMessage); - - let add_proposal_content = alice_group - .create_add_proposal( - framing_parameters, - bob_key_package_bundle.key_package.clone(), - &alice_credential_with_key_and_signer.signer.clone(), - ) - .unwrap(); - - let mut proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - add_proposal_content.clone(), - ) - .unwrap(), - ); - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .build(); - let create_commit_result = alice_group - .create_commit( - params, + let (proposal_pt, _) = alice_group + .propose_add_member( &provider, &alice_credential_with_key_and_signer.signer, + bob_key_package_bundle.key_package(), ) .unwrap(); - alice_group - .merge_staged_commit( - &provider, - create_commit_result.staged_commit, - &mut proposal_store, - ) + + let (commit_pt, welcome, _) = alice_group + .commit_to_pending_proposals(&provider, &alice_credential_with_key_and_signer.signer) .unwrap(); - let commit = if let FramedContentBody::Commit(commit) = create_commit_result.commit.content() { - commit.clone() - } else { - panic!("Wrong content of MLS plaintext"); + let welcome = welcome.unwrap(); + + alice_group.merge_pending_commit(&provider).unwrap(); + + let commit_pm = match commit_pt.clone().body { + MlsMessageBodyOut::PublicMessage(pm) => pm, + _ => panic!("Wrong message type."), }; - let alice_welcome = create_commit_result.welcome_option.unwrap(); + let franken_commit_pm = FrankenPublicMessage::from(commit_pm.clone()); - let mut receiver_group = StagedCoreWelcome::new_from_welcome( - alice_welcome.clone(), - Some(alice_group.public_group().export_ratchet_tree().into()), - bob_key_package_bundle, - &provider, - ResumptionPskStore::new(1024), - ) - .and_then(|staged_join| staged_join.into_core_group(&provider)) - .expect("Error creating receiver group."); - - // Clone the secret tree to bypass FS restrictions - let private_message_application = alice_group - .create_application_message( - b"aad", - b"msg", - random_u8() as usize, + let FrankenFramedContentBody::Commit(commit) = franken_commit_pm.content.body else { + panic!("Wrong content of MLS plaintext"); + }; + + let application_ctxt = alice_group + .create_message( &provider, &alice_credential_with_key_and_signer.signer, + b"test", ) .unwrap(); - // Replace the secret tree - let verifiable_public_message_application: VerifiableAuthenticatedContentIn = receiver_group - .decrypt_message( - provider.crypto(), - ProtocolMessage::from(PrivateMessageIn::from(private_message_application)), - &SenderRatchetConfiguration::default(), - ) - .unwrap() - .verifiable_content() - .to_owned(); - let mls_content_application: AuthenticatedContent = - AuthenticatedContentIn::from(verifiable_public_message_application).into(); - - let encryption_target = match random_u32() % 3 { - 0 => create_commit_result.commit.clone(), - 1 => add_proposal_content.clone(), - 2 => mls_content_application.clone(), - _ => panic!("Modulo 3 of u32 shouldn't give us anything larger than 2"), - }; - - let mut mac_value = vec![0u8; alice_group.ciphersuite().hash_length()]; - OsRng.fill_bytes(&mut mac_value); - let random_membership_tag = MembershipTag(Mac { - mac_value: mac_value.into(), - }); - - let mut application_pt: PublicMessage = mls_content_application.into(); - application_pt.set_membership_tag_test(random_membership_tag.clone()); - let mut proposal_pt: PublicMessage = add_proposal_content.into(); - proposal_pt.set_membership_tag_test(random_membership_tag.clone()); - - let mut commit_pt: PublicMessage = create_commit_result.commit.into(); - commit_pt.set_membership_tag_test(random_membership_tag); - - let private_message = alice_group - .encrypt(encryption_target, random_u8() as usize, &provider) - .unwrap(); + // Craft a fake public application message from the valid commit. + let mut application_pt = FrankenPublicMessage::from(commit_pm); + application_pt.content.body = FrankenFramedContentBody::Application(randombytes(32).into()); + application_pt.auth.confirmation_tag = None; + let application_pt = PublicMessage::from(application_pt); + let application_message = MlsMessageOut::from(application_pt); MessagesTestVector { - mls_welcome: MlsMessageOut::from_welcome(alice_welcome, ProtocolVersion::Mls10) - .tls_serialize_detached() - .unwrap(), - mls_group_info: MlsMessageOut::from(alice_group_info) - .tls_serialize_detached() - .unwrap(), + mls_welcome: welcome.tls_serialize_detached().unwrap(), + mls_group_info: alice_group_info.tls_serialize_detached().unwrap(), mls_key_package: MlsMessageOut::from(alice_key_package) .tls_serialize_detached() .unwrap(), @@ -371,21 +308,10 @@ pub fn generate_test_vector(ciphersuite: Ciphersuite) -> MessagesTestVector { commit: commit.tls_serialize_detached().unwrap(), - public_message_application: MlsMessageOut::from(application_pt) - .tls_serialize_detached() - .unwrap(), - public_message_proposal: MlsMessageOut::from(proposal_pt) - .tls_serialize_detached() - .unwrap(), - public_message_commit: MlsMessageOut::from(commit_pt) - .tls_serialize_detached() - .unwrap(), - private_message: MlsMessageOut::from_private_message( - private_message, - ProtocolVersion::Mls10, - ) - .tls_serialize_detached() - .unwrap(), + public_message_application: application_message.tls_serialize_detached().unwrap(), + public_message_proposal: proposal_pt.tls_serialize_detached().unwrap(), + public_message_commit: commit_pt.tls_serialize_detached().unwrap(), + private_message: application_ctxt.tls_serialize_detached().unwrap(), } } @@ -573,8 +499,6 @@ pub fn run_test_vector(tv: MessagesTestVector) -> Result<(), EncodingMismatch> { // MlsPlaintextApplication let tv_public_message_application = tv.public_message_application; - // // Fake the wire format so we can deserialize - //tv_public_message_application[0] = WireFormat::PublicMessage as u8; let my_public_message_application = MlsMessageIn::tls_deserialize_exact(&tv_public_message_application) .unwrap() @@ -644,7 +568,7 @@ pub fn run_test_vector(tv: MessagesTestVector) -> Result<(), EncodingMismatch> { #[test] fn read_test_vectors_messages() { - let tests: Vec = read_json!("../../../test_vectors/messages.json"); + let tests: Vec = read_json!("../../../../test_vectors/messages.json"); for test_vector in tests { match run_test_vector(test_vector) { diff --git a/openmls/src/group/tests_and_kats/kats/mod.rs b/openmls/src/group/tests_and_kats/kats/mod.rs new file mode 100644 index 0000000000..c6ed6b9011 --- /dev/null +++ b/openmls/src/group/tests_and_kats/kats/mod.rs @@ -0,0 +1,2 @@ +mod messages; +mod transcript_hashes; diff --git a/openmls/src/group/tests/kat_transcript_hashes.rs b/openmls/src/group/tests_and_kats/kats/transcript_hashes.rs similarity index 99% rename from openmls/src/group/tests/kat_transcript_hashes.rs rename to openmls/src/group/tests_and_kats/kats/transcript_hashes.rs index 5d7ec46c94..383b951508 100644 --- a/openmls/src/group/tests/kat_transcript_hashes.rs +++ b/openmls/src/group/tests_and_kats/kats/transcript_hashes.rs @@ -13,7 +13,7 @@ use crate::{ binary_tree::array_representation::LeafNodeIndex, framing::{mls_auth_content::AuthenticatedContent, *}, group::{ - tests::utils::{generate_credential_with_key, randombytes}, + tests_and_kats::utils::{generate_credential_with_key, randombytes}, *, }, messages::*, diff --git a/openmls/src/group/tests_and_kats/mod.rs b/openmls/src/group/tests_and_kats/mod.rs new file mode 100644 index 0000000000..62632607f6 --- /dev/null +++ b/openmls/src/group/tests_and_kats/mod.rs @@ -0,0 +1,8 @@ +#[cfg(test)] +mod kats; +#[cfg(test)] +mod tests; +#[cfg(any(feature = "test-utils", test))] +pub(crate) mod tree_printing; +#[cfg(test)] +pub(crate) mod utils; diff --git a/openmls/src/group/tests_and_kats/tests/aad.rs b/openmls/src/group/tests_and_kats/tests/aad.rs new file mode 100644 index 0000000000..67af269b18 --- /dev/null +++ b/openmls/src/group/tests_and_kats/tests/aad.rs @@ -0,0 +1,191 @@ +// Import necessary modules and dependencies +use crate::{ + binary_tree::LeafNodeIndex, + framing::*, + group::{ + tests_and_kats::utils::{generate_credential_with_key, generate_key_package}, + *, + }, +}; + +// Tests the different variants of the RemoveOperation enum. +#[openmls_test::openmls_test] +fn test_add_member_with_aad( + ciphersuite: Ciphersuite, + provider: &impl crate::storage::OpenMlsProvider, +) { + // Test over both wire format policies + for wire_format_policy in [ + PURE_PLAINTEXT_WIRE_FORMAT_POLICY, + PURE_CIPHERTEXT_WIRE_FORMAT_POLICY, + ] { + let group_id = GroupId::from_slice(b"Test Group"); + + // Generate credentials with keys + let alice_credential_with_key_and_signer = generate_credential_with_key( + "Alice".into(), + ciphersuite.signature_algorithm(), + provider, + ); + + let bob_credential_with_key_and_signer = + generate_credential_with_key("Bob".into(), ciphersuite.signature_algorithm(), provider); + + let charlie_credential_with_key_and_signer = generate_credential_with_key( + "Charlie".into(), + ciphersuite.signature_algorithm(), + provider, + ); + + // Generate KeyPackages + let bob_key_package = generate_key_package( + ciphersuite, + Extensions::empty(), + provider, + bob_credential_with_key_and_signer.clone(), + ); + let charlie_key_package = generate_key_package( + ciphersuite, + Extensions::empty(), + provider, + charlie_credential_with_key_and_signer, + ); + + // Define the MlsGroup configuration + let mls_group_create_config = MlsGroupCreateConfig::builder() + .ciphersuite(ciphersuite) + .wire_format_policy(wire_format_policy) + .build(); + + // === Alice creates a group === + + let mut alice_group = MlsGroup::new_with_group_id( + provider, + &alice_credential_with_key_and_signer.signer, + &mls_group_create_config, + group_id, + alice_credential_with_key_and_signer + .credential_with_key + .clone(), + ) + .expect("An unexpected error occurred."); + + let aad = b"Test AAD".to_vec(); + + alice_group.set_aad(aad.clone()); + + // Test the AAD was set correctly + assert_eq!(alice_group.aad(), &aad); + + // === Alice adds Bob === + + let (_message, welcome, _group_info) = alice_group + .add_members( + provider, + &alice_credential_with_key_and_signer.signer, + &[bob_key_package.key_package().clone()], + ) + .expect("An unexpected error occurred."); + alice_group + .merge_pending_commit(provider) + .expect("error merging pending commit"); + + let welcome: MlsMessageIn = welcome.into(); + let welcome = welcome + .into_welcome() + .expect("expected message to be a welcome"); + + let mut bob_group = StagedWelcome::new_from_welcome( + provider, + mls_group_create_config.join_config(), + welcome.clone(), + Some(alice_group.export_ratchet_tree().into()), + ) + .expect("Error creating staged join from Welcome") + .into_group(provider) + .expect("Error creating group from staged join"); + + // === Alice sends a message to Bob === + + let message = b"Hello, World!".to_vec(); + alice_group.set_aad(aad.clone()); + let alice_message: MlsMessageIn = alice_group + .create_message( + provider, + &alice_credential_with_key_and_signer.signer, + &message, + ) + .expect("Error creating message") + .into(); + + // Test the AAD was reset + assert_eq!(alice_group.aad().len(), 0); + + let bob_message = bob_group + .process_message( + provider, + alice_message.clone().into_protocol_message().unwrap(), + ) + .expect("Error handling message"); + + // Test the AAD was set correctly + assert_eq!(bob_message.aad(), &aad); + + // === Alice adds Charlie === + + alice_group.set_aad(aad.clone()); + let (commit, _welcome, _group_info) = alice_group + .add_members( + provider, + &alice_credential_with_key_and_signer.signer, + &[charlie_key_package.key_package().clone()], + ) + .expect("An unexpected error occurred."); + alice_group + .merge_pending_commit(provider) + .expect("error merging pending commit"); + + // Test the AAD was reset + assert_eq!(alice_group.aad().len(), 0); + + let bob_processed_message = bob_group + .process_message(provider, commit.clone().into_protocol_message().unwrap()) + .expect("Error handling message"); + + match bob_processed_message.into_content() { + ProcessedMessageContent::StagedCommitMessage(bob_staged_commit) => { + bob_group + .merge_staged_commit(provider, *bob_staged_commit) + .unwrap(); + } + _ => panic!("Expected a StagedCommitMessage"), + } + + // Test the AAD was set correctly + assert_eq!(bob_message.aad(), &aad); + + // === Alice removes Charlie === + + alice_group.set_aad(aad.clone()); + let (commit, _welcome, _group_info) = alice_group + .remove_members( + provider, + &alice_credential_with_key_and_signer.signer, + &[LeafNodeIndex::new(2)], + ) + .expect("An unexpected error occurred."); + alice_group + .merge_pending_commit(provider) + .expect("error merging pending commit"); + + // Test the AAD was reset + assert_eq!(alice_group.aad().len(), 0); + + let bob_processed_message = bob_group + .process_message(provider, commit.clone().into_protocol_message().unwrap()) + .expect("Error handling message"); + + // Test the AAD was set correctly + assert_eq!(bob_processed_message.aad(), &aad); + } +} diff --git a/openmls/src/group/tests/test_commit_validation.rs b/openmls/src/group/tests_and_kats/tests/commit_validation.rs similarity index 96% rename from openmls/src/group/tests/test_commit_validation.rs rename to openmls/src/group/tests_and_kats/tests/commit_validation.rs index 186f116668..acfd5fdb69 100644 --- a/openmls/src/group/tests/test_commit_validation.rs +++ b/openmls/src/group/tests_and_kats/tests/commit_validation.rs @@ -4,7 +4,7 @@ use openmls_traits::{prelude::*, signatures::Signer, types::Ciphersuite}; use tls_codec::{Deserialize, Serialize}; -use super::utils::{ +use crate::group::tests_and_kats::utils::{ generate_credential_with_key, generate_key_package, resign_message, CredentialWithKeyAndSigner, }; use crate::{ @@ -16,6 +16,7 @@ use crate::{ schedule::{ExternalPsk, PreSharedKeyId, Psk}, treesync::{ errors::ApplyUpdatePathError, node::parent_node::PlainUpdatePathNode, treekem::UpdatePath, + LeafNodeParameters, }, }; @@ -168,7 +169,11 @@ fn test_valsem200() { // Now let's stick it in the commit. let serialized_message = alice_group - .self_update(provider, &alice_credential.signer) + .self_update( + provider, + &alice_credential.signer, + LeafNodeParameters::default(), + ) .expect("Error creating self-update") .tls_serialize_detached() .expect("Could not serialize message."); @@ -348,7 +353,6 @@ fn test_valsem201() { let params = CreateCommitParams::builder() .framing_parameters(alice_group.framing_parameters()) - .proposal_store(&alice_group.proposal_store) // has to be turned off otherwise commit path is always present .force_self_update(false) .build(); @@ -453,7 +457,11 @@ fn test_valsem202() { // Create the self-update let serialized_update = alice_group - .self_update(provider, &alice_credential.signer) + .self_update( + provider, + &alice_credential.signer, + LeafNodeParameters::default(), + ) .expect("Error creating self-update") .tls_serialize_detached() .expect("Could not serialize message."); @@ -530,7 +538,11 @@ fn test_valsem203() { // Create the self-update let serialized_update = alice_group - .self_update(provider, &alice_credential.signer) + .self_update( + provider, + &alice_credential.signer, + LeafNodeParameters::default(), + ) .expect("Error creating self-update") .tls_serialize_detached() .expect("Could not serialize message."); @@ -609,7 +621,11 @@ fn test_valsem204() { // Create the self-update let serialized_update = alice_group - .self_update(provider, &alice_credential.signer) + .self_update( + provider, + &alice_credential.signer, + LeafNodeParameters::default(), + ) .expect("Error creating self-update") .tls_serialize_detached() .expect("Could not serialize message."); @@ -732,7 +748,11 @@ fn test_valsem205() { // Create the self-update let serialized_update = alice_group - .self_update(provider, &alice_credential.signer) + .self_update( + provider, + &alice_credential.signer, + LeafNodeParameters::default(), + ) .expect("Error creating self-update") .tls_serialize_detached() .expect("Could not serialize message."); @@ -820,7 +840,11 @@ fn test_partial_proposal_commit( // Create second proposal in Alice's group let proposal_2 = alice_group - .propose_self_update(provider, &alice_credential.signer, None) + .propose_self_update( + provider, + &alice_credential.signer, + LeafNodeParameters::default(), + ) .map(|(out, _)| MlsMessageIn::from(out)) .unwrap(); let proposal_2 = bob_group @@ -835,13 +859,13 @@ fn test_partial_proposal_commit( // Alice creates a commit with only a subset of the epoch's proposals. Bob should still be able to process it. let remaining_proposal = alice_group - .proposal_store + .proposal_store() .proposals() .next() .cloned() .unwrap(); - alice_group.proposal_store.empty(); - alice_group.proposal_store.add(remaining_proposal); + alice_group.proposal_store_mut().empty(); + alice_group.proposal_store_mut().add(remaining_proposal); let (commit, _, _) = alice_group .commit_to_pending_proposals(provider, &alice_credential.signer) .unwrap(); diff --git a/openmls/src/group/tests/test_encoding.rs b/openmls/src/group/tests_and_kats/tests/encoding.rs similarity index 57% rename from openmls/src/group/tests/test_encoding.rs rename to openmls/src/group/tests_and_kats/tests/encoding.rs index c48b89705d..f5b014b60b 100644 --- a/openmls/src/group/tests/test_encoding.rs +++ b/openmls/src/group/tests_and_kats/tests/encoding.rs @@ -1,10 +1,13 @@ use openmls_traits::crypto::OpenMlsCrypto; use tls_codec::{Deserialize, Serialize}; -use super::utils::*; use crate::{ - binary_tree::LeafNodeIndex, framing::*, group::*, key_packages::*, messages::*, - schedule::psk::store::ResumptionPskStore, test_utils::*, + binary_tree::LeafNodeIndex, + framing::*, + group::{tests_and_kats::utils::*, *}, + key_packages::*, + messages::*, + treesync::LeafNodeParameters, }; /// Creates a simple test setup for various encoding tests. @@ -69,15 +72,14 @@ fn test_application_message_encoding(provider: &impl crate::storage::OpenMlsProv // Test encoding/decoding of Application messages. let message = randombytes(random_usize() % 1000); let aad = randombytes(random_usize() % 1000); + group_state.set_aad(aad); let encrypted_message = group_state - .create_application_message( - &aad, - &message, - 0, - provider, - &credential_with_key_and_signer.signer, - ) - .expect("An unexpected error occurred."); + .create_message(provider, &credential_with_key_and_signer.signer, &message) + .unwrap(); + let encrypted_message = match encrypted_message.body { + MlsMessageBodyOut::PrivateMessage(pm) => pm, + _ => panic!("Expected a PrivateMessage"), + }; let encrypted_message_bytes = encrypted_message .tls_serialize_detached() .expect("An unexpected error occurred."); @@ -100,8 +102,6 @@ fn test_update_proposal_encoding(provider: &impl crate::storage::OpenMlsProvider .get("alice") .expect("An unexpected error occurred.") .borrow(); - // Framing parameters - let framing_parameters = FramingParameters::new(&[], WireFormat::PublicMessage); for group_state in alice.group_states.borrow_mut().values_mut() { let credential_with_key_and_signer = alice @@ -109,29 +109,17 @@ fn test_update_proposal_encoding(provider: &impl crate::storage::OpenMlsProvider .get(&group_state.ciphersuite()) .expect("An unexpected error occurred."); - let key_package_bundle = KeyPackageBundle::generate( - provider, - &credential_with_key_and_signer.signer, - group_state.ciphersuite(), - credential_with_key_and_signer.credential_with_key.clone(), - ); - - let mut update: PublicMessage = group_state - .create_update_proposal( - framing_parameters, - key_package_bundle.key_package().leaf_node().clone(), + let (update, _) = group_state + .propose_self_update( + provider, &credential_with_key_and_signer.signer, + LeafNodeParameters::default(), ) - .expect("Could not create proposal.") - .into(); - update - .set_membership_tag( - provider.crypto(), - group_state.ciphersuite(), - group_state.message_secrets().membership_key(), - group_state.message_secrets().serialized_context(), - ) - .expect("error setting membership tag"); + .unwrap(); + let update = match update.body { + MlsMessageBodyOut::PublicMessage(pm) => pm, + _ => panic!("Expected a PublicMessage"), + }; let update_encoded = update .tls_serialize_detached() .expect("Could not encode proposal."); @@ -154,8 +142,6 @@ fn test_add_proposal_encoding(provider: &impl crate::storage::OpenMlsProvider) { .get("alice") .expect("An unexpected error occurred.") .borrow(); - // Framing parameters - let framing_parameters = FramingParameters::new(&[], WireFormat::PublicMessage); for group_state in alice.group_states.borrow_mut().values_mut() { let credential_with_key_and_signer = alice @@ -171,21 +157,17 @@ fn test_add_proposal_encoding(provider: &impl crate::storage::OpenMlsProvider) { ); // Adds - let mut add: PublicMessage = group_state - .create_add_proposal( - framing_parameters, - key_package_bundle.key_package().clone(), + let (add, _) = group_state + .propose_add_member( + provider, &credential_with_key_and_signer.signer, + key_package_bundle.key_package(), ) - .expect("Could not create proposal.") - .into(); - add.set_membership_tag( - provider.crypto(), - group_state.ciphersuite(), - group_state.message_secrets().membership_key(), - group_state.message_secrets().serialized_context(), - ) - .expect("error setting membership tag"); + .unwrap(); + let add = match add.body { + MlsMessageBodyOut::PublicMessage(pm) => pm, + _ => panic!("Expected a PublicMessage"), + }; let add_encoded = add .tls_serialize_detached() .expect("Could not encode proposal."); @@ -205,8 +187,6 @@ fn test_remove_proposal_encoding(provider: &impl crate::storage::OpenMlsProvider .get("alice") .expect("An unexpected error occurred.") .borrow(); - // Framing parameters - let framing_parameters = FramingParameters::new(&[], WireFormat::PublicMessage); for group_state in alice.group_states.borrow_mut().values_mut() { let credential_with_key_and_signer = alice @@ -214,22 +194,18 @@ fn test_remove_proposal_encoding(provider: &impl crate::storage::OpenMlsProvider .get(&group_state.ciphersuite()) .expect("An unexpected error occurred."); - let mut remove: PublicMessage = group_state - .create_remove_proposal( - framing_parameters, - LeafNodeIndex::new(1), + let (remove, _) = group_state + .propose_remove_member( + provider, &credential_with_key_and_signer.signer, + LeafNodeIndex::new(1), ) - .expect("Could not create proposal.") - .into(); - remove - .set_membership_tag( - provider.crypto(), - group_state.ciphersuite(), - group_state.message_secrets().membership_key(), - group_state.message_secrets().serialized_context(), - ) - .expect("error setting membership tag"); + .unwrap(); + let remove = match remove.body { + MlsMessageBodyOut::PublicMessage(pm) => pm, + _ => panic!("Expected a PublicMessage"), + }; + let remove_encoded = remove .tls_serialize_detached() .expect("Could not encode proposal."); @@ -249,8 +225,6 @@ fn test_commit_encoding(provider: &impl crate::storage::OpenMlsProvider) { .get("alice") .expect("An unexpected error occurred.") .borrow(); - // Framing parameters - let framing_parameters = FramingParameters::new(&[], WireFormat::PublicMessage); for group_state in alice.group_states.borrow_mut().values_mut() { let alice_credential_with_key_and_signer = alice @@ -258,27 +232,7 @@ fn test_commit_encoding(provider: &impl crate::storage::OpenMlsProvider) { .get(&group_state.ciphersuite()) .expect("An unexpected error occurred."); - let alice_key_package_bundle = KeyPackageBundle::generate( - provider, - &alice_credential_with_key_and_signer.signer, - group_state.ciphersuite(), - alice_credential_with_key_and_signer - .credential_with_key - .clone(), - ); - - // Create a few proposals to put into the commit - - // Alice updates her own leaf - let update = group_state - .create_update_proposal( - framing_parameters, - alice_key_package_bundle.key_package().leaf_node().clone(), - &alice_credential_with_key_and_signer.signer, - ) - .expect("Could not create proposal."); - - // Alice adds Charlie to the group + // Alice updates her own leaf and adds Charlie to the group let charlie_key_package = test_setup ._key_store .borrow_mut() @@ -286,51 +240,18 @@ fn test_commit_encoding(provider: &impl crate::storage::OpenMlsProvider) { .expect("An unexpected error occurred.") .pop() .expect("An unexpected error occurred."); - let add = group_state - .create_add_proposal( - framing_parameters, - charlie_key_package.clone(), - &alice_credential_with_key_and_signer.signer, - ) - .expect("Could not create proposal."); - - let mut proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - group_state.ciphersuite(), - provider.crypto(), - add, - ) - .expect("Could not create QueuedProposal."), - ); - proposal_store.add( - QueuedProposal::from_authenticated_content_by_ref( - group_state.ciphersuite(), - provider.crypto(), - update, - ) - .expect("Could not create QueuedProposal."), - ); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .build(); - let create_commit_result = group_state - .create_commit( - params, + let (commit, _, _) = group_state + .add_members( provider, &alice_credential_with_key_and_signer.signer, + &[charlie_key_package.clone()], ) - .expect("An unexpected error occurred."); - let mut commit: PublicMessage = create_commit_result.commit.into(); - commit - .set_membership_tag( - provider.crypto(), - group_state.ciphersuite(), - group_state.message_secrets().membership_key(), - group_state.message_secrets().serialized_context(), - ) - .expect("error setting membership tag"); + .expect("Could not create commit."); + + let commit = match commit.body { + MlsMessageBodyOut::PublicMessage(pm) => pm, + _ => panic!("Expected a PublicMessage"), + }; let commit_encoded = commit .tls_serialize_detached() .expect("An unexpected error occurred."); @@ -350,8 +271,6 @@ fn test_welcome_message_encoding(provider: &impl crate::storage::OpenMlsProvider .get("alice") .expect("An unexpected error occurred.") .borrow(); - // Framing parameters - let framing_parameters = FramingParameters::new(&[], WireFormat::PublicMessage); for group_state in alice.group_states.borrow_mut().values_mut() { let credential_with_key_and_signer = alice @@ -369,41 +288,17 @@ fn test_welcome_message_encoding(provider: &impl crate::storage::OpenMlsProvider .expect("An unexpected error occurred.") .pop() .expect("An unexpected error occurred."); - let add = group_state - .create_add_proposal( - framing_parameters, - charlie_key_package.clone(), + let (_commit, welcome, _) = group_state + .add_members( + provider, &credential_with_key_and_signer.signer, + &[charlie_key_package.clone()], ) - .expect("Could not create proposal."); - - let proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - group_state.ciphersuite(), - provider.crypto(), - add, - ) - .expect("Could not create QueuedProposal."), - ); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .build(); - let create_commit_result = group_state - .create_commit(params, provider, &credential_with_key_and_signer.signer) - .expect("An unexpected error occurred."); - // Alice applies the commit - group_state - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging own commits"); + .expect("Could not create commit."); + group_state.merge_pending_commit(provider).unwrap(); + let welcome = welcome.into_welcome().unwrap(); // Welcome messages - - let welcome = create_commit_result - .welcome_option - .expect("An unexpected error occurred."); - let welcome_encoded = welcome .tls_serialize_detached() .expect("An unexpected error occurred."); @@ -414,25 +309,14 @@ fn test_welcome_message_encoding(provider: &impl crate::storage::OpenMlsProvider assert_eq!(welcome, welcome_decoded); - let charlie = test_clients - .get("charlie") - .expect("An unexpected error occurred.") - .borrow(); - - let charlie_key_package_bundle = charlie - .find_key_package_bundle(&charlie_key_package, provider.crypto()) - .expect("An unexpected error occurred."); - // This makes Charlie decode the internals of the Welcome message, for // example the RatchetTreeExtension. - assert!(StagedCoreWelcome::new_from_welcome( - welcome, - Some(group_state.public_group().export_ratchet_tree().into()), - charlie_key_package_bundle, - provider, - ResumptionPskStore::new(1024), - ) - .and_then(|staged_join| staged_join.into_core_group(provider)) - .is_ok()); + let config = MlsGroupJoinConfig::default(); + let ratchet_tree = Some(group_state.export_ratchet_tree().into()); + let charlie_group = + StagedWelcome::new_from_welcome(provider, &config, welcome, ratchet_tree) + .unwrap() + .into_group(provider); + assert!(charlie_group.is_ok()); } } diff --git a/openmls/src/group/tests/external_add_proposal.rs b/openmls/src/group/tests_and_kats/tests/external_add_proposal.rs similarity index 98% rename from openmls/src/group/tests/external_add_proposal.rs rename to openmls/src/group/tests_and_kats/tests/external_add_proposal.rs index a284ec20b1..9c47a2bde0 100644 --- a/openmls/src/group/tests/external_add_proposal.rs +++ b/openmls/src/group/tests_and_kats/tests/external_add_proposal.rs @@ -9,11 +9,12 @@ use crate::{ external_proposals::*, proposals::{AddProposal, Proposal, ProposalType}, }, + treesync::LeafNodeParameters, }; use openmls_traits::{types::Ciphersuite, OpenMlsProvider as _}; -use super::utils::*; +use crate::group::tests_and_kats::utils::*; struct ProposalValidationTestSetup { alice_group: (MlsGroup, SignatureKeyPair), @@ -268,7 +269,7 @@ fn external_add_proposal_should_be_signed_by_key_package_it_references< alice_group .process_message(provider, invalid_proposal.into_protocol_message().unwrap()) .unwrap_err(), - ProcessMessageError::InvalidSignature + ProcessMessageError::ValidationError(ValidationError::InvalidSignature) )); } @@ -343,7 +344,7 @@ fn new_member_proposal_sender_should_be_reserved_for_join_proposals { + alice_group + .merge_staged_commit(provider, *staged_commit) + .unwrap(); + } + _ => panic!("Expected Commit message"), + } + + // Compare Alice's and Bob's private & public state + + assert_eq!( + alice_group.export_secret(provider, "label", b"context", 32), + bob_group.export_secret(provider, "label", b"context", 32) + ); + assert_eq!( + alice_group.export_ratchet_tree(), + bob_group.export_ratchet_tree() + ); + + // === 2-member group external join === + + // Charlie wants to commit externally. + + let verifiable_group_info = alice_group + .export_group_info(provider, &alice_credential.signer, false) + .unwrap() + .into_verifiable_group_info() + .unwrap(); + let tree_option = alice_group.export_ratchet_tree(); + + let (mut charlie_group, public_message_commit, _) = MlsGroup::join_by_external_commit( + provider, + &charlie_credential.signer, + Some(tree_option.into()), + verifiable_group_info, + alice_group.configuration(), + None, + None, + &[], + charlie_credential.credential_with_key.clone(), + ) + .unwrap(); + charlie_group.merge_pending_commit(provider).unwrap(); + + // Alice & Bob process Charlie's Commit + + let charlie_commit = MlsMessageIn::from(public_message_commit) + .into_plaintext() + .unwrap(); + + let alice_processed_message = alice_group + .process_message(provider, charlie_commit.clone()) + .unwrap(); + + match alice_processed_message.into_content() { + ProcessedMessageContent::StagedCommitMessage(staged_commit) => { + alice_group + .merge_staged_commit(provider, *staged_commit) + .unwrap(); + } + _ => panic!("Expected Commit message"), + } + + let bob_processed_message = bob_group.process_message(provider, charlie_commit).unwrap(); + + match bob_processed_message.into_content() { + ProcessedMessageContent::StagedCommitMessage(staged_commit) => { + bob_group + .merge_staged_commit(provider, *staged_commit) + .unwrap(); + } + _ => panic!("Expected Commit message"), + } + + // Compare Alice's, Bob's and Charlie's private & public state + + assert_eq!( + alice_group.export_secret(provider, "label", b"context", 32), + bob_group.export_secret(provider, "label", b"context", 32) + ); + assert_eq!( + alice_group.export_secret(provider, "label", b"context", 32), + charlie_group.export_secret(provider, "label", b"context", 32) + ); + assert_eq!( + alice_group.export_ratchet_tree(), + bob_group.export_ratchet_tree() + ); + assert_eq!( + alice_group.export_ratchet_tree(), + charlie_group.export_ratchet_tree() + ); + + // === Resync === + + // Alice wants to resync + + let verifiable_group_info = bob_group + .export_group_info(provider, &bob_credential.signer, false) + .unwrap() + .into_verifiable_group_info() + .unwrap(); + let tree_option = bob_group.export_ratchet_tree(); + + let (mut alice_group, public_message_commit, _) = MlsGroup::join_by_external_commit( + provider, + &alice_credential.signer, + Some(tree_option.into()), + verifiable_group_info, + bob_group.configuration(), + None, + None, + &[], + alice_credential.credential_with_key.clone(), + ) + .unwrap(); + alice_group.merge_pending_commit(provider).unwrap(); + + // Bob & Charlie process Alice's Commit + + let alice_commit = MlsMessageIn::from(public_message_commit) + .into_plaintext() + .unwrap(); + + let bob_processed_message = bob_group + .process_message(provider, alice_commit.clone()) + .unwrap(); + + match bob_processed_message.into_content() { + ProcessedMessageContent::StagedCommitMessage(staged_commit) => { + // Make sure there is a remove proposal for Alice + let remove_proposals = staged_commit.remove_proposals().collect::>(); + assert_eq!(remove_proposals.len(), 1); + let remove_proposal = &remove_proposals[0]; + assert_eq!(remove_proposal.remove_proposal().removed().u32(), 0); + bob_group + .merge_staged_commit(provider, *staged_commit) + .unwrap(); + } + _ => panic!("Expected Commit message"), + } + + let charlie_processed_message = charlie_group + .process_message(provider, alice_commit) + .unwrap(); + + match charlie_processed_message.into_content() { + ProcessedMessageContent::StagedCommitMessage(staged_commit) => { + charlie_group + .merge_staged_commit(provider, *staged_commit) + .unwrap(); + } + _ => panic!("Expected Commit message"), + } + + // Compare Alice's, Bob's and Charlie's private & public state + + assert_eq!( + alice_group.export_secret(provider, "label", b"context", 32), + bob_group.export_secret(provider, "label", b"context", 32) + ); + assert_eq!( + alice_group.export_secret(provider, "label", b"context", 32), + charlie_group.export_secret(provider, "label", b"context", 32) + ); + assert_eq!( + alice_group.export_ratchet_tree(), + bob_group.export_ratchet_tree() + ); + assert_eq!( + alice_group.export_ratchet_tree(), + charlie_group.export_ratchet_tree() + ); +} diff --git a/openmls/src/group/tests/test_external_commit_validation.rs b/openmls/src/group/tests_and_kats/tests/external_commit_validation.rs similarity index 98% rename from openmls/src/group/tests/test_external_commit_validation.rs rename to openmls/src/group/tests_and_kats/tests/external_commit_validation.rs index c1b1e66634..df1031b647 100644 --- a/openmls/src/group/tests/test_external_commit_validation.rs +++ b/openmls/src/group/tests_and_kats/tests/external_commit_validation.rs @@ -16,7 +16,7 @@ use crate::{ errors::{ ExternalCommitValidationError, ProcessMessageError, StageCommitError, ValidationError, }, - tests::utils::{ + tests_and_kats::utils::{ generate_credential_with_key, generate_key_package, resign_external_commit, }, Extensions, MlsGroup, OpenMlsSignaturePublicKey, PURE_CIPHERTEXT_WIRE_FORMAT_POLICY, @@ -82,6 +82,8 @@ fn test_valsem240() { .process_message(provider, ProtocolMessage::from(public_message_commit_bad)) .expect_err("Could process message despite missing external init proposal."); + println!("Got the error: {:?}", err); + assert!(matches!( err, ProcessMessageError::InvalidCommit(StageCommitError::ExternalCommitValidation( @@ -201,6 +203,8 @@ fn test_valsem242() { None, verifiable_group_info, alice_group.configuration(), + None, + None, &[], bob_credential.credential_with_key.clone(), ) @@ -505,7 +509,10 @@ fn test_valsem246() { // This shows that signature verification fails if the signature is not done // using the credential in the path. - assert!(matches!(err, ProcessMessageError::InvalidSignature)); + assert!(matches!( + err, + ProcessMessageError::ValidationError(ValidationError::InvalidSignature) + )); // This shows that the credential in the original path key package is actually bob's credential. let commit = if let FramedContentBody::Commit(commit) = public_message_commit.content() { @@ -582,6 +589,8 @@ fn test_pure_ciphertest() { None, verifiable_group_info, alice_group.configuration(), + None, + None, &[], bob_credential.credential_with_key.clone(), ) @@ -606,7 +615,7 @@ mod utils { use crate::{ framing::{MlsMessageIn, PublicMessage, Sender}, group::{ - tests::utils::{generate_credential_with_key, CredentialWithKeyAndSigner}, + tests_and_kats::utils::{generate_credential_with_key, CredentialWithKeyAndSigner}, MlsGroup, MlsGroupCreateConfig, WireFormatPolicy, }, }; @@ -667,6 +676,8 @@ mod utils { Some(tree_option.into()), verifiable_group_info, alice_group.configuration(), + None, + None, &[], bob_credential.credential_with_key.clone(), ) diff --git a/openmls/src/group/tests/external_remove_proposal.rs b/openmls/src/group/tests_and_kats/tests/external_remove_proposal.rs similarity index 98% rename from openmls/src/group/tests/external_remove_proposal.rs rename to openmls/src/group/tests_and_kats/tests/external_remove_proposal.rs index c6393d3d46..3a5ad98a57 100644 --- a/openmls/src/group/tests/external_remove_proposal.rs +++ b/openmls/src/group/tests_and_kats/tests/external_remove_proposal.rs @@ -4,7 +4,7 @@ use crate::{credentials::BasicCredential, framing::*, group::*, messages::extern use openmls_traits::{types::Ciphersuite, OpenMlsProvider as _}; -use super::utils::*; +use crate::group::tests_and_kats::utils::*; // Creates a standalone group fn new_test_group( @@ -316,7 +316,10 @@ fn external_remove_proposal_should_fail_when_invalid_signature() { .unwrap(), ) .unwrap_err(); - assert!(matches!(error, ProcessMessageError::InvalidSignature)); + assert!(matches!( + error, + ProcessMessageError::ValidationError(ValidationError::InvalidSignature) + )); } #[openmls_test] diff --git a/openmls/src/group/tests/test_framing.rs b/openmls/src/group/tests_and_kats/tests/framing.rs similarity index 94% rename from openmls/src/group/tests/test_framing.rs rename to openmls/src/group/tests_and_kats/tests/framing.rs index 9dd1e8b43a..8d133260f1 100644 --- a/openmls/src/group/tests/test_framing.rs +++ b/openmls/src/group/tests_and_kats/tests/framing.rs @@ -5,7 +5,7 @@ use openmls_traits::random::OpenMlsRand; use tls_codec::Serialize; -use super::utils::*; +use crate::group::tests_and_kats::utils::*; use crate::{ binary_tree::{array_representation::TreeSize, *}, ciphersuite::signable::Signable, @@ -63,18 +63,23 @@ fn padding(provider: &impl crate::storage::OpenMlsProvider) { .credentials .get(&group_state.ciphersuite()) .expect("An unexpected error occurred."); + // Set the padding size + let mut new_config = group_state.configuration().clone(); + new_config.padding_size = padding_size; + group_state + .set_configuration(provider.storage(), &new_config) + .unwrap(); for _ in 0..10 { let message = randombytes(random_usize() % 1000); let aad = randombytes(random_usize() % 1000); - let private_message = group_state - .create_application_message( - &aad, - &message, - padding_size, - provider, - &credential.signer, - ) - .expect("An unexpected error occurred."); + group_state.set_aad(aad); + let application_message = group_state + .create_message(provider, &credential.signer, &message) + .unwrap(); + let private_message = match application_message.body() { + MlsMessageBodyOut::PrivateMessage(pm) => pm, + _ => panic!("Unexpected match."), + }; let ciphertext = private_message.ciphertext(); let length = ciphertext.len(); let overflow = if padding_size > 0 { diff --git a/openmls/src/group/tests/test_framing_validation.rs b/openmls/src/group/tests_and_kats/tests/framing_validation.rs similarity index 92% rename from openmls/src/group/tests/test_framing_validation.rs rename to openmls/src/group/tests_and_kats/tests/framing_validation.rs index 39e3d0f815..3c515a11ae 100644 --- a/openmls/src/group/tests/test_framing_validation.rs +++ b/openmls/src/group/tests_and_kats/tests/framing_validation.rs @@ -4,9 +4,11 @@ use openmls_traits::prelude::{openmls_types::Ciphersuite, *}; use tls_codec::{Deserialize, Serialize}; -use crate::{binary_tree::LeafNodeIndex, framing::*, group::*, key_packages::*}; +use crate::{ + binary_tree::LeafNodeIndex, framing::*, group::*, key_packages::*, treesync::LeafNodeParameters, +}; -use super::utils::{ +use crate::group::tests_and_kats::utils::{ generate_credential_with_key, generate_key_package, CredentialWithKeyAndSigner, }; @@ -117,7 +119,11 @@ fn test_valsem002() { } = validation_test_setup(PURE_PLAINTEXT_WIRE_FORMAT_POLICY, ciphersuite, provider); let (message, _welcome, _group_info) = alice_group - .self_update(provider, &_alice_credential.signer) + .self_update( + provider, + &_alice_credential.signer, + LeafNodeParameters::default(), + ) .expect("Could not self-update."); let serialized_message = message @@ -164,7 +170,11 @@ fn test_valsem003() { // Alice needs to create a new message that Bob can process. let (message, _welcome, _group_info) = alice_group - .self_update(provider, &_alice_credential.signer) + .self_update( + provider, + &_alice_credential.signer, + LeafNodeParameters::default(), + ) .expect("Could not self update."); alice_group.merge_pending_commit(provider).unwrap(); @@ -188,7 +198,11 @@ fn test_valsem003() { // Do a second Commit to increase the epoch number let (message, _welcome, _group_info) = alice_group - .self_update(provider, &_alice_credential.signer) + .self_update( + provider, + &_alice_credential.signer, + LeafNodeParameters::default(), + ) .expect("Could not add member."); let current_epoch = alice_group.epoch(); @@ -257,7 +271,11 @@ fn test_valsem004() { } = validation_test_setup(PURE_PLAINTEXT_WIRE_FORMAT_POLICY, ciphersuite, provider); let (message, _welcome, _group_info) = alice_group - .self_update(provider, &_alice_credential.signer) + .self_update( + provider, + &_alice_credential.signer, + LeafNodeParameters::default(), + ) .expect("Could not self-update."); let serialized_message = message @@ -314,7 +332,11 @@ fn test_valsem005() { } = validation_test_setup(PURE_PLAINTEXT_WIRE_FORMAT_POLICY, ciphersuite, provider); let (message, _welcome, _group_info) = alice_group - .self_update(provider, &_alice_credential.signer) + .self_update( + provider, + &_alice_credential.signer, + LeafNodeParameters::default(), + ) .expect("Could not self-update."); let serialized_message = message @@ -418,7 +440,11 @@ fn test_valsem007() { } = validation_test_setup(PURE_PLAINTEXT_WIRE_FORMAT_POLICY, ciphersuite, provider); let (message, _welcome, _group_info) = alice_group - .self_update(provider, &_alice_credential.signer) + .self_update( + provider, + &_alice_credential.signer, + LeafNodeParameters::default(), + ) .expect("Could not self-update."); let serialized_message = message @@ -465,7 +491,11 @@ fn test_valsem008() { // Alice needs to create a new message that Bob can process. let (message, _welcome, _group_info) = alice_group - .self_update(provider, &_alice_credential.signer) + .self_update( + provider, + &_alice_credential.signer, + LeafNodeParameters::default(), + ) .expect("Could not self-update."); let serialized_message = message @@ -519,7 +549,11 @@ fn test_valsem009() { } = validation_test_setup(PURE_PLAINTEXT_WIRE_FORMAT_POLICY, ciphersuite, provider); let (message, _welcome, _group_info) = alice_group - .self_update(provider, &_alice_credential.signer) + .self_update( + provider, + &_alice_credential.signer, + LeafNodeParameters::default(), + ) .expect("Could not self-update."); let serialized_message = message @@ -576,7 +610,11 @@ fn test_valsem010() { // Alice needs to create a new message that Bob can process. let (message, _welcome, _group_info) = alice_group - .self_update(provider, &_alice_credential.signer) + .self_update( + provider, + &_alice_credential.signer, + LeafNodeParameters::default(), + ) .expect("Could not self update."); let serialized_message = message @@ -609,7 +647,10 @@ fn test_valsem010() { .process_message(provider, message_in) .expect_err("Could process message despite wrong signature."); - assert!(matches!(err, ProcessMessageError::InvalidSignature)); + assert!(matches!( + err, + ProcessMessageError::ValidationError(ValidationError::InvalidSignature) + )); // Positive case bob_group diff --git a/openmls/src/group/tests_and_kats/tests/group.rs b/openmls/src/group/tests_and_kats/tests/group.rs new file mode 100644 index 0000000000..3bfc5f40d6 --- /dev/null +++ b/openmls/src/group/tests_and_kats/tests/group.rs @@ -0,0 +1,493 @@ +use crate::{framing::*, group::*, test_utils::*, *}; +use mls_group::tests_and_kats::utils::{setup_alice_bob, setup_alice_bob_group, setup_client}; +use treesync::LeafNodeParameters; + +#[openmls_test::openmls_test] +fn create_commit_optional_path( + ciphersuite: Ciphersuite, + provider: &impl crate::storage::OpenMlsProvider, +) { + // Define identities + let (alice_credential_with_key, alice_signer, bob_kpb, _bob_signer) = + setup_alice_bob(ciphersuite, provider); + + // Alice creates a group + let mut alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .with_wire_format_policy(PURE_PLAINTEXT_WIRE_FORMAT_POLICY) + .build(provider, &alice_signer, alice_credential_with_key) + .unwrap(); + + // Alice proposes to add Bob with forced self-update + // Even though there are only Add Proposals, this should generated a path field + // on the Commit + let (commit_message, _welcome, _) = alice_group + .add_members(provider, &alice_signer, &[bob_kpb.key_package().clone()]) + .unwrap(); + + let commit = match commit_message.body() { + MlsMessageBodyOut::PublicMessage(pm) => match pm.content() { + FramedContentBody::Commit(commit) => commit, + _ => panic!(), + }, + _ => panic!(), + }; + + assert!(commit.has_path()); + + alice_group + .clear_pending_commit(provider.storage()) + .unwrap(); + + // Alice adds Bob without forced self-update + let (commit_message, welcome, _) = alice_group + .add_members_without_update(provider, &alice_signer, &[bob_kpb.key_package().clone()]) + .unwrap(); + + let commit = match commit_message.body() { + MlsMessageBodyOut::PublicMessage(pm) => match pm.content() { + FramedContentBody::Commit(commit) => commit, + _ => panic!(), + }, + _ => panic!(), + }; + + assert!(!commit.has_path()); + + // Alice applies the Commit without the forced self-update + alice_group.merge_pending_commit(provider).unwrap(); + let ratchet_tree = alice_group.export_ratchet_tree(); + + // Bob creates group from Welcome + let bob_group = StagedWelcome::new_from_welcome( + provider, + &MlsGroupJoinConfig::default(), + welcome.into_welcome().unwrap(), + Some(ratchet_tree.into()), + ) + .unwrap() + .into_group(provider) + .unwrap(); + + assert_eq!( + alice_group.export_ratchet_tree(), + bob_group.export_ratchet_tree() + ); + + // Alice updates + let (commit_message, _, _) = alice_group + .self_update(provider, &alice_signer, LeafNodeParameters::default()) + .unwrap(); + + let commit = match commit_message.body() { + MlsMessageBodyOut::PublicMessage(pm) => match pm.content() { + FramedContentBody::Commit(commit) => commit, + _ => panic!(), + }, + _ => panic!(), + }; + + assert!(commit.has_path()); + + // Apply UpdateProposal + alice_group.merge_pending_commit(provider).unwrap(); +} + +#[openmls_test::openmls_test] +fn basic_group_setup() { + let (mut alice_group, alice_signer, _, _, _) = setup_alice_bob_group(ciphersuite, provider); + + let _result = + match alice_group.self_update(provider, &alice_signer, LeafNodeParameters::default()) { + Ok(c) => c, + Err(e) => panic!("Error creating commit: {e:?}"), + }; +} + +/// This test simulates various group operations like Add, Update, Remove in a +/// small group +/// - Alice creates a group +/// - Alice adds Bob +/// - Alice sends a message to Bob +/// - Bob updates and commits +/// - Alice updates and commits +/// - Bob updates and Alice commits +/// - Bob adds Charlie +/// - Charlie sends a message to the group +/// - Charlie updates and commits +/// - Charlie removes Bob +#[openmls_test::openmls_test] +fn group_operations() { + // Create group with alice and bob + let (mut alice_group, alice_signer, mut bob_group, bob_signer, _) = + setup_alice_bob_group(ciphersuite, provider); + + // Make sure that both groups have the same public tree + assert_eq!( + alice_group.export_ratchet_tree(), + bob_group.export_ratchet_tree() + ); + + // Make sure that both groups have the same group context + if alice_group.export_group_context() != bob_group.export_group_context() { + panic!("Different group contexts"); + } + + // === Alice sends a message to Bob === + let message_alice = [1, 2, 3]; + let mls_cipertext_alice = alice_group + .create_message(provider, &alice_signer, &message_alice) + .expect("An unexpected error occurred."); + + let processed_message = bob_group + .process_message( + provider, + mls_cipertext_alice.into_protocol_message().unwrap(), + ) + .unwrap(); + + match processed_message.content() { + ProcessedMessageContent::ApplicationMessage(message) => { + assert_eq!(message, &ApplicationMessage::new(message_alice.to_vec())); + } + _ => panic!("Wrong content type"), + } + + // === Bob updates and commits === + let (commit_message, welcome_option, _) = bob_group + .self_update(provider, &bob_signer, LeafNodeParameters::default()) + .expect("Error updating group"); + + // Check that there is a path + let commit = match &commit_message.body { + MlsMessageBodyOut::PublicMessage(pm) => match pm.content() { + FramedContentBody::Commit(commit) => commit, + _ => panic!("Wrong content type"), + }, + _ => panic!("Wrong message type"), + }; + assert!(commit.has_path()); + // Check there is no Welcome message + assert!(welcome_option.is_none()); + + bob_group + .merge_pending_commit(provider) + .expect("error merging commit"); + + let processed_message = alice_group + .process_message(provider, commit_message.into_protocol_message().unwrap()) + .unwrap(); + match processed_message.into_content() { + ProcessedMessageContent::StagedCommitMessage(staged_commit) => { + alice_group + .merge_staged_commit(provider, *staged_commit) + .expect("error merging commit"); + } + _ => panic!("Wrong content type"), + } + + // Make sure that both groups have the same public tree + assert_eq!( + alice_group.export_ratchet_tree(), + bob_group.export_ratchet_tree() + ); + + // === Alice updates and commits === + let (commit_message, _, _) = alice_group + .self_update(provider, &alice_signer, LeafNodeParameters::default()) + .expect("Error updating group"); + + let commit = match &commit_message.body { + MlsMessageBodyOut::PublicMessage(pm) => match pm.content() { + FramedContentBody::Commit(commit) => commit, + _ => panic!("Wrong content type"), + }, + _ => panic!("Wrong message type"), + }; + + // Check that there is a path + assert!(commit.has_path()); + + alice_group + .merge_pending_commit(provider) + .expect("error merging commit"); + + let processed_message = bob_group + .process_message(provider, commit_message.into_protocol_message().unwrap()) + .unwrap(); + + match processed_message.into_content() { + ProcessedMessageContent::StagedCommitMessage(staged_commit) => { + bob_group + .merge_staged_commit(provider, *staged_commit) + .expect("error merging commit"); + } + _ => panic!("Wrong content type"), + } + + // Make sure that both groups have the same public tree + assert_eq!( + alice_group.export_ratchet_tree(), + bob_group.export_ratchet_tree() + ); + + // === Bob updates and Alice commits === + let (bob_update_proposal, _) = bob_group + .propose_self_update(provider, &bob_signer, LeafNodeParameters::default()) + .expect("Error proposing update"); + + match alice_group + .process_message( + provider, + bob_update_proposal.into_protocol_message().unwrap(), + ) + .unwrap() + .into_content() + { + ProcessedMessageContent::ProposalMessage(proposal) => { + alice_group + .store_pending_proposal(provider.storage(), *proposal) + .unwrap(); + } + _ => panic!("Wrong content type"), + } + + let (commit_message, _, _) = alice_group + .commit_to_pending_proposals(provider, &alice_signer) + .unwrap(); + + let commit = match &commit_message.body { + MlsMessageBodyOut::PublicMessage(pm) => match pm.content() { + FramedContentBody::Commit(commit) => commit, + _ => panic!("Wrong content type"), + }, + _ => panic!("Wrong message type"), + }; + + // Check that there is a path + assert!(commit.has_path()); + + alice_group.merge_pending_commit(provider).unwrap(); + + match bob_group.process_message(provider, commit_message.into_protocol_message().unwrap()) { + Ok(processed_message) => match processed_message.into_content() { + ProcessedMessageContent::StagedCommitMessage(staged_commit) => { + bob_group + .merge_staged_commit(provider, *staged_commit) + .expect("error merging commit"); + } + _ => panic!("Wrong content type"), + }, + Err(e) => panic!("Error processing message: {e:?}"), + } + + // Make sure that both groups have the same public tree + assert_eq!( + alice_group.export_ratchet_tree(), + bob_group.export_ratchet_tree() + ); + + // === Bob adds Charlie === + let (_charlie_credential_with_key, charlie_kpb, charlie_signer, _charlie_sig_pk) = + setup_client("Charlie", ciphersuite, provider); + + let (commit_message, welcome, _) = bob_group + .add_members(provider, &bob_signer, &[charlie_kpb.key_package().clone()]) + .expect("Could not create add commit."); + + bob_group.merge_pending_commit(provider).unwrap(); + + match alice_group.process_message(provider, commit_message.into_protocol_message().unwrap()) { + Ok(processed_message) => match processed_message.into_content() { + ProcessedMessageContent::StagedCommitMessage(staged_commit) => { + alice_group + .merge_staged_commit(provider, *staged_commit) + .expect("error merging commit"); + } + _ => panic!("Wrong content type"), + }, + Err(e) => panic!("Error processing message: {e:?}"), + } + + let config = MlsGroupJoinConfig::builder() + .wire_format_policy(PURE_PLAINTEXT_WIRE_FORMAT_POLICY) + .build(); + + let ratchet_tree = alice_group.export_ratchet_tree(); + let mut charlie_group = StagedWelcome::new_from_welcome( + provider, + &config, + welcome.into_welcome().unwrap(), + Some(ratchet_tree.into()), + ) + .unwrap() + .into_group(provider) + .unwrap(); + + // Make sure that all groups have the same public tree + assert_eq!( + alice_group.export_ratchet_tree(), + bob_group.export_ratchet_tree() + ); + assert_eq!( + alice_group.export_ratchet_tree(), + charlie_group.export_ratchet_tree() + ); + + // === Charlie sends a message to the group === + let message_charlie = [1, 2, 3]; + let mls_ciphertext_charlie = charlie_group + .create_message(provider, &charlie_signer, &message_charlie) + .expect("An unexpected error occurred."); + + let processed_message = alice_group + .process_message( + provider, + mls_ciphertext_charlie + .clone() + .into_protocol_message() + .unwrap(), + ) + .unwrap(); + + assert!(matches!( + processed_message.content(), + ProcessedMessageContent::ApplicationMessage(message) if message == &ApplicationMessage::new(message_charlie.to_vec()))); + + let processed_message = bob_group + .process_message( + provider, + mls_ciphertext_charlie.into_protocol_message().unwrap(), + ) + .unwrap(); + + assert!(matches!( + processed_message.content(), + ProcessedMessageContent::ApplicationMessage(message) if message == &ApplicationMessage::new(message_charlie.to_vec()))); + + // === Charlie updates and commits === + let (commit_message, _, _) = charlie_group + .self_update(provider, &charlie_signer, LeafNodeParameters::default()) + .expect("Error updating group"); + + let commit = match &commit_message.body { + MlsMessageBodyOut::PublicMessage(pm) => match pm.content() { + FramedContentBody::Commit(commit) => commit, + _ => panic!("Wrong content type"), + }, + _ => panic!("Wrong message type"), + }; + + assert!(commit.has_path()); + + charlie_group + .merge_pending_commit(provider) + .expect("error merging commit"); + + match alice_group + .process_message( + provider, + commit_message.clone().into_protocol_message().unwrap(), + ) + .unwrap() + .into_content() + { + ProcessedMessageContent::StagedCommitMessage(staged_commit) => { + alice_group + .merge_staged_commit(provider, *staged_commit) + .expect("error merging commit"); + } + _ => panic!("Wrong content type"), + }; + + match bob_group + .process_message(provider, commit_message.into_protocol_message().unwrap()) + .unwrap() + .into_content() + { + ProcessedMessageContent::StagedCommitMessage(staged_commit) => { + bob_group + .merge_staged_commit(provider, *staged_commit) + .expect("error merging commit"); + } + _ => panic!("Wrong content type"), + }; + + // Make sure that all groups have the same public tree + assert_eq!( + alice_group.export_ratchet_tree(), + bob_group.export_ratchet_tree() + ); + assert_eq!( + alice_group.export_ratchet_tree(), + charlie_group.export_ratchet_tree() + ); + + // === Charlie removes Bob === + let (commit_message, _, _) = charlie_group + .remove_members(provider, &charlie_signer, &[bob_group.own_leaf_index()]) + .expect("Could not create remove commit."); + + let commit = match &commit_message.body { + MlsMessageBodyOut::PublicMessage(pm) => match pm.content() { + FramedContentBody::Commit(commit) => commit, + _ => panic!("Wrong content type"), + }, + _ => panic!("Wrong message type"), + }; + + assert!(commit.has_path()); + + charlie_group + .merge_pending_commit(provider) + .expect("error merging commit"); + + match alice_group + .process_message( + provider, + commit_message.clone().into_protocol_message().unwrap(), + ) + .unwrap() + .into_content() + { + ProcessedMessageContent::StagedCommitMessage(staged_commit) => { + alice_group + .merge_staged_commit(provider, *staged_commit) + .expect("error merging commit"); + } + _ => panic!("Wrong content type"), + }; + + match bob_group + .process_message(provider, commit_message.into_protocol_message().unwrap()) + .unwrap() + .into_content() + { + ProcessedMessageContent::StagedCommitMessage(staged_commit) => { + bob_group + .merge_staged_commit(provider, *staged_commit) + .expect("error merging commit"); + } + _ => panic!("Wrong content type"), + }; + + assert_eq!( + alice_group.export_ratchet_tree(), + bob_group.export_ratchet_tree() + ); + assert_eq!( + alice_group.export_ratchet_tree(), + charlie_group.export_ratchet_tree() + ); + + // Make sure all groups export the same key + let alice_exporter = alice_group.epoch_authenticator(); + let charlie_exporter = charlie_group.epoch_authenticator(); + assert_eq!(alice_exporter, charlie_exporter); + + // Now alice tries to derive an exporter with too large of a key length. + let exporter_length: usize = u16::MAX.into(); + let exporter_length = exporter_length + 1; + let alice_exporter = alice_group.export_secret(provider, "export test", &[], exporter_length); + assert!(alice_exporter.is_err()) +} diff --git a/openmls/src/group/tests_and_kats/tests/group_context_extensions.rs b/openmls/src/group/tests_and_kats/tests/group_context_extensions.rs new file mode 100644 index 0000000000..542f4367f7 --- /dev/null +++ b/openmls/src/group/tests_and_kats/tests/group_context_extensions.rs @@ -0,0 +1,1137 @@ +use mls_group::tests_and_kats::utils::setup_client; +use openmls_basic_credential::SignatureKeyPair; +use openmls_test::openmls_test; +use openmls_traits::types::Ciphersuite; +use openmls_traits::OpenMlsProvider as _; +use tls_codec::{Deserialize as _, Serialize as _}; + +use crate::{ + ciphersuite::hash_ref::ProposalRef, + credentials::CredentialWithKey, + framing::*, + group::*, + key_packages::{errors::KeyPackageVerifyError, *}, + messages::group_info::GroupInfo, + test_utils::frankenstein::{self, FrankenMlsMessage}, + treesync::{node::leaf_node::Capabilities, LeafNodeParameters}, +}; + +/// The state of a group member: A PartyState and the corresponding MlsGroup. +struct MemberState { + party: PartyState, + group: MlsGroup, +} + +/// The state of a party that is not part of any groups. +#[allow(dead_code)] +struct PartyState { + provider: Provider, + credential_with_key: CredentialWithKey, + key_package_bundle: KeyPackageBundle, + signer: SignatureKeyPair, + sig_pk: OpenMlsSignaturePublicKey, + name: &'static str, +} + +impl PartyState { + /// Generate the PartyState for a new identity. + fn generate(name: &'static str, ciphersuite: Ciphersuite) -> Self { + let provider = Provider::default(); + let (credential_with_key, key_package_bundle, signer, sig_pk) = + setup_client(name, ciphersuite, &provider); + + PartyState { + provider, + name, + credential_with_key, + key_package_bundle, + signer, + sig_pk, + } + } + + /// Generate a new [`KeyPackage`] for the party. + fn key_package KeyPackageBuilder>( + &self, + ciphersuite: Ciphersuite, + f: F, + ) -> KeyPackageBundle { + f(KeyPackage::builder()) + .build( + ciphersuite, + &self.provider, + &self.signer, + self.credential_with_key.clone(), + ) + .unwrap_or_else(|err| panic!("failed to build key package at {}: {err}", self.name)) + } +} + +struct TestState { + alice: MemberState, + bob: MemberState, +} + +/// Sets up a group with two parties Alice and Bob, where Alice has capabilities for unknown +/// extensions 0xf001 and 0xf002, and Bob has capabilities for extension 0xf001, 0xf002 and +/// 0xf003. +fn setup( + ciphersuite: Ciphersuite, +) -> TestState { + let alice_party = PartyState::generate("alice", ciphersuite); + let bob_party = PartyState::generate("bob", ciphersuite); + + // === Alice creates a group === + let alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .with_wire_format_policy(WireFormatPolicy::new( + OutgoingWireFormatPolicy::AlwaysPlaintext, + IncomingWireFormatPolicy::Mixed, + )) + .with_capabilities( + Capabilities::builder() + .extensions(vec![ + ExtensionType::Unknown(0xf001), + ExtensionType::Unknown(0xf002), + ]) + .build(), + ) + .build( + &alice_party.provider, + &alice_party.signer, + alice_party.credential_with_key.clone(), + ) + .expect("error creating group using builder"); + + let mut alice = MemberState { + party: alice_party, + group: alice_group, + }; + + // === Alice adds Bob === + let bob_key_package = bob_party.key_package(ciphersuite, |builder| { + builder.leaf_node_capabilities( + Capabilities::builder() + .extensions(vec![ + ExtensionType::Unknown(0xf001), + ExtensionType::Unknown(0xf002), + ExtensionType::Unknown(0xf003), + ]) + .build(), + ) + }); + + alice.propose_add_member(bob_key_package.key_package()); + let (_, Some(welcome), _) = alice.commit_and_merge_pending() else { + panic!("expected receiving a welcome") + }; + + let welcome: MlsMessageIn = welcome.into(); + let welcome = welcome + .into_welcome() + .expect("expected message to be a welcome"); + + let bob_group = StagedWelcome::new_from_welcome( + &bob_party.provider, + alice.group.configuration(), + welcome, + Some(alice.group.export_ratchet_tree().into()), + ) + .expect("Error creating staged join from Welcome") + .into_group(&bob_party.provider) + .expect("Error creating group from staged join"); + + TestState { + alice, + bob: MemberState { + party: bob_party, + group: bob_group, + }, + } +} + +impl MemberState { + /// Thin wrapper around [`MlsGroup::propose_group_context_extensions`]. + fn propose_group_context_extensions( + &mut self, + extensions: Extensions, + ) -> (MlsMessageOut, ProposalRef) { + self.group + .propose_group_context_extensions(&self.party.provider, extensions, &self.party.signer) + .unwrap_or_else(|err| panic!("couldn't propose GCE at {}: {err}", self.party.name)) + } + + /// Thin wrapper around [`MlsGroup::update_group_context_extensions`]. + fn update_group_context_extensions( + &mut self, + extensions: Extensions, + ) -> (MlsMessageOut, Option, Option) { + self.group + .update_group_context_extensions(&self.party.provider, extensions, &self.party.signer) + .unwrap_or_else(|err| panic!("couldn't propose GCE at {}: {err}", self.party.name)) + } + + /// Thin wrapper around [`MlsGroup::propose_add_member`]. + fn propose_add_member(&mut self, key_package: &KeyPackage) -> (MlsMessageOut, ProposalRef) { + self.group + .propose_add_member(&self.party.provider, &self.party.signer, key_package) + .unwrap_or_else(|err| panic!("failed to propose member at {}: {err}", self.party.name)) + } + + /// Wrapper around [`MlsGroup::process_message`], asserting it's a commit and [`MlsGroup::merge_staged_commit`]. + fn process_and_merge_commit(&mut self, msg: MlsMessageIn) { + let msg = msg.into_protocol_message().unwrap(); + + let processed_msg = self + .group + .process_message(&self.party.provider, msg) + .unwrap_or_else(|err| panic!("error processing message at {}: {err}", self.party.name)); + + match processed_msg.into_content() { + ProcessedMessageContent::StagedCommitMessage(staged_commit) => self + .group + .merge_staged_commit(&self.party.provider, *staged_commit) + .unwrap_or_else(|err| { + panic!("error merging staged commit at {}: {err}", self.party.name) + }), + + other => { + panic!( + "expected a commit message at {}, got {:?}", + self.party.name, other + ) + } + } + } + + /// Wrapper around [`MlsGroup::process_message`], asserting it's a proposal and [`MlsGroup::store_pending_proposal`]. + fn process_and_store_proposal(&mut self, msg: MlsMessageIn) -> ProposalRef { + let msg = msg.into_protocol_message().unwrap(); + + let processed_msg = self + .group + .process_message(&self.party.provider, msg) + .unwrap_or_else(|err| panic!("error processing message at {}: {err}", self.party.name)); + + match processed_msg.into_content() { + ProcessedMessageContent::ProposalMessage(proposal) => { + let reference = proposal.proposal_reference(); + + self.group + .store_pending_proposal(self.party.provider.storage(), *proposal) + .unwrap_or_else(|err| { + panic!("error storing proposal at {}: {err}", self.party.name) + }); + + reference + } + other => { + panic!( + "expected a proposal message at {}, got {:?}", + self.party.name, other + ) + } + } + } + + /// This wrapper that expects [`MlsGroup::process_message`] to return an error. + fn fail_processing(&mut self, msg: MlsMessageIn) -> ProcessMessageError { + let msg = msg.into_protocol_message().unwrap(); + let err_msg = format!( + "expected an error when processing message at {}", + self.party.name + ); + + self.group + .process_message(&self.party.provider, msg) + .expect_err(&err_msg) + } + + /// This wrapper around [`MlsGroup::commit_to_pending_proposals`] + fn commit_to_pending_proposals( + &mut self, + ) -> (MlsMessageOut, Option, Option) { + self.group + .commit_to_pending_proposals(&self.party.provider, &self.party.signer) + .unwrap_or_else(|err| { + panic!( + "{} couldn't commit pending proposal: {err}", + self.party.name + ) + }) + } + + /// This wrapper around [`MlsGroup::merge_pending_commit`] + fn merge_pending_commit(&mut self) { + self.group + .merge_pending_commit(&self.party.provider) + .unwrap_or_else(|err| panic!("{} couldn't merge commit: {err}", self.party.name)); + } + + /// Wrapper around [`MlsGroup::commit_to_pending_proposals`] and [`MlsGroup::merge_pending_commit`]. + fn commit_and_merge_pending( + &mut self, + ) -> (MlsMessageOut, Option, Option) { + let commit_out = self.commit_to_pending_proposals(); + self.merge_pending_commit(); + commit_out + } +} + +/// Test that the happy case of group context extensions works +/// 1. set up group +/// 2. alice sets gce, commits +#[openmls_test] +fn happy_case() { + let TestState { mut alice, mut bob } = setup::(ciphersuite); + + // make extension with type 0xf001 a required capability + let (commit, _, _) = + alice.update_group_context_extensions(Extensions::single(Extension::RequiredCapabilities( + RequiredCapabilitiesExtension::new(&[ExtensionType::Unknown(0xf001)], &[], &[]), + ))); + + alice.merge_pending_commit(); + bob.process_and_merge_commit(commit.into()); + + // make extensions with type 0xf001 0xf002 a required capability, too; + // this time with a separate proposal + let (proposal, _) = bob.propose_group_context_extensions(Extensions::single( + Extension::RequiredCapabilities(RequiredCapabilitiesExtension::new( + &[ + ExtensionType::Unknown(0xf001), + ExtensionType::Unknown(0xf002), + ], + &[], + &[], + )), + )); + + alice.process_and_store_proposal(proposal.into()); + + let (commit, _, _) = alice.commit_and_merge_pending(); + bob.process_and_merge_commit(commit.into()); +} + +#[openmls_test] +fn self_update_happy_case() { + let TestState { mut alice, mut bob } = setup::(ciphersuite); + + let (update_prop, _) = bob + .group + .propose_self_update( + &bob.party.provider, + &bob.party.signer, + LeafNodeParameters::builder().build(), + ) + .unwrap(); + alice.process_and_store_proposal(update_prop.into()); + let (commit, _, _) = alice.commit_and_merge_pending(); + bob.process_and_merge_commit(commit.into()) +} + +/// This test does the same as self_update_happy_case, but does not use MemberState, so we can +/// can exactly see which calls to OpenMLS are done +#[openmls_test] +fn self_update_happy_case_simple() { + let alice_party = PartyState::::generate("alice", ciphersuite); + let bob_party = PartyState::::generate("bob", ciphersuite); + + // === Alice creates a group === + let mut alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .with_wire_format_policy(WireFormatPolicy::new( + OutgoingWireFormatPolicy::AlwaysPlaintext, + IncomingWireFormatPolicy::Mixed, + )) + .build( + &alice_party.provider, + &alice_party.signer, + alice_party.credential_with_key.clone(), + ) + .expect("error creating group using builder"); + + // === Alice adds Bob === + let bob_key_package = bob_party.key_package(ciphersuite, |builder| builder); + + alice_group + .propose_add_member( + &alice_party.provider, + &alice_party.signer, + bob_key_package.key_package(), + ) + .unwrap(); + + let (_, Some(welcome), _) = alice_group + .commit_to_pending_proposals(&alice_party.provider, &alice_party.signer) + .unwrap() + else { + panic!("expected receiving a welcome") + }; + + alice_group + .merge_pending_commit(&alice_party.provider) + .unwrap(); + + let welcome: MlsMessageIn = welcome.into(); + let welcome = welcome + .into_welcome() + .expect("expected message to be a welcome"); + + let mut bob_group = StagedWelcome::new_from_welcome( + &bob_party.provider, + alice_group.configuration(), + welcome, + Some(alice_group.export_ratchet_tree().into()), + ) + .expect("Error creating staged join from Welcome") + .into_group(&bob_party.provider) + .expect("Error creating group from staged join"); + + let (update_proposal_msg, _) = bob_group + .propose_self_update( + &bob_party.provider, + &bob_party.signer, + LeafNodeParameters::builder().build(), + ) + .unwrap(); + + let ProcessedMessageContent::ProposalMessage(update_proposal) = alice_group + .process_message( + &alice_party.provider, + update_proposal_msg.clone().into_protocol_message().unwrap(), + ) + .unwrap() + .into_content() + else { + panic!("expected a proposal, got {update_proposal_msg:?}"); + }; + alice_group + .store_pending_proposal(alice_party.provider.storage(), *update_proposal) + .unwrap(); + + let (commit_msg, _, _) = alice_group + .commit_to_pending_proposals(&alice_party.provider, &alice_party.signer) + .unwrap(); + + bob_group + .process_message( + &bob_party.provider, + commit_msg.into_protocol_message().unwrap(), + ) + .unwrap(); + + bob_group.merge_pending_commit(&bob_party.provider).unwrap() +} + +/// This tests makes sure that validation check 103 is performed: +/// +/// Verify that the LeafNode is compatible with the group's parameters. +/// If the GroupContext has a required_capabilities extension, then the +/// required extensions, proposals, and credential types MUST be listed +/// in the LeafNode's capabilities field. +/// +/// So far, we only test whether the check is done for extension types. +#[openmls_test] +fn fail_insufficient_extensiontype_capabilities_add_valno103() { + let TestState { mut alice, mut bob } = setup::(ciphersuite); + + let (gce_req_cap_commit, _, _) = + alice.update_group_context_extensions(Extensions::single(Extension::RequiredCapabilities( + RequiredCapabilitiesExtension::new(&[ExtensionType::Unknown(0xf002)], &[], &[]), + ))); + + alice.merge_pending_commit(); + bob.process_and_merge_commit(gce_req_cap_commit.clone().into()); + + // extract values we need later + let frankenstein::FrankenMlsMessage { + version, + body: + frankenstein::FrankenMlsMessageBody::PublicMessage(frankenstein::FrankenPublicMessage { + content: + frankenstein::FrankenFramedContent { + group_id, + epoch: gce_commit_epoch, + sender, + authenticated_data, + .. + }, + .. + }), + } = frankenstein::FrankenMlsMessage::from(gce_req_cap_commit) + else { + unreachable!() + }; + + let charlie = PartyState::::generate("charlie", ciphersuite); + let charlie_kpb = charlie.key_package(ciphersuite, |builder| { + builder.leaf_node_capabilities( + Capabilities::builder() + .extensions(vec![ExtensionType::Unknown(0xf001)]) + .build(), + ) + }); + + let commit_content = frankenstein::FrankenFramedContent { + body: frankenstein::FrankenFramedContentBody::Commit(frankenstein::FrankenCommit { + proposals: vec![frankenstein::FrankenProposalOrRef::Proposal( + frankenstein::FrankenProposal::Add(frankenstein::FrankenAddProposal { + key_package: charlie_kpb.key_package.into(), + }), + )], + path: None, + }), + group_id, + epoch: gce_commit_epoch + 1, + sender, + authenticated_data, + }; + + let group_context = alice.group.export_group_context().clone(); + + let bob_group_context = bob.group.export_group_context(); + assert_eq!( + bob_group_context.confirmed_transcript_hash(), + group_context.confirmed_transcript_hash() + ); + + let secrets = alice.group.group().message_secrets(); + let membership_key = secrets.membership_key().as_slice(); + + let franken_commit = frankenstein::FrankenMlsMessage { + version, + body: frankenstein::FrankenMlsMessageBody::PublicMessage( + frankenstein::FrankenPublicMessage::auth( + &alice.party.provider, + ciphersuite, + &alice.party.signer, + commit_content, + Some(&group_context.into()), + Some(membership_key), + // this is a dummy confirmation_tag: + Some(vec![0u8; 32].into()), + ), + ), + }; + + let fake_commit = MlsMessageIn::tls_deserialize( + &mut franken_commit.tls_serialize_detached().unwrap().as_slice(), + ) + .unwrap(); + + // Note: If this starts failing, the order in which validation is checked may have changed and we + // fail on the fact that the confirmation tag is wrong. in that case, either the check has to be + // disabled, or the frankenstein framework needs code to properly compute it. + let err = bob.fail_processing(fake_commit); + assert!( + matches!( + err, + ProcessMessageError::InvalidCommit(StageCommitError::ProposalValidationError( + ProposalValidationError::InsufficientCapabilities + )) + ), + "got wrong error: {err:#?}" + ); +} + +// Test structure: +// - (alice creates group, adds bob, bob accepts) +// - This is part of the setup function +// - alice proposal GCE with required capabilities and commits +// - bob adds the proposal and merges the commit +// - bob proposes a self-update, but we tamper with it by removing +// an extension type from the capabilities. This makes it invalid. +// - we craft a commit by alice, committing the invalid proposal +// - it can't be done by bob, because the sender of a commit +// containing an update proposal can not be the owner of the +// leaf node +// - bob processes the invalid commit, which should give an InsufficientCapabilities error +#[openmls_test] +fn fail_insufficient_extensiontype_capabilities_update_valno103() { + let TestState { mut alice, mut bob } = setup::(ciphersuite); + + // requires that all members need support for extension type 0xf002 + let (gce_req_cap_commit, _, _) = + alice.update_group_context_extensions(Extensions::single(Extension::RequiredCapabilities( + RequiredCapabilitiesExtension::new(&[ExtensionType::Unknown(0xf002)], &[], &[]), + ))); + + alice.merge_pending_commit(); + bob.process_and_merge_commit(gce_req_cap_commit.clone().into()); + + // let bob propose an update to their leaf node. + // we immediately discard it, because we want to tamper with it. + let (update_prop, _) = bob + .group + .propose_self_update( + &bob.party.provider, + &bob.party.signer, + LeafNodeParameters::builder().build(), + ) + .unwrap(); + bob.group + .clear_pending_proposals(bob.party.provider.storage()) + .unwrap(); + + // extract the FramedContent from the proposal MlsMessage, because that is + // what we'll have to pass into the `FrankenPublicMessage::auth` method later. + let frankenstein::FrankenMlsMessage { + version, + body: + frankenstein::FrankenMlsMessageBody::PublicMessage(frankenstein::FrankenPublicMessage { + content: mut franken_proposal_content, + .. + }), + } = frankenstein::FrankenMlsMessage::from(update_prop.clone()) + else { + unreachable!() + }; + + // we want to change the leaf node in the update proposal, so let's get a mutable borrow on that + let frankenstein::FrankenFramedContent { + body: + frankenstein::FrankenFramedContentBody::Proposal(frankenstein::FrankenProposal::Update( + frankenstein::FrankenUpdateProposal { + leaf_node: bob_franken_leaf_node, + }, + )), + .. + } = &mut franken_proposal_content + else { + unreachable!(); + }; + + // Remove the extension type from the capabilities that is part of required capabilities + // Committing this would be illegal + assert_eq!( + bob_franken_leaf_node.capabilities.extensions.remove(1), + 0xf002 + ); + + // Re-sign the leaf node so the signature checks pass + bob_franken_leaf_node.resign( + Some(frankenstein::FrankenTreePosition { + group_id: bob.group.group_id().as_slice().to_vec().into(), + leaf_index: bob.group.own_leaf_index().u32(), + }), + &bob.party.signer, + ); + + // prepare data needed for proposal + let group_context = bob.group.export_group_context().clone(); + let secrets = bob.group.group().message_secrets(); + let membership_key = secrets.membership_key().as_slice(); + + // build MlsMessage containing the proposal + let franken_proposal = frankenstein::FrankenMlsMessage { + version, + body: frankenstein::FrankenMlsMessageBody::PublicMessage( + frankenstein::FrankenPublicMessage::auth( + &bob.party.provider, + ciphersuite, + &bob.party.signer, + franken_proposal_content.clone(), + Some(&group_context.into()), + Some(membership_key), + // proposals don't have confirmation tags + None, + ), + ), + }; + let fake_proposal = MlsMessageIn::tls_deserialize( + &mut franken_proposal + .tls_serialize_detached() + .unwrap() + .as_slice(), + ) + .unwrap(); + + // alice stores the proposal. + alice.process_and_store_proposal(fake_proposal.clone()); + + // Now we'll craft a commit to the proposal signed by alice. + // For that we need a few values, let's fetch and build them. + let proposal_ref = bob.process_and_store_proposal(fake_proposal); + let alice_sender = frankenstein::FrankenSender::Member(0); + + // This is a commit, claimed to be from alice, that commits to the proposal ref of the invalid proposal + let commit_content = frankenstein::FrankenFramedContent { + sender: alice_sender, + body: frankenstein::FrankenFramedContentBody::Commit(frankenstein::FrankenCommit { + proposals: vec![frankenstein::FrankenProposalOrRef::Reference( + proposal_ref.as_slice().to_vec().into(), + )], + path: None, + }), + + ..franken_proposal_content + }; + + // prepare data needed for making the message authentic + let group_context = alice.group.export_group_context().clone(); + let secrets = alice.group.group().message_secrets(); + let membership_key = secrets.membership_key().as_slice(); + + let franken_commit = frankenstein::FrankenMlsMessage { + version, + body: frankenstein::FrankenMlsMessageBody::PublicMessage( + frankenstein::FrankenPublicMessage::auth( + &alice.party.provider, + ciphersuite, + &alice.party.signer, + commit_content, + Some(&group_context.into()), + Some(membership_key), + Some(vec![0; 32].into()), + ), + ), + }; + let fake_commit = MlsMessageIn::tls_deserialize( + &mut franken_commit.tls_serialize_detached().unwrap().as_slice(), + ) + .unwrap(); + + // when bob processes the commit, it should fail because the leaf node's capabilties do not + // satisfy those required by the group. + let err = bob.fail_processing(fake_commit); + + // Note: If this starts failing, the order in which validation is checked may have changed and we + // fail on the fact that the confirmation tag is wrong. in that case, either the check has to be + // disabled, or the frankenstein framework yet yet needs code to properly commpute it. + assert!( + matches!( + err, + ProcessMessageError::InvalidCommit(StageCommitError::ProposalValidationError( + ProposalValidationError::InsufficientCapabilities + )) + ), + "expected a different error, got: {err} ({err:#?})" + ); +} + +// This test doesn't belong here, but it's nice to have. It would be nice to factor it out, but +// it relies on the testing functions. +// +// I suppose we need to talk about which test framework is the one we need. +// See https://github.com/openmls/openmls/issues/1618. +#[openmls_test] +fn fail_key_package_version_valno201() { + let TestState { mut alice, mut bob } = setup::(ciphersuite); + + let charlie = PartyState::::generate("charlie", ciphersuite); + let charlie_key_package_bundle = charlie.key_package(ciphersuite, |b| b); + let charlie_key_package = charlie_key_package_bundle.key_package(); + + let (original_proposal, _) = alice.propose_add_member(charlie_key_package); + + alice + .group + .clear_pending_proposals(alice.party.provider.storage()) + .unwrap(); + + let Ok(frankenstein::FrankenMlsMessage { + version, + body: + frankenstein::FrankenMlsMessageBody::PublicMessage(frankenstein::FrankenPublicMessage { + content: + frankenstein::FrankenFramedContent { + group_id, + epoch, + sender, + authenticated_data, + body: + frankenstein::FrankenFramedContentBody::Proposal( + frankenstein::FrankenProposal::Add( + frankenstein::FrankenAddProposal { mut key_package }, + ), + ), + }, + .. + }), + }) = frankenstein::FrankenMlsMessage::tls_deserialize( + &mut original_proposal + .tls_serialize_detached() + .unwrap() + .as_slice(), + ) + else { + panic!("proposal message has unexpected format: {original_proposal:#?}") + }; + + key_package.protocol_version = 2; + key_package.resign(&charlie.signer); + + let group_context = alice.group.export_group_context(); + let membership_key = alice.group.group().message_secrets().membership_key(); + + let franken_commit_message = frankenstein::FrankenMlsMessage { + version, + body: frankenstein::FrankenMlsMessageBody::PublicMessage( + frankenstein::FrankenPublicMessage::auth( + &alice.party.provider, + ciphersuite, + &alice.party.signer, + frankenstein::FrankenFramedContent { + group_id, + epoch, + sender, + authenticated_data, + body: frankenstein::FrankenFramedContentBody::Commit( + frankenstein::FrankenCommit { + proposals: vec![frankenstein::FrankenProposalOrRef::Proposal( + frankenstein::FrankenProposal::Add( + frankenstein::FrankenAddProposal { key_package }, + ), + )], + path: None, + }, + ), + }, + Some(&group_context.clone().into()), + Some(membership_key.as_slice()), + // dummy value + Some(vec![0; 32].into()), + ), + ), + }; + + let fake_commit_message = MlsMessageIn::tls_deserialize( + &mut franken_commit_message + .tls_serialize_detached() + .unwrap() + .as_slice(), + ) + .unwrap(); + + let err = { + let validation_skip_handle = crate::skip_validation::checks::confirmation_tag::handle(); + validation_skip_handle.with_disabled(|| bob.fail_processing(fake_commit_message.clone())) + }; + + assert!(matches!( + err, + ProcessMessageError::ValidationError(ValidationError::KeyPackageVerifyError( + KeyPackageVerifyError::InvalidProtocolVersion + )) + )); +} + +// This tests that a commit containing more than one GCE Proposals does not pass validation. +#[openmls_test] +fn fail_2_gce_proposals_1_commit_valno308() { + let TestState { mut alice, mut bob } = setup::(ciphersuite); + + // No required capabilities, so no specifically required extensions. + assert!(alice + .group + .group() + .context() + .extensions() + .required_capabilities() + .is_none()); + + let new_extensions = Extensions::single(Extension::RequiredCapabilities( + RequiredCapabilitiesExtension::new(&[ExtensionType::Unknown(0xf001)], &[], &[]), + )); + + let (proposal, _) = alice.propose_group_context_extensions(new_extensions.clone()); + bob.process_and_store_proposal(proposal.into()); + + assert_eq!(alice.group.pending_proposals().count(), 1); + + let (commit, _, _) = alice.commit_to_pending_proposals(); + + // we'll change the commit we feed to bob to include two GCE proposals + let mut franken_commit = FrankenMlsMessage::tls_deserialize( + &mut commit.tls_serialize_detached().unwrap().as_slice(), + ) + .unwrap(); + + // Craft a commit that has two GroupContextExtension proposals. This is forbidden by the RFC. + // Change the commit before alice commits, so alice's state is still in the old epoch and we can + // use her state to forge the macs and signatures + match &mut franken_commit.body { + frankenstein::FrankenMlsMessageBody::PublicMessage(msg) => { + match &mut msg.content.body { + frankenstein::FrankenFramedContentBody::Commit(commit) => { + let second_gces = frankenstein::FrankenProposalOrRef::Proposal( + frankenstein::FrankenProposal::GroupContextExtensions(vec![ + // ideally this should be some unknown extension, but it's tricky + // to get the payload set up correctly so we'll just go with this + frankenstein::FrankenExtension::LastResort, + ]), + ); + + commit.proposals.push(second_gces); + } + _ => unreachable!(), + } + + let group_context = alice.group.export_group_context().clone(); + + let bob_group_context = bob.group.export_group_context(); + assert_eq!( + bob_group_context.confirmed_transcript_hash(), + group_context.confirmed_transcript_hash() + ); + + let secrets = alice.group.group().message_secrets(); + let membership_key = secrets.membership_key().as_slice(); + + *msg = frankenstein::FrankenPublicMessage::auth( + &alice.party.provider, + group_context.ciphersuite(), + &alice.party.signer, + msg.content.clone(), + Some(&group_context.into()), + Some(membership_key), + // this is a dummy confirmation_tag: + Some(vec![0u8; 32].into()), + ); + } + _ => unreachable!(), + } + + let fake_commit = MlsMessageIn::tls_deserialize( + &mut franken_commit.tls_serialize_detached().unwrap().as_slice(), + ) + .unwrap(); + + let err = { + let validation_skip_handle = crate::skip_validation::checks::confirmation_tag::handle(); + validation_skip_handle.with_disabled(|| bob.fail_processing(fake_commit.clone())) + }; + + assert!(matches!( + err, + ProcessMessageError::InvalidCommit( + StageCommitError::GroupContextExtensionsProposalValidationError( + GroupContextExtensionsProposalValidationError::TooManyGCEProposals + ) + ) + )); +} + +/// This test makes sure that a commit to a GCE proposal with required_capabilities that are +/// not satisfied by all members' capabilities does not pass validation. +/// +// Test structure: +// - (alice creates group, adds bob, bob accepts) +// - This is part of the setup function +// - bob proposes updating the GC to have required_capabilities with extensions 0xf001 +// - both alice and bob support this extension +// - we modify the proposal and add 0xf003 - this is only supported by bob (see setup function) +// - we craft a commit to the proposal, signed by bob +// - alice processes the commit expecting an error, and the error should be that the GCE is +// invalid +#[openmls_test] +fn fail_unsupported_gces_add_valno1001() { + let TestState { mut alice, mut bob }: TestState = setup(ciphersuite); + + // No required capabilities, so no specifically required extensions. + assert!(alice + .group + .group() + .context() + .extensions() + .required_capabilities() + .is_none()); + + let new_extensions = Extensions::single(Extension::RequiredCapabilities( + RequiredCapabilitiesExtension::new(&[ExtensionType::Unknown(0xf001)], &[], &[]), + )); + + let (original_proposal, _) = bob.propose_group_context_extensions(new_extensions.clone()); + + assert_eq!(bob.group.pending_proposals().count(), 1); + bob.group + .clear_pending_proposals(bob.party.provider.storage()) + .unwrap(); + + let Ok(frankenstein::FrankenMlsMessage { + version, + body: + frankenstein::FrankenMlsMessageBody::PublicMessage(frankenstein::FrankenPublicMessage { + content: + frankenstein::FrankenFramedContent { + group_id, + epoch, + sender: bob_sender, + authenticated_data, + body: + frankenstein::FrankenFramedContentBody::Proposal( + frankenstein::FrankenProposal::GroupContextExtensions(mut gces), + ), + }, + .. + }), + }) = frankenstein::FrankenMlsMessage::tls_deserialize( + &mut original_proposal + .tls_serialize_detached() + .unwrap() + .as_slice(), + ) + else { + panic!("proposal message has unexpected format: {original_proposal:#?}") + }; + + let Some(frankenstein::FrankenExtension::RequiredCapabilities( + frankenstein::FrankenRequiredCapabilitiesExtension { + extension_types, .. + }, + )) = gces.get_mut(0) + else { + panic!("required capabilities are malformed") + }; + + // this one is supported by bob, but not alice + extension_types.push(0xf003); + + let group_context = bob.group.export_group_context().clone(); + let secrets = bob.group.group().message_secrets(); + let membership_key = secrets.membership_key().as_slice(); + + let franken_commit_message = frankenstein::FrankenMlsMessage { + version, + body: frankenstein::FrankenMlsMessageBody::PublicMessage( + frankenstein::FrankenPublicMessage::auth( + &bob.party.provider, + ciphersuite, + &bob.party.signer, + frankenstein::FrankenFramedContent { + group_id, + epoch, + sender: bob_sender, + authenticated_data, + body: frankenstein::FrankenFramedContentBody::Commit( + frankenstein::FrankenCommit { + proposals: vec![frankenstein::FrankenProposalOrRef::Proposal( + frankenstein::FrankenProposal::GroupContextExtensions(gces), + )], + path: None, + }, + ), + }, + Some(&group_context.into()), + Some(membership_key), + // this is a dummy confirmation_tag: + Some(vec![0u8; 32].into()), + ), + ), + }; + + let fake_commit = MlsMessageIn::tls_deserialize( + &mut franken_commit_message + .tls_serialize_detached() + .unwrap() + .as_slice(), + ) + .unwrap(); + + let err = { + let validation_skip_handle = crate::skip_validation::checks::confirmation_tag::handle(); + validation_skip_handle.with_disabled(|| alice.fail_processing(fake_commit.clone())) + }; + + assert!( + matches!( + err, + ProcessMessageError::InvalidCommit( + StageCommitError::GroupContextExtensionsProposalValidationError( + GroupContextExtensionsProposalValidationError::RequiredExtensionNotSupportedByAllMembers + ) + ) + ), + "expected different error. got {err:?}" + ); +} + +// Test that the builder pattern accurately configures the new group. +#[openmls_test] +fn proposal() { + let TestState { mut alice, mut bob }: TestState = setup(ciphersuite); + + // No required capabilities, so no specifically required extensions. + assert!(alice + .group + .group() + .context() + .extensions() + .required_capabilities() + .is_none()); + + let new_extensions = Extensions::single(Extension::RequiredCapabilities( + RequiredCapabilitiesExtension::new(&[ExtensionType::Unknown(0xf001)], &[], &[]), + )); + + let (proposal, _) = alice.propose_group_context_extensions(new_extensions.clone()); + bob.process_and_store_proposal(proposal.into()); + + assert_eq!(alice.group.pending_proposals().count(), 1); + + let (commit, _, _) = alice.commit_and_merge_pending(); + bob.process_and_merge_commit(commit.into()); + assert_eq!(alice.group.pending_proposals().count(), 0); + + let required_capabilities = alice + .group + .group() + .context() + .extensions() + .required_capabilities() + .expect("couldn't get required_capabilities"); + + // has required_capabilities as required capability + assert!(required_capabilities.extension_types() == [ExtensionType::Unknown(0xf001)]); + + // === committing to two group context extensions should fail + let new_extensions_2 = Extensions::single(Extension::RequiredCapabilities( + RequiredCapabilitiesExtension::new(&[ExtensionType::RatchetTree], &[], &[]), + )); + + alice + .group + .propose_group_context_extensions( + &alice.party.provider, + new_extensions, + &alice.party.signer, + ) + .expect("failed to build group context extensions proposal"); + + // the proposals need to be different or they will be deduplicated + alice + .group + .propose_group_context_extensions( + &alice.party.provider, + new_extensions_2, + &alice.party.signer, + ) + .expect("failed to build group context extensions proposal"); + + assert_eq!(alice.group.pending_proposals().count(), 2); + + alice + .group + .commit_to_pending_proposals(&alice.party.provider, &alice.party.signer) + .expect_err( + "expected error when committing to multiple group context extensions proposals", + ); + + // === can't update required required_capabilities to extensions that existing group members + // are not capable of + + // contains unsupported extension + let new_extensions = Extensions::single(Extension::RequiredCapabilities( + RequiredCapabilitiesExtension::new(&[ExtensionType::Unknown(0xf042)], &[], &[]), + )); + + alice + .group + .propose_group_context_extensions( + &alice.party.provider, + new_extensions, + &alice.party.signer, + ) + .expect_err("expected an error building GCE proposal with bad required_capabilities"); +} diff --git a/openmls/src/group/tests_and_kats/tests/mod.rs b/openmls/src/group/tests_and_kats/tests/mod.rs new file mode 100644 index 0000000000..3bcc322e9a --- /dev/null +++ b/openmls/src/group/tests_and_kats/tests/mod.rs @@ -0,0 +1,17 @@ +//! Unit tests for the core group + +mod aad; +mod commit_validation; +mod encoding; +mod external_add_proposal; +mod external_commit; +mod external_commit_validation; +mod external_remove_proposal; +mod framing; +mod framing_validation; +mod group; +mod group_context_extensions; +mod past_secrets; +mod proposal_validation; +mod remove_operation; +mod wire_format_policy; diff --git a/openmls/src/group/tests/test_past_secrets.rs b/openmls/src/group/tests_and_kats/tests/past_secrets.rs similarity index 94% rename from openmls/src/group/tests/test_past_secrets.rs rename to openmls/src/group/tests_and_kats/tests/past_secrets.rs index f065919d83..b5158e6735 100644 --- a/openmls/src/group/tests/test_past_secrets.rs +++ b/openmls/src/group/tests_and_kats/tests/past_secrets.rs @@ -1,9 +1,10 @@ //! This module contains tests regarding the use of [`MessageSecretsStore`] in [`MlsGroup`] -use super::utils::{generate_credential_with_key, generate_key_package}; +use crate::group::tests_and_kats::utils::{generate_credential_with_key, generate_key_package}; use crate::{ framing::{MessageDecryptionError, MlsMessageIn, ProcessedMessageContent}, group::*, + treesync::LeafNodeParameters, }; #[openmls_test::openmls_test] @@ -93,7 +94,11 @@ fn test_past_secrets_in_group( application_messages.push(application_message.into_protocol_message().unwrap()); let (message, _welcome, _group_info) = alice_group - .self_update(provider, &alice_credential_with_keys.signer) + .self_update( + provider, + &alice_credential_with_keys.signer, + LeafNodeParameters::default(), + ) .expect("An unexpected error occurred."); update_commits.push(message.clone()); diff --git a/openmls/src/group/tests/test_proposal_validation.rs b/openmls/src/group/tests_and_kats/tests/proposal_validation.rs similarity index 95% rename from openmls/src/group/tests/test_proposal_validation.rs rename to openmls/src/group/tests_and_kats/tests/proposal_validation.rs index 904c886fcb..ae81628a27 100644 --- a/openmls/src/group/tests/test_proposal_validation.rs +++ b/openmls/src/group/tests_and_kats/tests/proposal_validation.rs @@ -1,14 +1,14 @@ //! This module tests the validation of proposals as defined in //! https://openmls.tech/book/message_validation.html#semantic-validation-of-proposals-covered-by-a-commit -use crate::storage::OpenMlsProvider; +use crate::{storage::OpenMlsProvider, test_utils::frankenstein::*, treesync::LeafNodeParameters}; use openmls_traits::{ prelude::{openmls_types::*, *}, signatures::Signer, }; use tls_codec::{Deserialize, Serialize}; -use super::utils::{ +use crate::group::tests_and_kats::utils::{ generate_credential_with_key, generate_key_package, resign_message, CredentialWithKeyAndSigner, }; use crate::{ @@ -914,7 +914,11 @@ fn test_valsem103_valsem104(ciphersuite: Ciphersuite, provider: &impl OpenMlsPro // Create the Commit. let serialized_update = alice_group - .self_update(provider, &alice_credential_with_key_and_signer.signer) + .self_update( + provider, + &alice_credential_with_key_and_signer.signer, + LeafNodeParameters::default(), + ) .expect("Error creating self-update") .tls_serialize_detached() .expect("Could not serialize message."); @@ -1186,7 +1190,11 @@ fn test_valsem105() { // Create the Commit. let serialized_update = alice_group - .self_update(provider, &alice_credential_with_key_and_signer.signer) + .self_update( + provider, + &alice_credential_with_key_and_signer.signer, + LeafNodeParameters::default(), + ) .unwrap() .tls_serialize_detached() .unwrap(); @@ -1255,11 +1263,9 @@ fn test_valsem105() { KeyPackageTestVersion::ValidTestCase => { assert!(matches!( err, - ProcessMessageError::<::StorageError>::InvalidCommit( - StageCommitError::UpdatePathError( - ApplyUpdatePathError::PathLengthMismatch, - ), - ) + ProcessMessageError::InvalidCommit(StageCommitError::UpdatePathError( + ApplyUpdatePathError::PathLengthMismatch, + ),) )); } KeyPackageTestVersion::WrongCiphersuite => { @@ -1271,21 +1277,21 @@ fn test_valsem105() { assert!( matches!( err, - ProcessMessageError::<::StorageError>::InvalidCommit( + ProcessMessageError::InvalidCommit( StageCommitError::ProposalValidationError( ProposalValidationError::InvalidAddProposalCiphersuiteOrVersion, ), ) ) || matches!( err, - ProcessMessageError::<::StorageError>::ValidationError( + ProcessMessageError::ValidationError( ValidationError::KeyPackageVerifyError( KeyPackageVerifyError::InvalidLeafNodeSignature, ), ) ) || matches!( err, - ProcessMessageError::<::StorageError>::ValidationError( + ProcessMessageError::ValidationError( ValidationError::InvalidAddProposalCiphersuite, ) ) @@ -1298,14 +1304,14 @@ fn test_valsem105() { assert!( matches!( err, - ProcessMessageError::<::StorageError>::InvalidCommit( + ProcessMessageError::InvalidCommit( StageCommitError::ProposalValidationError( ProposalValidationError::InvalidAddProposalCiphersuiteOrVersion, ), ) ) || matches!( err, - ProcessMessageError::<::StorageError>::ValidationError( + ProcessMessageError::ValidationError( ValidationError::KeyPackageVerifyError( KeyPackageVerifyError::InvalidProtocolVersion, ), @@ -1317,14 +1323,14 @@ fn test_valsem105() { assert!( matches!( err, - ProcessMessageError::<::StorageError>::ValidationError( + ProcessMessageError::ValidationError( ValidationError::KeyPackageVerifyError( KeyPackageVerifyError::InvalidProtocolVersion, ), ) ) || matches!( err, - ProcessMessageError::<::StorageError>::InvalidCommit( + ProcessMessageError::InvalidCommit( StageCommitError::ProposalValidationError( ProposalValidationError::InsufficientCapabilities, ), @@ -1335,7 +1341,7 @@ fn test_valsem105() { KeyPackageTestVersion::UnsupportedCiphersuite => { assert!(matches!( err, - ProcessMessageError::<::StorageError>::InvalidCommit( + ProcessMessageError::InvalidCommit( StageCommitError::ProposalValidationError( ProposalValidationError::InsufficientCapabilities, ), @@ -1591,7 +1597,11 @@ fn test_valsem108() { // Create the Commit. let serialized_update = alice_group - .self_update(provider, &alice_credential_with_key_and_signer.signer) + .self_update( + provider, + &alice_credential_with_key_and_signer.signer, + LeafNodeParameters::default(), + ) .expect("Error creating self-update") .tls_serialize_detached() .expect("Could not serialize message."); @@ -1685,33 +1695,74 @@ fn test_valsem110() { .encryption_key() .clone(); - let mut update_leaf_node = bob_leaf_node; - update_leaf_node - .update_and_re_sign( - alice_encryption_key.clone(), - None, - bob_group.group_id().clone(), - LeafNodeIndex::new(1), - &bob_credential_with_key_and_signer.signer, - ) - .unwrap(); - // We first go the manual route let update_proposal: MlsMessageIn = bob_group .propose_self_update( provider, &bob_credential_with_key_and_signer.signer, - Some(update_leaf_node.clone()), + LeafNodeParameters::default(), ) .map(|(out, _)| MlsMessageIn::from(out)) .expect("error while creating remove proposal"); + // Prepare the modified update proposal: + + let mut franken_leaf_node = FrankenLeafNode::from(bob_leaf_node.clone()); + franken_leaf_node.encryption_key = alice_encryption_key.key().clone(); + franken_leaf_node.leaf_node_source = FrankenLeafNodeSource::Update; + franken_leaf_node.resign( + Some(bob_group.group().own_tree_position().into()), + &bob_credential_with_key_and_signer.signer, + ); + + let franken_message_in = FrankenMlsMessage::from(MlsMessageOut::from(update_proposal.clone())); + + // Access the content that's inside the message. + let mut content = + if let FrankenMlsMessageBody::PublicMessage(public_message) = franken_message_in.body { + public_message.content + } else { + panic!("Unexpected message type"); + }; + + // Replace the proposal inside the public message + match content.body { + FrankenFramedContentBody::Proposal(FrankenProposal::Update(ref mut update)) => { + let update_proposal = FrankenUpdateProposal { + leaf_node: franken_leaf_node.clone(), + }; + *update = update_proposal; + } + _ => { + panic!("Unexpected content type"); + } + } + + // Rebuild the PublicMessage with the new content + let group_context = bob_group.export_group_context().clone(); + let membership_key = bob_group + .group() + .message_secrets() + .membership_key() + .as_slice(); + + let new_public_message = FrankenPublicMessage::auth( + provider, + ciphersuite, + &bob_credential_with_key_and_signer.signer, + content, + Some(&group_context.into()), + Some(membership_key), + None, + ); + + // And turn it into a protocol message + let protocol_message = + ProtocolMessage::PublicMessage(PublicMessage::from(new_public_message).into()); + // Have Alice process this proposal. if let ProcessedMessageContent::ProposalMessage(proposal) = alice_group - .process_message( - provider, - update_proposal.try_into_protocol_message().unwrap(), - ) + .process_message(provider, protocol_message) .expect("error processing proposal") .into_content() { @@ -1750,7 +1801,11 @@ fn test_valsem110() { // Create the Commit. let serialized_update = alice_group - .self_update(provider, &alice_credential_with_key_and_signer.signer) + .self_update( + provider, + &alice_credential_with_key_and_signer.signer, + LeafNodeParameters::default(), + ) .expect("Error creating self-update") .tls_serialize_detached() .expect("Could not serialize message."); @@ -1763,7 +1818,7 @@ fn test_valsem110() { let original_plaintext = plaintext.clone(); let update_proposal = Proposal::Update(UpdateProposal { - leaf_node: update_leaf_node, + leaf_node: franken_leaf_node.into(), }); // Artificially add the proposal. @@ -1837,7 +1892,11 @@ fn test_valsem111() { // We now have Alice create a commit. That commit should not contain any // proposals, just a path. let commit = alice_group - .self_update(provider, &alice_credential_with_key_and_signer.signer) + .self_update( + provider, + &alice_credential_with_key_and_signer.signer, + LeafNodeParameters::default(), + ) .expect("Error creating self-update"); // Check that there's no proposal in it. @@ -1918,7 +1977,11 @@ fn test_valsem111() { .unwrap(); let commit = alice_group - .self_update(provider, &alice_credential_with_key_and_signer.signer) + .self_update( + provider, + &alice_credential_with_key_and_signer.signer, + LeafNodeParameters::default(), + ) .expect("Error creating self-update"); let serialized_update = commit @@ -1998,7 +2061,11 @@ fn test_valsem112() { // However, we can test the receiving side by crafting such a proposal // manually. let commit = alice_group - .propose_self_update(provider, &alice_credential_with_key_and_signer.signer, None) + .propose_self_update( + provider, + &alice_credential_with_key_and_signer.signer, + LeafNodeParameters::default(), + ) .expect("Error creating self-update"); // Check that the sender type is indeed `member`. @@ -2206,10 +2273,7 @@ fn test_valsem401_valsem402() { let bob_provider = Provider::default(); // TODO(#1354): This is currently not tested because we can't easily create invalid commits. - let bad_psks: [( - Vec, - ProcessMessageError<::StorageError>, - ); 0] = [ + let bad_psks: [(Vec, ProcessMessageError); 0] = [ // // ValSem401 // ( // vec![PreSharedKeyId::external( diff --git a/openmls/src/group/tests/test_remove_operation.rs b/openmls/src/group/tests_and_kats/tests/remove_operation.rs similarity index 99% rename from openmls/src/group/tests/test_remove_operation.rs rename to openmls/src/group/tests_and_kats/tests/remove_operation.rs index f287a5e13e..d5daa05406 100644 --- a/openmls/src/group/tests/test_remove_operation.rs +++ b/openmls/src/group/tests_and_kats/tests/remove_operation.rs @@ -1,6 +1,6 @@ //! This module tests the classification of remove operations with RemoveOperation -use super::utils::{generate_credential_with_key, generate_key_package}; +use crate::group::tests_and_kats::utils::{generate_credential_with_key, generate_key_package}; use crate::{framing::*, group::*}; use openmls_traits::prelude::*; diff --git a/openmls/src/group/tests/test_wire_format_policy.rs b/openmls/src/group/tests_and_kats/tests/wire_format_policy.rs similarity index 95% rename from openmls/src/group/tests/test_wire_format_policy.rs rename to openmls/src/group/tests_and_kats/tests/wire_format_policy.rs index 2748785d37..805462256e 100644 --- a/openmls/src/group/tests/test_wire_format_policy.rs +++ b/openmls/src/group/tests_and_kats/tests/wire_format_policy.rs @@ -2,9 +2,9 @@ use openmls_traits::{signatures::Signer, types::Ciphersuite}; -use crate::{framing::*, group::*}; +use crate::{framing::*, group::*, treesync::LeafNodeParameters}; -use super::utils::{ +use crate::group::tests_and_kats::utils::{ generate_credential_with_key, generate_key_package, CredentialWithKeyAndSigner, }; @@ -86,7 +86,11 @@ fn receive_message( .expect("error creating bob's group from staged join"); let (message, _welcome, _group_info) = bob_group - .self_update(provider, &bob_credential_with_key_and_signer.signer) + .self_update( + provider, + &bob_credential_with_key_and_signer.signer, + LeafNodeParameters::default(), + ) .expect("An unexpected error occurred."); message.into() } diff --git a/openmls/src/group/tests/tree_printing.rs b/openmls/src/group/tests_and_kats/tree_printing.rs similarity index 100% rename from openmls/src/group/tests/tree_printing.rs rename to openmls/src/group/tests_and_kats/tree_printing.rs diff --git a/openmls/src/group/tests/utils.rs b/openmls/src/group/tests_and_kats/utils.rs similarity index 70% rename from openmls/src/group/tests/utils.rs rename to openmls/src/group/tests_and_kats/utils.rs index 3c88fba601..9907b7fd52 100644 --- a/openmls/src/group/tests/utils.rs +++ b/openmls/src/group/tests_and_kats/utils.rs @@ -7,14 +7,13 @@ use std::{cell::RefCell, collections::HashMap}; use openmls_basic_credential::SignatureKeyPair; -use openmls_traits::crypto::OpenMlsCrypto; use openmls_traits::{signatures::Signer, types::SignatureScheme}; use rand::{rngs::OsRng, RngCore}; use tls_codec::Serialize; use crate::{ ciphersuite::signable::Signable, credentials::*, framing::*, group::*, key_packages::*, - messages::ConfirmationTag, schedule::psk::store::ResumptionPskStore, test_utils::*, *, + messages::ConfirmationTag, test_utils::*, *, }; use self::storage::OpenMlsProvider; @@ -45,22 +44,7 @@ pub(crate) struct TestSetupConfig { /// A client in a test setup. pub(crate) struct TestClient { pub(crate) credentials: HashMap, - pub(crate) key_package_bundles: RefCell>, - pub(crate) group_states: RefCell>, -} - -impl TestClient { - pub(crate) fn find_key_package_bundle( - &self, - key_package: &KeyPackage, - crypto: &impl OpenMlsCrypto, - ) -> Option { - let mut key_package_bundles = self.key_package_bundles.borrow_mut(); - key_package_bundles - .iter() - .position(|x| x.key_package().hash_ref(crypto) == key_package.hash_ref(crypto)) - .map(|index| key_package_bundles.remove(index)) - } + pub(crate) group_states: RefCell>, } /// The state of a test setup, including the state of the clients and the @@ -117,7 +101,6 @@ pub(crate) fn setup( // Create the client. let test_client = TestClient { credentials, - key_package_bundles: RefCell::new(key_package_bundles), group_states: RefCell::new(HashMap::new()), }; test_clients.insert(client.name, RefCell::new(test_client)); @@ -139,30 +122,30 @@ pub(crate) fn setup( .get(&group_config.ciphersuite) .expect("An unexpected error occurred."); // Initialize the group state for the initial member. - let core_group = CoreGroup::builder( - GroupId::from_slice(&group_id.to_be_bytes()), - group_config.ciphersuite, - credential_with_key_and_signer.credential_with_key.clone(), - ) - .with_config(group_config.config) - .build(provider, &credential_with_key_and_signer.signer) - .expect("Error creating new CoreGroup"); - let mut proposal_list = Vec::new(); - let group_aad = b""; - // Framing parameters - let framing_parameters = FramingParameters::new(group_aad, WireFormat::PublicMessage); + let mls_group = MlsGroup::builder() + .with_group_id(GroupId::from_slice(&group_id.to_be_bytes())) + .ciphersuite(group_config.ciphersuite) + .use_ratchet_tree_extension(group_config.config.add_ratchet_tree_extension) + .with_wire_format_policy(PURE_PLAINTEXT_WIRE_FORMAT_POLICY) + .build( + provider, + &credential_with_key_and_signer.signer, + credential_with_key_and_signer.credential_with_key.clone(), + ) + .expect("Error creating group."); initial_group_member .group_states .borrow_mut() - .insert(core_group.context().group_id().clone(), core_group); + .insert(mls_group.group_id().clone(), mls_group); // If there is more than one member in the group, prepare proposals and // commit. Then distribute the Welcome message to the new // members. if group_config.members.len() > 1 { let mut group_states = initial_group_member.group_states.borrow_mut(); - let core_group = group_states + let mls_group = group_states .get_mut(&GroupId::from_slice(&group_id.to_be_bytes())) .expect("An unexpected error occurred."); + let mut key_packages = vec![]; for client_id in 1..group_config.members.len() { // Pull a KeyPackage from the key_store for the new member. let next_member_key_package = key_store @@ -173,102 +156,45 @@ pub(crate) fn setup( .expect("An unexpected error occurred.") .pop() .expect("An unexpected error occurred."); - // Have the initial member create an Add proposal using the new - // KeyPackage. - let add_proposal = core_group - .create_add_proposal( - framing_parameters, - next_member_key_package, - &credential_with_key_and_signer.signer, - ) - .expect("An unexpected error occurred."); - proposal_list.push(add_proposal); + key_packages.push(next_member_key_package.clone()); } // Create the commit based on the previously compiled list of // proposals. - let mut proposal_store = ProposalStore::new(); - for proposal in proposal_list { - proposal_store.add( - QueuedProposal::from_authenticated_content_by_ref( - group_config.ciphersuite, - provider.crypto(), - proposal, - ) - .expect("Could not create staged proposal."), - ); - } - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .build(); - let create_commit_result = core_group - .create_commit(params, provider, &credential_with_key_and_signer.signer) - .expect("An unexpected error occurred."); - let welcome = create_commit_result - .welcome_option - .expect("An unexpected error occurred."); - - core_group - .merge_staged_commit( + let (_commit, welcome, _) = mls_group + .add_members( provider, - create_commit_result.staged_commit, - &mut proposal_store, + &credential_with_key_and_signer.signer, + &key_packages, ) + .expect("An unexpected error occurred."); + let welcome = welcome.into_welcome().unwrap(); + + mls_group + .merge_pending_commit(provider) .expect("Error merging commit."); + let join_config = MlsGroupJoinConfig::builder() + .wire_format_policy(PURE_CIPHERTEXT_WIRE_FORMAT_POLICY) + .build(); + // Distribute the Welcome message to the other members. for client_id in 1..group_config.members.len() { let new_group_member = test_clients .get(group_config.members[client_id].name) .expect("An unexpected error occurred.") .borrow_mut(); - // Figure out which key package bundle we should use. This is - // a bit ugly and inefficient. - let member_secret = welcome - .secrets() - .iter() - .find(|x| { - new_group_member - .key_package_bundles - .borrow() - .iter() - .any(|y| { - y.key_package() - .hash_ref(provider.crypto()) - .expect("Could not hash KeyPackage.") - == x.new_member() - }) - }) - .expect("An unexpected error occurred."); - let kpb_position = new_group_member - .key_package_bundles - .borrow() - .iter() - .position(|y| { - y.key_package() - .hash_ref(provider.crypto()) - .expect("Could not hash KeyPackage.") - == member_secret.new_member() - }) - .expect("An unexpected error occurred."); - let key_package_bundle = new_group_member - .key_package_bundles - .borrow_mut() - .remove(kpb_position); // Create the local group state of the new member based on the // Welcome. - let new_group = match StagedCoreWelcome::new_from_welcome( - welcome.clone(), - Some(core_group.public_group().export_ratchet_tree().into()), - key_package_bundle, + let ratchet_tree = Some(mls_group.export_ratchet_tree().into()); + let new_group = StagedWelcome::new_from_welcome( provider, - ResumptionPskStore::new(1024), + &join_config, + welcome.clone(), + ratchet_tree, ) - .and_then(|staged_join| staged_join.into_core_group(provider)) - { - Ok(group) => group, - Err(err) => panic!("Error creating new group from Welcome: {err:?}"), - }; + .unwrap() + .into_group(provider) + .unwrap(); new_group_member .group_states diff --git a/openmls/src/key_packages/mod.rs b/openmls/src/key_packages/mod.rs index 20d401e546..8a808d4c33 100644 --- a/openmls/src/key_packages/mod.rs +++ b/openmls/src/key_packages/mod.rs @@ -128,7 +128,7 @@ mod lifetime; // Tests #[cfg(test)] -pub(crate) mod test_key_packages; +pub(crate) mod tests; // Public types pub use key_package_in::KeyPackageIn; @@ -481,6 +481,7 @@ impl KeyPackageBuilder { } } + #[cfg(test)] pub(crate) fn build_without_storage( mut self, ciphersuite: Ciphersuite, diff --git a/openmls/src/key_packages/test_key_packages.rs b/openmls/src/key_packages/tests.rs similarity index 100% rename from openmls/src/key_packages/test_key_packages.rs rename to openmls/src/key_packages/tests.rs diff --git a/openmls/src/lib.rs b/openmls/src/lib.rs index 3f46f0455d..1a5930560f 100644 --- a/openmls/src/lib.rs +++ b/openmls/src/lib.rs @@ -142,11 +142,7 @@ #![cfg_attr(not(feature = "test-utils"), deny(missing_docs))] #![deny(rustdoc::broken_intra_doc_links)] #![deny(rustdoc::private_intra_doc_links)] -#![cfg(any( - target_pointer_width = "32", - target_pointer_width = "64", - target_pointer_width = "128" -))] +#![cfg(any(target_pointer_width = "32", target_pointer_width = "64",))] #[cfg(all(target_arch = "wasm32", not(feature = "js")))] compile_error!("In order for OpenMLS to build for WebAssembly, JavaScript APIs must be available (for access to secure randomness and the current time). This can be signalled by setting the `js` feature on OpenMLS."); diff --git a/openmls/src/messages/external_proposals.rs b/openmls/src/messages/external_proposals.rs index e88b1fbead..99838c799c 100644 --- a/openmls/src/messages/external_proposals.rs +++ b/openmls/src/messages/external_proposals.rs @@ -69,7 +69,7 @@ impl ExternalProposal { /// * `epoch` - group's epoch /// * `signer` - of the sender to sign the message /// * `sender` - index of the sender of the proposal (in the [crate::extensions::ExternalSendersExtension] array - /// from the Group Context) + /// from the Group Context) pub fn new_remove( removed: LeafNodeIndex, group_id: GroupId, diff --git a/openmls/src/messages/mod.rs b/openmls/src/messages/mod.rs index 395b566a80..be861a1208 100644 --- a/openmls/src/messages/mod.rs +++ b/openmls/src/messages/mod.rs @@ -3,6 +3,7 @@ //! This module contains the types and implementations for Commit & Welcome messages, //! as well as Proposals & the group info used for External Commits. +use hash_ref::HashReference; use openmls_traits::{ crypto::OpenMlsCrypto, types::{Ciphersuite, HpkeCiphertext, HpkeKeyPair}, @@ -81,6 +82,15 @@ impl Welcome { } } + pub(crate) fn find_encrypted_group_secret( + &self, + hash_ref: HashReference, + ) -> Option<&EncryptedGroupSecrets> { + self.secrets() + .iter() + .find(|egs| hash_ref == egs.new_member()) + } + /// Returns a reference to the ciphersuite in this Welcome message. pub(crate) fn ciphersuite(&self) -> Ciphersuite { self.cipher_suite diff --git a/openmls/src/messages/tests/test_codec.rs b/openmls/src/messages/tests/codec.rs similarity index 100% rename from openmls/src/messages/tests/test_codec.rs rename to openmls/src/messages/tests/codec.rs diff --git a/openmls/src/messages/tests/test_export_group_info.rs b/openmls/src/messages/tests/export_group_info.rs similarity index 68% rename from openmls/src/messages/tests/test_export_group_info.rs rename to openmls/src/messages/tests/export_group_info.rs index 54dd4f1c17..e1b33314c9 100644 --- a/openmls/src/messages/tests/test_export_group_info.rs +++ b/openmls/src/messages/tests/export_group_info.rs @@ -2,8 +2,9 @@ use tls_codec::{Deserialize, Serialize}; use crate::{ ciphersuite::signable::Verifiable, - group::test_core_group::setup_alice_group, + group::mls_group::tests_and_kats::utils::setup_alice_group, messages::group_info::{GroupInfo, VerifiableGroupInfo}, + prelude::MlsMessageBodyOut, test_utils::*, }; @@ -13,10 +14,15 @@ fn export_group_info() { // Alice creates a group let (group_alice, _, signer, pk) = setup_alice_group(ciphersuite, provider); - let group_info: GroupInfo = group_alice - .export_group_info(provider.crypto(), &signer, true) + let group_info_message = group_alice + .export_group_info(provider, &signer, true) .unwrap(); + let group_info = match group_info_message.body() { + MlsMessageBodyOut::GroupInfo(group_info) => group_info, + _ => panic!("Wrong message type"), + }; + let verifiable_group_info = { let serialized = group_info.tls_serialize_detached().unwrap(); VerifiableGroupInfo::tls_deserialize(&mut serialized.as_slice()).unwrap() diff --git a/openmls/src/messages/tests/mod.rs b/openmls/src/messages/tests/mod.rs index 74f35e27d3..053b9e2cd7 100644 --- a/openmls/src/messages/tests/mod.rs +++ b/openmls/src/messages/tests/mod.rs @@ -1,6 +1,6 @@ //! Unit tests for messages -mod test_codec; -mod test_export_group_info; -mod test_proposals; -mod test_welcome; +mod codec; +mod export_group_info; +mod proposals; +mod welcome; diff --git a/openmls/src/messages/tests/test_proposals.rs b/openmls/src/messages/tests/proposals.rs similarity index 100% rename from openmls/src/messages/tests/test_proposals.rs rename to openmls/src/messages/tests/proposals.rs diff --git a/openmls/src/messages/tests/test_welcome.rs b/openmls/src/messages/tests/welcome.rs similarity index 96% rename from openmls/src/messages/tests/test_welcome.rs rename to openmls/src/messages/tests/welcome.rs index 888f94fd89..3b331c5005 100644 --- a/openmls/src/messages/tests/test_welcome.rs +++ b/openmls/src/messages/tests/welcome.rs @@ -9,8 +9,8 @@ use crate::{ }, extensions::Extensions, group::{ - errors::WelcomeError, GroupContext, GroupId, MlsGroup, MlsGroupCreateConfig, - ProcessedWelcome, StagedWelcome, + errors::WelcomeError, mls_group::tests_and_kats::utils::setup_client, GroupContext, + GroupId, MlsGroup, MlsGroupCreateConfig, ProcessedWelcome, StagedWelcome, }, messages::{ group_info::{GroupInfoTBS, VerifiableGroupInfo}, @@ -47,9 +47,9 @@ fn test_welcome_context_mismatch( .build(); let (alice_credential_with_key, _alice_kpb, alice_signer, _alice_signature_key) = - crate::group::test_core_group::setup_client("Alice", ciphersuite, provider); + setup_client("Alice", ciphersuite, provider); let (_bob_credential, bob_kpb, _bob_signer, _bob_signature_key) = - crate::group::test_core_group::setup_client("Bob", ciphersuite, provider); + setup_client("Bob", ciphersuite, provider); let bob_kp = bob_kpb.key_package(); let bob_private_key = bob_kpb.init_private_key(); @@ -308,9 +308,9 @@ fn test_welcome_processing() { .build(); let (alice_credential_with_key, _alice_kpb, alice_signer, _alice_signature_key) = - crate::group::test_core_group::setup_client("Alice", ciphersuite, provider); + setup_client("Alice", ciphersuite, provider); let (_bob_credential, bob_kpb, _bob_signer, _bob_signature_key) = - crate::group::test_core_group::setup_client("Bob", ciphersuite, provider); + setup_client("Bob", ciphersuite, provider); let bob_kp = bob_kpb.key_package(); diff --git a/openmls/src/prelude.rs b/openmls/src/prelude.rs index 2957e3bcdb..7e34d2d804 100644 --- a/openmls/src/prelude.rs +++ b/openmls/src/prelude.rs @@ -2,7 +2,7 @@ //! Include this to get access to all the public functions of OpenMLS. // MlsGroup -pub use crate::group::{core_group::Member, ser::*, *}; +pub use crate::group::{core_group::Member, *}; pub use crate::group::public_group::{errors::*, PublicGroup}; @@ -42,7 +42,7 @@ pub use crate::binary_tree::LeafNodeIndex; // TreeSync pub use crate::treesync::{ errors::{ApplyUpdatePathError, PublicTreeError}, - node::leaf_node::{Capabilities, LeafNode}, + node::leaf_node::{Capabilities, CapabilitiesBuilder, LeafNode, LeafNodeParameters}, node::parent_node::ParentNode, node::Node, RatchetTreeIn, diff --git a/openmls/src/prelude_test.rs b/openmls/src/prelude_test.rs index f926676a07..9de9f3153d 100644 --- a/openmls/src/prelude_test.rs +++ b/openmls/src/prelude_test.rs @@ -6,7 +6,7 @@ pub use crate::ciphersuite::{signable::Verifiable, *}; // KATs pub use crate::binary_tree::array_representation::kat_treemath; pub use crate::key_packages::KeyPackage; -pub use crate::schedule::kat_key_schedule::{self, KeyScheduleTestVector}; +pub use crate::schedule::tests_and_kats::kats::key_schedule::{self, KeyScheduleTestVector}; // TODO: #624 - re-enable test vectors. // pub use crate::group::tests::{ // kat_messages::{self, MessagesTestVector}, diff --git a/openmls/src/schedule/message_secrets.rs b/openmls/src/schedule/message_secrets.rs index 485127d19c..1742f91936 100644 --- a/openmls/src/schedule/message_secrets.rs +++ b/openmls/src/schedule/message_secrets.rs @@ -4,7 +4,7 @@ use super::*; /// Combined message secrets that need to be stored for later decryption/verification #[derive(Serialize, Deserialize)] -#[cfg_attr(test, derive(Clone))] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone))] #[cfg_attr(feature = "crypto-debug", derive(Debug))] pub(crate) struct MessageSecrets { sender_data_secret: SenderDataSecret, @@ -117,7 +117,7 @@ impl MessageSecrets { } // In tests we allow comparing secrets. -#[cfg(test)] +#[cfg(any(test, feature = "test-utils"))] impl PartialEq for MessageSecrets { fn eq(&self, other: &Self) -> bool { self.sender_data_secret == other.sender_data_secret diff --git a/openmls/src/schedule/mod.rs b/openmls/src/schedule/mod.rs index b82a0610ba..ea8aec63b8 100644 --- a/openmls/src/schedule/mod.rs +++ b/openmls/src/schedule/mod.rs @@ -149,13 +149,9 @@ use message_secrets::MessageSecrets; use openmls_traits::random::OpenMlsRand; use psk::PskSecret; -// Tests +// Tests and kats #[cfg(any(feature = "test-utils", test))] -pub mod kat_key_schedule; -#[cfg(test)] -pub mod kat_psk_secret; -#[cfg(test)] -mod unit_tests; +pub mod tests_and_kats; // Public types pub use psk::{ExternalPsk, PreSharedKeyId, Psk}; @@ -163,7 +159,7 @@ pub use psk::{ExternalPsk, PreSharedKeyId, Psk}; /// A group secret that can be used among members to prove that a member was /// part of a group in a given epoch. #[derive(Clone, Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(Eq, PartialEq))] +#[cfg_attr(any(test, feature = "test-utils"), derive(Eq, PartialEq))] pub struct ResumptionPskSecret { secret: Secret, } @@ -190,7 +186,7 @@ impl ResumptionPskSecret { /// A secret that can be used among members to make sure everyone has the same /// group state. #[derive(Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(Eq, PartialEq, Clone))] +#[cfg_attr(any(test, feature = "test-utils"), derive(Eq, PartialEq, Clone))] pub struct EpochAuthenticator { secret: Secret, } @@ -255,7 +251,7 @@ impl CommitSecret { /// The `InitSecret` is used to connect the next epoch to the current one. #[derive(Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq, Clone))] +#[cfg_attr(any(test, feature = "test-utils"), derive(PartialEq, Clone))] pub(crate) struct InitSecret { secret: Secret, } @@ -711,7 +707,7 @@ impl EncryptionSecret { /// A secret that we can derive secrets from, that are used outside of OpenMLS. #[derive(Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq, Clone))] +#[cfg_attr(any(test, feature = "test-utils"), derive(PartialEq, Clone))] pub(crate) struct ExporterSecret { secret: Secret, } @@ -757,7 +753,7 @@ impl ExporterSecret { /// A secret used when joining a group with an external Commit. #[derive(Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq, Clone))] +#[cfg_attr(any(test, feature = "test-utils"), derive(PartialEq, Clone))] pub(crate) struct ExternalSecret { secret: Secret, } @@ -792,7 +788,7 @@ impl ExternalSecret { /// The confirmation key is used to calculate the `ConfirmationTag`. #[derive(Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq, Clone))] +#[cfg_attr(any(test, feature = "test-utils"), derive(PartialEq, Clone))] pub(crate) struct ConfirmationKey { secret: Secret, } @@ -864,7 +860,7 @@ impl ConfirmationKey { /// The membership key is used to calculate the `MembershipTag`. #[derive(Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq, Clone))] +#[cfg_attr(any(test, feature = "test-utils"), derive(PartialEq, Clone))] pub(crate) struct MembershipKey { secret: Secret, } @@ -939,10 +935,9 @@ fn ciphertext_sample(ciphersuite: Ciphersuite, ciphertext: &[u8]) -> &[u8] { /// A key that can be used to derive an `AeadKey` and an `AeadNonce`. #[derive(Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq))] #[cfg_attr( any(feature = "test-utils", feature = "crypto-debug", test), - derive(Debug, Clone) + derive(Debug, Clone, PartialEq) )] pub(crate) struct SenderDataSecret { secret: Secret, @@ -1225,7 +1220,7 @@ impl EpochSecrets { } #[derive(Serialize, Deserialize)] -#[cfg_attr(test, derive(Clone))] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone, PartialEq))] pub(crate) struct GroupEpochSecrets { init_secret: InitSecret, exporter_secret: ExporterSecret, @@ -1240,24 +1235,13 @@ impl std::fmt::Debug for GroupEpochSecrets { } } -#[cfg(not(test))] +#[cfg(not(any(test, feature = "test-utils")))] impl PartialEq for GroupEpochSecrets { fn eq(&self, _other: &Self) -> bool { false } } -// In tests we allow comparing secrets. -#[cfg(test)] -impl PartialEq for GroupEpochSecrets { - fn eq(&self, other: &Self) -> bool { - self.exporter_secret == other.exporter_secret - && self.epoch_authenticator == other.epoch_authenticator - && self.external_secret == other.external_secret - && self.resumption_psk == other.resumption_psk - } -} - impl GroupEpochSecrets { /// Init secret pub(crate) fn init_secret(&self) -> &InitSecret { diff --git a/openmls/src/schedule/psk.rs b/openmls/src/schedule/psk.rs index a725bb8285..f9acff865e 100644 --- a/openmls/src/schedule/psk.rs +++ b/openmls/src/schedule/psk.rs @@ -490,7 +490,7 @@ pub mod store { /// /// This is where the resumption PSKs are kept in a rollover list. #[derive(Debug, Serialize, Deserialize)] - #[cfg_attr(test, derive(PartialEq, Clone))] + #[cfg_attr(any(test, feature = "test-utils"), derive(Clone, PartialEq))] pub(crate) struct ResumptionPskStore { max_number_of_secrets: usize, resumption_psk: Vec<(GroupEpoch, ResumptionPskSecret)>, @@ -532,4 +532,11 @@ pub mod store { .map(|(_e, s)| s) } } + + #[cfg(test)] + impl ResumptionPskStore { + pub(crate) fn cursor(&self) -> usize { + self.cursor + } + } } diff --git a/openmls/src/schedule/kat_key_schedule.rs b/openmls/src/schedule/tests_and_kats/kats/key_schedule.rs similarity index 98% rename from openmls/src/schedule/kat_key_schedule.rs rename to openmls/src/schedule/tests_and_kats/kats/key_schedule.rs index 5e8e7e9df5..a46765b1b7 100644 --- a/openmls/src/schedule/kat_key_schedule.rs +++ b/openmls/src/schedule/tests_and_kats/kats/key_schedule.rs @@ -10,10 +10,15 @@ use openmls_traits::{random::OpenMlsRand, types::HpkeKeyPair, OpenMlsProvider}; use serde::{self, Deserialize, Serialize}; use tls_codec::Serialize as TlsSerializeTrait; -use super::{errors::KsTestVectorError, CommitSecret}; #[cfg(test)] use crate::test_utils::write; -use crate::{ciphersuite::*, extensions::Extensions, group::*, schedule::*, test_utils::*}; +use crate::{ + ciphersuite::*, + extensions::Extensions, + group::*, + schedule::{errors::KsTestVectorError, CommitSecret, *}, + test_utils::*, +}; #[derive(Serialize, Deserialize, Debug, Clone, Default)] struct Exporter { @@ -258,7 +263,8 @@ fn write_test_vectors() { fn read_test_vectors_key_schedule() { let _ = pretty_env_logger::try_init(); - let tests: Vec = read_json!("../../test_vectors/key-schedule.json"); + let tests: Vec = + read_json!("../../../../test_vectors/key-schedule.json"); for test_vector in tests { match run_test_vector(test_vector, provider) { diff --git a/openmls/src/schedule/tests_and_kats/kats/mod.rs b/openmls/src/schedule/tests_and_kats/kats/mod.rs new file mode 100644 index 0000000000..98c704da1b --- /dev/null +++ b/openmls/src/schedule/tests_and_kats/kats/mod.rs @@ -0,0 +1,4 @@ +#[cfg(any(feature = "test-utils", test))] +pub mod key_schedule; +#[cfg(test)] +pub mod psk_secret; diff --git a/openmls/src/schedule/kat_psk_secret.rs b/openmls/src/schedule/tests_and_kats/kats/psk_secret.rs similarity index 93% rename from openmls/src/schedule/kat_psk_secret.rs rename to openmls/src/schedule/tests_and_kats/kats/psk_secret.rs index f13d6c592f..56f64b65e5 100644 --- a/openmls/src/schedule/kat_psk_secret.rs +++ b/openmls/src/schedule/tests_and_kats/kats/psk_secret.rs @@ -35,9 +35,10 @@ use openmls_traits::crypto::OpenMlsCrypto; use serde::Deserialize; -use super::psk::{ExternalPsk, PreSharedKeyId, Psk, PskSecret}; use crate::{ - schedule::psk::{load_psks, store::ResumptionPskStore}, + schedule::psk::{ + load_psks, store::ResumptionPskStore, ExternalPsk, PreSharedKeyId, Psk, PskSecret, + }, test_utils::*, }; @@ -106,7 +107,7 @@ fn read_test_vectors_ps() { let _ = pretty_env_logger::try_init(); log::debug!("Reading test vectors ..."); - let tests: Vec = read_json!("../../test_vectors/psk_secret.json"); + let tests: Vec = read_json!("../../../../test_vectors/psk_secret.json"); for test_vector in tests { match run_test_vector(test_vector, provider) { diff --git a/openmls/src/schedule/tests_and_kats/mod.rs b/openmls/src/schedule/tests_and_kats/mod.rs new file mode 100644 index 0000000000..ee33dc0401 --- /dev/null +++ b/openmls/src/schedule/tests_and_kats/mod.rs @@ -0,0 +1,4 @@ +#[cfg(any(feature = "test-utils", test))] +pub mod kats; +#[cfg(test)] +mod tests; diff --git a/openmls/src/schedule/unit_tests.rs b/openmls/src/schedule/tests_and_kats/tests.rs similarity index 94% rename from openmls/src/schedule/unit_tests.rs rename to openmls/src/schedule/tests_and_kats/tests.rs index 64305a899d..2a89320e04 100644 --- a/openmls/src/schedule/unit_tests.rs +++ b/openmls/src/schedule/tests_and_kats/tests.rs @@ -2,10 +2,9 @@ use openmls_traits::{random::OpenMlsRand, OpenMlsProvider}; -use super::PskSecret; use crate::{ ciphersuite::Secret, - schedule::psk::{store::ResumptionPskStore, *}, + schedule::psk::{store::ResumptionPskStore, PskSecret, *}, }; #[openmls_test::openmls_test] diff --git a/openmls/src/storage.rs b/openmls/src/storage.rs index 585ee4471d..ff68132835 100644 --- a/openmls/src/storage.rs +++ b/openmls/src/storage.rs @@ -27,12 +27,27 @@ use crate::{ treesync::{node::encryption_keys::EncryptionKeyPair, EncryptionKey}, }; +#[cfg(test)] +pub mod kat_storage_stability; + /// A convenience trait for the current version of the storage. /// Throughout the code, this one should be used instead of `openmls_traits::storage::StorageProvider`. pub trait StorageProvider: openmls_traits::storage::StorageProvider {} +/// A convenience trait for the current version of the public storage. +/// Throughout the code, this one should be used instead of `openmls_traits::public_storage::PublicStorageProvider`. +pub trait PublicStorageProvider: + openmls_traits::public_storage::PublicStorageProvider +{ +} + impl> StorageProvider for P {} +impl> + PublicStorageProvider for P +{ +} + /// A convenience trait for the OpenMLS provider that defines the storage provider /// for the current version of storage. /// Throughout the code, this one should be used instead of `openmls_traits::OpenMlsProvider`. @@ -123,7 +138,9 @@ impl traits::PskBundle for PskBundle {} #[cfg(test)] mod test { - use crate::{group::test_core_group::setup_client, prelude::KeyPackageBuilder}; + use crate::{ + group::mls_group::tests_and_kats::utils::setup_client, prelude::KeyPackageBuilder, + }; use super::*; diff --git a/openmls/src/storage/kat_storage_stability.rs b/openmls/src/storage/kat_storage_stability.rs new file mode 100644 index 0000000000..29692c1056 --- /dev/null +++ b/openmls/src/storage/kat_storage_stability.rs @@ -0,0 +1,726 @@ +//! This modules contains KATs for testing the stability of storage. +//! +//! The KAT generation performs a few group operations (e.g. create, add, set required capabilties) +//! and at each step saves a serialized copy of the provider, along with the group id of the +//! created group. +//! +//! The KAT test reads the serialized providers, loads the [`MlsGroup`] for the given group id, and +//! checks that the group contains the expected information. +//! +//! It contains +//! - a helper function that does the generation of the KAT for a single pair of provider and +//! ciphersuite +//! - a test that runs the KAT generation +//! - a test that runs the KAT generation for all supported providers and ciphersuites and writes +//! the vectors to disk. This test is annotated with #[ignore] and not usually run. +//! - a test that +//! - loads the test data for the given provider and ciphersuite, +//! - deserializes the provider and group id +//! - loads the [`MlsGroup`] +//! - checks that the group matches expectations + +use base64::Engine; +use serde::{Deserialize, Serialize}; + +use std::collections::HashMap; +use std::marker::PhantomData; +use std::{convert::Infallible, io::Write}; + +use openmls_test::openmls_test; +use openmls_traits::OpenMlsProvider as _; + +use crate::{ + prelude::{test_utils::new_credential, *}, + storage::OpenMlsProvider, +}; + +#[derive(Serialize, Deserialize)] +struct KatData { + group_id: GroupId, + storages: Vec, +} + +struct DeterministicRandProvider { + id: String, + ctr: std::sync::atomic::AtomicUsize, + _phantom: PhantomData, +} + +impl DeterministicRandProvider { + fn new(id: &str) -> Self { + Self { + id: id.to_string(), + ctr: std::sync::atomic::AtomicUsize::new(0), + _phantom: PhantomData, + } + } + + fn encode(ctr: usize, id: &str) -> Vec { + ctr.to_be_bytes().into_iter().chain(id.bytes()).collect() + } + + fn block(&self, mut dst: &mut [u8]) -> usize { + let provider = Provider::default(); + let ctr = self.ctr.fetch_add(1, std::sync::atomic::Ordering::Relaxed); + + let block = provider + .crypto() + .hash(HashType::Sha2_256, &Self::encode(ctr, &self.id)) + .unwrap(); + + let write = usize::min(dst.len(), block.len()); + dst.write_all(&block[..write]).unwrap(); + write + } + + fn fill(&self, mut dst: &mut [u8]) { + while !dst.is_empty() { + let written = self.block(dst); + dst = &mut dst[written..]; + } + } +} + +impl openmls_traits::random::OpenMlsRand + for DeterministicRandProvider +{ + type Error = Infallible; + + fn random_array(&self) -> Result<[u8; N], Self::Error> { + let mut arr = [0u8; N]; + self.fill(&mut arr); + Ok(arr) + } + + fn random_vec(&self, len: usize) -> Result, Self::Error> { + let mut arr = vec![0u8; len]; + self.fill(&mut arr); + Ok(arr) + } +} + +struct StorageTestProvider { + rand: DeterministicRandProvider, + storage: openmls_memory_storage::MemoryStorage, + other: Provider, +} + +impl StorageTestProvider { + fn new(id: &str) -> Self { + Self { + rand: DeterministicRandProvider::new(id), + storage: Default::default(), + other: Default::default(), + } + } +} + +impl openmls_traits::OpenMlsProvider + for StorageTestProvider +{ + type CryptoProvider = ::CryptoProvider; + + type RandProvider = DeterministicRandProvider; + + type StorageProvider = openmls_memory_storage::MemoryStorage; + + fn storage(&self) -> &Self::StorageProvider { + &self.storage + } + + fn crypto(&self) -> &Self::CryptoProvider { + self.other.crypto() + } + + fn rand(&self) -> &Self::RandProvider { + &self.rand + } +} + +fn deserialize_provider( + r: &mut R, + name: &str, +) -> StorageTestProvider { + StorageTestProvider:: { + storage: openmls_memory_storage::MemoryStorage::deserialize(r).unwrap(), + rand: DeterministicRandProvider::new(name), + other: Default::default(), + } +} + +fn check_serialized_group_equality( + r: &mut R, + name: &str, + group_id: &GroupId, + group: &MlsGroup, +) { + let provider = deserialize_provider::<_, Provider>(r, name); + let loaded_group = MlsGroup::load(provider.storage(), group_id) + .unwrap() + .unwrap(); + + assert_eq!(group, &loaded_group); +} + +fn helper_generate_kat( + ciphersuite: Ciphersuite, +) -> (GroupId, Vec>) { + let alice_provider = StorageTestProvider::::new("alice"); + let (alice_cwk, alice_signer) = + new_credential(&alice_provider, b"alice", ciphersuite.signature_algorithm()); + + let bob_provider = StorageTestProvider::::new("bob"); + let (bob_cwk, bob_signer) = + new_credential(&bob_provider, b"bob", ciphersuite.signature_algorithm()); + + let charlie_provider = StorageTestProvider::::new("charlie"); + let (charlie_cwk, charlie_signer) = new_credential( + &charlie_provider, + b"charlie", + ciphersuite.signature_algorithm(), + ); + + /////// prepare a group that has some content + let mut alice_group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .with_capabilities(Capabilities::new( + None, + None, + Some(&[ExtensionType::Unknown(0xf042)]), + None, + None, + )) + .build(&alice_provider, &alice_signer, alice_cwk) + .expect("error creating group using builder"); + + let group_id = alice_group.group_id().clone(); + + let mut testdata_new_group = vec![]; + alice_provider + .storage + .serialize(&mut testdata_new_group) + .unwrap(); + + check_serialized_group_equality::<_, Provider>( + &mut testdata_new_group.as_slice(), + "alice", + &group_id, + &alice_group, + ); + + let bob_kpb = KeyPackageBuilder::new() + .leaf_node_capabilities(Capabilities::new( + None, + None, + Some(&[ExtensionType::Unknown(0xf042)]), + None, + None, + )) + .build(ciphersuite, &bob_provider, &bob_signer, bob_cwk.clone()) + .unwrap(); + + alice_group + .add_members( + &alice_provider, + &alice_signer, + &[bob_kpb.key_package().to_owned()], + ) + .unwrap(); + + let mut testdata_pending_add_commit = vec![]; + alice_provider + .storage + .serialize(&mut testdata_pending_add_commit) + .unwrap(); + + check_serialized_group_equality::<_, Provider>( + &mut testdata_pending_add_commit.as_slice(), + "alice", + &group_id, + &alice_group, + ); + + alice_group.merge_pending_commit(&alice_provider).unwrap(); + + let mut testdata_bob_added = vec![]; + alice_provider + .storage + .serialize(&mut testdata_bob_added) + .unwrap(); + + alice_group + .update_group_context_extensions( + &alice_provider, + Extensions::single(Extension::RequiredCapabilities( + RequiredCapabilitiesExtension::new(&[ExtensionType::Unknown(0xf042)], &[], &[]), + )), + &alice_signer, + ) + .unwrap(); + + let mut testdata_pending_gce_commit = vec![]; + alice_provider + .storage + .serialize(&mut testdata_pending_gce_commit) + .unwrap(); + + check_serialized_group_equality::<_, Provider>( + &mut testdata_pending_gce_commit.as_slice(), + "alice", + &group_id, + &alice_group, + ); + + alice_group.merge_pending_commit(&alice_provider).unwrap(); + + let mut testdata_gce_updated = vec![]; + alice_provider + .storage + .serialize(&mut testdata_gce_updated) + .unwrap(); + + check_serialized_group_equality::<_, Provider>( + &mut testdata_gce_updated.as_slice(), + "alice", + &group_id, + &alice_group, + ); + + //// also serialize with a pending proposal + + let charlie_kpb = KeyPackageBuilder::new() + .leaf_node_capabilities(Capabilities::new( + None, + None, + Some(&[ExtensionType::Unknown(0xf042)]), + None, + None, + )) + .build( + ciphersuite, + &charlie_provider, + &charlie_signer, + charlie_cwk.clone(), + ) + .unwrap(); + + alice_group + .propose_add_member(&alice_provider, &alice_signer, charlie_kpb.key_package()) + .unwrap(); + + let mut testdata_pending_proposal = vec![]; + alice_provider + .storage + .serialize(&mut testdata_pending_proposal) + .unwrap(); + + check_serialized_group_equality::<_, Provider>( + &mut testdata_pending_proposal.as_slice(), + "alice", + &group_id, + &alice_group, + ); + + ( + group_id, + vec![ + testdata_new_group, + testdata_pending_add_commit, + testdata_bob_added, + testdata_pending_gce_commit, + testdata_gce_updated, + testdata_pending_proposal, + ], + ) +} + +#[openmls_test] +fn generate_kats(ciphersuite: Ciphersuite, provider: &Provider) { + helper_generate_kat::(ciphersuite); +} + +#[test] +#[ignore] +#[cfg(not(all( + feature = "libcrux-provider", + not(any( + target_arch = "wasm32", + all(target_arch = "x86", target_os = "windows") + )) +)))] +fn write_kats() { + // setup + let rustcrypto_provider = openmls_rust_crypto::OpenMlsRustCrypto::default(); + + // make a list of all supported ciphersuites + let ciphersuites = rustcrypto_provider.crypto().supported_ciphersuites(); + + // generate the kat data + let kat_data = ciphersuites + .into_iter() + .map(|ciphersuite| { + let (group_id, storages) = + helper_generate_kat::(ciphersuite); + + (ciphersuite, group_id, storages) + }) + .collect(); + + // encode and write to disk + helper_write_kats(kat_data); +} + +#[test] +#[ignore] +#[cfg(all( + feature = "libcrux-provider", + not(any( + target_arch = "wasm32", + all(target_arch = "x86", target_os = "windows") + )) +))] +fn write_kats() { + // setup + let libcrux_provider = openmls_libcrux_crypto::Provider::default(); + let rustcrypto_provider = openmls_rust_crypto::OpenMlsRustCrypto::default(); + + // make a list of all supported ciphersuites + let mut ciphersuites = libcrux_provider.crypto().supported_ciphersuites(); + for ciphersuite in rustcrypto_provider.crypto().supported_ciphersuites() { + if !ciphersuites.contains(&ciphersuite) { + ciphersuites.push(ciphersuite); + } + } + + // generate the kat data + let kat_data = ciphersuites + .into_iter() + .map(|ciphersuite| { + let (group_id, storages) = if libcrux_provider.crypto().supports(ciphersuite).is_ok() { + helper_generate_kat::(ciphersuite) + } else { + helper_generate_kat::(ciphersuite) + }; + + (ciphersuite, group_id, storages) + }) + .collect(); + + // encode and write to disk + helper_write_kats(kat_data); +} + +fn helper_write_kats(kat_data: Vec<(Ciphersuite, GroupId, Vec>)>) { + let base64_engine = base64::engine::GeneralPurpose::new( + &base64::alphabet::URL_SAFE, + base64::engine::GeneralPurposeConfig::new(), + ); + + // test data, keyed by ciphersuite + let mut data = HashMap::new(); + + for (ciphersuite, group_id, storages_bytes) in kat_data { + let storages: Vec = storages_bytes + .iter() + .map(|test| base64_engine.encode(test)) + .collect(); + + data.insert(ciphersuite, KatData { group_id, storages }); + } + // write to file + let mut file = std::fs::File::create("test_vectors/storage-stability-new.json").unwrap(); + serde_json::to_writer(&mut file, &data).unwrap(); +} + +#[openmls_test] +fn test(ciphersuite: Ciphersuite, provider: &Provider) { + // setup + let base64_engine = base64::engine::GeneralPurpose::new( + &base64::alphabet::URL_SAFE, + base64::engine::GeneralPurposeConfig::new(), + ); + + // load data + let mut data: HashMap = { + let file = std::fs::File::open("test_vectors/storage-stability.json").unwrap(); + serde_json::from_reader(file).unwrap() + }; + + let KatData { group_id, storages } = data.remove(&ciphersuite).unwrap(); + + // parse base64-encoded serialized storage + let mut storages = storages + .iter() + .map(|storage| base64_engine.decode(storage).unwrap()); + + //// load group from state right after creation + + let provider_new_group = + deserialize_provider::<_, Provider>(&mut storages.next().unwrap().as_slice(), "alice"); + + let alice_group_new_group = MlsGroup::load(provider_new_group.storage(), &group_id) + .unwrap() + .unwrap(); + + // alice is the sole member + let members = alice_group_new_group.members().collect::>(); + assert_eq!(members.len(), 1); + assert_eq!(members[0].index, LeafNodeIndex::new(0)); + assert_eq!( + members[0].credential, + BasicCredential::new(b"alice".to_vec()).into() + ); + + // there are no pending proposals or commits + assert!(alice_group_new_group.pending_proposals().next().is_none()); + assert!(alice_group_new_group.pending_commit().is_none()); + + // we are in the right epoch + assert_eq!(alice_group_new_group.epoch(), 0.into()); + assert_eq!( + alice_group_new_group + .group() + .resumption_psk_store() + .cursor(), + 1 + ); + + // dropping to prevent accidentally using the wrong provider or group later + drop(alice_group_new_group); + drop(provider_new_group); + + //// load group from state after bob was added, but commit not yet merged + + let provider_pending_add_commit = + deserialize_provider::<_, Provider>(&mut storages.next().unwrap().as_slice(), "alice"); + + let alice_group_pending_add_commit = + MlsGroup::load(provider_pending_add_commit.storage(), &group_id) + .unwrap() + .unwrap(); + + // alice is the sole member + let members = alice_group_pending_add_commit.members().collect::>(); + assert_eq!(members.len(), 1); + assert_eq!(members[0].index, LeafNodeIndex::new(0)); + assert_eq!( + members[0].credential, + BasicCredential::new(b"alice".to_vec()).into() + ); + + // there is one pending add commit + match alice_group_pending_add_commit.pending_commit() { + Some(staged_commit) => { + assert_eq!(staged_commit.queued_proposals().count(), 1); + assert_eq!(staged_commit.add_proposals().count(), 1); + let add_proposal = staged_commit.add_proposals().next().unwrap(); + assert_eq!( + add_proposal + .add_proposal() + .key_package() + .leaf_node() + .credential(), + &BasicCredential::new(b"bob".to_vec()).into() + ); + } + None => panic!("expected a pending commit"), + }; + + // there are no pending proposals + assert_eq!( + alice_group_pending_add_commit.pending_proposals().count(), + 0 + ); + + // we are in the right epoch + assert_eq!(alice_group_pending_add_commit.epoch(), 0.into()); + assert_eq!( + alice_group_pending_add_commit + .group() + .resumption_psk_store() + .cursor(), + 1 + ); + + // dropping to prevent accidentally using the wrong provider or group later + drop(alice_group_pending_add_commit); + drop(provider_pending_add_commit); + + //// load group from state after bob was added + + let provider_bob_added = + deserialize_provider::<_, Provider>(&mut storages.next().unwrap().as_slice(), "alice"); + + let alice_group_bob_added = MlsGroup::load(provider_bob_added.storage(), &group_id) + .unwrap() + .unwrap(); + + // alice and bob are members + let members = alice_group_bob_added.members().collect::>(); + assert_eq!(members.len(), 2); + assert_eq!(members[0].index, LeafNodeIndex::new(0)); + assert_eq!(members[1].index, LeafNodeIndex::new(1)); + assert_eq!( + members[0].credential, + BasicCredential::new(b"alice".to_vec()).into() + ); + assert_eq!( + members[1].credential, + BasicCredential::new(b"bob".to_vec()).into() + ); + + // there are no pending proposals or commits + assert!(alice_group_bob_added.pending_proposals().next().is_none()); + assert!(alice_group_bob_added.pending_commit().is_none()); + + // we are in the right epoch + assert_eq!(alice_group_bob_added.epoch(), 1.into()); + assert_eq!( + alice_group_bob_added + .group() + .resumption_psk_store() + .cursor(), + 2 + ); + + // dropping to prevent accidentally using the wrong provider or group later + drop(alice_group_bob_added); + drop(provider_bob_added); + + //// load group from state after alice updated GCE, but commit is not yet merged + + let provider_pending_gce_commit = + deserialize_provider::<_, Provider>(&mut storages.next().unwrap().as_slice(), "alice"); + + let alice_group_pending_gce_commit = + MlsGroup::load(provider_pending_gce_commit.storage(), &group_id) + .unwrap() + .unwrap(); + + // alice and bob are members + let members = alice_group_pending_gce_commit.members().collect::>(); + assert_eq!(members.len(), 2); + assert_eq!(members[0].index, LeafNodeIndex::new(0)); + assert_eq!(members[1].index, LeafNodeIndex::new(1)); + assert_eq!( + members[0].credential, + BasicCredential::new(b"alice".to_vec()).into() + ); + assert_eq!( + members[1].credential, + BasicCredential::new(b"bob".to_vec()).into() + ); + + // there are no pending proposals + assert!(alice_group_pending_gce_commit + .pending_proposals() + .next() + .is_none()); + + // there is one pending gce commit + match alice_group_pending_gce_commit.pending_commit() { + Some(staged_commit) => { + let proposals: Vec<_> = staged_commit.queued_proposals().collect(); + assert_eq!(proposals.len(), 1); + + let Proposal::GroupContextExtensions(gce_proposal) = &proposals[0].proposal() else { + panic!( + "expected a group context extension proposal, got {:?}", + proposals[0] + ) + }; + + assert_eq!( + gce_proposal.extensions(), + &Extensions::single(Extension::RequiredCapabilities( + RequiredCapabilitiesExtension::new(&[ExtensionType::Unknown(0xf042)], &[], &[]) + )) + ); + } + None => panic!("expected a pending commit"), + }; + + // we are in the right epoch + assert_eq!(alice_group_pending_gce_commit.epoch(), 1.into()); + assert_eq!( + alice_group_pending_gce_commit + .group() + .resumption_psk_store() + .cursor(), + 2 + ); + + // dropping to prevent accidentally using the wrong provider or group later + drop(alice_group_pending_gce_commit); + drop(provider_pending_gce_commit); + + //// load group from state after alice updated GCE + + let provider_gce_updated = + deserialize_provider::<_, Provider>(&mut storages.next().unwrap().as_slice(), "alice"); + + let alice_group_gce_updated = MlsGroup::load(provider_gce_updated.storage(), &group_id) + .unwrap() + .unwrap(); + + // alice and bob are members + let members = alice_group_gce_updated.members().collect::>(); + assert_eq!(members.len(), 2); + assert_eq!(members[0].index, LeafNodeIndex::new(0)); + assert_eq!(members[1].index, LeafNodeIndex::new(1)); + assert_eq!( + members[0].credential, + BasicCredential::new(b"alice".to_vec()).into() + ); + assert_eq!( + members[1].credential, + BasicCredential::new(b"bob".to_vec()).into() + ); + + // there are no pending proposals or commits + assert!(alice_group_gce_updated.pending_proposals().next().is_none()); + assert!(alice_group_gce_updated.pending_commit().is_none()); + + drop(alice_group_gce_updated); + drop(provider_gce_updated); + + //// load group from state after alice creates another proposal + + let provider_pending_proposal = + deserialize_provider::<_, Provider>(&mut storages.next().unwrap().as_slice(), "alice"); + + let alice_group_pending_proposal = + MlsGroup::load(provider_pending_proposal.storage(), &group_id) + .unwrap() + .unwrap(); + + // alice and bob are members + let members = alice_group_pending_proposal.members().collect::>(); + assert_eq!(members.len(), 2); + assert_eq!(members[0].index, LeafNodeIndex::new(0)); + assert_eq!(members[1].index, LeafNodeIndex::new(1)); + assert_eq!( + members[0].credential, + BasicCredential::new(b"alice".to_vec()).into() + ); + assert_eq!( + members[1].credential, + BasicCredential::new(b"bob".to_vec()).into() + ); + + // there is one pending add proposal + let proposals: Vec<_> = alice_group_pending_proposal.pending_proposals().collect(); + assert_eq!(proposals.len(), 1); + match &proposals[0].proposal() { + Proposal::Add(add_proposal) => { + assert_eq!( + add_proposal.key_package().leaf_node().credential(), + &BasicCredential::new(b"charlie".to_vec()).into() + ) + } + other => panic!("expected add proposal, got {:?}", other), + } + + // there is no pending commit + assert!(alice_group_pending_proposal.pending_commit().is_none()); +} diff --git a/openmls/src/test_utils/frankenstein/commit.rs b/openmls/src/test_utils/frankenstein/commit.rs index c635a0dfd9..b2537a961d 100644 --- a/openmls/src/test_utils/frankenstein/commit.rs +++ b/openmls/src/test_utils/frankenstein/commit.rs @@ -32,8 +32,8 @@ pub struct FrankenUpdatePathIn { Debug, Clone, PartialEq, Eq, TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, )] pub struct FrankenUpdatePathNode { - pub(super) public_key: VLBytes, - pub(super) encrypted_path_secrets: Vec, + pub public_key: VLBytes, + pub encrypted_path_secrets: Vec, } #[derive( diff --git a/openmls/src/test_utils/frankenstein/framing.rs b/openmls/src/test_utils/frankenstein/framing.rs index 5c4afb1c21..7d867ec16d 100644 --- a/openmls/src/test_utils/frankenstein/framing.rs +++ b/openmls/src/test_utils/frankenstein/framing.rs @@ -160,8 +160,8 @@ impl FrankenPublicMessage { let wire_format = 1; // PublicMessage let franken_tbs = FrankenFramedContentTbs { - version: 1, - wire_format: 1, // PublicMessage + version, + wire_format, content: &content, group_context, }; diff --git a/openmls/src/test_utils/frankenstein/leaf_node.rs b/openmls/src/test_utils/frankenstein/leaf_node.rs index 1c27746189..74b4789aa1 100644 --- a/openmls/src/test_utils/frankenstein/leaf_node.rs +++ b/openmls/src/test_utils/frankenstein/leaf_node.rs @@ -6,11 +6,12 @@ use tls_codec::*; use super::{extensions::FrankenExtension, key_package::FrankenLifetime, FrankenCredential}; use crate::{ - binary_tree::array_representation::tree, + binary_tree::{array_representation::tree, LeafNodeIndex}, ciphersuite::{ signable::{Signable, SignedStruct}, signature::Signature, }, + group::GroupId, treesync::{ node::leaf_node::{LeafNodeIn, LeafNodeTbs, TreePosition}, LeafNode, @@ -115,6 +116,25 @@ pub struct FrankenTreePosition { pub leaf_index: u32, } +impl From for FrankenTreePosition { + fn from(tp: TreePosition) -> Self { + let (group_id, leaf_index) = tp.into_parts(); + Self { + group_id: group_id.as_slice().to_owned().into(), + leaf_index: leaf_index.u32(), + } + } +} + +impl From for TreePosition { + fn from(ftp: FrankenTreePosition) -> Self { + Self::new( + GroupId::from_slice(ftp.group_id.as_slice()), + LeafNodeIndex::new(ftp.leaf_index), + ) + } +} + #[derive(Debug, Clone, PartialEq, Eq, TlsSize)] pub struct FrankenLeafNodeTbs { pub payload: FrankenLeafNodePayload, diff --git a/openmls/src/test_utils/mod.rs b/openmls/src/test_utils/mod.rs index 85fa9dd757..21efccaf00 100644 --- a/openmls/src/test_utils/mod.rs +++ b/openmls/src/test_utils/mod.rs @@ -17,7 +17,7 @@ pub use openmls_traits::{ use serde::{self, de::DeserializeOwned, Serialize}; #[cfg(test)] -use crate::group::tests::utils::CredentialWithKeyAndSigner; +use crate::group::tests_and_kats::utils::CredentialWithKeyAndSigner; pub use crate::utils::*; use crate::{ ciphersuite::{HpkePrivateKey, OpenMlsSignaturePublicKey}, diff --git a/openmls/src/test_utils/test_framework/client.rs b/openmls/src/test_utils/test_framework/client.rs index ebdb3bc47c..9b4ef9c1c4 100644 --- a/openmls/src/test_utils/test_framework/client.rs +++ b/openmls/src/test_utils/test_framework/client.rs @@ -24,7 +24,7 @@ use crate::{ storage::OpenMlsProvider, treesync::{ node::{leaf_node::Capabilities, Node}, - LeafNode, RatchetTree, RatchetTreeIn, + LeafNode, LeafNodeParameters, RatchetTree, RatchetTreeIn, }, versions::ProtocolVersion, }; @@ -157,7 +157,9 @@ impl Client { group_state.clear_pending_commit(self.provider.storage())?; } // Process the message. - let processed_message = group_state.process_message(&self.provider, message.clone())?; + let processed_message = group_state + .process_message(&self.provider, message.clone()) + .map_err(ClientError::ProcessMessageError)?; match processed_message.into_content() { ProcessedMessageContent::ApplicationMessage(_) => {} @@ -209,7 +211,7 @@ impl Client { &self, action_type: ActionType, group_id: &GroupId, - leaf_node: Option, + leaf_node_parameters: LeafNodeParameters, ) -> Result< (MlsMessageOut, Option, Option), ClientError, @@ -228,10 +230,12 @@ impl Client { ) .unwrap(); let (msg, welcome_option, group_info) = match action_type { - ActionType::Commit => group.self_update(&self.provider, &signer)?, + ActionType::Commit => { + group.self_update(&self.provider, &signer, LeafNodeParameters::default())? + } ActionType::Proposal => ( group - .propose_self_update(&self.provider, &signer, leaf_node) + .propose_self_update(&self.provider, &signer, leaf_node_parameters) .map(|(out, _)| out)?, None, None, diff --git a/openmls/src/test_utils/test_framework/errors.rs b/openmls/src/test_utils/test_framework/errors.rs index 370fe9ac49..3375426c17 100644 --- a/openmls/src/test_utils/test_framework/errors.rs +++ b/openmls/src/test_utils/test_framework/errors.rs @@ -23,7 +23,7 @@ pub enum SetupError { ClientError(#[from] ClientError), /// See [`ExportSecretError`] for more details. #[error(transparent)] - ExportSecretError(#[from] ExportSecretError), + ExportSecretError(#[from] ExportSecretError), /// See [`LibraryError`] for more details. #[error(transparent)] LibraryError(#[from] LibraryError), @@ -56,11 +56,8 @@ pub enum ClientError { #[error(transparent)] TlsCodecError(tls_codec::Error), /// See [`ProcessMessageError`] for more details. - #[error(transparent)] - ProcessMessageError(#[from] ProcessMessageError), - /// See [`MlsGroupStateError`] for more details. - #[error(transparent)] - MlsGroupStateError(#[from] MlsGroupStateError), + #[error("See ProcessMessageError for more details.")] + ProcessMessageError(ProcessMessageError), /// See [`AddMembersError`] for more details. #[error(transparent)] AddMembersError(#[from] AddMembersError), @@ -74,8 +71,8 @@ pub enum ClientError { #[error(transparent)] ProposeRemoveMemberError(#[from] ProposeRemoveMemberError), /// See [`ExportSecretError`] for more details. - #[error(transparent)] - ExportSecretError(#[from] ExportSecretError), + #[error("Error exporting secret")] + ExportSecretError(ExportSecretError), /// See [`NewGroupError`] for more details. #[error(transparent)] NewGroupError(#[from] NewGroupError), diff --git a/openmls/src/test_utils/test_framework/mod.rs b/openmls/src/test_utils/test_framework/mod.rs index 383283f529..3fec5bc232 100644 --- a/openmls/src/test_utils/test_framework/mod.rs +++ b/openmls/src/test_utils/test_framework/mod.rs @@ -23,6 +23,7 @@ use crate::storage::OpenMlsProvider; use crate::test_utils::OpenMlsRustCrypto; +use crate::treesync::LeafNodeParameters; use crate::{ binary_tree::array_representation::LeafNodeIndex, ciphersuite::{hash_ref::KeyPackageRef, *}, @@ -353,7 +354,9 @@ impl MlsGroupTestSetup { ) .collect(); group.public_tree = sender_group.export_ratchet_tree(); - group.exporter_secret = sender_group.export_secret(&sender.provider, "test", &[], 32)?; + group.exporter_secret = sender_group + .export_secret(&sender.provider, "test", &[], 32) + .map_err(ClientError::ExportSecretError)?; Ok(()) } @@ -538,7 +541,7 @@ impl MlsGroupTestSetup { action_type: ActionType, group: &mut Group, client_id: &[u8], - leaf_node: Option, + leaf_node_parameters: LeafNodeParameters, authentication_service: &AS, ) -> Result<(), SetupError> { let clients = self.clients.read().expect("An unexpected error occurred."); @@ -548,7 +551,7 @@ impl MlsGroupTestSetup { .read() .expect("An unexpected error occurred."); let (messages, welcome_option, _) = - client.self_update(action_type, &group.group_id, leaf_node)?; + client.self_update(action_type, &group.group_id, leaf_node_parameters)?; self.distribute_to_members( &client.identity, group, @@ -671,7 +674,7 @@ impl MlsGroupTestSetup { action_type, group, &member_id.1, - None, + LeafNodeParameters::default(), authentication_service, )?; } diff --git a/openmls/src/tree/sender_ratchet.rs b/openmls/src/tree/sender_ratchet.rs index 240a87465f..380a71ae21 100644 --- a/openmls/src/tree/sender_ratchet.rs +++ b/openmls/src/tree/sender_ratchet.rs @@ -21,14 +21,14 @@ pub(crate) type Generation = u32; /// /// **Parameters** /// -/// - out_of_order_tolerance: -/// This parameter defines a window for which decryption secrets are kept. -/// This is useful in case the DS cannot guarantee that all application messages have total order within an epoch. -/// Use this carefully, since keeping decryption secrets affects forward secrecy within an epoch. -/// The default value is 5. -/// - maximum_forward_distance: -/// This parameter defines how many incoming messages can be skipped. This is useful if the DS -/// drops application messages. The default value is 1000. +/// - out_of_order_tolerance: +/// This parameter defines a window for which decryption secrets are kept. +/// This is useful in case the DS cannot guarantee that all application messages have total order within an epoch. +/// Use this carefully, since keeping decryption secrets affects forward secrecy within an epoch. +/// The default value is 5. +/// - maximum_forward_distance: +/// This parameter defines how many incoming messages can be skipped. This is useful if the DS +/// drops application messages. The default value is 1000. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct SenderRatchetConfiguration { out_of_order_tolerance: Generation, diff --git a/openmls/src/tree/tests_and_kats/kats/kat_encryption.rs b/openmls/src/tree/tests_and_kats/kats/kat_encryption.rs index 0b430b6c55..38f9c623d6 100644 --- a/openmls/src/tree/tests_and_kats/kats/kat_encryption.rs +++ b/openmls/src/tree/tests_and_kats/kats/kat_encryption.rs @@ -161,20 +161,17 @@ fn generate_credential( fn group( ciphersuite: Ciphersuite, provider: &impl OpenMlsProvider, -) -> (CoreGroup, CredentialWithKey, SignatureKeyPair) { +) -> (MlsGroup, CredentialWithKey, SignatureKeyPair) { let (credential_with_key, signer) = generate_credential( "Kreator".into(), ciphersuite.signature_algorithm(), provider, ); - let group = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - credential_with_key.clone(), - ) - .build(provider, &signer) - .unwrap(); + let group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .build(provider, &signer, credential_with_key.clone()) + .unwrap(); (group, credential_with_key, signer) } @@ -184,15 +181,17 @@ fn receiver_group( ciphersuite: Ciphersuite, provider: &impl OpenMlsProvider, group_id: GroupId, -) -> (CoreGroup, CredentialWithKey, SignatureKeyPair) { +) -> (MlsGroup, CredentialWithKey, SignatureKeyPair) { let (credential_with_key, signer) = generate_credential( "Receiver".into(), ciphersuite.signature_algorithm(), provider, ); - let group = CoreGroup::builder(group_id, ciphersuite, credential_with_key.clone()) - .build(provider, &signer) + let group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .with_group_id(group_id) + .build(provider, &signer, credential_with_key.clone()) .unwrap(); (group, credential_with_key, signer) @@ -202,7 +201,7 @@ fn receiver_group( #[cfg(any(feature = "test-utils", test))] fn build_handshake_messages( sender_index: LeafNodeIndex, - group: &mut CoreGroup, + group: &mut MlsGroup, signer: &impl Signer, provider: &impl OpenMlsProvider, ) -> (Vec, Vec) { @@ -223,7 +222,7 @@ fn build_handshake_messages( Proposal::Remove(RemoveProposal { removed: LeafNodeIndex::new(7), }), // XXX: use random removed - group.context(), + group.export_group_context(), signer, ) .expect("An unexpected error occurred."), @@ -235,7 +234,10 @@ fn build_handshake_messages( provider.crypto(), group.ciphersuite(), &membership_key, - &group.context().tls_serialize_detached().unwrap(), + &group + .export_group_context() + .tls_serialize_detached() + .unwrap(), ) .expect("Error setting membership tag."); let ciphertext = PrivateMessage::encrypt_without_check( @@ -259,7 +261,7 @@ fn build_handshake_messages( #[cfg(any(feature = "test-utils", test))] fn build_application_messages( sender_index: LeafNodeIndex, - group: &mut CoreGroup, + group: &mut MlsGroup, signer: &impl Signer, provider: &impl OpenMlsProvider, ) -> (Vec, Vec) { @@ -276,7 +278,7 @@ fn build_application_messages( sender_index, &[1, 2, 3], &[4, 5, 6], - group.context(), + group.export_group_context(), signer, ) .expect("An unexpected error occurred."); @@ -286,7 +288,10 @@ fn build_application_messages( provider.crypto(), group.ciphersuite(), &membership_key, - &group.context().tls_serialize_detached().unwrap(), + &group + .export_group_context() + .tls_serialize_detached() + .unwrap(), ) .expect("Error setting membership tag."); let ciphertext = match PrivateMessage::encrypt_without_check( @@ -321,25 +326,25 @@ pub fn generate_test_vector( use crate::binary_tree::array_representation::TreeSize; let ciphersuite_name = ciphersuite; - let crypto = OpenMlsRustCrypto::default(); - let encryption_secret_bytes = crypto + let provider = OpenMlsRustCrypto::default(); + let encryption_secret_bytes = provider .rand() .random_vec(ciphersuite.hash_length()) .expect("An unexpected error occurred."); - let sender_data_secret = SenderDataSecret::random(ciphersuite, crypto.rand()); + let sender_data_secret = SenderDataSecret::random(ciphersuite, provider.rand()); let sender_data_secret_bytes = sender_data_secret.as_slice(); // Create sender_data_key/secret - let ciphertext = crypto + let ciphertext = provider .rand() .random_vec(77) .expect("An unexpected error occurred."); let sender_data_key = sender_data_secret - .derive_aead_key(crypto.crypto(), ciphersuite, &ciphertext) + .derive_aead_key(provider.crypto(), ciphersuite, &ciphertext) .expect("Could not derive AEAD key."); // Derive initial nonce from the key schedule using the ciphertext. let sender_data_nonce = sender_data_secret - .derive_aead_nonce(ciphersuite, crypto.crypto(), &ciphertext) + .derive_aead_nonce(ciphersuite, provider.crypto(), &ciphertext) .expect("Could not derive nonce."); let sender_data_info = SenderDataInfo { ciphertext: bytes_to_hex(&ciphertext), @@ -347,7 +352,7 @@ pub fn generate_test_vector( nonce: bytes_to_hex(sender_data_nonce.as_slice()), }; - let (mut group, _, signer) = group(ciphersuite, &crypto); + let (mut group, _, signer) = group(ciphersuite, &provider); *group.message_secrets_test_mut().sender_data_secret_mut() = SenderDataSecret::from_slice(sender_data_secret_bytes); @@ -372,7 +377,7 @@ pub fn generate_test_vector( let (application_secret_key, application_secret_nonce) = decryption_secret_tree .secret_for_decryption( ciphersuite, - crypto.crypto(), + provider.crypto(), sender_leaf, SecretType::ApplicationSecret, generation, @@ -382,7 +387,7 @@ pub fn generate_test_vector( let application_key_string = bytes_to_hex(application_secret_key.as_slice()); let application_nonce_string = bytes_to_hex(application_secret_nonce.as_slice()); let (application_plaintext, application_ciphertext) = - build_application_messages(sender_leaf, &mut group, &signer, &crypto); + build_application_messages(sender_leaf, &mut group, &signer, &provider); println!("Sender Group: {group:?}"); application.push(RatchetStep { key: application_key_string, @@ -395,7 +400,7 @@ pub fn generate_test_vector( let (handshake_secret_key, handshake_secret_nonce) = decryption_secret_tree .secret_for_decryption( ciphersuite, - crypto.crypto(), + provider.crypto(), sender_leaf, SecretType::HandshakeSecret, generation, @@ -406,7 +411,7 @@ pub fn generate_test_vector( let handshake_nonce_string = bytes_to_hex(handshake_secret_nonce.as_slice()); let (handshake_plaintext, handshake_ciphertext) = - build_handshake_messages(sender_leaf, &mut group, &signer, &crypto); + build_handshake_messages(sender_leaf, &mut group, &signer, &provider); handshake.push(RatchetStep { key: handshake_key_string, @@ -599,7 +604,10 @@ pub fn run_test_vector( sender_data_secret.clone(), MembershipKey::random(ciphersuite, provider.rand()), // we don't care about this value ConfirmationKey::random(ciphersuite, provider.rand()), // we don't care about this value - group.context().tls_serialize_detached().unwrap(), + group + .export_group_context() + .tls_serialize_detached() + .unwrap(), fresh_secret_tree.clone(), ); diff --git a/openmls/src/tree/tests_and_kats/kats/kat_message_protection.rs b/openmls/src/tree/tests_and_kats/kats/kat_message_protection.rs index f972186ff0..14d14eafbb 100644 --- a/openmls/src/tree/tests_and_kats/kats/kat_message_protection.rs +++ b/openmls/src/tree/tests_and_kats/kats/kat_message_protection.rs @@ -62,7 +62,6 @@ //! * When protecting the Commit message, add the supplied confirmation tag use openmls_basic_credential::SignatureKeyPair; -use openmls_traits::types::SignatureScheme; use serde::{self, Deserialize, Serialize}; use crate::{ @@ -104,65 +103,6 @@ pub struct MessageProtectionTest { application_priv: String, } -fn generate_credential( - identity: Vec, - signature_algorithm: SignatureScheme, - provider: &impl crate::storage::OpenMlsProvider, -) -> (CredentialWithKey, SignatureKeyPair) { - let credential = BasicCredential::new(identity); - let signature_keys = SignatureKeyPair::new(signature_algorithm).unwrap(); - signature_keys.store(provider.storage()).unwrap(); - - ( - CredentialWithKey { - credential: credential.into(), - signature_key: signature_keys.to_public_vec().into(), - }, - signature_keys, - ) -} - -#[cfg(any(feature = "test-utils", test))] -fn group( - ciphersuite: Ciphersuite, - provider: &impl crate::storage::OpenMlsProvider, -) -> (CoreGroup, CredentialWithKey, SignatureKeyPair) { - let (credential_with_key, signer) = generate_credential( - "Kreator".into(), - ciphersuite.signature_algorithm(), - provider, - ); - - let group = CoreGroup::builder( - GroupId::random(provider.rand()), - ciphersuite, - credential_with_key.clone(), - ) - .build(provider, &signer) - .unwrap(); - - (group, credential_with_key, signer) -} - -#[cfg(any(feature = "test-utils", test))] -fn receiver_group( - ciphersuite: Ciphersuite, - provider: &impl crate::storage::OpenMlsProvider, - group_id: GroupId, -) -> (CoreGroup, CredentialWithKey, SignatureKeyPair) { - let (credential_with_key, signer) = generate_credential( - "Receiver".into(), - ciphersuite.signature_algorithm(), - provider, - ); - - let group = CoreGroup::builder(group_id, ciphersuite, credential_with_key.clone()) - .build(provider, &signer) - .unwrap(); - - (group, credential_with_key, signer) -} - #[cfg(test)] pub fn run_test_vector( test: MessageProtectionTest, @@ -218,7 +158,7 @@ pub fn run_test_vector( ciphersuite: Ciphersuite, test: &MessageProtectionTest, sender: bool, - ) -> CoreGroup { + ) -> MlsGroup { let group_context = GroupContext::new( ciphersuite, GroupId::from_slice(&hex_to_bytes(&test.group_id)), @@ -240,16 +180,18 @@ pub fn run_test_vector( random_own_signature_key.to_vec(), ); - let mut group = CoreGroup::builder( - group_context.group_id().clone(), - ciphersuite, - CredentialWithKey { - credential: credential.into(), - signature_key: random_own_signature_key.into(), - }, - ) - .build(provider, &signer) - .unwrap(); + let mut group = MlsGroup::builder() + .ciphersuite(ciphersuite) + .with_wire_format_policy(MIXED_PLAINTEXT_WIRE_FORMAT_POLICY) + .build( + provider, + &signer, + CredentialWithKey { + credential: credential.into(), + signature_key: random_own_signature_key.into(), + }, + ) + .unwrap(); let credential = BasicCredential::new("Fake user".into()); let signature_keys = SignatureKeyPair::new(ciphersuite.signature_algorithm()).unwrap(); @@ -263,33 +205,10 @@ pub fn run_test_vector( }, ); let bob_key_package = bob_key_package_bundle.key_package(); - let framing_parameters = FramingParameters::new(&[], WireFormat::PublicMessage); - let bob_add_proposal = group - .create_add_proposal(framing_parameters, bob_key_package.clone(), &signer) - .expect("Could not create proposal."); - - let proposal_store = ProposalStore::from_queued_proposal( - QueuedProposal::from_authenticated_content_by_ref( - ciphersuite, - provider.crypto(), - bob_add_proposal, - ) - .expect("Could not create QueuedProposal."), - ); - - let params = CreateCommitParams::builder() - .framing_parameters(framing_parameters) - .proposal_store(&proposal_store) - .force_self_update(false) - .build(); - - let create_commit_result = group - .create_commit(params, provider, &signer) - .expect("Error creating Commit"); - - group - .merge_commit(provider, create_commit_result.staged_commit) - .expect("error merging pending commit"); + let (_commit, _welcome, _) = group + .add_members(provider, &signature_keys, &[bob_key_package.clone()]) + .unwrap(); + group.merge_pending_commit(provider).unwrap(); // Inject the test values into the group @@ -331,34 +250,19 @@ pub fn run_test_vector( MlsMessageIn::tls_deserialize_exact(hex_to_bytes(&test.proposal_priv)).unwrap(); fn test_proposal_pub( - mut group: CoreGroup, + mut group: MlsGroup, provider: &impl crate::storage::OpenMlsProvider, - ciphersuite: Ciphersuite, proposal: ProposalIn, proposal_pub: MlsMessageIn, ) { - // Group stuff we need for openmls - let sender_ratchet_config = SenderRatchetConfiguration::new(0, 0); - // check that the proposal in proposal_pub == proposal - let decrypted_message = group - .decrypt_message( - provider.crypto(), - proposal_pub.into_protocol_message().unwrap(), - &sender_ratchet_config, - ) - .unwrap(); - - let processed_unverified_message = group - .public_group() - .parse_message(decrypted_message, group.message_secrets_store()) + let processed_message = group + .process_message(provider, proposal_pub.into_protocol_message().unwrap()) .unwrap(); - let processed_message: AuthenticatedContent = processed_unverified_message - .verify(ciphersuite, provider, ProtocolVersion::Mls10) - .unwrap() - .0; - match processed_message.content().to_owned() { - FramedContentBody::Proposal(p) => assert_eq!(proposal, p.into()), + match processed_message.content() { + ProcessedMessageContent::ProposalMessage(p) => { + assert_eq!(proposal, p.proposal().to_owned().into()) + } _ => panic!("Wrong processed message content"), } } @@ -366,43 +270,12 @@ pub fn run_test_vector( test_proposal_pub( setup_group(provider, ciphersuite, &test, false), provider, - ciphersuite, proposal.clone(), proposal_pub, ); - fn test_proposal_priv( - mut group: CoreGroup, - provider: &impl crate::storage::OpenMlsProvider, - proposal: ProposalIn, - proposal_priv: MlsMessageIn, - ) { - // Group stuff we need for openmls - let sender_ratchet_config = SenderRatchetConfiguration::new(0, 0); - let proposal_store = ProposalStore::default(); - - // decrypt private message - let processed_message = group - .process_message( - provider, - proposal_priv.into_protocol_message().unwrap(), - &sender_ratchet_config, - &proposal_store, - &[], - ) - .unwrap(); - - // check that proposal == processed_message - match processed_message.content().to_owned() { - ProcessedMessageContent::ProposalMessage(p) => { - assert_eq!(proposal, p.proposal().to_owned().into()) - } - _ => panic!("Wrong processed message content"), - } - } - let group = setup_group(provider, ciphersuite, &test, false); - test_proposal_priv(group, provider, proposal.clone(), proposal_priv); + test_proposal_pub(group, provider, proposal.clone(), proposal_priv); // Wrap `proposal` into a `PrivateMessage`. let group = setup_group(provider, ciphersuite, &test, false); @@ -418,10 +291,12 @@ pub fn run_test_vector( let my_proposal_priv = sender_group .encrypt(proposal_authenticated_content, 0, provider) .unwrap(); - let my_proposal_priv_out = - MlsMessageOut::from_private_message(my_proposal_priv, group.version()); + let my_proposal_priv_out = MlsMessageOut::from_private_message( + my_proposal_priv, + group.export_group_context().protocol_version(), + ); - test_proposal_priv( + test_proposal_pub( group, provider, proposal.clone(), @@ -430,7 +305,7 @@ pub fn run_test_vector( // Wrap `proposal` into a `PublicMessage`. let group = setup_group(provider, ciphersuite, &test, false); - let sender_group = setup_group(provider, ciphersuite, &test, true); + let mut sender_group = setup_group(provider, ciphersuite, &test, true); let proposal_authenticated_content = AuthenticatedContent::member_proposal( FramingParameters::new(&[], WireFormat::PublicMessage), sender_index, @@ -444,19 +319,16 @@ pub fn run_test_vector( .set_membership_tag( provider.crypto(), ciphersuite, - sender_group.message_secrets().membership_key(), - sender_group.message_secrets().serialized_context(), + &sender_group + .message_secrets_test_mut() + .membership_key() + .clone(), + sender_group.message_secrets_test_mut().serialized_context(), ) .expect("error setting membership tag"); let my_proposal_pub_out: MlsMessageOut = my_proposal_pub.into(); - test_proposal_pub( - group, - provider, - ciphersuite, - proposal, - my_proposal_pub_out.into(), - ); + test_proposal_pub(group, provider, proposal, my_proposal_pub_out.into()); } // Commit @@ -468,7 +340,7 @@ pub fn run_test_vector( MlsMessageIn::tls_deserialize_exact(hex_to_bytes(&test.commit_priv)).unwrap(); fn test_commit_pub( - mut group: CoreGroup, + mut group: MlsGroup, provider: &impl crate::storage::OpenMlsProvider, ciphersuite: Ciphersuite, commit: CommitIn, @@ -477,7 +349,7 @@ pub fn run_test_vector( // Group stuff we need for openmls let sender_ratchet_config = SenderRatchetConfiguration::new(10, 10); - // check that the proposal in proposal_pub == proposal + // check that the commit in commit_pub == commit let decrypted_message = group .decrypt_message( provider.crypto(), @@ -487,11 +359,12 @@ pub fn run_test_vector( .unwrap(); let processed_unverified_message = group + .group() .public_group() - .parse_message(decrypted_message, group.message_secrets_store()) + .parse_message(decrypted_message, group.group().message_secrets_store()) .unwrap(); let processed_message: AuthenticatedContent = processed_unverified_message - .verify(ciphersuite, provider, ProtocolVersion::Mls10) + .verify(ciphersuite, provider.crypto(), ProtocolVersion::Mls10) .unwrap() .0; match processed_message.content().to_owned() { @@ -510,42 +383,7 @@ pub fn run_test_vector( commit_pub, ); - fn test_commit_priv( - mut group: CoreGroup, - provider: &impl crate::storage::OpenMlsProvider, - ciphersuite: Ciphersuite, - commit: CommitIn, - commit_priv: MlsMessageIn, - ) { - // Group stuff we need for openmls - let sender_ratchet_config = SenderRatchetConfiguration::new(10, 10); - - // check that the proposal in proposal_priv == proposal - let decrypted_message = group - .decrypt_message( - provider.crypto(), - commit_priv.into_protocol_message().unwrap(), - &sender_ratchet_config, - ) - .unwrap(); - - let processed_unverified_message = group - .public_group() - .parse_message(decrypted_message, group.message_secrets_store()) - .unwrap(); - let processed_message: AuthenticatedContent = processed_unverified_message - .verify(ciphersuite, provider, ProtocolVersion::Mls10) - .unwrap() - .0; - match processed_message.content().to_owned() { - FramedContentBody::Commit(c) => { - assert_eq!(commit, CommitIn::from(c)) - } - _ => panic!("Wrong processed message content"), - } - } - - test_commit_priv( + test_commit_pub( setup_group(provider, ciphersuite, &test, false), provider, ciphersuite, @@ -570,10 +408,12 @@ pub fn run_test_vector( let my_commit_pub = sender_group .encrypt(commit_authenticated_content, 0, provider) .unwrap(); - let my_commit_priv_out = - MlsMessageOut::from_private_message(my_commit_pub, group.version()); + let my_commit_priv_out = MlsMessageOut::from_private_message( + my_commit_pub, + group.export_group_context().protocol_version(), + ); - test_commit_priv( + test_commit_pub( group, provider, ciphersuite, @@ -583,7 +423,7 @@ pub fn run_test_vector( // Wrap `commit` into a `PublicMessage`. let group = setup_group(provider, ciphersuite, &test, false); - let sender_group = setup_group(provider, ciphersuite, &test, true); + let mut sender_group = setup_group(provider, ciphersuite, &test, true); let mut commit_authenticated_content = AuthenticatedContent::commit( FramingParameters::new(&[], WireFormat::PublicMessage), Sender::Member(sender_index), @@ -600,8 +440,11 @@ pub fn run_test_vector( .set_membership_tag( provider.crypto(), ciphersuite, - sender_group.message_secrets().membership_key(), - sender_group.message_secrets().serialized_context(), + &sender_group + .message_secrets_test_mut() + .membership_key() + .clone(), + sender_group.message_secrets_test_mut().serialized_context(), ) .expect("error setting membership tag"); let my_commit_pub_out: MlsMessageOut = my_commit_pub_msg.into(); @@ -622,24 +465,14 @@ pub fn run_test_vector( MlsMessageIn::tls_deserialize_exact(hex_to_bytes(&test.application_priv)).unwrap(); fn test_application_priv( - mut group: CoreGroup, + mut group: MlsGroup, provider: &impl crate::storage::OpenMlsProvider, application: Vec, application_priv: MlsMessageIn, ) { - // Group stuff we need for openmls - let sender_ratchet_config = SenderRatchetConfiguration::new(0, 0); - let proposal_store = ProposalStore::default(); - // check that the proposal in proposal_pub == proposal let processed_message = group - .process_message( - provider, - application_priv.into_ciphertext().unwrap(), - &sender_ratchet_config, - &proposal_store, - &[], - ) + .process_message(provider, application_priv.into_protocol_message().unwrap()) .unwrap(); match processed_message.into_content() { ProcessedMessageContent::ApplicationMessage(a) => { @@ -659,16 +492,14 @@ pub fn run_test_vector( // Wrap `application` into a `PrivateMessage`. let mut sender_group = setup_group(provider, ciphersuite, &test, true); let private_message = sender_group - .create_application_message(&[], &application, 0, provider, &signer) + .create_message(provider, &signer, &application) .unwrap(); - let my_application_priv_out = - MlsMessageOut::from_private_message(private_message, sender_group.version()); test_application_priv( setup_group(provider, ciphersuite, &test, false), provider, application.clone(), - my_application_priv_out.into(), + private_message.into(), ); } diff --git a/openmls/src/treesync/diff.rs b/openmls/src/treesync/diff.rs index 71a1624413..5d3ef2df96 100644 --- a/openmls/src/treesync/diff.rs +++ b/openmls/src/treesync/diff.rs @@ -21,9 +21,10 @@ use std::collections::HashSet; use log::debug; use openmls_traits::crypto::OpenMlsCrypto; -use openmls_traits::{signatures::Signer, types::Ciphersuite, OpenMlsProvider}; +use openmls_traits::{signatures::Signer, types::Ciphersuite}; use serde::{Deserialize, Serialize}; +use super::node::leaf_node::UpdateLeafNodeParams; use super::{ errors::*, node::{ @@ -35,6 +36,7 @@ use super::{ treesync_node::{TreeSyncLeafNode, TreeSyncParentNode}, LeafNode, TreeSync, TreeSyncParentHashError, }; +use crate::group::{create_commit_params::CommitType, GroupId}; use crate::{ binary_tree::{ array_representation::{ @@ -44,9 +46,9 @@ use crate::{ }, ciphersuite::Secret, error::LibraryError, - group::GroupId, messages::PathSecret, schedule::CommitSecret, + storage::OpenMlsProvider, treesync::RatchetTree, }; @@ -59,6 +61,7 @@ pub(crate) type UpdatePathResult = ( /// The [`StagedTreeSyncDiff`] can be created from a [`TreeSyncDiff`], examined /// and later merged into a [`TreeSync`] instance. #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(any(test, feature = "test-utils"), derive(Clone, PartialEq))] pub(crate) struct StagedTreeSyncDiff { diff: StagedMlsBinaryTreeDiff, new_tree_hash: Vec, @@ -288,28 +291,50 @@ impl<'a> TreeSyncDiff<'a> { /// derivation, as well as the newly derived [`EncryptionKeyPair`]s. /// /// Returns an error if the target leaf is not in the tree. + #[allow(clippy::too_many_arguments)] pub(crate) fn apply_own_update_path( &mut self, provider: &impl OpenMlsProvider, signer: &impl Signer, ciphersuite: Ciphersuite, + commit_type: &CommitType, group_id: GroupId, leaf_index: LeafNodeIndex, - ) -> Result { - debug_assert!( - self.leaf(leaf_index).is_some(), - "Tree diff is missing own leaf" - ); + leaf_node_params: UpdateLeafNodeParams, + ) -> Result { + // For External Commits, we temporarily add a placeholder leaf node to the tree, because it + // might be required to make the tree grow to the right size. If we + // don't do that, calculating the direct path might fail. It's important + // to not do anything with the value of that leaf until it has been + // replaced. + if let CommitType::External(_) = commit_type { + let leaf_node = LeafNode::new_placeholder(); + self.add_leaf(leaf_node)?; + } - let (path, update_path_nodes, keypairs, commit_secret) = + // We calculate the parent hash so that we can use it for a fresh leaf + let (path, update_path_nodes, parent_keypairs, commit_secret) = self.derive_path(provider, ciphersuite, leaf_index)?; - let parent_hash = self.process_update_path(provider.crypto(), ciphersuite, leaf_index, path)?; - self.leaf_mut(leaf_index) - .ok_or_else(|| LibraryError::custom("Didn't find own leaf in diff."))? - .update_parent_hash(&parent_hash, group_id, leaf_index, signer)?; + // We generate the new leaf with all parameters + let (leaf_node, node_keypair) = LeafNode::new_with_parent_hash( + provider, + ciphersuite, + &parent_hash, + leaf_node_params, + group_id, + leaf_index, + signer, + )?; + + // We insert the fresh leaf into the tree. + self.diff.replace_leaf(leaf_index, leaf_node.into()); + + // Prepend parent keypairs with node keypair + let mut keypairs = vec![node_keypair]; + keypairs.extend(parent_keypairs); Ok((update_path_nodes, keypairs, commit_secret)) } @@ -666,7 +691,7 @@ impl<'a> TreeSyncDiff<'a> { /// This turns the diff into a staged diff. In the process, the diff /// computes and sets the new tree hash. pub(crate) fn into_staged_diff( - mut self, + self, crypto: &impl OpenMlsCrypto, ciphersuite: Ciphersuite, ) -> Result { @@ -681,7 +706,7 @@ impl<'a> TreeSyncDiff<'a> { /// Helper function to compute and set the tree hash of the given node and /// all nodes below it in the tree. The leaf nodes in `exclusion_list` are /// not included in the tree hash. - pub(super) fn compute_tree_hash( + pub(crate) fn compute_tree_hash( &self, crypto: &impl OpenMlsCrypto, ciphersuite: Ciphersuite, @@ -720,14 +745,9 @@ impl<'a> TreeSyncDiff<'a> { self.diff.leaf(index).node().as_ref() } - /// Return a mutable reference to the leaf with the given index. - pub(crate) fn leaf_mut(&mut self, index: LeafNodeIndex) -> Option<&mut LeafNode> { - self.diff.leaf_mut(index).node_mut().as_mut() - } - /// Compute and set the tree hash of all nodes in the tree. pub(crate) fn compute_tree_hashes( - &mut self, + &self, crypto: &impl OpenMlsCrypto, ciphersuite: Ciphersuite, ) -> Result, LibraryError> { diff --git a/openmls/src/treesync/errors.rs b/openmls/src/treesync/errors.rs index 53f53a45e8..c0ecf3fcb9 100644 --- a/openmls/src/treesync/errors.rs +++ b/openmls/src/treesync/errors.rs @@ -128,7 +128,7 @@ pub(crate) enum DerivePathError { /// TreeSync set path error #[derive(Error, Debug, PartialEq, Clone)] -pub(crate) enum TreeSyncAddLeaf { +pub enum TreeSyncAddLeaf { /// See [`LibraryError`] for more details. #[error(transparent)] LibraryError(#[from] LibraryError), diff --git a/openmls/src/treesync/mod.rs b/openmls/src/treesync/mod.rs index d1813b59ac..fbb60de19d 100644 --- a/openmls/src/treesync/mod.rs +++ b/openmls/src/treesync/mod.rs @@ -25,7 +25,6 @@ use openmls_traits::{ crypto::OpenMlsCrypto, signatures::Signer, types::{Ciphersuite, CryptoError}, - OpenMlsProvider, }; use serde::{Deserialize, Serialize}; use thiserror::Error; @@ -46,7 +45,7 @@ use self::{ use crate::binary_tree::array_representation::ParentNodeIndex; #[cfg(any(feature = "test-utils", test))] use crate::{ - binary_tree::array_representation::level, group::tests::tree_printing::root, + binary_tree::array_representation::level, group::tests_and_kats::tree_printing::root, test_utils::bytes_to_hex, }; use crate::{ @@ -62,6 +61,7 @@ use crate::{ key_packages::Lifetime, messages::{PathSecret, PathSecretError}, schedule::CommitSecret, + storage::OpenMlsProvider, }; // Private @@ -83,7 +83,11 @@ pub use node::encryption_keys::test_utils; pub use node::encryption_keys::EncryptionKey; // Public re-exports -pub use node::{leaf_node::LeafNode, parent_node::ParentNode, Node}; +pub use node::{ + leaf_node::{LeafNode, LeafNodeParameters, LeafNodeParametersBuilder, LeafNodeUpdateError}, + parent_node::ParentNode, + Node, +}; // Tests #[cfg(any(feature = "test-utils", test))] @@ -354,7 +358,7 @@ impl fmt::Display for RatchetTree { /// creating a new instance from an imported set of nodes, as well as when /// merging a diff. #[derive(Debug, Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq, Clone))] +#[cfg_attr(any(test, feature = "test-utils"), derive(PartialEq, Clone))] pub(crate) struct TreeSync { tree: MlsBinaryTree, tree_hash: Vec, @@ -727,8 +731,9 @@ mod test { ciphersuite: Ciphersuite, provider: &impl OpenMlsProvider, ) { - let (key_package, _, _) = - crate::key_packages::test_key_packages::key_package(ciphersuite, provider); + use openmls_traits::OpenMlsProvider; + + let (key_package, _, _) = crate::key_packages::tests::key_package(ciphersuite, provider); let node_in = NodeIn::from(Node::LeafNode(LeafNode::from(key_package))); let tests = [ (vec![], false), diff --git a/openmls/src/treesync/node/encryption_keys.rs b/openmls/src/treesync/node/encryption_keys.rs index 0aab483a4d..13a18e2437 100644 --- a/openmls/src/treesync/node/encryption_keys.rs +++ b/openmls/src/treesync/node/encryption_keys.rs @@ -4,7 +4,6 @@ use openmls_traits::{ crypto::OpenMlsCrypto, storage::{StorageProvider as StorageProviderTrait, CURRENT_VERSION}, types::{Ciphersuite, HpkeCiphertext, HpkeKeyPair}, - OpenMlsProvider, }; use serde::{Deserialize, Serialize}; use tls_codec::{TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize, VLBytes}; @@ -12,7 +11,7 @@ use tls_codec::{TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize, VLBy use crate::{ ciphersuite::{hpke, HpkePrivateKey, HpkePublicKey, Secret}, error::LibraryError, - storage::StorageProvider, + storage::{OpenMlsProvider, StorageProvider}, }; /// [`EncryptionKey`] contains an HPKE public key that allows the encryption of @@ -65,10 +64,16 @@ impl EncryptionKey { } } +impl From> for EncryptionKey { + fn from(key: Vec) -> Self { + Self { key: key.into() } + } +} + #[derive( Clone, Serialize, Deserialize, TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize, )] -#[cfg_attr(test, derive(PartialEq, Eq))] +#[cfg_attr(any(test, feature = "test-utils"), derive(PartialEq, Eq))] pub struct EncryptionPrivateKey { key: HpkePrivateKey, } @@ -140,7 +145,7 @@ impl From for EncryptionKey { #[derive( Debug, Clone, Serialize, Deserialize, TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize, )] -#[cfg_attr(test, derive(PartialEq, Eq))] +#[cfg_attr(any(test, feature = "test-utils"), derive(PartialEq, Eq))] pub(crate) struct EncryptionKeyPair { public_key: EncryptionKey, private_key: EncryptionPrivateKey, diff --git a/openmls/src/treesync/node/leaf_node.rs b/openmls/src/treesync/node/leaf_node.rs index c90a7b69aa..f32a4c3f72 100644 --- a/openmls/src/treesync/node/leaf_node.rs +++ b/openmls/src/treesync/node/leaf_node.rs @@ -1,14 +1,12 @@ //! This module contains the [`LeafNode`] struct and its implementation. use openmls_traits::{signatures::Signer, types::Ciphersuite}; use serde::{Deserialize, Serialize}; +use thiserror::Error; use tls_codec::{ Serialize as TlsSerializeTrait, TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize, VLBytes, }; -#[cfg(test)] -use thiserror::Error; - use super::encryption_keys::{EncryptionKey, EncryptionKeyPair}; use crate::{ binary_tree::array_representation::LeafNodeIndex, @@ -16,14 +14,13 @@ use crate::{ signable::{Signable, SignedStruct, Verifiable, VerifiedStruct}, Signature, SignaturePublicKey, }, - credentials::{Credential, CredentialWithKey}, + credentials::{Credential, CredentialType, CredentialWithKey}, error::LibraryError, extensions::{ExtensionType, Extensions}, group::GroupId, key_packages::{KeyPackage, Lifetime}, prelude::KeyPackageBundle, storage::OpenMlsProvider, - treesync::errors::PublicTreeError, }; use crate::treesync::errors::LeafNodeValidationError; @@ -42,6 +39,102 @@ pub(crate) struct NewLeafNodeParams { pub(crate) tree_info_tbs: TreeInfoTbs, } +/// Set of LeafNode parameters that are used when regenerating a LeafNodes +/// during an update operation. +#[derive(Debug, PartialEq, Clone)] +pub(crate) struct UpdateLeafNodeParams { + pub(crate) credential_with_key: CredentialWithKey, + pub(crate) capabilities: Capabilities, + pub(crate) extensions: Extensions, +} + +impl UpdateLeafNodeParams { + #[cfg(test)] + pub(crate) fn derive(leaf_node: &LeafNode) -> Self { + Self { + credential_with_key: CredentialWithKey { + credential: leaf_node.payload.credential.clone(), + signature_key: leaf_node.payload.signature_key.clone(), + }, + capabilities: leaf_node.payload.capabilities.clone(), + extensions: leaf_node.payload.extensions.clone(), + } + } +} + +/// Parameters for a leaf node that can be chosen by the application. +#[derive(Debug, PartialEq, Clone, Default)] +pub struct LeafNodeParameters { + credential_with_key: Option, + capabilities: Option, + extensions: Option, +} + +impl LeafNodeParameters { + /// Create a new [`LeafNodeParametersBuilder`]. + pub fn builder() -> LeafNodeParametersBuilder { + LeafNodeParametersBuilder::default() + } + + /// Returns the credential with key. + pub fn credential_with_key(&self) -> Option<&CredentialWithKey> { + self.credential_with_key.as_ref() + } + + /// Returns the capabilities. + pub fn capabilities(&self) -> Option<&Capabilities> { + self.capabilities.as_ref() + } + + /// Returns the extensions. + pub fn extensions(&self) -> Option<&Extensions> { + self.extensions.as_ref() + } + + pub(crate) fn is_empty(&self) -> bool { + self.credential_with_key.is_none() + && self.capabilities.is_none() + && self.extensions.is_none() + } +} + +/// Builder for [`LeafNodeParameters`]. +#[derive(Debug, Default)] +pub struct LeafNodeParametersBuilder { + credential_with_key: Option, + capabilities: Option, + extensions: Option, +} + +impl LeafNodeParametersBuilder { + /// Set the credential with key. + pub fn with_credential_with_key(mut self, credential_with_key: CredentialWithKey) -> Self { + self.credential_with_key = Some(credential_with_key); + self + } + + /// Set the capabilities. + pub fn with_capabilities(mut self, capabilities: Capabilities) -> Self { + self.capabilities = Some(capabilities); + self + } + + /// Set the extensions. + pub fn with_extensions(mut self, extensions: Extensions) -> Self { + self.extensions = Some(extensions); + self + } + + /// Build the [`LeafNodeParameters`]. + pub fn build(self) -> LeafNodeParameters { + LeafNodeParameters { + credential_with_key: self.credential_with_key, + capabilities: self.capabilities, + extensions: self.extensions, + } + } +} + /// This struct implements the MLS leaf node. /// /// ```c @@ -114,6 +207,27 @@ impl LeafNode { Ok((leaf_node, encryption_key_pair)) } + /// Creates a new placeholder [`LeafNode`] that is used to build external + /// commits. + /// + /// Note: This is not a valid leaf node and it must be rekeyed and signed + /// before it can be used. + pub(crate) fn new_placeholder() -> Self { + let payload = LeafNodePayload { + encryption_key: EncryptionKey::from(Vec::new()), + signature_key: Vec::new().into(), + credential: Credential::new(CredentialType::Basic, Vec::new()), + capabilities: Capabilities::default(), + leaf_node_source: LeafNodeSource::Update, + extensions: Extensions::default(), + }; + + Self { + payload, + signature: Vec::new().into(), + } + } + /// Create a new leaf node with a given HPKE encryption key pair. /// The key pair must be stored in the key store by the caller. fn new_with_key( @@ -132,67 +246,44 @@ impl LeafNode { leaf_node_source, extensions, tree_info_tbs, - )?; + ); leaf_node_tbs .sign(signer) .map_err(|_| LibraryError::custom("Signing failed")) } - /// Update the parent hash of this [`LeafNode`]. - /// - /// This re-signs the leaf node. - pub(in crate::treesync) fn update_parent_hash( - &mut self, + /// New [`LeafNode`] with a parent hash. + #[allow(clippy::too_many_arguments)] + pub(in crate::treesync) fn new_with_parent_hash( + provider: &impl OpenMlsProvider, + ciphersuite: Ciphersuite, parent_hash: &[u8], + leaf_node_params: UpdateLeafNodeParams, group_id: GroupId, leaf_index: LeafNodeIndex, signer: &impl Signer, - ) -> Result<(), LibraryError> { - self.payload.leaf_node_source = LeafNodeSource::Commit(parent_hash.into()); - let tbs = LeafNodeTbs::from( - self.clone(), // TODO: With a better setup we wouldn't have to clone here. + ) -> Result<(Self, EncryptionKeyPair), LibraryError> { + let encryption_key_pair = EncryptionKeyPair::random(provider, ciphersuite)?; + + let leaf_node_tbs = LeafNodeTbs::new( + encryption_key_pair.public_key().clone(), + leaf_node_params.credential_with_key, + leaf_node_params.capabilities, + LeafNodeSource::Commit(parent_hash.into()), + leaf_node_params.extensions, TreeInfoTbs::Commit(TreePosition { group_id, leaf_index, }), ); - let leaf_node = tbs + + // Sign the leaf node + let leaf_node = leaf_node_tbs .sign(signer) .map_err(|_| LibraryError::custom("Signing failed"))?; - self.payload = leaf_node.payload; - self.signature = leaf_node.signature; - Ok(()) - } - - /// Generate a fresh leaf node with a fresh encryption key but otherwise - /// the same properties as the current leaf node. - /// - /// The newly generated encryption key pair is stored in the key store. - /// - /// This function can be used when generating an update. In most other cases - /// a leaf node should be generated as part of a new [`KeyPackage`]. - #[cfg(test)] - pub(crate) fn updated( - &self, - ciphersuite: Ciphersuite, - tree_info_tbs: TreeInfoTbs, - provider: &Provider, - signer: &impl Signer, - ) -> Result> { - Self::generate_update( - ciphersuite, - CredentialWithKey { - credential: self.payload.credential.clone(), - signature_key: self.payload.signature_key.clone(), - }, - self.payload.capabilities.clone(), - self.payload.extensions.clone(), - tree_info_tbs, - provider, - signer, - ) + Ok((leaf_node, encryption_key_pair)) } /// Generate a fresh leaf node. @@ -234,86 +325,59 @@ impl LeafNode { Ok(leaf_node) } - /// Update the `encryption_key` in this leaf node and re-signs it. + /// Update a leaf node. + /// + /// This function generates a new encryption key pair that is stored in the + /// key store and also returned. /// - /// Optionally, a new leaf node can be provided to update more values such as - /// the credential. - pub(crate) fn update_and_re_sign( + /// This function can be used when generating an update. In most other cases + /// a leaf node should be generated as part of a new [`KeyPackage`]. + pub(crate) fn update( &mut self, - new_encryption_key: impl Into>, - leaf_node: impl Into>, + ciphersuite: Ciphersuite, + provider: &Provider, + signer: &impl Signer, group_id: GroupId, leaf_index: LeafNodeIndex, - signer: &impl Signer, - ) -> Result<(), PublicTreeError> { + leaf_node_parmeters: LeafNodeParameters, + ) -> Result> { let tree_info = TreeInfoTbs::Update(TreePosition::new(group_id, leaf_index)); - // TODO: If we could take out the leaf_node without cloning, this would all be nicer. let mut leaf_node_tbs = LeafNodeTbs::from(self.clone(), tree_info); // Update credential - if let Some(leaf_node) = leaf_node.into() { - leaf_node_tbs.payload.credential = leaf_node.credential().clone(); - leaf_node_tbs.payload.encryption_key = leaf_node.encryption_key().clone(); - leaf_node_tbs.payload.leaf_node_source = LeafNodeSource::Update; - } else if let Some(new_encryption_key) = new_encryption_key.into() { - leaf_node_tbs.payload.leaf_node_source = LeafNodeSource::Update; - - // If there's no new leaf, the encryption key must be provided - // explicitly. - leaf_node_tbs.payload.encryption_key = new_encryption_key; - } else { - debug_assert!(false, "update_and_re_sign needs to be called with a new leaf node or a new encryption key. Neither was the case."); - return Err(LibraryError::custom( - "update_and_re_sign needs to be called with a new leaf node or a new encryption key. Neither was the case.").into()); + if let Some(credential_with_key) = leaf_node_parmeters.credential_with_key { + leaf_node_tbs.payload.credential = credential_with_key.credential; + leaf_node_tbs.payload.signature_key = credential_with_key.signature_key; } - // Set the new signed leaf node with the new encryption key - let leaf_node = leaf_node_tbs.sign(signer)?; - self.payload = leaf_node.payload; - self.signature = leaf_node.signature; - - Ok(()) - } + // Update extensions + if let Some(extensions) = leaf_node_parmeters.extensions { + leaf_node_tbs.payload.extensions = extensions; + } - /// Replace the encryption key in this leaf with a random one. - /// - /// This signs the new leaf node as well. - pub(crate) fn rekey( - &mut self, - group_id: &GroupId, - leaf_index: LeafNodeIndex, - ciphersuite: Ciphersuite, - provider: &impl OpenMlsProvider, - signer: &impl Signer, - ) -> Result { - if !self - .payload - .capabilities - .ciphersuites - .contains(&ciphersuite.into()) - { - debug_assert!( - false, - "Ciphersuite or protocol version is not supported by this leaf node.\ - \ncapabilities: {:?}\nciphersuite: {:?}", - self.payload.capabilities, ciphersuite - ); - return Err(LibraryError::custom( - "Ciphersuite or protocol version is not supported by this leaf node.", - ) - .into()); + // Update capabilities + if let Some(capabilities) = leaf_node_parmeters.capabilities { + leaf_node_tbs.payload.capabilities = capabilities; } - let key_pair = EncryptionKeyPair::random(provider, ciphersuite)?; - self.update_and_re_sign( - key_pair.public_key().clone(), - None, - group_id.clone(), - leaf_index, - signer, - )?; + // Create a new encryption key pair + let encryption_key_pair = EncryptionKeyPair::random(provider, ciphersuite)?; + leaf_node_tbs.payload.encryption_key = encryption_key_pair.public_key().clone(); - Ok(key_pair) + // Store the encryption key pair in the key store. + encryption_key_pair + .write(provider.storage()) + .map_err(LeafNodeUpdateError::Storage)?; + + // Set the leaf node source to update + leaf_node_tbs.payload.leaf_node_source = LeafNodeSource::Update; + + // Sign the leaf node + let leaf_node = leaf_node_tbs.sign(signer)?; + self.payload = leaf_node.payload; + self.signature = leaf_node.signature; + + Ok(encryption_key_pair) } /// Returns the `encryption_key`. @@ -355,10 +419,15 @@ impl LeafNode { } /// Return a reference to [`Capabilities`]. - pub(crate) fn capabilities(&self) -> &Capabilities { + pub fn capabilities(&self) -> &Capabilities { &self.payload.capabilities } + /// Return a reference to the leaf node source. + pub fn leaf_node_source(&self) -> &LeafNodeSource { + &self.payload.leaf_node_source + } + /// Return a reference to the leaf node extensions. pub fn extensions(&self) -> &Extensions { &self.payload.extensions @@ -508,7 +577,7 @@ impl LeafNodeTbs { leaf_node_source: LeafNodeSource, extensions: Extensions, tree_info_tbs: TreeInfoTbs, - ) -> Result { + ) -> Self { let payload = LeafNodePayload { encryption_key, signature_key: credential_with_key.signature_key, @@ -517,11 +586,11 @@ impl LeafNodeTbs { leaf_node_source, extensions, }; - let tbs = LeafNodeTbs { + + LeafNodeTbs { payload, tree_info_tbs, - }; - Ok(tbs) + } } } @@ -566,6 +635,11 @@ impl TreePosition { leaf_index, } } + + #[cfg(feature = "test-utils")] + pub(crate) fn into_parts(self) -> (GroupId, LeafNodeIndex) { + (self.group_id, self.leaf_index) + } } const LEAF_NODE_SIGNATURE_LABEL: &str = "LeafNodeTBS"; @@ -856,3 +930,19 @@ pub enum LeafNodeGenerationError { #[error("Error storing leaf private key.")] StorageError(StorageError), } + +/// Leaf Node Update Error +#[derive(Error, Debug, PartialEq, Clone)] +pub enum LeafNodeUpdateError { + /// See [`LibraryError`] for more details. + #[error(transparent)] + LibraryError(#[from] LibraryError), + + /// Error storing leaf private key in storage. + #[error("Error storing leaf private key.")] + Storage(StorageError), + + /// Signature error. + #[error(transparent)] + Signature(#[from] crate::ciphersuite::signable::SignatureError), +} diff --git a/openmls/src/treesync/node/leaf_node/capabilities.rs b/openmls/src/treesync/node/leaf_node/capabilities.rs index 5dfc510828..057e1fb82f 100644 --- a/openmls/src/treesync/node/leaf_node/capabilities.rs +++ b/openmls/src/treesync/node/leaf_node/capabilities.rs @@ -93,6 +93,11 @@ impl Capabilities { } } + /// Creates a new [`CapabilitiesBuilder`] for constructing [`Capabilities`] + pub fn builder() -> CapabilitiesBuilder { + CapabilitiesBuilder(Self::default()) + } + // --------------------------------------------------------------------------------------------- /// Get a reference to the list of versions in this extension. @@ -174,6 +179,56 @@ impl Capabilities { } } +/// A helper for building [`Capabilities`] +#[derive(Debug, Clone)] +pub struct CapabilitiesBuilder(Capabilities); + +impl CapabilitiesBuilder { + /// Sets the `versions` field on the [`Capabilities`]. + pub fn versions(self, versions: Vec) -> Self { + Self(Capabilities { versions, ..self.0 }) + } + + /// Sets the `ciphersuites` field on the [`Capabilities`]. + pub fn ciphersuites(self, ciphersuites: Vec) -> Self { + let ciphersuites = ciphersuites.into_iter().map(|cs| cs.into()).collect(); + + Self(Capabilities { + ciphersuites, + ..self.0 + }) + } + + /// Sets the `extensions` field on the [`Capabilities`]. + pub fn extensions(self, extensions: Vec) -> Self { + Self(Capabilities { + extensions, + ..self.0 + }) + } + + /// Sets the `proposals` field on the [`Capabilities`]. + pub fn proposals(self, proposals: Vec) -> Self { + Self(Capabilities { + proposals, + ..self.0 + }) + } + + /// Sets the `credentials` field on the [`Capabilities`]. + pub fn credentials(self, credentials: Vec) -> Self { + Self(Capabilities { + credentials, + ..self.0 + }) + } + + /// Builds the [`Capabilities`]. + pub fn build(self) -> Capabilities { + self.0 + } +} + #[cfg(test)] impl Capabilities { /// Set the versions list. diff --git a/openmls/src/treesync/tests_and_kats/kats/kat_treekem.rs b/openmls/src/treesync/tests_and_kats/kats/kat_treekem.rs index f33aaf4b43..1f6f6c50c7 100644 --- a/openmls/src/treesync/tests_and_kats/kats/kat_treekem.rs +++ b/openmls/src/treesync/tests_and_kats/kats/kat_treekem.rs @@ -9,13 +9,13 @@ use tls_codec::{Deserialize as TlsDeserializeTrait, Serialize as TlsSerializeTra use crate::{ binary_tree::{array_representation::ParentNodeIndex, LeafNodeIndex}, extensions::{Extensions, RatchetTreeExtension}, - group::{GroupContext, GroupEpoch, GroupId}, + group::{CommitType, GroupContext, GroupEpoch, GroupId}, messages::PathSecret, prelude_test::Secret, schedule::CommitSecret, test_utils::{hex_to_bytes, OpenMlsRustCrypto}, treesync::{ - node::encryption_keys::EncryptionKeyPair, + node::{encryption_keys::EncryptionKeyPair, leaf_node::UpdateLeafNodeParams}, treekem::{DecryptPathParams, UpdatePath, UpdatePathIn}, TreeSync, }, @@ -243,14 +243,20 @@ pub fn run_test_vector(test: TreeKemTest, provider: &impl OpenMlsProvider) { ) }; + let leaf_index = LeafNodeIndex::new(path_test.sender); + let leaf_node = diff_after_kat.leaf(leaf_index).unwrap(); + let leaf_node_params = UpdateLeafNodeParams::derive(leaf_node); + // TODO(#1279): Update own leaf. let (vec_plain_update_path_nodes, _, commit_secret) = diff_after_kat .apply_own_update_path( provider, &signer, ciphersuite, + &CommitType::Member, group_context.group_id().clone(), LeafNodeIndex::new(path_test.sender), + leaf_node_params, ) .unwrap(); diff --git a/openmls/src/treesync/tests_and_kats/tests.rs b/openmls/src/treesync/tests_and_kats/tests.rs index 210a2986ad..6cf703665d 100644 --- a/openmls/src/treesync/tests_and_kats/tests.rs +++ b/openmls/src/treesync/tests_and_kats/tests.rs @@ -1,6 +1,6 @@ use crate::{ group::{ - tests::utils::{generate_credential_with_key, CredentialWithKeyAndSigner}, + tests_and_kats::utils::{generate_credential_with_key, CredentialWithKeyAndSigner}, MlsGroup, MlsGroupCreateConfig, }, key_packages::KeyPackage, diff --git a/openmls/src/treesync/treesync_node.rs b/openmls/src/treesync/treesync_node.rs index 5b074fb995..bc3faf2806 100644 --- a/openmls/src/treesync/treesync_node.rs +++ b/openmls/src/treesync/treesync_node.rs @@ -57,7 +57,7 @@ impl From for TreeNode { } #[derive(Debug, Clone, Default, Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq))] +#[cfg_attr(any(test, feature = "test-utils"), derive(PartialEq))] /// This intermediate struct on top of `Option` allows us to cache tree /// hash values. Blank nodes are represented by [`TreeSyncNode`] instances where /// `node = None`. @@ -76,11 +76,6 @@ impl TreeSyncLeafNode { &self.node } - /// Return a mutable reference to the contained `Option`. - pub(in crate::treesync) fn node_mut(&mut self) -> &mut Option { - &mut self.node - } - /// Compute the tree hash for this node, thus populating the `tree_hash` /// field. pub(in crate::treesync) fn compute_tree_hash( @@ -109,7 +104,7 @@ impl From for Option { } #[derive(Debug, Clone, Default, Serialize, Deserialize)] -#[cfg_attr(test, derive(PartialEq))] +#[cfg_attr(any(test, feature = "test-utils"), derive(PartialEq))] /// This intermediate struct on top of `Option` allows us to cache tree /// hash values. Blank nodes are represented by [`TreeSyncNode`] instances where /// `node = None`. diff --git a/openmls/test_vectors/storage-stability.json b/openmls/test_vectors/storage-stability.json new file mode 100644 index 0000000000..f5f7e85627 --- /dev/null +++ b/openmls/test_vectors/storage-stability.json @@ -0,0 +1 @@ +{"MLS_128_DHKEMP256_AES128GCM_SHA256_P256":{"group_id":{"value":{"vec":[214,206,173,27,206,87,231,4,172,30,130,210,232,69,61,222]}},"storages":["AAAAAAAAAA0AAAAAAAAAXQAAAAAAAAGaRXBvY2hLZXlQYWlyc3sidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0wMAABW3sicHVibGljX2tleSI6eyJrZXkiOnsidmVjIjpbNCw2Nyw1LDEyOCwxMDUsMTU0LDEyNyw5MCwyMDgsNTksMjQ3LDE2MiwyMjQsMjM1LDE5MSwxNjAsMjAzLDg3LDEwLDMsMTA2LDUyLDc1LDgyLDQxLDIxMyw1NSw4NywyMTUsMzIsMTM0LDE4MCwxNDQsNSw0MCwxOCwxNDQsMjE5LDg5LDg0LDE4LDE0NCwxOTEsMTc0LDExOSwyMjAsNTksOTEsMTUxLDExMiwxMTgsMTYxLDIyNSw2NywyNDUsMTgzLDEzOCw5MSwyNywyMjcsMTA5LDIyMywyNDAsNzUsMTgxXX19LCJwcml2YXRlX2tleSI6eyJrZXkiOnsidmVjIjpbMjcsMjMzLDExNyw3MSwxNTgsNDMsMTE3LDI0LDEyLDEyOCw2MiwxMTEsNjAsMjMyLDE0NywyMTgsMjA3LDg2LDE4NywxNjcsMjQsMTc5LDIxMiwxNTAsODUsMTUwLDIxNCw5MSwxMjEsMTcyLDQ4LDU3XX19fV0AAAAAAAAAXQAAAAAAAACJQ29uZmlybWF0aW9uVGFneyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJtYWNfdmFsdWUiOnsidmVjIjpbMTkzLDk2LDEwMiwyNDksMTg5LDM4LDgxLDE2MCwyMTksNzYsODEsOTgsMjA3LDE1MywxMDksMTEwLDc0LDkxLDg0LDE4OSwyMzgsMTE3LDg5LDE5NSwyNTQsMTUsMTgyLDE3NCw2MCwxNzUsNjIsNDVdfX0AAAAAAAAAUgAAAAAAAAWMVHJlZXsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsidHJlZSI6eyJsZWFmX25vZGVzIjpbeyJub2RlIjp7InBheWxvYWQiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzQsNjcsNSwxMjgsMTA1LDE1NCwxMjcsOTAsMjA4LDU5LDI0NywxNjIsMjI0LDIzNSwxOTEsMTYwLDIwMyw4NywxMCwzLDEwNiw1Miw3NSw4Miw0MSwyMTMsNTUsODcsMjE1LDMyLDEzNCwxODAsMTQ0LDUsNDAsMTgsMTQ0LDIxOSw4OSw4NCwxOCwxNDQsMTkxLDE3NCwxMTksMjIwLDU5LDkxLDE1MSwxMTIsMTE4LDE2MSwyMjUsNjcsMjQ1LDE4MywxMzgsOTEsMjcsMjI3LDEwOSwyMjMsMjQwLDc1LDE4MV19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0LDE1LDEyMSwxMjQsMTc1LDEwMCw4LDI5LDIxNSwyMjMsMzMsMTc3LDIyNyw3NSwxOTAsNDcsMjMsNzMsMzMsMTYsNDYsNzEsMTEsMTM4LDYzLDgyLDE4OCwyMjIsMTAzLDgxLDU3LDUyLDIxNywxMTgsODIsMTAyLDE5OSwxNDAsMTQyLDIzNSwxNDQsMTQ1LDE4OSwxMzYsMzMsMTYxLDI1MywxMjIsMTg5LDgxLDQ4LDE2NSw2NiwxMzIsMTEwLDI0OCw1MSwxOTksMjE1LDE3Nyw4MSwyNDAsMTAyLDE2Myw0Ml19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJLZXlQYWNrYWdlIjp7Im5vdF9iZWZvcmUiOjE3MjA2ODg5NDksIm5vdF9hZnRlciI6MTcyNzk1MDE0OX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0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NCw3OCwyMzQsMTgzLDEzNCw0NSwyLDUwLDEwNCwxMCw1MSw5MywxNDcsNTMsMTA4LDIxOSwxNzgsMjExLDE0NiwxODFdfX19LCJzZXJpYWxpemVkX2NvbnRleHQiOlswLDEsMCwyLDE2LDIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyLDAsMCwwLDAsMCwwLDAsMCwzMiwyMDgsMjQ2LDIzOSwyMTQsMTcxLDIwMSwxMTQsMSwxMDUsMjE3LDM3LDIxNCwyMzksMTUsOTAsMTQzLDIwMCw5NiwxNzksMTc3LDE1NiwxODksNzEsMzgsMTQxLDU1LDg5LDE2MywxMjksMjUxLDE5OSw5NSwwLDBdLCJzZWNyZXRfdHJlZSI6eyJvd25faW5kZXgiOjAsImxlYWZfbm9kZXMiOlt7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNjEsMTc3LDE3NiwxNTEsMTc1LDEwNSwxOTAsMjE1LDU0LDIwLDE0Nyw2NSw3MywyLDgzLDM5LDIwMSw1Nyw1OCwyMCwxOTIsMTAzLDI3LDY5LDkxLDIwOCwzMCwzOSwxNjIsMTY5LDE2MSw3XX19fV0sInBhcmVudF9ub2RlcyI6W251bGxdLCJoYW5kc2hha2Vfc2VuZGVyX3JhdGNoZXRzIjpbbnVsbF0sImFwcGxpY2F0aW9uX3NlbmRlcl9yYXRjaGV0cyI6W251bGxdLCJzaXplIjoxfX19","AAAAAAAAAA0AAAAAAAAAXQAAAAAAAAGaRXBvY2hLZXlQYWlyc3sidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0wMAABW3sicHVibGljX2tleSI6eyJrZXkiOnsidmVjIjpbNCw2Nyw1LDEyOCwxMDUsMTU0LDEyNyw5MCwyMDgsNTksMjQ3LDE2MiwyMjQsMjM1LDE5MSwxNjAsMjAzLDg3LDEwLDMsMTA2LDUyLDc1LDgyLDQxLDIxMyw1NSw4NywyMTUsMzIsMTM0LDE4MCwxNDQsNSw0MCwxOCwxNDQsMjE5LDg5LDg0LDE4LDE0NCwxOTEsMTc0LDExOSwyMjAsNTksOTEsMTUxLDExMiwxMTgsMTYxLDIyNSw2NywyNDUsMTgzLDEzOCw5MSwyNywyMjcsMTA5LDIyMywyNDAsNzUsMTgxXX19LCJwcml2YXRlX2tleSI6eyJrZXkiOnsidmVjIjpbMjcsMjMzLDExNyw3MSwxNTgsNDMsMTE3LDI0LDEyLDEyOCw2MiwxMTEsNjAsMjMyLDE0NywyMTgsMjA3LDg2LDE4NywxNjcsMjQsMTc5LDIxMiwxNTAsODUsMTUwLDIxNCw5MSwxMjEsMTcyLDQ4LDU3XX19fV0AAAAAAAAAXQAAAAAAAACJQ29uZmlybWF0aW9uVGFneyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJtYWNfdmFsdWUiOnsidmVjIjpbMTkzLDk2LDEwMiwyNDksMTg5LDM4LDgxLDE2MCwyMTksNzYsODEsOTgsMjA3LDE1MywxMDksMTEwLDc0LDkxLDg0LDE4OSwyMzgsMTE3LDg5LDE5NSwyNTQsMTUsMTgyLDE3NCw2MCwxNzUsNjIsNDVdfX0AAAAAAAAAUgAAAAAAAAWMVHJlZXsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsidHJlZSI6eyJsZWFmX25vZGVzIjpbeyJub2RlIjp7InBheWxvYWQiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzQsNjcsNSwxMjgsMTA1LDE1NCwxMjcsOTAsMjA4LDU5LDI0NywxNjIsMjI0LDIzNSwxOTEsMTYwLDIwMyw4NywxMCwzLDEwNiw1Miw3NSw4Miw0MSwyMTMsNTUsODcsMjE1LDMyLDEzNCwxODAsMTQ0LDUsNDAsMTgsMTQ0LDIxOSw4OSw4NCwxOCwxNDQsMTkxLDE3NCwxMTksMjIwLDU5LDkxLDE1MSwxMTIsMTE4LDE2MSwyMjUsNjcsMjQ1LDE4MywxMzgsOTEsMjcsMjI3LDEwOSwyMjMsMjQwLDc1LDE4MV19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0LDE1LDEyMSwxMjQsMTc1LDEwMCw4LDI5LDIxNSwyMjMsMzMsMTc3LDIyNyw3NSwxOTAsNDcsMjMsNzMsMzMsMTYsNDYsNzEsMTEsMTM4LDYzLDgyLDE4OCwyMjIsMTAzLDgxLDU3LDUyLDIxNywxMTgsODIsMTAyLDE5OSwxNDAsMTQyLDIzNSwxNDQsMTQ1LDE4OSwxMzYsMzMsMTYxLDI1MywxMjIsMTg5LDgxLDQ4LDE2NSw2NiwxMzIsMTEwLDI0OCw1MSwxOTksMjE1LDE3Nyw4MSwyNDAsMTAyLDE2Myw0Ml19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJLZXlQYWNrYWdlIjp7Im5vdF9iZWZvcmUiOjE3MjA2ODg5NDksIm5vdF9hZnRlciI6MTcyNzk1MDE0OX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0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LDI2LDEwNiwxMjMsMTQ2LDI0NCwxODEsMTY2LDE0MSwxNzcsNjEsMTQ2XX19LCJsZWFmX25vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbNCwxMDgsMTU4LDI0NSwyMzgsMTU5LDEyMiwyMywxODgsNzUsMTc0LDIzMSwyMTMsMzksMTgsMTAwLDIxOSwxODYsMTY4LDUxLDMxLDI1MSwyMTgsMzEsMTI5LDIwNyw5MiwyMjgsNTQsNjIsMTEzLDEzMCwyMzUsNTgsNzcsNDEsMjUyLDYwLDEzMCwyNDcsMTk4LDU5LDEyNCw0Myw1MCwxNjksNzEsMTM0LDk4LDExMywyNTMsMTc0LDEzOSw1Niw2OCw5NSwyMjQsOTUsODgsNjcsNzMsMTI0LDE2LDE1NywyMjldfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbNCw2LDIxOCwxODAsMTI2LDY4LDIwMSwyMzIsNDUsMjcsMTAsMSwzOCwxNjYsMTczLDM5LDgzLDI0NSwyNTIsMjQxLDcsMTkwLDE1NiwxNjQsMjA1LDIzMyw3MCwyMzcsMjQ1LDE2MSwxNzgsMTg5LDExMiwxMSw4OSwyMzgsMTE2LDE5NSwyNDQsMTYsMTc4LDE4NCwyMDEsMTUwLDIwMCwyMTUsMTIzLDE2OCwxNDYsNTYsMTU3LDMzLDI4LDEyNCwxMywxNTYsMjgsMjA0LDg4LDMwLDk5LDEzLDU4LDI1MiwxMDBdfX0sImNyZWRlbnRpYWwiOnsiY3JlZGVudGlhbF90eXBlIjoiQmFzaWMiLCJzZXJpYWxpemVkX2NyZWRlbnRpYWxfY29udGVudCI6eyJ2ZWMiOls5OCwxMTEsOThdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IktleVBhY2thZ2UiOnsibm90X2JlZm9yZSI6MTcyMDY4ODk0OSwibm90X2FmdGVyIjoxNzI3OTUwMTQ5fX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbNDgsNjgsMiwzMiw2OCwxNTYsMTUwLDE3NSwyMTQsMzQsMTksODcsMTQ0LDc5LDYwLDE1MCwyMTEsMTM2LDE3MywyMDUsMjUwLDE2LDE5NywxODcsMjA1LDE3NywyMzYsMTI0LDcxLDEwOCwyMDcsMTM3LDg4LDE4MCwxMjUsOTEsMiwzMiwxMiw2MSw5NywyNDksODEsMTg0LDIzNCwxMjcsNjMsMTYyLDU3LDE2MCw5NSw4NSwxNTgsODYsMjI2LDE3LDgsMjQwLDIzMywyMSw4MSwxNzQsMTI3LDEyOSw5NSwxNzAsMTY5LDEzNSw0MSw4OF19fX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbNDgsNjgsMiwzMiw4Nyw2Myw0OSwyMSw4NSwxNDYsNjcsMTM1LDEzNSw3NSwxMywxNTMsMTk3LDQ3LDE4NiwxNTgsMTYsMTAyLDc5LDIsMTg0LDU4LDExMywxOTQsODgsMTMsMTMyLDYzLDgsMTIxLDEsMjA4LDIsMzIsMzMsODMsMjQ0LDgyLDE5NywxNjIsMTg1LDg0LDUwLDE0MiwyNTAsMzQsMTY4LDk1LDEzMCwxNzksODUsMTU1LDQyLDExLDAsMTk5LDIwMSwyMjcsMTY2LDE1NSwxODQsNTgsMjQzLDU1LDIzLDE4NV19fX19fSwicHJvcG9zYWxfcmVmZXJlbmNlIjp7InZhbHVlIjp7InZlYyI6WzIwNSw5NSwxLDE4OCw2Miw0NywxMTMsMTg3LDIwMiwxODgsNzIsODUsMTc2LDgzLDg1LDE5NywyMDIsMTQzLDM3LDExNyw2OCwxNjYsMiwxMDEsMTEwLDI2LDI0OSwyNCw2NiwxMjMsODUsMTExXX19LCJzZW5kZXIiOnsiTWVtYmVyIjowfSwicHJvcG9zYWxfb3JfcmVmX3R5cGUiOiJQcm9wb3NhbCJ9XV19LCJzdGF0ZSI6eyJHcm91cE1lbWJlciI6eyJncm91cF9lcG9jaF9zZWNyZXRzIjp7ImluaXRfc2VjcmV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNzAsMTkxLDczLDI5LDQ4LDE3NiwyNyw3NiwyMSwxNTQsOTYsNDQsMjM5LDE5MSwxMzcsMjEwLDQ2LDI0NSwxNTMsMTQsMTQzLDUwLDEzOCwxMDUsMTA2LDEzOSwyNDcsMTMxLDE0NywxNTksMTk2LDIyNl19fX0sImV4cG9ydGVyX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTA5LDExMiwxNDcsMzQsOSwyMjUsMTI5LDI0Nyw0NSwzMywxMzQsMTA5LDE3NSwyMzgsMTU1LDczLDE4MCwxMDAsMjA3LDcsMTgzLDEzMiwxMDYsMTI1LDgxLDI0MiwxMjEsMjE4LDE5NCw0MSwyMDMsMTk2XX19fSwiZXBvY2hfYXV0aGVudGljYXRvciI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTc1LDE0NSwxMzEsNTIsMjA1LDEzMCwxNTksMTMzLDI0NSwxOTQsOCw4NCw5NCwxNTAsMywxOTMsMjEyLDQsMTkyLDYsMzksMTEsNDAsNTcsMSwyNDcsMTEwLDQ4LDEwNSw0MSwxMjcsNjFdfX19LCJleHRlcm5hbF9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzQzLDEwOSwxMTksMjM2LDE1NCw0NSwyNTAsMTM3LDIxNyw1NCw1NywxNjIsMTEsMTEsMjI4LDIyMywyMzMsOTIsMTU1LDYzLDE4NiwxNzIsMjIsNzAsMTM4LDMwLDcsNzMsMTg0LDIyMSwyMzksMTYzXX19fSwicmVzdW1wdGlvbl9wc2siOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzgzLDc4LDExMiwxODMsMzksMjMsMTc4LDc0LDk0LDUsMjEwLDQwLDI0OCwxMDQsMTc1LDIxMCwxMDMsMzgsMjEyLDUsMTUxLDEzMCwyNCwyMiw3OSwyNywxNzgsNzIsMTE0LDE2MSwxMTYsMjA2XX19fX0sIm1lc3NhZ2Vfc2VjcmV0cyI6eyJzZW5kZXJfZGF0YV9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzU0LDUwLDIxNiwyMDcsMjMsMTI5LDc3LDY2LDQ2LDU0LDIxLDEwNCw1OSwyMTMsMjEwLDIxMSwxNzQsMjExLDI0OSwxMTIsODYsMTIsMTIwLDk3LDE4OSw3Niw3MSwxNyw3LDIxNiwxMjEsMTgxXX19fSwibWVtYmVyc2hpcF9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzEyMCwyOCwxMDYsNTEsMTE3LDEyNCwxMjgsMjI3LDE2MCwxMTgsMzQsMjM0LDMsMTA2LDI1MiwxNjcsNjIsMjAxLDEyOSw5LDI0MywzOSwxOTgsMjA4LDIzNiwyMzksNDIsNjAsMjYsMzksMjMsMTIwXX19fSwiY29uZmlybWF0aW9uX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTM0LDE4NSwxMzgsODMsMTMyLDM0LDc5LDIzNiwxMTYsMTc4LDE0NiwxOTAsMTU1LDE2MiwzMiwxMDksODIsMTkxLDM5LDIyMywyMzIsMjksMjYsNzQsMTQ4LDI1NCwyNiwxODEsMzMsMzMsMTksMTg4XX19fSwic2VyaWFsaXplZF9jb250ZXh0IjpbMCwxLDAsMiwxNiwyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMiwwLDAsMCwwLDAsMCwwLDEsMzIsMTE3LDEyNiwxOTgsMzQsMTkyLDExMiwxMTcsMjMyLDIzMywxNTksNzAsMjQzLDI0OCw0LDE4NCw4LDExLDg0LDUwLDkzLDkxLDQsNzcsMjQ0LDk3LDY4LDAsMSw5MSwxNjAsMTE0LDE4OCwzMiwxOCwyNDgsNzUsNzYsMTEyLDIzNywyMjIsNzksNDcsNyw3OCw1MywxMDQsMTcwLDEyMiwxOTMsMTQ4LDUyLDE1NCwxNDYsMTc4LDQxLDEzNSw4LDM2LDIxMywxNjYsMTI2LDEwNiwyMjAsNzAsMjcsMF0sInNlY3JldF90cmVlIjp7Im93bl9pbmRleCI6MCwibGVhZl9ub2RlcyI6W251bGwsbnVsbF0sInBhcmVudF9ub2RlcyI6W3sic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6Wzk0LDYyLDkwLDY3LDEwNiw2MywxODAsMjUwLDQ4LDE3Myw3OSwxNzYsMTQ5LDExLDg1LDk1LDIzLDIwNiwyMzYsMTYwLDE4MSwxNiwyMjUsNjUsNzYsMTI2LDQ4LDI0OCw5LDc2LDE3NSwxMTRdfX19LG51bGxdLCJoYW5kc2hha2Vfc2VuZGVyX3JhdGNoZXRzIjpbbnVsbCxudWxsXSwiYXBwbGljYXRpb25fc2VuZGVyX3JhdGNoZXRzIjpbbnVsbCxudWxsXSwic2l6ZSI6M319LCJzdGFnZWRfZGlmZiI6eyJzdGFnZWRfZGlmZiI6eyJkaWZmIjp7ImxlYWZfZGlmZiI6eyIwIjp7Im5vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbNCwxOTksNTAsMTcsMTMwLDE2MiwyMzAsMTE3LDQ1LDEzNSwyMzcsNiwxMTUsMTQsNDQsMjI4LDE1MSwyMDEsMTYzLDIxNSwyMyw1OCwxMzYsOTUsMjM1LDEzNCwxNjYsNywxNjQsNTIsMTA1LDE0NCwxNjQsMTc3LDg4LDE4MCwxNjIsMjE0LDI0NiwxMSwxODUsOTgsMTM2LDEzOSwyMDQsOTEsMTQ4LDIwLDEyMCwxNTAsMTQxLDI1Miw0NCwxNTQsMjM2LDU0LDk5LDYwLDE1NCw1NiwxOTcsNDUsMTAwLDEzOCwxMDNdfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbNCwxNSwxMjEsMTI0LDE3NSwxMDAsOCwyOSwyMTUsMjIzLDMzLDE3NywyMjcsNzUsMTkwLDQ3LDIzLDczLDMzLDE2LDQ2LDcxLDExLDEzOCw2Myw4MiwxODgsMjIyLDEwMyw4MSw1Nyw1MiwyMTcsMTE4LDgyLDEwMiwxOTksMTQwLDE0MiwyMzUsMTQ0LDE0NSwxODksMTM2LDMzLDE2MSwyNTMsMTIyLDE4OSw4MSw0OCwxNjUsNjYsMTMyLDExMCwyNDgsNTEsMTk5LDIxNSwxNzcsODEsMjQwLDEwMiwxNjMsNDJdfX0sImNyZWRlbnRpYWwiOnsiY3JlZGVudGlhbF90eXBlIjoiQmFzaWMiLCJzZXJpYWxpemVkX2NyZWRlbnRpYWxfY29udGVudCI6eyJ2ZWMiOls5NywxMDgsMTA1LDk5LDEwMV19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiQ29tbWl0Ijp7InZlYyI6WzIxMywxMTgsNDEsMjA2LDIxMSwxMzMsMjgsMTczLDE3MCwyMTIsMTU2LDc3LDEyNSwyNTUsNDcsOTUsMTUwLDE0OSw5MSw2OCw3MCwyNDEsMTUxLDIyOSwxMDIsMTM1LDM2LDc4LDEwMSwyMjYsMjksNzFdfX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbNDgsNjksMiwzMiwxMjEsMjMzLDE1NCwxMjYsNjgsMzQsMTA1LDE0Niw5OSwxNjMsMzcsNjQsMTIzLDM1LDQwLDI0MSwxMDIsMjE4LDIxMywxNTEsMjI1LDIxOCwxMjgsMTY3LDE2NywxNzYsMTQ2LDI1MiwyMjAsMjUxLDE1OSwyMDUsMiwzMywwLDIzOSwxMjAsMTEwLDIzMCwyMzQsMTUwLDk0LDI4LDEzOSwyNDEsODEsMTk0LDc2LDE4MCwxNjQsMjAxLDY3LDk2LDEwNSwxNjQsMTk0LDE0LDY5LDk0LDQwLDkyLDY4LDIwMCwxMjksNTcsNzMsNTZdfX19fSwiMSI6eyJub2RlIjp7InBheWxvYWQiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzQsMTA4LDE1OCwyNDUsMjM4LDE1OSwxMjIsMjMsMTg4LDc1LDE3NCwyMzEsMjEzLDM5LDE4LDEwMCwyMTksMTg2LDE2OCw1MSwzMSwyNTEsMjE4LDMxLDEyOSwyMDcsOTIsMjI4LDU0LDYyLDExMywxMzAsMjM1LDU4LDc3LDQxLDI1Miw2MCwxMzAsMjQ3LDE5OCw1OSwxMjQsNDMsNTAsMTY5LDcxLDEzNCw5OCwxMTMsMjUzLDE3NCwxMzksNTYsNjgsOTUsMjI0LDk1LDg4LDY3LDczLDEyNCwxNiwxNTcsMjI5XX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6WzQsNiwyMTgsMTgwLDEyNiw2OCwyMDEsMjMyLDQ1LDI3LDEwLDEsMzgsMTY2LDE3MywzOSw4MywyNDUsMjUyLDI0MSw3LDE5MCwxNTYsMTY0LDIwNSwyMzMsNzAsMjM3LDI0NSwxNjEsMTc4LDE4OSwxMTIsMTEsODksMjM4LDExNiwxOTUsMjQ0LDE2LDE3OCwxODQsMjAxLDE1MCwyMDAsMjE1LDEyMywxNjgsMTQ2LDU2LDE1NywzMywyOCwxMjQsMTMsMTU2LDI4LDIwNCw4OCwzMCw5OSwxMyw1OCwyNTIsMTAwXX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTgsMTExLDk4XX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJLZXlQYWNrYWdlIjp7Im5vdF9iZWZvcmUiOjE3MjA2ODg5NDksIm5vdF9hZnRlciI6MTcyNzk1MDE0OX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzQ4LDY4LDIsMzIsNjgsMTU2LDE1MCwxNzUsMjE0LDM0LDE5LDg3LDE0NCw3OSw2MCwxNTAsMjExLDEzNiwxNzMsMjA1LDI1MCwxNiwxOTcsMTg3LDIwNSwxNzcsMjM2LDEyNCw3MSwxMDgsMjA3LDEzNyw4OCwxODAsMTI1LDkxLDIsMzIsMTIsNjEsOTcsMjQ5LDgxLDE4NCwyMzQsMTI3LDYzLDE2Miw1NywxNjAsOTUsODUsMTU4LDg2LDIyNiwxNyw4LDI0MCwyMzMsMjEsODEsMTc0LDEyNywxMjksOTUsMTcwLDE2OSwxMzUsNDEsODhdfX19fX0sInBhcmVudF9kaWZmIjp7IjAiOnsibm9kZSI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbNCw5NywxOTQsMTI5LDEwMSwxNzcsNzgsODYsMzYsMTk4LDE3MSw2MiwxNTUsMTgsMTE1LDE1NCw4Miw3NSwyMDIsNDIsMywxMjEsNzEsOTcsMjcsMjIwLDYwLDE3NywxMjMsMjAxLDE0MCwxLDE3NSw3MCwxODQsMTUyLDYwLDE5OSwxNjEsMjE5LDExMCw3MiwxMSwxMzIsMTkyLDE3NywxMDQsMjE3LDM1LDI0NiwyOCwxMjMsMzQsMjI1LDE2MiwxNzEsMjIsMTI1LDU0LDQyLDQwLDIxMiwyNDMsMjIwLDg4XX19LCJwYXJlbnRfaGFzaCI6eyJ2ZWMiOltdfSwidW5tZXJnZWRfbGVhdmVzIjp7Imxpc3QiOltdfX19fSwic2l6ZSI6M30sIm5ld190cmVlX2hhc2giOlsxMTcsMTI2LDE5OCwzNCwxOTIsMTEyLDExNywyMzIsMjMzLDE1OSw3MCwyNDMsMjQ4LDQsMTg0LDgsMTEsODQsNTAsOTMsOTEsNCw3NywyNDQsOTcsNjgsMCwxLDkxLDE2MCwxMTQsMTg4XX0sImdyb3VwX2NvbnRleHQiOnsicHJvdG9jb2xfdmVyc2lvbiI6Ik1sczEwIiwiY2lwaGVyc3VpdGUiOiJNTFNfMTI4X0RIS0VNUDI1Nl9BRVMxMjhHQ01fU0hBMjU2X1AyNTYiLCJncm91cF9pZCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fSwiZXBvY2giOjEsInRyZWVfaGFzaCI6eyJ2ZWMiOlsxMTcsMTI2LDE5OCwzNCwxOTIsMTEyLDExNywyMzIsMjMzLDE1OSw3MCwyNDMsMjQ4LDQsMTg0LDgsMTEsODQsNTAsOTMsOTEsNCw3NywyNDQsOTcsNjgsMCwxLDkxLDE2MCwxMTQsMTg4XX0sImNvbmZpcm1lZF90cmFuc2NyaXB0X2hhc2giOnsidmVjIjpbMTgsMjQ4LDc1LDc2LDExMiwyMzcsMjIyLDc5LDQ3LDcsNzgsNTMsMTA0LDE3MCwxMjIsMTkzLDE0OCw1MiwxNTQsMTQ2LDE3OCw0MSwxMzUsOCwzNiwyMTMsMTY2LDEyNiwxMDYsMjIwLDcwLDI3XX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJpbnRlcmltX3RyYW5zY3JpcHRfaGFzaCI6Wzc1LDIzMywxMjMsMjcsMTk3LDExOSwxNjYsMjA1LDczLDI1NSw4OSwxNCw1OCwyMTgsMTM2LDgzLDMwLDExOSwzMiwxOTcsMTE2LDIxMCwyNTEsNiwxNzgsMTEzLDIyOCwxOSwxMjAsMTg1LDE5OSw5NF0sImNvbmZpcm1hdGlvbl90YWciOnsibWFjX3ZhbHVlIjp7InZlYyI6WzIxNywyMzEsMTIwLDU3LDczLDEwOCwxNTksMTY4LDIzLDI5LDcwLDQ0LDIxMywyNTIsMTAsMTAwLDIxLDExNiwxNzgsMjEyLDkyLDkyLDI0OCwzMCwyNDUsMjQ4LDExNiwxMDIsMTIyLDIyMywxNSw2MV19fX0sIm5ld19rZXlwYWlycyI6W3sicHVibGljX2tleSI6eyJrZXkiOnsidmVjIjpbNCwxOTksNTAsMTcsMTMwLDE2MiwyMzAsMTE3LDQ1LDEzNSwyMzcsNiwxMTUsMTQsNDQsMjI4LDE1MSwyMDEsMTYzLDIxNSwyMyw1OCwxMzYsOTUsMjM1LDEzNCwxNjYsNywxNjQsNTIsMTA1LDE0NCwxNjQsMTc3LDg4LDE4MCwxNjIsMjE0LDI0NiwxMSwxODUsOTgsMTM2LDEzOSwyMDQsOTEsMTQ4LDIwLDEyMCwxNTAsMTQxLDI1Miw0NCwxNTQsMjM2LDU0LDk5LDYwLDE1NCw1NiwxOTcsNDUsMTAwLDEzOCwxMDNdfX0sInByaXZhdGVfa2V5Ijp7ImtleSI6eyJ2ZWMiOls5NiwxODEsMzUsMTI3LDE4MywxODIsMTk3LDI4LDEyNiwxNTMsNSw3MCw1Nyw4NSwzLDExOSwyMDIsMjE3LDE1MywxNjYsMTU0LDExMywxODEsMTEzLDIxNSwyNDMsMjA3LDE5MSwxMTEsMTY2LDEwNywxNTddfX19LHsicHVibGljX2tleSI6eyJrZXkiOnsidmVjIjpbNCw5NywxOTQsMTI5LDEwMSwxNzcsNzgsODYsMzYsMTk4LDE3MSw2MiwxNTUsMTgsMTE1LDE1NCw4Miw3NSwyMDIsNDIsMywxMjEsNzEsOTcsMjcsMjIwLDYwLDE3NywxMjMsMjAxLDE0MCwxLDE3NSw3MCwxODQsMTUyLDYwLDE5OSwxNjEsMjE5LDExMCw3MiwxMSwxMzIsMTkyLDE3NywxMDQsMjE3LDM1LDI0NiwyOCwxMjMsMzQsMjI1LDE2MiwxNzEsMjIsMTI1LDU0LDQyLDQwLDIxMiwyNDMsMjIwLDg4XX19LCJwcml2YXRlX2tleSI6eyJrZXkiOnsidmVjIjpbMTQ3LDUsMjE3LDE0OCwxMyw3Miw3MywxMjksMTk1LDI1NCwyNTMsMTk4LDE3LDIsMjExLDI4LDI1LDc1LDIzNCwyNiwxMTAsMTE3LDE2LDE3NSwxNjAsNDcsNDAsMTA3LDEwMywxNjMsOTMsMTg0XX19fV0sIm5ld19sZWFmX2tleXBhaXJfb3B0aW9uIjpudWxsLCJ1cGRhdGVfcGF0aF9sZWFmX25vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbNCwxOTksNTAsMTcsMTMwLDE2MiwyMzAsMTE3LDQ1LDEzNSwyMzcsNiwxMTUsMTQsNDQsMjI4LDE1MSwyMDEsMTYzLDIxNSwyMyw1OCwxMzYsOTUsMjM1LDEzNCwxNjYsNywxNjQsNTIsMTA1LDE0NCwxNjQsMTc3LDg4LDE4MCwxNjIsMjE0LDI0NiwxMSwxODUsOTgsMTM2LDEzOSwyMDQsOTEsMTQ4LDIwLDEyMCwxNTAsMTQxLDI1Miw0NCwxNTQsMjM2LDU0LDk5LDYwLDE1NCw1NiwxOTcsNDUsMTAwLDEzOCwxMDNdfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbNCwxNSwxMjEsMTI0LDE3NSwxMDAsOCwyOSwyMTUsMjIzLDMzLDE3NywyMjcsNzUsMTkwLDQ3LDIzLDczLDMzLDE2LDQ2LDcxLDExLDEzOCw2Myw4MiwxODgsMjIyLDEwMyw4MSw1Nyw1MiwyMTcsMTE4LDgyLDEwMiwxOTksMTQwLDE0MiwyMzUsMTQ0LDE0NSwxODksMTM2LDMzLDE2MSwyNTMsMTIyLDE4OSw4MSw0OCwxNjUsNjYsMTMyLDExMCwyNDgsNTEsMTk5LDIxNSwxNzcsODEsMjQwLDEwMiwxNjMsNDJdfX0sImNyZWRlbnRpYWwiOnsiY3JlZGVudGlhbF90eXBlIjoiQmFzaWMiLCJzZXJpYWxpemVkX2NyZWRlbnRpYWxfY29udGVudCI6eyJ2ZWMiOls5NywxMDgsMTA1LDk5LDEwMV19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiQ29tbWl0Ijp7InZlYyI6WzIxMywxMTgsNDEsMjA2LDIxMSwxMzMsMjgsMTczLDE3MCwyMTIsMTU2LDc3LDEyNSwyNTUsNDcsOTUsMTUwLDE0OSw5MSw2OCw3MCwyNDEsMTUxLDIyOSwxMDIsMTM1LDM2LDc4LDEwMSwyMjYsMjksNzFdfX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbNDgsNjksMiwzMiwxMjEsMjMzLDE1NCwxMjYsNjgsMzQsMTA1LDE0Niw5OSwxNjMsMzcsNjQsMTIzLDM1LDQwLDI0MSwxMDIsMjE4LDIxMywxNTEsMjI1LDIxOCwxMjgsMTY3LDE2NywxNzYsMTQ2LDI1MiwyMjAsMjUxLDE1OSwyMDUsMiwzMywwLDIzOSwxMjAsMTEwLDIzMCwyMzQsMTUwLDk0LDI4LDEzOSwyNDEsODEsMTk0LDc2LDE4MCwxNjQsMjAxLDY3LDk2LDEwNSwxNjQsMTk0LDE0LDY5LDk0LDQwLDkyLDY4LDIwMCwxMjksNTcsNzMsNTZdfX19fX19fX0AAAAAAAAAXgAAAAAAAAABT3duTGVhZk5vZGVJbmRleHsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AATAAAAAAAAAAXAAAAAAAAAUMTWVzc2FnZVNlY3JldHN7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAF7Im1heF9lcG9jaHMiOjAsInBhc3RfZXBvY2hfdHJlZXMiOltdLCJtZXNzYWdlX3NlY3JldHMiOnsic2VuZGVyX2RhdGFfc2VjcmV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNiwyNDksMTYsNTMsMjM0LDE0MCw3MSwxNDIsMjMwLDk1LDc0LDI0NywyNDUsMjE3LDE1MSwyMTgsMjIsMTIxLDE0LDIxOCwyNTAsMTA0LDIzMSwxNDEsMTIzLDEwOCwzMywzLDE3MywzMywxMjQsMjM1XX19fSwibWVtYmVyc2hpcF9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE3NCw5OSwyMDYsMjEyLDMyLDQ4LDU2LDIyMSwxMDUsODgsMTk1LDIyNCwxMDUsNTQsMjEwLDIxMCw3NywxMTUsMzUsMTQ1LDE5OSwxNTIsNDgsMTkyLDIyNiwxMzIsMTkzLDExNCwxMTMsNjAsMjQ2LDM1XX19fSwiY29uZmlybWF0aW9uX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTEsNzgsMTM3LDkxLDE1MywyMCwxODAsMzEsNzksMTI0LDEzNiwyNTUsMTQsNzgsMjM0LDE4MywxMzQsNDUsMiw1MCwxMDQsMTAsNTEsOTMsMTQ3LDUzLDEwOCwyMTksMTc4LDIxMSwxNDYsMTgxXX19fSwic2VyaWFsaXplZF9jb250ZXh0IjpbMCwxLDAsMiwxNiwyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMiwwLDAsMCwwLDAsMCwwLDAsMzIsMjA4LDI0NiwyMzksMjE0LDE3MSwyMDEsMTE0LDEsMTA1LDIxNywzNywyMTQsMjM5LDE1LDkwLDE0MywyMDAsOTYsMTc5LDE3NywxNTYsMTg5LDcxLDM4LDE0MSw1NSw4OSwxNjMsMTI5LDI1MSwxOTksOTUsMCwwXSwic2VjcmV0X3RyZWUiOnsib3duX2luZGV4IjowLCJsZWFmX25vZGVzIjpbbnVsbF0sInBhcmVudF9ub2RlcyI6W251bGxdLCJoYW5kc2hha2Vfc2VuZGVyX3JhdGNoZXRzIjpbeyJFbmNyeXB0aW9uUmF0Y2hldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbNzksMTQyLDE2LDE1MSw4Miw1MSwxNzUsMjEwLDM2LDI1MSwyNDEsMTI5LDIzNCwxMTksMTM4LDEzMyw3NCwyMywyMDMsMTU0LDE2MSwxNzIsMTY5LDM4LDkzLDE2LDkwLDg4LDg1LDE5MiwxNDIsMTAxXX19LCJnZW5lcmF0aW9uIjoxfX1dLCJhcHBsaWNhdGlvbl9zZW5kZXJfcmF0Y2hldHMiOlt7IkVuY3J5cHRpb25SYXRjaGV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMyw0MywyMTcsMjQ2LDExNiwxODksMTg4LDU1LDExMSw1OSwxNDMsMjI5LDE4OSw3Miw5NCw4Myw2MywxMzYsODIsODYsMSwxMjEsMjMwLDE2Nyw0MCwyMTEsMjI1LDE4NCwxMzcsMTc5LDY0LDIwMV19fSwiZ2VuZXJhdGlvbiI6MH19XSwic2l6ZSI6MX19fQ==","AAAAAAAAAA0AAAAAAAAAXQAAAAAAAACKQ29uZmlybWF0aW9uVGFneyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJtYWNfdmFsdWUiOnsidmVjIjpbMjE3LDIzMSwxMjAsNTcsNzMsMTA4LDE1OSwxNjgsMjMsMjksNzAsNDQsMjEzLDI1MiwxMCwxMDAsMjEsMTE2LDE3OCwyMTIsOTIsOTIsMjQ4LDMwLDI0NSwyNDgsMTE2LDEwMiwxMjIsMjIzLDE1LDYxXX19AAAAAAAAAFIAAAAAAAALrFRyZWV7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAF7InRyZWUiOnsibGVhZl9ub2RlcyI6W3sibm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOls0LDE5OSw1MCwxNywxMzAsMTYyLDIzMCwxMTcsNDUsMTM1LDIzNyw2LDExNSwxNCw0NCwyMjgsMTUxLDIwMSwxNjMsMjE1LDIzLDU4LDEzNiw5NSwyMzUsMTM0LDE2Niw3LDE2NCw1MiwxMDUsMTQ0LDE2NCwxNzcsODgsMTgwLDE2MiwyMTQsMjQ2LDExLDE4NSw5OCwxMzYsMTM5LDIwNCw5MSwxNDgsMjAsMTIwLDE1MCwxNDEsMjUyLDQ0LDE1NCwyMzYsNTQsOTksNjAsMTU0LDU2LDE5Nyw0NSwxMDAsMTM4LDEwM119fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0LDE1LDEyMSwxMjQsMTc1LDEwMCw4LDI5LDIxNSwyMjMsMzMsMTc3LDIyNyw3NSwxOTAsNDcsMjMsNzMsMzMsMTYsNDYsNzEsMTEsMTM4LDYzLDgyLDE4OCwyMjIsMTAzLDgxLDU3LDUyLDIxNywxMTgsODIsMTAyLDE5OSwxNDAsMTQyLDIzNSwxNDQsMTQ1LDE4OSwxMzYsMzMsMTYxLDI1MywxMjIsMTg5LDgxLDQ4LDE2NSw2NiwxMzIsMTEwLDI0OCw1MSwxOTksMjE1LDE3Nyw4MSwyNDAsMTAyLDE2Myw0Ml19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJDb21taXQiOnsidmVjIjpbMjEzLDExOCw0MSwyMDYsMjExLDEzMywyOCwxNzMsMTcwLDIxMiwxNTYsNzcsMTI1LDI1NSw0Nyw5NSwxNTAsMTQ5LDkxLDY4LDcwLDI0MSwxNTEsMjI5LDEwMiwxMzUsMzYsNzgsMTAxLDIyNiwyOSw3MV19fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0OCw2OSwyLDMyLDEyMSwyMzMsMTU0LDEyNiw2OCwzNCwxMDUsMTQ2LDk5LDE2MywzNyw2NCwxMjMsMzUsNDAsMjQxLDEwMiwyMTgsMjEzLDE1MSwyMjUsMjE4LDEyOCwxNjcsMTY3LDE3NiwxNDYsMjUyLDIyMCwyNTEsMTU5LDIwNSwyLDMzLDAsMjM5LDEyMCwxMTAsMjMwLDIzNCwxNTAsOTQsMjgsMTM5LDI0MSw4MSwxOTQsNzYsMTgwLDE2NCwyMDEsNjcsOTYsMTA1LDE2NCwxOTQsMTQsNjksOTQsNDAsOTIsNjgsMjAwLDEyOSw1Nyw3Myw1Nl19fX19LHsibm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOls0LDEwOCwxNTgsMjQ1LDIzOCwxNTksMTIyLDIzLDE4OCw3NSwxNzQsMjMxLDIxMywzOSwxOCwxMDAsMjE5LDE4NiwxNjgsNTEsMzEsMjUxLDIxOCwzMSwxMjksMjA3LDkyLDIyOCw1NCw2MiwxMTMsMTMwLDIzNSw1OCw3Nyw0MSwyNTIsNjAsMTMwLDI0NywxOTgsNTksMTI0LDQzLDUwLDE2OSw3MSwxMzQsOTgsMTEzLDI1MywxNzQsMTM5LDU2LDY4LDk1LDIyNCw5NSw4OCw2Nyw3MywxMjQsMTYsMTU3LDIyOV19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0LDYsMjE4LDE4MCwxMjYsNjgsMjAxLDIzMiw0NSwyNywxMCwxLDM4LDE2NiwxNzMsMzksODMsMjQ1LDI1MiwyNDEsNywxOTAsMTU2LDE2NCwyMDUsMjMzLDcwLDIzNywyNDUsMTYxLDE3OCwxODksMTEyLDExLDg5LDIzOCwxMTYsMTk1LDI0NCwxNiwxNzgsMTg0LDIwMSwxNTAsMjAwLDIxNSwxMjMsMTY4LDE0Niw1NiwxNTcsMzMsMjgsMTI0LDEzLDE1NiwyOCwyMDQsODgsMzAsOTksMTMsNTgsMjUyLDEwMF19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk4LDExMSw5OF19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiS2V5UGFja2FnZSI6eyJub3RfYmVmb3JlIjoxNzIwNjg4OTQ5LCJub3RfYWZ0ZXIiOjE3Mjc5NTAxNDl9fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0OCw2OCwyLDMyLDY4LDE1NiwxNTAsMTc1LDIxNCwzNCwxOSw4NywxNDQsNzksNjAsMTUwLDIxMSwxMzYsMTczLDIwNSwyNTAsMTYsMTk3LDE4NywyMDUsMTc3LDIzNiwxMjQsNzEsMTA4LDIwNywxMzcsODgsMTgwLDEyNSw5MSwyLDMyLDEyLDYx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InNlbmRlcl9kYXRhX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbNTQsNTAsMjE2LDIwNywyMywxMjksNzcsNjYsNDYsNTQsMjEsMTA0LDU5LDIxMywyMTAsMjExLDE3NCwyMTEsMjQ5LDExMiw4NiwxMiwxMjAsOTcsMTg5LDc2LDcxLDE3LDcsMjE2LDEyMSwxODFdfX19LCJtZW1iZXJzaGlwX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTIwLDI4LDEwNiw1MSwxMTcsMTI0LDEyOCwyMjcsMTYwLDExOCwzNCwyMzQsMywxMDYsMjUyLDE2Nyw2MiwyMDEsMTI5LDksMjQzLDM5LDE5OCwyMDgsMjM2LDIzOSw0Miw2MCwyNiwzOSwyMywxMjBdfX19LCJjb25maXJtYXRpb25fa2V5Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMzQsMTg1LDEzOCw4MywxMzIsMzQsNzksMjM2LDExNiwxNzgsMTQ2LDE5MCwxNTUsMTYyLDMyLDEwOSw4MiwxOTEsMzksMjIzLDIzMiwyOSwyNiw3NCwxNDgsMjU0LDI2LDE4MSwzMywzMywxOSwxODhdfX19LCJzZXJpYWxpemVkX2NvbnRleHQiOlswLDEsMCwyLDE2LDIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyLDAsMCwwLDAsMCwwLDAsMSwzMiwxMTcsMTI2LDE5OCwzNCwxOTIsMTEyLDExNywyMzIsMjMzLDE1OSw3MCwyNDMsMjQ4LDQsMTg0LDgsMTEsODQsNTAsOTMsOTEsNCw3NywyNDQsOTcsNjgsMCwxLDkxLDE2MCwxMTQsMTg4LDMyLDE4LDI0OCw3NSw3NiwxMTIsMjM3LDIyMiw3OSw0Nyw3LDc4LDUzLDEwNCwxNzAsMTIyLDE5MywxNDgsNTIsMTU0LDE0NiwxNzgsNDEsMTM1LDgsMzYsMjEzLDE2NiwxMjYsMTA2LDIyMCw3MCwyNywwXSwic2VjcmV0X3RyZWUiOnsib3duX2luZGV4IjowLCJsZWFmX25vZGVzIjpbbnVsbCxudWxsXSwicGFyZW50X25vZGVzIjpbeyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbOTQsNjIsOTAsNjcsMTA2LDYzLDE4MCwyNTAsNDgsMTczLDc5LDE3NiwxNDksMTEsODUsOTUsMjMsMjA2LDIzNiwxNjAsMTgxLDE2LDIyNSw2NSw3NiwxMjYsNDgsMjQ4LDksNzYsMTc1LDExNF19fX0sbnVsbF0sImhhbmRzaGFrZV9zZW5kZXJfcmF0Y2hldHMiOltudWxsLG51bGxdLCJhcHBsaWNhdGlvbl9zZW5kZXJfcmF0Y2hldHMiOltudWxsLG51bGxdLCJzaXplIjozfX19AAAAAAAAAF0AAAAAAAADOEVwb2NoS2V5UGFpcnN7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19MTAAAVt7InB1YmxpY19rZXkiOnsia2V5Ijp7InZlYyI6WzQsMTk5LDUwLDE3LDEzMCwxNjIsMjMwLDExNyw0NSwxMzUsMjM3LDYsMTE1LDE0LDQ0LDIyOCwxNTEsMjAxLDE2MywyMTUsMjMsNTgsMTM2LDk1LDIzNSwxMzQsMTY2LDcsMTY0LDUyLDEwNSwxNDQsMTY0LDE3Nyw4OCwxODAsMTYyLDIxNCwyNDYsMTEsMTg1LDk4LDEzNiwxMzksMjA0LDkxLDE0OCwyMCwxMjAsMTUwLDE0MSwyNTIsNDQsMTU0LDIzNiw1NCw5OSw2MCwxNTQsNTYsMTk3LDQ1LDEwMCwxMzgsMTAzXX19LCJwcml2YXRlX2tleSI6eyJrZXkiOnsidmVjIjpbOTYsMTgxLDM1LDEyNywxODMsMTgyLDE5NywyOCwxMjYsMTUzLDUsNzAsNTcsODUsMywxMTksMjAyLDIxNywxNTMsMTY2LDE1NCwxMTMsMTgxLDExMywyMTUsMjQzLDIwNywxOTEsMTExLDE2NiwxMDcsMTU3XX19fSx7InB1YmxpY19rZXkiOnsia2V5Ijp7InZlYyI6WzQsOTcsMTk0LDEyOSwxMDEsMTc3LDc4LDg2LDM2LDE5OCwxNzEsNjIsMTU1LDE4LDExNSwxNTQsODIsNzUsMjAyLDQyLDMsMTIxLDcxLDk3LDI3LDIyMCw2MCwxNzcsMTIzLDIwMSwxNDAsMSwxNzUsNzAsMTg0LDE1Miw2MCwxOTksMTYxLDIxOSwxMTAsNzIsMTEsMTMyLDE5MiwxNzcsMTA0LDIxNywzNSwyNDYsMjgsMTIzLDM0LDIyNSwxNjIsMTcxLDIyLDEyNSw1NCw0Miw0MCwyMTIsMjQzLDIyMCw4OF19fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6WzE0Nyw1LDIxNywxNDgsMTMsNzIsNzMsMTI5LDE5NSwyNTQsMjUzLDE5OCwxNywyLDIxMSwyOCwyNSw3NSwyMzQsMjYsMTEwLDExNywxNiwxNzUsMTYwLDQ3LDQwLDEwNywxMDMsMTYzLDkzLDE4NF19fX1d","AAAAAAAAAA0AAAAAAAAAXQAAAAAAAACKQ29uZmlybWF0aW9uVGFneyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJtYWNfdmFsdWUiOnsidmVjIjpbMjE3LDIzMSwxMjAsNTcsNzMsMTA4LDE1OSwxNjgsMjMsMjksNzAsNDQsMjEzLDI1MiwxMCwxMDAsMjEsMTE2LDE3OCwyMTIsOTIsOTIsMjQ4LDMwLDI0NSwyNDgsMTE2LDEwMiwxMjIsMjIzLDE1LDYxXX19AAAAAAAAAFIAAAAAAAALrFRyZWV7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAF7InRyZWUiOnsibGVhZl9ub2RlcyI6W3sibm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOls0LDE5OSw1MCwxNywxMzAsMTYyLDIzMCwxMTcsNDUsMTM1LDIzNyw2LDExNSwxNCw0NCwyMjgsMTUxLDIwMSwxNjMsMjE1LDIzLDU4LDEzNiw5NSwyMzUsMTM0LDE2Niw3LDE2NCw1MiwxMDUsMTQ0LDE2NCwxNzcsODgsMTgwLDE2MiwyMTQsMjQ2LDExLDE4NSw5OCwxMzYsMTM5LDIwNCw5MSwxNDgsMjAsMTIwLDE1MCwxNDEsMjUyLDQ0LDE1NCwyMzYsNTQsOTksNjAsMTU0LDU2LDE5Nyw0NSwxMDAsMTM4LDEwM119fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0LDE1LDEyMSwxMjQsMTc1LDEwMCw4LDI5LDIxNSwyMjMsMzMsMTc3LDIyNyw3NSwxOTAsNDcsMjMsNzMsMzMsMTYsNDYsNzEsMTEsMTM4LDYzLDgyLDE4OCwyMjIsMTAzLDgxLDU3LDUyLDIxNywxMTgsODIsMTAyLDE5OSwxNDAsMTQyLDIzNSwxNDQsMTQ1LDE4OSwxMzYsMzMsMTYxLDI1MywxMjIsMTg5LDgxLDQ4LDE2NSw2NiwxMzIsMTEwLDI0OCw1MSwxOTksMjE1LDE3Nyw4MSwyNDAsMTAyLDE2Myw0Ml19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJDb21taXQiOnsidmVjIjpbMjEzLDExOCw0MSwyMDYsMjExLDEzMywyOCwxNzMsMTcwLDIxMiwxNTYsNzcsMTI1LDI1NSw0Nyw5NSwxNTAsMTQ5LDkxLDY4LDcwLDI0MSwxNTEsMjI5LDEwMiwxMzUsMzYsNzgsMTAxLDIyNiwyOSw3MV19fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0OCw2OSwyLDMyLDEyMSwyMzMsMTU0LDEyNiw2OCwzNCwxMDUsMTQ2LDk5LDE2MywzNyw2NCwxMjMsMzUsNDAsMjQxLDEwMiwyMTgsMjEzLDE1MSwyMjUsMjE4LDEyOCwxNjcsMTY3LDE3NiwxNDYsMjUyLDIyMCwyNTEsMTU5LDIwNSwyLDMzLDAsMjM5LDEyMCwxMTAsMjMwLDIzNCwxNTAsOTQsMjgsMTM5LDI0MSw4MSwxOTQsNzYsMTgwLDE2NCwyMDEsNjcsOTYsMTA1LDE2NCwxOTQsMTQsNjksOTQsNDAsOTIsNjgsMjAwLDEyOSw1Nyw3Myw1Nl19fX19LHsibm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOls0LDEwOCwxNTgsMjQ1LDIzOCwxNTksMTIyLDIzLDE4OCw3NSwxNzQsMjMxLDIxMywzOSwxOCwxMDAsMjE5LDE4NiwxNjgsNTEsMzEsMjUxLDIxOCwzMSwxMjksMjA3LDkyLDIyOCw1NCw2MiwxMTMsMTMwLDIzNSw1OCw3Nyw0MSwyNTIsNjAsMTMwLDI0NywxOTgsNTksMTI0LDQzLDUwLDE2OSw3MSwxMzQsOTgsMTEzLDI1MywxNzQsMTM5LDU2LDY4LDk1LDIyNCw5NSw4OCw2Nyw3MywxMjQsMTYsMTU3LDIyOV19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0LDYsMjE4LDE4MCwxMjYsNjgsMjAxLDIzMiw0NSwyNywxMCwxLDM4LDE2NiwxNzMsMzksODMsMjQ1LDI1MiwyNDEsNywxOTAsMTU2LDE2NCwyMDUsMjMzLDcwLDIzNywyNDUsMTYxLDE3OCwxODksMTEyLDExLDg5LDIzOCwxMTYsMTk1LDI0NCwxNiwxNzgsMTg0LDIwMSwxNTAsMjAwLDIxNSwxMjMsMTY4LDE0Niw1NiwxNTcsMzMsMjgsMTI0LDEzLDE1NiwyOCwyMDQsODgsMzAsOTksMTMsNTgsMjUyLDEwMF19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk4LDExMSw5OF19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiS2V5UGFja2FnZSI6eyJub3RfYmVmb3JlIjoxNzIwNjg4OTQ5LCJub3RfYWZ0ZXIiOjE3Mjc5NTAxNDl9fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0OCw2OCwyLDMyLDY4LDE1NiwxNTAsMTc1LDIxNCwzNCwxOSw4NywxNDQsNzksNjAsMTUwLDIxMSwxMzYsMTczLDIwNSwyNTAsMTYsMTk3LDE4NywyMDUsMTc3LDIzNiwxMjQsNzEsMTA4LDIwNywxMzcsODgsMTgwLDEyNSw5MSwyLDMyLDEyLDYx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NTEsOTAsMTM2LDIxNCwyMDIsMiwxNSwxNzgsNSwxMzIsOCw1LDU3LDIsNDUsNjcsMTk0LDcwLDgxXX19LHsicHJvcG9zYWwiOnsiR3JvdXBDb250ZXh0RXh0ZW5zaW9ucyI6eyJleHRlbnNpb25zIjp7InVuaXF1ZSI6W3siUmVxdWlyZWRDYXBhYmlsaXRpZXMiOnsiZXh0ZW5zaW9uX3R5cGVzIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbF90eXBlcyI6W10sImNyZWRlbnRpYWxfdHlwZXMiOltdfX1dfX19LCJwcm9wb3NhbF9yZWZlcmVuY2UiOnsidmFsdWUiOnsidmVjIjpbMTQ4LDEwNiwyNSwxMDQsMjA3LDE3Myw1NCw4OCwxNzMsNjAsMTg4LDE4MSwxMiwyNTEsOTAsMTM2LDIxNCwyMDIsMiwxNSwxNzgsNSwxMzIsOCw1LDU3LDIsNDUsNjcsMTk0LDcwLDgxXX19LCJzZW5kZXIiOnsiTWVtYmVyIjowfSwicHJvcG9zYWxfb3JfcmVmX3R5cGUiOiJQcm9wb3NhbCJ9XV19LCJzdGF0ZSI6eyJHcm91cE1lbWJlciI6eyJncm91cF9lcG9jaF9zZWNyZXRzIjp7ImluaXRfc2VjcmV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlszOCwxNTQsMjQ1LDE1MiwyMDcsMTQxLDE4MywxODQsNzUsODEsMjMsNDIsMTEyLDM2LDIxMCwxNTUsMjMsMTc3LDExLDE2NiwxMTksMTg5LDE2NywxODEsMjMxLDI0NCwxNjcsNDEsMjQzLDIwMiwyMjAsNzZdfX19LCJleHBvcnRlcl9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzIyNSwxMjIsNjYsNDAsNDYsMTQ2LDIwNiwzNSwxNzAsNjEsMjI4LDIwNiwyMDQsNSwxODgsMTc4LDE3NSwxODAsNDIsOTksOTUsMTcwLDExMCwxNjksMTk4LDU2LDIxMSw4MSw3OSwyNTEsOTAsMTU2XX19fSwiZXBvY2hfYXV0aGVudGljYXRvciI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMjQ0LDIzOCw0OSw3MSwyNywxNjEsMjIzLDQsMjI2LDIwOCwxMzQsMTg2LDI0NCwxODAsMTAyLDExNCw1NSw0OSwxNiwxOTQsMjEsMTA3LDIyNiwyMjQsNTEsMjQ1LDExOSwyNDcsMjM4LDE4NywxNTgsNzZdfX19LCJleHRlcm5hbF9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzExNiwxOSwyMzMsMjQyLDI0NSw3OSw2NSwyMjcsMTE1LDcxLDE3LDEwOSwxMTMsMTU0LDI0MiwyMDUsMTExLDUyLDY5LDE5MCwyMzksMTU1LDM0LDExNyw3NCwxMTYsMTAxLDY1LDE2MywxNjUsNjYsNDFdfX19LCJyZXN1bXB0aW9uX3BzayI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTc1LDExMSwyMzUsMTYxLDE0OSw1NSwxNzMsMTMzLDk4LDEwNyw4MSwxMTcsNDMsNTcsMjEsMTgzLDIwOCw2NSwxOTQsMCwxNjQsODMsNDIsMjIwLDQsMjI2LDY2LDEzMywxNDksNjIsMjEsMjA0XX19fX0sIm1lc3NhZ2Vfc2VjcmV0cyI6eyJzZW5kZXJfZGF0YV9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE2MCwyMCwyMzMsMTgxLDI1MCwxOTUsMTkyLDI0LDIxOSwyMTcsMTE1LDIxNywyMjMsMjM1LDgyLDE4MywxNTAsMTQ3LDE3NiwxMTgsODMsMjUyLDc2LDk1LDE5NiwxMDIsMjUzLDIxNSwxOTksNzQsMTc2LDIzMl19fX0sIm1lbWJlcnNoaXBfa2V5Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMDEsMTgyLDE3MSwyMywxMTMsMjM5LDYzLDE5LDE0NCwyNDIsOTUsNzYsMzMsMjAwLDc1LDcwLDE1NSwzNSwxNTQsNjEsMTA3LDE5MiwxOSwxMzAsMTQ3LDYzLDI1MiwxNzgsNCwxNzQsMjAwLDEzNF19fX0sImNvbmZpcm1hdGlvbl9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzU0LDY3LDc2LDE4NSw1LDEyNiwxNTIsODIsMTk2LDYwLDE1NSwyMjEsMTc3LDIwLDE2OSwxNjcsMzAsMjA3LDEwNyw0MCw5Nyw4NiwyLDE0NCw5Nyw0LDI0NywyNTMsMjM5LDIxMSwyNDcsMTEwXX19fSwic2VyaWFsaXplZF9jb250ZXh0IjpbMCwxLDAsMiwxNiwyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMiwwLDAsMCwwLDAsMCwwLDIsMzIsMTUwLDIwMSwyMDgsMTgyLDIxNiw0MiwxMTksMTUsMjMsNywxMDAsMTcwLDIxNSwxMTYsODEsMTAxLDI1MCwyMTgsMTExLDQ5LDEyMCwyMTcsNDMsMTcyLDE2MiwyNDcsMjEsMTMsNjAsNTcsMjM0LDE3OSwzMiw4NiwxNTgsMTc4LDk2LDE1NCwxODMsMTEwLDE1Myw5LDcwLDE1NywxOTIsMjQ2LDI3LDQxLDEyNSwyNCwyOCwyOCw1OCwxODksMjQ5LDEwNSwyOCwyNDYsNSwyMjAsMTE5LDEwMSw2OCwxODIsMzMsOCwwLDMsNSwyLDI0MCw2NiwwLDBdLCJzZWNyZXRfdHJlZSI6eyJvd25faW5kZXgiOjAsImxlYWZfbm9kZXMiOltudWxsLG51bGxdLCJwYXJlbnRfbm9kZXMiOlt7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNTksMTcyLDI1MCwyMDYsMTI2LDMxLDQ5LDE3NCw2NSwyMDksMjIxLDcwLDM4LDI0OCw1MCwxMjQsMTQ3LDE1MiwyMjQsODgsMjAwLDczLDIxOSwyMDksMTEyLDE3MiwxMDQsNjIsMTc2LDIxOSw2LDIyMV19fX0sbnVsbF0sImhhbmRzaGFrZV9zZW5kZXJfcmF0Y2hldHMiOltudWxsLG51bGxdLCJhcHBsaWNhdGlvbl9zZW5kZXJfcmF0Y2hldHMiOltudWxsLG51bGxdLCJzaXplIjozfX0sInN0YWdlZF9kaWZmIjp7InN0YWdlZF9kaWZmIjp7ImRpZmYiOnsibGVhZl9kaWZmIjp7IjAiOnsibm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOls0LDEyOSwxMTYsMTcwLDE5NSwxOCw0NSwyNSwzNCwzNCwxNTAsMTY1LDEyOCwxNjQsMTAxLDIyLDU1LDE2MywyMzAsNCwyMSwxMCwxMzgsMjI0LDIyMSwyNDIsMTMsMjA4LDIxNSw1MywxODAsMjI3LDYsNywxNSwxMDgsMTk1LDIwMywyMjAsODQsMjcsMjEwLDUzLDIwLDE2NSwxMjIsMjEwLDE4NiwwLDM5LDE4LDUzLDIyMSwxMTgsMjExLDY0LDEzMSwxOTYsMTk0LDIyMSw0LDIxOCwxNzAsMzUsMTk3XX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6WzQsMTUsMTIxLDEyNCwxNzUsMTAwLDgsMjksMjE1LDIyMywzMywxNzcsMjI3LDc1LDE5MCw0NywyMyw3MywzMywxNiw0Niw3MSwxMSwxMzgsNjMsODIsMTg4LDIyMiwxMDMsODEsNTcsNTIsMjE3LDExOCw4MiwxMDIsMTk5LDE0MCwxNDIsMjM1LDE0NCwxNDUsMTg5LDEzNiwzMywxNjEsMjUzLDEyMiwxODksODEsNDgsMTY1LDY2LDEzMiwxMTAsMjQ4LDUxLDE5OSwyMTUsMTc3LDgxLDI0MCwxMDIsMTYzLDQyXX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTcsMTA4LDEwNSw5OSwxMDFdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IkNvbW1pdCI6eyJ2ZWMiOls2NSwyMzgsMjQ2LDI0MywxNzMsOSwxMzUsMyw1MywxMzEsMTU1LDE2OSwyNDYsMTk1LDI0OSwyNDEsMjMyLDE3OSwyMTYsODUsMjIxLDIyMCw5LDY5LDgxLDEwOCw2NSwzNywyMjcsMTExLDU3LDcxXX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzQ4LDcwLDIsMzMsMCwxMzYsMTA2LDY0LDI1MSwyMjYsNTgsNjMsMTMsNDcsMzYsMTg3LDEyNCwyNTQsNTUsMTA3LDc0LDExMCwxNjAsMTUzLDE3Nyw2Miw5NywxMjcsMjQ5LDc3LDE5MSwxNDksMTM4LDMxLDQ5LDgyLDE2OCwyLDMzLDAsMTM5LDk1LDE1Miw2NCwxMzksNzEsMTI1LDIyNiwyMzUsMTE2LDIzMSwyNTMsMTAsMzYsMTksNjEsMTE3LDE0MiwxMzYsMywyNDMsMjMzLDc0LDI0OCwxODgsMTI0LDgyLDEyOSwyMTQsMjM4LDEyOCw3Ml19fX19fSwicGFyZW50X2RpZmYiOnsiMCI6eyJub2RlIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOls0LDIwOCwzNiwyNTIsMjIwLDE2LDIxMCwyMDEsMTEwLDIzMywzMiwxMzIsMTU4LDI0LDYzLDEyNCwxMzQsMTQ1LDE4Niw3NSw2LDE3OSwyNDIsNDIsMTkyLDQ1LDc0LDE4MywxNjEsNjIsMjQ5LDI0Niw0OSwyMjcsMywyMDIsMTUzLDQ1LDE1MCw1OCwxMDQsMTgyLDI2LDY5LDE5OSw2NCwyMDQsMTY5LDE1NywxMjYsMjUsMTMxLDMwLDcyLDEyLDAsMjYsMTM2LDM4LDE2MCwxNzEsNjIsMjMyLDM3LDIxNV19fSwicGFyZW50X2hhc2giOnsidmVjIjpbXX0sInVubWVyZ2VkX2xlYXZlcyI6eyJsaXN0IjpbXX19fX0sInNpemUiOjN9LCJuZXdfdHJlZV9oYXNoIjpbMTUwLDIwMSwyMDgsMTgyLDIxNiw0MiwxMTksMTUsMjMsNywxMDAsMTcwLDIxNSwxMTYsODEsMTAxLDI1MCwyMTgsMTExLDQ5LDEyMCwyMTcsNDMsMTcyLDE2MiwyNDcsMjEsMTMsNjAsNTcsMjM0LDE3OV19LCJncm91cF9jb250ZXh0Ijp7InByb3RvY29sX3ZlcnNpb24iOiJNbHMxMCIsImNpcGhlcnN1aXRlIjoiTUxTXzEyOF9ESEtFTVAyNTZfQUVTMTI4R0NNX1NIQTI1Nl9QMjU2IiwiZ3JvdXBfaWQiOnsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0sImVwb2NoIjoyLCJ0cmVlX2hhc2giOnsidmVjIjpbMTUwLDIwMSwyMDgsMTgyLDIxNiw0MiwxMTksMTUsMjMsNywxMDAsMTcwLDIxNSwxMTYsODEsMTAxLDI1MCwyMTgsMTExLDQ5LDEyMCwyMTcsNDMsMTcyLDE2MiwyNDcsMjEsMTMsNjAsNTcsMjM0LDE3OV19LCJjb25maXJtZWRfdHJhbnNjcmlwdF9oYXNoIjp7InZlYyI6Wzg2LDE1OCwxNzgsOTYsMTU0LDE4MywxMTAsMTUzLDksNzAsMTU3LDE5MiwyNDYsMjcsNDEsMTI1LDI0LDI4LDI4LDU4LDE4OSwyNDksMTA1LDI4LDI0Niw1LDIyMCwxMTksMTAxLDY4LDE4MiwzM119LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W3siUmVxdWlyZWRDYXBhYmlsaXRpZXMiOnsiZXh0ZW5zaW9uX3R5cGVzIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbF90eXBlcyI6W10sImNyZWRlbnRpYWxfdHlwZXMiOltdfX1dfX0sImludGVyaW1fdHJhbnNjcmlwdF9oYXNoIjpbMTgzLDIwNiw0OSwxODUsMjQ5LDIxNCwxMzMsMTAwLDEwLDUzLDEyMCwxODUsMTcxLDIyNiwyMjEsNzgsMTUsMTY4LDYsNTYsMjE2LDE3MCwyMTQsMjMzLDE0MiwyMTQsMTAsMzQsNDUsMTM1LDIwNCwyMjFdLCJjb25maXJtYXRpb25fdGFnIjp7Im1hY192YWx1ZSI6eyJ2ZWMiOlsxNzUsMTg3LDE2NCwyNywxNDYsNTAsMjE3LDE4OCwyNTUsMTc4LDIwMSwxMzIsMTUsMTM3LDg1LDEzNCwxMTUsMTQ3LDIzMSwxMDksMzYsMjExLDIzNiwyNDksMTE5LDExNywyMjksMTYsMTQyLDIzNywxMDksMjE1XX19fSwibmV3X2tleXBhaXJzIjpbeyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOls0LDEyOSwxMTYsMTcwLDE5NSwxOCw0NSwyNSwzNCwzNCwxNTAsMTY1LDEyOCwxNjQsMTAxLDIyLDU1LDE2MywyMzAsNCwyMSwxMCwxMzgsMjI0LDIyMSwyNDIsMTMsMjA4LDIxNSw1MywxODAsMjI3LDYsNywxNSwxMDgsMTk1LDIwMywyMjAsODQsMjcsMjEwLDUzLDIwLDE2NSwxMjIsMjEwLDE4NiwwLDM5LDE4LDUzLDIyMSwxMTgsMjExLDY0LDEzMSwxOTYsMTk0LDIyMSw0LDIxOCwxNzAsMzUsMTk3XX19LCJwcml2YXRlX2tleSI6eyJrZXkiOnsidmVjIjpbMjE3LDc1LDM4LDI1NSwyMTgsMTk0LDk4LDg0LDY0LDEsNzksMTkxLDEzMywxODksMTIyLDg4LDYsMjEwLDIyMSwxMyw1LDUzLDY0LDExMiwyOSwxNTMsNTUsNDAsMjA0LDU5LDE4OSw1NV19fX0seyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOls0LDIwOCwzNiwyNTIsMjIwLDE2LDIxMCwyMDEsMTEwLDIzMywzMiwxMzIsMTU4LDI0LDYzLDEyNCwxMzQsMTQ1LDE4Niw3NSw2LDE3OSwyNDIsNDIsMTkyLDQ1LDc0LDE4MywxNjEsNjIsMjQ5LDI0Niw0OSwyMjcsMywyMDIsMTUzLDQ1LDE1MCw1OCwxMDQsMTgyLDI2LDY5LDE5OSw2NCwyMDQsMTY5LDE1NywxMjYsMjUsMTMxLDMwLDcyLDEyLDAsMjYsMTM2LDM4LDE2MCwxNzEsNjIsMjMyLDM3LDIxNV19fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6WzI0MCwyMDQsMzIsMjU0LDE2MCw0MCw5LDIxMSw0OSwyMzAsMTE0LDEwMiwyNTUsODAsMjAsMTE5LDQ1LDc2LDIyLDE4OCwxMDgsNjIsODgsMTU0LDI0MywxOSwxMDYsMTg2LDQyLDExNiw1MywyMTldfX19XSwibmV3X2xlYWZfa2V5cGFpcl9vcHRpb24iOm51bGwsInVwZGF0ZV9wYXRoX2xlYWZfbm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOls0LDEyOSwxMTYsMTcwLDE5NSwxOCw0NSwyNSwzNCwzNCwxNTAsMTY1LDEyOCwxNjQsMTAxLDIyLDU1LDE2MywyMzAsNCwyMSwxMCwxMzgsMjI0LDIyMSwyNDIsMTMsMjA4LDIxNSw1MywxODAsMjI3LDYsNywxNSwxMDgsMTk1LDIwMywyMjAsODQsMjcsMjEwLDUzLDIwLDE2NSwxMjIsMjEwLDE4NiwwLDM5LDE4LDUzLDIyMSwxMTgsMjExLDY0LDEzMSwxOTYsMTk0LDIyMSw0LDIxOCwxNzAsMzUsMTk3XX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6WzQsMTUsMTIxLDEyNCwxNzUsMTAwLDgsMjksMjE1LDIyMywzMywxNzcsMjI3LDc1LDE5MCw0NywyMyw3MywzMywxNiw0Niw3MSwxMSwxMzgsNjMsODIsMTg4LDIyMiwxMDMsODEsNTcsNTIsMjE3LDExOCw4MiwxMDIsMTk5LDE0MCwxNDIsMjM1LDE0NCwxNDUsMTg5LDEzNiwzMywxNjEsMjUzLDEyMiwxODksODEsNDgsMTY1LDY2LDEzMiwxMTAsMjQ4LDUxLDE5OSwyMTUsMTc3LDgxLDI0MCwxMDIsMTYzLDQyXX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTcsMTA4LDEwNSw5OSwxMDFdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IkNvbW1pdCI6eyJ2ZWMiOls2NSwyMzgsMjQ2LDI0MywxNzMsOSwxMzUsMyw1MywxMzEsMTU1LDE2OSwyNDYsMTk1LDI0OSwyNDEsMjMyLDE3OSwyMTYsODUsMjIxLDIyMCw5LDY5LDgxLDEwOCw2NSwzNywyMjcsMTExLDU3LDcxXX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzQ4LDcwLDIsMzMsMCwxMzYsMTA2LDY0LDI1MSwyMjYsNTgsNjMsMTMsNDcsMzYsMTg3LDEyNCwyNTQsNTUsMTA3LDc0LDExMCwxNjAsMTUzLDE3Nyw2Miw5NywxMjcsMjQ5LDc3LDE5MSwxNDksMTM4LDMxLDQ5LDgyLDE2OCwyLDMzLDAsMTM5LDk1LDE1Miw2NCwxMzksNzEsMTI1LDIyNiwyMzUsMTE2LDIzMSwyNTMsMTAsMzYsMTksNjEsMTE3LDE0MiwxMzYsMywyNDMsMjMzLDc0LDI0OCwxODgsMTI0LDgyLDEyOSwyMTQsMjM4LDEyOCw3Ml19fX19fX19fQAAAAAAAABeAAAAAAAAAAFPd25MZWFmTm9kZUluZGV4eyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABMAAAAAAAAABcAAAAAAAABg9NZXNzYWdlU2VjcmV0c3sidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsibWF4X2Vwb2NocyI6MCwicGFzdF9lcG9jaF90cmVlcyI6W10sIm1lc3NhZ2Vfc2VjcmV0cyI6eyJzZW5kZXJfZGF0YV9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzU0LDUwLDIxNiwyMDcsMjMsMTI5LDc3LDY2LDQ2LDU0LDIxLDEwNCw1OSwyMTMsMjEwLDIxMSwxNzQsMjExLDI0OSwxMTIsODYsMTIsMTIwLDk3LDE4OSw3Niw3MSwxNyw3LDIxNiwxMjEsMTgxXX19fSwibWVtYmVyc2hpcF9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzEyMCwyOCwxMDYsNTEsMTE3LDEyNCwxMjgsMjI3LDE2MCwxMTgsMzQsMjM0LDMsMTA2LDI1MiwxNjcsNjIsMjAxLDEyOSw5LDI0MywzOSwxOTgsMjA4LDIzNiwyMzksNDIsNjAsMjYsMzksMjMsMTIwXX19fSwiY29uZmlybWF0aW9uX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTM0LDE4NSwxMzgsODMsMTMyLDM0LDc5LDIzNiwxMTYsMTc4LDE0NiwxOTAsMTU1LDE2MiwzMiwxMDksODIsMTkxLDM5LDIyMywyMzIsMjksMjYsNzQsMTQ4LDI1NCwyNiwxODEsMzMsMzMsMTksMTg4XX19fSwic2VyaWFsaXplZF9jb250ZXh0IjpbMCwxLDAsMiwxNiwyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMiwwLDAsMCwwLDAsMCwwLDEsMzIsMTE3LDEyNiwxOTgsMzQsMTkyLDExMiwxMTcsMjMyLDIzMywxNTksNzAsMjQzLDI0OCw0LDE4NCw4LDExLDg0LDUwLDkzLDkxLDQsNzcsMjQ0LDk3LDY4LDAsMSw5MSwxNjAsMTE0LDE4OCwzMiwxOCwyNDgsNzUsNzYsMTEyLDIzNywyMjIsNzksNDcsNyw3OCw1MywxMDQsMTcwLDEyMiwxOTMsMTQ4LDUyLDE1NCwxNDYsMTc4LDQxLDEzNSw4LDM2LDIxMywxNjYsMTI2LDEwNiwyMjAsNzAsMjcsMF0sInNlY3JldF90cmVlIjp7Im93bl9pbmRleCI6MCwibGVhZl9ub2RlcyI6W251bGwseyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTk0LDE0OCwxNzYsMjE5LDIzMywxODQsNTAsODYsMTU0LDIwNCwyMzAsNTIsMjE5LDcxLDEzNCwxOTIsMCw3OCwxMTcsMTM1LDQ2LDc2LDc2LDQyLDIxNywxOTEsMTY4LDk1LDU1LDEyOCwxMDMsMjMzXX19fV0sInBhcmVudF9ub2RlcyI6W251bGwsbnVsbF0sImhhbmRzaGFrZV9zZW5kZXJfcmF0Y2hldHMiOlt7IkVuY3J5cHRpb25SYXRjaGV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNiwyMTEsMTI0LDE4MywyNCw2LDE0MCwyOCwxODYsMjA5LDIzNywxODUsMTUyLDE2OSwxODUsMjMzLDksMTU0LDExMCwyMjMsMTEsNzYsMjAyLDM5LDQ3LDI2LDE1OCwxNjYsODYsODYsMTI3LDIyMF19fSwiZ2VuZXJhdGlvbiI6MX19LG51bGxdLCJhcHBsaWNhdGlvbl9zZW5kZXJfcmF0Y2hldHMiOlt7IkVuY3J5cHRpb25SYXRjaGV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyNDAsNjIsMywxOTksMTMyLDE1NSwxMzIsMjAsMjIwLDMxLDI0MSwyMzIsMjQ5LDM5LDE0OSw0MSwxMTEsMjM1LDIxOCw3NSwxMSw4OCwyMCwyMDgsODEsMjEzLDIxNiw2MiwyMzksMjIyLDE2MiwyMjVdfX0sImdlbmVyYXRpb24iOjB9fSxudWxsXSwic2l6ZSI6M319fQAAAAAAAABdAAAAAAAAAzhFcG9jaEtleVBhaXJzeyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fTEwAAFbeyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOls0LDE5OSw1MCwxNywxMzAsMTYyLDIzMCwxMTcsNDUsMTM1LDIzNyw2LDExNSwxNCw0NCwyMjgsMTUxLDIwMSwxNjMsMjE1LDIzLDU4LDEzNiw5NSwyMzUsMTM0LDE2Niw3LDE2NCw1MiwxMDUsMTQ0LDE2NCwxNzcsODgsMTgwLDE2MiwyMTQsMjQ2LDExLDE4NSw5OCwxMzYsMTM5LDIwNCw5MSwxNDgsMjAsMTIwLDE1MCwxNDEsMjUyLDQ0LDE1NCwyMzYsNTQsOTksNjAsMTU0LDU2LDE5Nyw0NSwxMDAsMTM4LDEwM119fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6Wzk2LDE4MSwzNSwxMjcsMTgzLDE4MiwxOTcsMjgsMTI2LDE1Myw1LDcwLDU3LDg1LDMsMTE5LDIwMiwyMTcsMTUzLDE2NiwxNTQsMTEzLDE4MSwxMTMsMjE1LDI0MywyMDcsMTkxLDExMSwxNjYsMTA3LDE1N119fX0seyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOls0LDk3LDE5NCwxMjksMTAxLDE3Nyw3OCw4NiwzNiwxOTgsMTcxLDYyLDE1NSwxOCwxMTUsMTU0LDgyLDc1LDIwMiw0MiwzLDEyMSw3MSw5NywyNywyMjAsNjAsMTc3LDEyMywyMDEsMTQwLDEsMTc1LDcwLDE4NCwxNTIsNjAsMTk5LDE2MSwyMTksMTEwLDcyLDExLDEzMiwxOTIsMTc3LDEwNCwyMTcsMzUsMjQ2LDI4LDEyMywzNCwyMjUsMTYyLDE3MSwyMiwxMjUsNTQsNDIsNDAsMjEyLDI0MywyMjAsODhdfX0sInByaXZhdGVfa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxNDcsNSwyMTcsMTQ4LDEzLDcyLDczLDEyOSwxOTUsMjU0LDI1MywxOTgsMTcsMiwyMTEsMjgsMjUsNzUsMjM0LDI2LDExMCwxMTcsMTYsMTc1LDE2MCw0Nyw0MCwxMDcsMTAzLDE2Myw5MywxODRdfX19XQ==","AAAAAAAAAA0AAAAAAAAAXQAAAAAAAAMmRXBvY2hLZXlQYWlyc3sidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0yMAABW3sicHVibGljX2tleSI6eyJrZXkiOnsidmVjIjpbNCwxMjksMTE2LDE3MCwxOTUsMTgsNDUsMjUsMzQsMzQsMTUwLDE2NSwxMjgsMTY0LDEwMSwyMiw1NSwxNjMsMjMwLDQsMjEsMTAsMTM4LDIyNCwyMjEsMjQyLDEzLDIwOCwyMTUsNTMsMTgwLDIyNyw2LDcsMTUsMTA4LDE5NSwyMDMsMjIwLDg0LDI3LDIxMCw1MywyMCwxNjUsMTIyLDIxMCwxODYsMCwzOSwxOCw1MywyMjEsMTE4LDIxMSw2NCwxMzEsMTk2LDE5NCwyMjEsNCwyMTgsMTcwLDM1LDE5N119fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6WzIxNyw3NSwzOCwyNTUsMjE4LDE5NCw5OCw4NCw2NCwxLDc5LDE5MSwxMzMsMTg5LDEyMiw4OCw2LDIxMCwyMjEsMTMsNSw1Myw2NCwxMTIsMjksMTUzLDU1LDQwLDIwNCw1OSwxODksNTVdfX19LHsicHVibGljX2tleSI6eyJrZXkiOnsidmVjIjpbNCwyMDgsMzYsMjUyLDIyMCwxNiwyMTAsMjAxLDExMCwyMzMsMzIsMTMyLDE1OCwyNCw2MywxMjQsMTM0LDE0NSwxODYsNzUsNiwxNzksMjQyLDQyLDE5Miw0NSw3NCwxODMsMTYxLDYyLDI0OSwyNDYsNDksMjI3LDMsMjAyLDE1Myw0NSwxNTAsNTgsMTA0LDE4MiwyNiw2OSwxOTksNjQsMjA0LDE2OSwxNTcsMTI2LDI1LDEzMSwzMCw3MiwxMiwwLDI2LDEzNiwzOCwxNjAsMTcxLDYyLDIzMiwzNywyMTVdfX0sInByaXZhdGVfa2V5Ijp7ImtleSI6eyJ2ZWMiOlsyNDAsMjA0LDMyLDI1NCwxNjAsNDAsOSwyMTEsNDksMjMwLDExNCwxMDIsMjU1LDgwLDIwLDExOSw0NSw3NiwyMiwxODgsMTA4LDYyLDg4LDE1NCwyNDMsMTksMTA2LDE4Niw0MiwxMTYsNTMsMjE5XX19fV0AAAAAAAAAXQAAAAAAAACRQ29uZmlybWF0aW9uVGFneyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJtYWNfdmFsdWUiOnsidmVjIjpbMTc1LDE4NywxNjQsMjcsMTQ2LDUwLDIxNywxODgsMjU1LDE3OCwyMDEsMTMyLDE1LDEzNyw4NSwxMzQsMTE1LDE0NywyMzEsMTA5LDM2LDIxMSwyMzYsMjQ5LDExOSwxMTcsMjI5LDE2LDE0MiwyMzcsMTA5LDIxNV19fQAAAAAAAABSAAAAAAAAC6hUcmVleyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJ0cmVlIjp7ImxlYWZfbm9kZXMiOlt7Im5vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbNCwxMjksMTE2LDE3MCwxOTUsMTgsNDUsMjUsMzQsMzQsMTUwLDE2NSwxMjgsMTY0LDEwMSwyMiw1NSwxNjMsMjMwLDQsMjEsMTAsMTM4LDIyNCwyMjEsMjQyLDEzLDIwOCwyMTUsNTMsMTgwLDIyNyw2LDcsMTUsMTA4LDE5NSwyMDMsMjIwLDg0LDI3LDIxMCw1MywyMCwxNjUsMTIyLDIxMCwxODYsMCwzOSwxOCw1MywyMjEsMTE4LDIxMSw2NCwxMzEsMTk2LDE5NCwyMjEsNCwyMTgsMTcwLDM1LDE5N119fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0LDE1LDEyMSwxMjQsMTc1LDEwMCw4LDI5LDIxNSwyMjMsMzMsMTc3LDIyNyw3NSwxOTAsNDcsMjMsNzMsMzMsMTYsNDYsNzEsMTEsMTM4LDYzLDgyLDE4OCwyMjIsMTAzLDgxLDU3LDUyLDIxNywxMTgsODIsMTAyLDE5OSwxNDAsMTQyLDIzNSwxNDQsMTQ1LDE4OSwxMzYsMzMsMTYxLDI1MywxMjIsMTg5LDgxLDQ4LDE2NSw2NiwxMzIsMTEwLDI0OCw1MSwxOTksMjE1LDE3Nyw4MSwyNDAsMTAyLDE2Myw0Ml19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJDb21taXQiOnsidmVjIjpbNjUsMjM4LDI0NiwyNDMsMTczLDksMTM1LDMsNTMsMTMxLDE1NSwxNjksMjQ2LDE5NSwyNDksMjQxLDIzMiwxNzksMjE2LDg1LDIyMSwyMjAsOSw2OSw4MSwxMDgsNjUsMzcsMjI3LDExMSw1Nyw3MV19fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0OCw3MCwyLDMzLDAsMTM2LDEwNiw2NCwyNTEsMjI2LDU4LDYzLDEzLDQ3LDM2LDE4NywxMjQsMjU0LDU1LDEwNyw3NCwxMTAsMTYwLDE1MywxNzcsNjIsOTcsMTI3LDI0OSw3NywxOTEsMTQ5LDEzOCwzMSw0OSw4MiwxNjgsMiwzMywwLDEzOSw5NSwxNTIsNjQsMTM5LDcxLDEyNSwyMjYsMjM1LDExNiwyMzEsMjUzLDEwLDM2LDE5LDYxLDExNywxNDIsMTM2LDMsMjQzLDIzMyw3NCwyNDgsMTg4LDEyNCw4MiwxMjksMjE0LDIzOCwxMjgsNzJdfX19fSx7Im5vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbNCwxMDgsMTU4LDI0NSwyMzgsMTU5LDEyMiwyMywxODgsNzUsMTc0LDIzMSwyMTMsMzksMTgsMTAwLDIxOSwxODYsMTY4LDUxLDMxLDI1MSwyMTgsMzEsMTI5LDIwNyw5MiwyMjgsNTQsNjIsMTEzLDEzMCwyMzUsNTgsNzcsNDEsMjUyLDYwLDEzMCwyNDcsMTk4LDU5LDEyNCw0Myw1MCwxNjksNzEsMTM0LDk4LDExMywyNTMsMTc0LDEzOSw1Niw2OCw5NSwyMjQsOTUsODgsNjcsNzMsMTI0LDE2LDE1NywyMjldfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbNCw2LDIxOCwxODAsMTI2LDY4LDIwMSwyMzIsNDUsMjcsMTAsMSwzOCwxNjYsMTczLDM5LDgzLDI0NSwyNTIsMjQxLDcsMTkwLDE1NiwxNjQsMjA1LDIzMyw3MCwyMzcsMjQ1LDE2MSwxNzgsMTg5LDExMiwxMSw4OSwyMzgsMTE2LDE5NSwyNDQsMTYsMTc4LDE4NCwyMDEsMTUwLDIwMCwyMTUsMTIzLDE2OCwxNDYsNTYsMTU3LDMzLDI4LDEyNCwxMywxNTYsMjgsMjA0LDg4LDMwLDk5LDEzLDU4LDI1MiwxMDBdfX0sImNyZWRlbnRpYWwiOnsiY3JlZGVudGlhbF90eXBlIjoiQmFzaWMiLCJzZXJpYWxpemVkX2NyZWRlbnRpYWxfY29udGVudCI6eyJ2ZWMiOls5OCwxMTEsOThdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IktleVBhY2thZ2UiOnsibm90X2JlZm9yZSI6MTcyMDY4ODk0OSwibm90X2FmdGVyIjoxNzI3OTUwMTQ5fX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbNDgsNjgsMiwzMiw2OCwxNTYsMTUwLDE3NSwyMTQsMzQsMTksODcsMTQ0LDc5LDYwLDE1MCwyMTEsMTM2LDE3MywyMDUsMjUwLDE2LDE5NywxODcsMjA1LDE3NywyMzYsMTI0LDcxLDEwOCwyMDcsMTM3LDg4LDE4MCwxMjUsOTEs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MjAxLDIwOCwxODIsMjE2LDQyLDExOSwxNSwyMyw3LDEwMCwxNzAsMjE1LDExNiw4MSwxMDEsMjUwLDIxOCwxMTEsNDksMTIwLDIxNyw0MywxNzIsMTYyLDI0NywyMSwxMyw2MCw1NywyMzQsMTc5LDMyLDg2LDE1OCwxNzgsOTYsMTU0LDE4MywxMTAsMTUzLDksNzAsMTU3LDE5MiwyNDYsMjcsNDEsMTI1LDI0LDI4LDI4LDU4LDE4OSwyNDksMTA1LDI4LDI0Niw1LDIyMCwxMTksMTAxLDY4LDE4MiwzMyw4LDAsMyw1LDIsMjQwLDY2LDAsMF0sInNlY3JldF90cmVlIjp7Im93bl9pbmRleCI6MCwibGVhZl9ub2RlcyI6W251bGwsbnVsbF0sInBhcmVudF9ub2RlcyI6W3sic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE1OSwxNzIsMjUwLDIwNiwxMjYsMzEsNDksMTc0LDY1LDIwOSwyMjEsNzAsMzgsMjQ4LDUwLDEyNCwxNDcsMTUyLDIyNCw4OCwyMDAsNzMsMjE5LDIwOSwxMTIsMTcyLDEwNCw2MiwxNzYsMjE5LDYsMjIxXX19fSxudWxsXSwiaGFuZHNoYWtlX3NlbmRlcl9yYXRjaGV0cyI6W251bGwsbnVsbF0sImFwcGxpY2F0aW9uX3NlbmRlcl9yYXRjaGV0cyI6W251bGwsbnVsbF0sInNpemUiOjN9fX0=","AAAAAAAAAA8AAAAAAAAA5AAAAAAAAAg4UXVldWVkUHJvcG9zYWxbeyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fSx7InZhbHVlIjp7InZlYyI6WzE5NCwyMjEsMjQ5LDYzLDIxMCwyNDksOCwxMSwyNDksMTI5LDMzLDI0NiwxNDgsNDIsMTgwLDIzNCwyMDMsMTAwLDM1LDYzLDEwMCwxMSw0NCwyNDEsMjQsMTExLDY3LDI1NSwyMzUsMjM1LDE4MywwXX19XQABeyJwcm9wb3NhbCI6eyJBZGQiOnsia2V5X3BhY2thZ2UiOnsicGF5bG9hZCI6eyJwcm90b2NvbF92ZXJzaW9uIjoiTWxzMTAiLCJjaXBoZXJzdWl0ZSI6Ik1MU18xMjhfREhLRU1QMjU2X0FFUzEyOEdDTV9TSEEyNTZfUDI1NiIsImluaXRfa2V5Ijp7ImtleSI6eyJ2ZWMiOls0LDg5LDEzMSwxNjIsNTAsMTM2LDk4LDE5Myw2MSw1OCw1MCw2LDIwNiwyMzQsMTYxLDU5LDEyNSwyNDUsMTExLDg5LDE2OCw0OCw1Miw0Nyw1OCwyNTIsOTcsMjI1LDIyOSwzNCwyMzYsODIsMjQ2LDkwLDQ0LDEwNywyNDYsMjQsMjQ0LDEwOSwxMDUsMTI1LDIsMTEzLDE3LDE1MiwxMTQsMTQ4LDE2OCwxMTgsMTA1LDY4LDIwMiwxODksMjM4LDIzMiwxNTgsODEsMzcsMTYyLDY4LDEwMiwyNDksNDUsMjExXX19LCJsZWFmX25vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbNCwzOSwxNDMsMjQzLDYzLDM1LDUyLDIxNiw4OSwyMjUsODYsMjA3LDk3LDI0NSwxOCwyMjUsMjQ4LDIzMiwyOCwxMDAsMjQ3LDY0LDYwLDI1MSw2MiwyNDgsMjI2LDIyOCwxNjMsMjAyLDg4LDcwLDcwLDExMCwyNywyNDcsMTQxLDU0LDE0OSwxMTQsNzAsNTQsNjMsMTc2LDIyMSwyMjQsMjQyLDgxLDE5MiwxMDEsODUsMTEsMzcsMTQ1LDYwLDE1MywxODgsMTQyLDg3LDI1LDEwOSwxMjEsMjE5LDE4MywxMDNdfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbNCwxOTIsMTAzLDE4LDE2Niw3MCwxMDksMjE2LDcyLDE1NSw0LDE4NywxOTIsMTQ4LDU3LDIzMiwxNTksMTg2LDY2LDYzLDE4Myw2OSwxOSwxNjIsNywxNDgsMTIxLDIzMCwxMzAsMzAsNywyMTAsNzYsMTU3LDIzMCwyNDAsMjI2LDIwMSwxNDksMTI5LDE5MiwxNjQsMjM1LDQ4LDIyOSwxMTMsMjEwLDE4OCwzOSwzNiwxOTIsMTA5LDI1MywxODYsMjAxLDE1OSwxNDcsNzEsNTYsMTczLDI0Niw2LDE4MCwyMDEsMjU0XX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTksMTA0LDk3LDExNCwxMDgsMTA1LDEwMV19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiS2V5UGFja2FnZSI6eyJub3RfYmVmb3JlIjoxNzIwNjg4OTUwLCJub3RfYWZ0ZXIiOjE3Mjc5NTAxNTB9fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0OCw3MCwyLDMzLDAsMjMzLDE1NywyMzEsNTUsMjM4LDIxOCwxODIsNzAsMTE2LDk1LDIyNywxMzAsMTc5LDIxMCwyMTcsMjI0LDIyMywxOTUsOTgsODcsNjgsMTkxLDE3NiwyMDcsMzcsMTI0LDIyNyw4MywxMTksMTkwLDIyMSw3NSwyLDMzLDAsMjE0LDE3MywxMTYsMzEsNzksMzksNTUsMSwxNTUsMjMyLDcyLDEwNSwxODYsODMsMTI2LDIzNiw1NiwxMzksNTYsOTIsNzUsMTgx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Miw2OSw2MSwyMjJdfX0AAXsidHJlZSI6eyJsZWFmX25vZGVzIjpbeyJub2RlIjp7InBheWxvYWQiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzQsMTI5LDExNiwxNzAsMTk1LDE4LDQ1LDI1LDM0LDM0LDE1MCwxNjUsMTI4LDE2NCwxMDEsMjIsNTUsMTYzLDIzMCw0LDIxLDEwLDEzOCwyMjQsMjIxLDI0MiwxMywyMDgsMjE1LDUzLDE4MCwyMjcsNiw3LDE1LDEwOCwxOTUsMjAzLDIyMCw4NCwyNywyMTAsNTMsMjAsMTY1LDEyMiwyMTAsMTg2LDAsMzksMTgsNTMsMjIxLDExOCwyMTEsNjQsMTMxLDE5NiwxOTQsMjIxLDQsMjE4LDE3MCwzNSwxOTddfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbNCwxNSwxMjEsMTI0LDE3NSwxMDAsOCwyOSwyMTUsMjIzLDMzLDE3NywyMjcsNzUsMTkwLDQ3LDIzLDczLDMzLDE2LDQ2LDcxLDExLDEzOCw2Myw4MiwxODgsMjIyLDEwMyw4MSw1Nyw1MiwyMTcsMTE4LDgyLDEwMiwxOTksMTQwLDE0MiwyMzUsMTQ0LDE0NSwxODksMTM2LDMzLDE2MSwyNTMsMTIyLDE4OSw4MSw0OCwxNjUsNjYsMTMyLDExMCwyNDgsNTEsMTk5LDIxNSwxNzcsODEsMjQwLDEwMiwxNjMsNDJdfX0sImNyZWRlbnRpYWwiOnsiY3JlZGVudGlhbF90eXBlIjoiQmFzaWMiLCJzZXJpYWxpemVkX2NyZWRlbnRpYWxfY29udGVudCI6eyJ2ZWMiOls5NywxMDgsMTA1LDk5LDEwMV19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiQ29tbWl0Ijp7InZlYyI6WzY1LDIzOCwyNDYsMjQzLDE3Myw5LDEzNSwzLDUzLDEzMSwxNTUsMTY5LDI0NiwxOTUsMjQ5LDI0MSwyMzIsMTc5LDIxNiw4NSwyMjEsMjIwLDksNjksODEsMTA4LDY1LDM3LDIyNywxMTEsNTcsNzFdfX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbNDgsNzAsMiwzMywwLDEzNiwxMDYsNjQsMjUxLDIyNiw1OCw2MywxMyw0NywzNiwxODcsMTI0LDI1NCw1NSwxMDcsNzQsMTEwLDE2MCwxNTMsMTc3LDYyLDk3LDEyNywyNDksNzcsMTkxLDE0OSwxMzgsMzEsNDksODIsMTY4LDIsMzMsMCwxMzksOTUsMTUyLDY0LDEzOSw3MSwxMjUsMjI2LDIzNSwxMTYsMjMxLDI1MywxMCwzNiwxOSw2MSwxMTcsMTQyLDEzNiwzLDI0MywyMzMsNzQsMjQ4LDE4OCwxMjQsODIsMTI5LDIxNCwyMzgsMTI4LDcyXX19fX0seyJub2RlIjp7InBheWxvYWQiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzQsMTA4LDE1OCwyNDUsMjM4LDE1OSwxMjIsMjMsMTg4LDc1LDE3NCwyMzEsMjEzLDM5LDE4LDEwMCwyMTksMTg2LDE2OCw1MSwzMSwyNTEsMjE4LDMxLDEyOSwyMDcsOTIsMjI4LDU0LDYyLDExMywxMzAsMjM1LDU4LDc3LDQxLDI1Miw2MCwxMzAsMjQ3LDE5OCw1OSwxMjQsNDMsNTAsMTY5LDcxLDEzNCw5OCwxMTMsMjUzLDE3NCwxMzksNTYsNjgsOTUsMjI0LDk1LDg4LDY3LDczLDEyNCwxNiwxNTcsMjI5XX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6WzQsNiwyMTgsMTgwLDEyNiw2OCwyMDEsMjMyLDQ1LDI3LDEwLDEsMzgsMTY2LDE3MywzOSw4MywyNDUsMjUyLDI0MSw3LDE5MCwxNTYsMTY0LDIwNSwyMzMsNzAsMjM3LDI0NSwxNjEsMTc4LDE4OSwxMTIsMTEsODksMjM4LDExNiwxOTUsMjQ0LDE2LDE3OCwxODQsMjAxLDE1MCwyMDAsMjE1LDEyMywxNjgsMTQ2LDU2LDE1NywzMywyOCwxMjQsMTMsMTU2LDI4LDIwNCw4OCwzMCw5OSwxMyw1OCwyNTIsMTAwXX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTgsMTExLDk4XX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJLZXlQYWNrYWdlIjp7Im5vdF9iZWZvcmUiOjE3MjA2ODg5NDksIm5vdF9hZnRlciI6MTcyNzk1MDE0OX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzQ4LDY4LDIsMzIsNjgsMTU2LDE1MCwxNzUsMjE0LDM0LDE5LDg3LDE0NCw3OSw2MCwxNTAsMjExLDEzNiwxNzMsMjA1LDI1MCwxNiwxOTcsMTg3LDIwNSwxNzcsMjM2LDEyNCw3MSwxMDgsMjA3LDEzNyw4OCwxODAsMTI1LDkxLDIsMzIsMTIsNjEsOTcsMjQ5LDgxLDE4NCwyMzQsMTI3LDYzLDE2Miw1NywxNjAsOTUsODUsMTU4LDg2LDIyNiwxNyw4LDI0MCwyMzMsMjEsODEsMTc0LDEyNywxMjksOTUsMTcwLDE2OSwxMzUsNDEsODhdfX19fV0sInBhcmVudF9ub2RlcyI6W3sibm9kZSI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbNCwyMDgsMzYsMjUyLDIyMCwxNiwyMTAsMjAxLDExMCwyMzMsMzIsMTMyLDE1OCwyNCw2MywxMjQsMTM0LDE0NSwxODYsNzUsNiwxNzksMjQyLDQyLDE5Miw0NSw3NCwxODMsMTYxLDYyLDI0OSwyNDYsNDksMjI3LDMsMjAyLDE1Myw0NSwxNTAsNTgsMTA0LDE4MiwyNiw2OSwxOTksNjQsMjA0LDE2OSwxNTcsMTI2LDI1LDEzMSwzMCw3MiwxMiwwLDI2LDEzNiwzOCwxNjAsMTcxLDYyLDIzMiwzNywyMTVdfX0sInBhcmVudF9oYXNoIjp7InZlYyI6W119LCJ1bm1lcmdlZF9sZWF2ZXMiOnsibGlzdCI6W119fX1dLCJkZWZhdWx0X2xlYWYiOnsibm9kZSI6bnVsbH0sImRlZmF1bHRfcGFyZW50Ijp7Im5vZGUiOm51bGx9fSwidHJlZV9oYXNoIjpbMTUwLDIwMSwyMDgsMTgyLDIxNiw0MiwxMTksMTUsMjMsNywxMDAsMTcwLDIxNSwxMTYsODEsMTAxLDI1MCwyMTgsMTExLDQ5LDEyMCwyMTcsNDMsMTcyLDE2MiwyNDcsMjEsMTMsNjAsNTcsMjM0LDE3OV19AAAAAAAAAFoAAAAAAAACW0dyb3VwQ29udGV4dHsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsicHJvdG9jb2xfdmVyc2lvbiI6Ik1sczEwIiwiY2lwaGVyc3VpdGUiOiJNTFNfMTI4X0RIS0VNUDI1Nl9BRVMxMjhHQ01fU0hBMjU2X1AyNTYiLCJncm91cF9pZCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fSwiZXBvY2giOjIsInRyZWVfaGFzaCI6eyJ2ZWMiOlsxNTAsMjAxLDIwOCwxODIsMjE2LDQyLDExOSwxNSwyMyw3LDEwMCwxNzAsMjE1LDExNiw4MSwxMDEsMjUwLDIxOCwxMTEsNDksMTIwLDIxNyw0MywxNzIsMTYyLDI0NywyMSwxMyw2MCw1NywyMzQsMTc5XX0sImNvbmZpcm1lZF90cmFuc2NyaXB0X2hhc2giOnsidmVjIjpbODYsMTU4LDE3OCw5NiwxNTQsMTgzLDExMCwxNTMsOSw3MCwxNTcsMTkyLDI0NiwyNyw0MSwxMjUsMjQsMjgsMjgsNTgsMTg5LDI0OSwxMDUsMjgsMjQ2LDUsMjIwLDExOSwxMDEsNjgsMTgyLDMzXX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbeyJSZXF1aXJlZENhcGFiaWxpdGllcyI6eyJleHRlbnNpb25fdHlwZXMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FsX3R5cGVzIjpbXSwiY3JlZGVudGlhbF90eXBlcyI6W119fV19fQAAAAAAAABdAAAAAAAAAyZFcG9jaEtleVBhaXJzeyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fTIwAAFbeyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOls0LDEyOSwxMTYsMTcwLDE5NSwxOCw0NSwyNSwzNCwzNCwxNTAsMTY1LDEyOCwxNjQsMTAxLDIyLDU1LDE2MywyMzAsNCwyMSwxMCwxMzgsMjI0LDIyMSwyNDIsMTMsMjA4LDIxNSw1MywxODAsMjI3LDYsNywxNSwxMDgsMTk1LDIwMywyMjAsODQsMjcsMjEwLDUzLDIwLDE2NSwxMjIsMjEwLDE4NiwwLDM5LDE4LDUzLDIyMSwxMTgsMjExLDY0LDEzMSwxOTYsMTk0LDIyMSw0LDIxOCwxNzAsMzUsMTk3XX19LCJwcml2YXRlX2tleSI6eyJrZXkiOnsidmVjIjpbMjE3LDc1LDM4LDI1NSwyMTgsMTk0LDk4LDg0LDY0LDEsNzksMTkxLDEzMywxODksMTIyLDg4LDYsMjEwLDIyMSwxMyw1LDUzLDY0LDExMiwyOSwxNTMsNTUsNDAsMjA0LDU5LDE4OSw1NV19fX0seyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOls0LDIwOCwzNiwyNTIsMjIwLDE2LDIxMCwyMDEsMTEwLDIzMywzMiwxMzIsMTU4LDI0LDYzLDEyNCwxMzQsMTQ1LDE4Niw3NSw2LDE3OSwyNDIsNDIsMTkyLDQ1LDc0LDE4MywxNjEsNjIsMjQ5LDI0Niw0OSwyMjcsMywyMDIsMTUzLDQ1LDE1MCw1OCwxMDQsMTgyLDI2LDY5LDE5OSw2NCwyMDQsMTY5LDE1NywxMjYsMjUsMTMxLDMwLDcyLDEyLDAsMjYsMTM2LDM4LDE2MCwxNzEsNjIsMjMyLDM3LDIxNV19fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6WzI0MCwyMDQsMzIsMjU0LDE2MCw0MCw5LDIxMSw0OSwyMzAsMTE0LDEwMiwyNTUsODAsMjAsMTE5LDQ1LDc2LDIyLDE4OCwxMDgsNjIsODgsMTU0LDI0MywxOSwxMDYsMTg2LDQyLDExNiw1MywyMTldfX19XQAAAAAAAABjAAAAAAAAAHZJbnRlcmltVHJhbnNjcmlwdEhhc2h7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAFbMTgzLDIwNiw0OSwxODUsMjQ5LDIxNCwxMzMsMTAwLDEwLDUzLDEyMCwxODUsMTcxLDIyNiwyMjEsNzgsMTUsMTY4LDYsNTYsMjE2LDE3MCwyMTQsMjMzLDE0MiwyMTQsMTAsMzQsNDUsMTM1LDIwNCwyMjFdAAAAAAAAAFwAAAAAAAAABVVzZVJhdGNoZXRUcmVleyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABZmFsc2UAAAAAAAAAWwAAAAAAAAHqUmVzdW1wdGlvblBza3sidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsibWF4X251bWJlcl9vZl9zZWNyZXRzIjozMiwicmVzdW1wdGlvbl9wc2siOltbMCx7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOls4NCw0NSwyMjcsMjgsNjksMTMsMTQwLDUwLDQ0LDE0OSw5NCwyLDY0LDMxLDIxMyw2MCw1NSwxMDcsMjQzLDExNCwxODksMTEsMTk2LDIxOCwxMywyNCw1NiwxNDgsNzksNiwzLDY5XX19fV0sWzEseyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbODMsNzgsMTEyLDE4MywzOSwyMywxNzgsNzQsOTQsNSwyMTAsNDAsMjQ4LDEwNCwxNzUsMjEwLDEwMywzOCwyMTIsNSwxNTEsMTMwLDI0LDIyLDc5LDI3LDE3OCw3MiwxMTQsMTYxLDExNiwyMDZdfX19XSxbMix7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNzUsMTExLDIzNSwxNjEsMTQ5LDU1LDE3MywxMzMsOTgsMTA3LDgxLDExNyw0Myw1NywyMSwxODMsMjA4LDY1LDE5NCwwLDE2NCw4Myw0MiwyMjAsNCwyMjYsNjYsMTMzLDE0OSw2MiwyMSwyMDRdfX19XV0sImN1cnNvciI6M30AAAAAAAAAYAAAAAAAAAEWTWxzR3JvdXBKb2luQ29uZmlneyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJ3aXJlX2Zvcm1hdF9wb2xpY3kiOnsib3V0Z29pbmciOiJBbHdheXNDaXBoZXJ0ZXh0IiwiaW5jb21pbmciOiJBbHdheXNDaXBoZXJ0ZXh0In0sInBhZGRpbmdfc2l6ZSI6MCwibWF4X3Bhc3RfZXBvY2hzIjowLCJudW1iZXJfb2ZfcmVzdW1wdGlvbl9wc2tzIjowLCJ1c2VfcmF0Y2hldF90cmVlX2V4dGVuc2lvbiI6ZmFsc2UsInNlbmRlcl9yYXRjaGV0X2NvbmZpZ3VyYXRpb24iOnsib3V0X29mX29yZGVyX3RvbGVyYW5jZSI6NSwibWF4aW11bV9mb3J3YXJkX2Rpc3RhbmNlIjoxMDAwfX0AAAAAAAAAWAAAAAAAAAANR3JvdXBTdGF0ZXsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AASJPcGVyYXRpb25hbCIAAAAAAAAAXwAAAAAAAAGcUHJvcG9zYWxRdWV1ZVJlZnN7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAFbWzEyMywzNCwxMTgsOTcsMTA4LDExNywxMDEsMzQsNTgsMTIzLDM0LDExOCwxMDEsOTksMzQsNTgsOTEsNDksNTcsNTIsNDQsNTAsNTAsNDksNDQsNTAsNTIsNTcsNDQsNTQsNTEsNDQsNTAsNDksNDgsNDQsNTAsNTIsNTcsNDQsNTYsNDQsNDksNDksNDQsNTAsNTIsNTcsNDQsNDksNTAsNTcsNDQsNTEsNTEsNDQsNTAsNTIsNTQsNDQsNDksNTIsNTYsNDQsNTIsNTAsNDQsNDksNTYsNDgsNDQsNTAsNTEsNTIsNDQsNTAsNDgsNTEsNDQsNDksNDgsNDgsNDQsNTEsNTMsNDQsNTQsNTEsNDQsNDksNDgsNDgsNDQsNDksNDksNDQsNTIsNTIsNDQsNTAsNTIsNDksNDQsNTAsNTIsNDQsNDksNDksNDksNDQsNTQsNTUsNDQsNTAsNTMsNTMsNDQsNTAsNTEsNTMsNDQsNTAsNTEsNTMsNDQsNDksNTYsNTEsNDQsNDgsOTMsMTI1LDEyNV1dAAAAAAAAAFwAAAAAAAAGM01lc3NhZ2VTZWNyZXRzeyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJtYXhfZXBvY2hzIjowLCJwYXN0X2Vwb2NoX3RyZWVzIjpbXSwibWVzc2FnZV9zZWNyZXRzIjp7InNlbmRlcl9kYXRhX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTYwLDIwLDIzMywxODEsMjUwLDE5NSwxOTIsMjQsMjE5LDIxNywxMTUsMjE3LDIyMywyMzUsODIsMTgzLDE1MCwxNDcsMTc2LDExOCw4MywyNTIsNzYsOTUsMTk2LDEwMiwyNTMsMjE1LDE5OSw3NCwxNzYsMjMyXX19fSwibWVtYmVyc2hpcF9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzEwMSwxODIsMTcxLDIzLDExMywyMzksNjMsMTksMTQ0LDI0Miw5NSw3NiwzMywyMDAsNzUsNzAsMTU1LDM1LDE1NCw2MSwxMDcsMTkyLDE5LDEzMCwxNDcsNjMsMjUyLDE3OCw0LDE3NCwyMDAsMTM0XX19fSwiY29uZmlybWF0aW9uX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbNTQsNjcsNzYsMTg1LDUsMTI2LDE1Miw4MiwxOTYsNjAsMTU1LDIyMSwxNzcsMjAsMTY5LDE2NywzMCwyMDcsMTA3LDQwLDk3LDg2LDIsMTQ0LDk3LDQsMjQ3LDI1MywyMzksMjExLDI0NywxMTBdfX19LCJzZXJpYWxpemVkX2NvbnRleHQiOlswLDEsMCwyLDE2LDIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyLDAsMCwwLDAsMCwwLDAsMiwzMiwxNTAsMjAxLDIwOCwxODIsMjE2LDQyLDExOSwxNSwyMyw3LDEwMCwxNzAsMjE1LDExNiw4MSwxMDEsMjUwLDIxOCwxMTEsNDksMTIwLDIxNyw0MywxNzIsMTYyLDI0NywyMSwxMyw2MCw1NywyMzQsMTc5LDMyLDg2LDE1OCwxNzgsOTYsMTU0LDE4MywxMTAsMTUzLDksNzAsMTU3LDE5MiwyNDYsMjcsNDEsMTI1LDI0LDI4LDI4LDU4LDE4OSwyNDksMTA1LDI4LDI0Niw1LDIyMCwxMTksMTAxLDY4LDE4MiwzMyw4LDAsMyw1LDIsMjQwLDY2LDAsMF0sInNlY3JldF90cmVlIjp7Im93bl9pbmRleCI6MCwibGVhZl9ub2RlcyI6W251bGwseyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTk5LDc3LDIxMiwyNTIsMTcwLDM0LDE0NiwxNTEsMTE1LDEwNCw0MCwzNiwxNCw2MiwxMDIsMTExLDIyNyw2MCw3MSwyMDYsNzUsMjIzLDY4LDE0Niw0MywxNzEsNjMsMTc1LDI0OSwyMzksODYsMTQyXX19fV0sInBhcmVudF9ub2RlcyI6W251bGwsbnVsbF0sImhhbmRzaGFrZV9zZW5kZXJfcmF0Y2hldHMiOlt7IkVuY3J5cHRpb25SYXRjaGV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyMywyNTUsMTk3LDE2OSwxMTIsNjksMjI0LDE2MCw4NywzOCwxNDQsODMsNzUsMTE0LDIwNCw0NiwxNDQsMjUyLDUzLDIyMywxMzksMTU0LDU3LDE5OCwyMjIsODIsNzksNTAsMTYzLDEwMSwyNDIsNTNdfX0sImdlbmVyYXRpb24iOjF9fSxudWxsXSwiYXBwbGljYXRpb25fc2VuZGVyX3JhdGNoZXRzIjpbeyJFbmNyeXB0aW9uUmF0Y2hldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMjUyLDExNCwxMDQsODMsMjE2LDE1LDI2LDUwLDExNiwyNDYsOCwxNTMsMTY1LDExNCwxMTEsMTQzLDQ5LDE5NSwxMTMsNjgsMTgyLDExMCw3NiwxNTMsMTc5LDQ3LDEyMSwyMjUsMTg1LDEwMCw3NCwzNF19fSwiZ2VuZXJhdGlvbiI6MH19LG51bGxdLCJzaXplIjozfX19"]},"MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519":{"group_id":{"value":{"vec":[214,206,173,27,206,87,231,4,172,30,130,210,232,69,61,222]}},"storages":["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OTksMTIxLDIwNCw3NiwyMjksODMsMTQ1LDIwNyw1Nyw1NCwyMiwyMjAsMjM3LDI1NCw3MiwyNiwxMDQsMTEyLDc0LDIyMiwyNDcsMjIzLDM4LDg5LDE5MCwxODcsMzhdfX19LCJtZW1iZXJzaGlwX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTIxLDExMSwxMTgsMTI5LDIwNiw3MiwxNCwyMTQsMTI4LDEyNiwxMTgsMjM5LDE0LDE3MywyNTUsMjUzLDEzOCwzOSw5LDEzLDE2NCwxNDUsMTYxLDIzMCwxNTQsMzMsMTcyLDI1MiwyMjcsODksNTgsODBdfX19LCJjb25maXJtYXRpb25fa2V5Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOls3NywxMzEsMTQyLDIzMiwxMTUsMCwxMTUsOTAsODAsMjQzLDI1MSwxMiwxMjUsNDcsMTE1LDE0OSwxNjUsMjQzLDY0LDExLDE5OSw5NSwxNTQsMTQsMTYzLDEyNSwxNTcsMjAyLDE2NiwxODQsMTg5LDEwNl19fX0sInNlcmlhbGl6ZWRfY29udGV4dCI6WzAsMSwwLDMsMTYsMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjIsMCwwLDAsMCwwLDAsMCwwLDMyLDE0NCwyNDQsNjcsNzYsNDMsMTgsMTY5LDEyMSwyNDQsMjA3LDIwOCw4MywyMDAsNDcsMjIyLDE3OCwxOTMsMTU0LDEzNCwyMTgsMTA2LDIzNCwxMDUsMTkwLDEyNCwyMDAsMzksOTEsMTY0LDEzMSwxMjgsMTE2LDAsMF0sInNlY3JldF90cmVlIjp7Im93bl9pbmRleCI6MCwibGVhZl9ub2RlcyI6W3sic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzI5LDE3NiwzMSwyNDksMTQ1LDIxMSw3MCw1MSw3NCwxMDIsMTE3LDEwNSw2MywxMDgsMTY4LDE2Nyw5OSwxMzUsMTQ5LDksMiwxMjcsODAsOTksMTU1LDE0NywxNjQsMTY5LDEzMywxMTIsMjA0LDY2XX19fV0sInBhcmVudF9ub2RlcyI6W251bGxdLCJoYW5kc2hha2Vfc2VuZGVyX3JhdGNo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LDg5LDIyNCw0OCwxMjYsNzgsMTI0LDE4NiwxNDgsMTU5LDI0NSwxNzUsMTIyLDE1NSwxNiwyMDksMTUzLDIxNiwyMiwxNDEsMTE3LDc1LDk3LDcyLDI0NywzNl19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMTYsMTEwLDE2LDkxLDk5LDQ0LDE3MCwxMjEsMTY0LDEwMiwxMjMsMTIzLDExNCwyMzksNzIsMTk2LDY5LDUsNTgsODcsMjU0LDQ1LDEwNywyMjksMTgyLDQyLDI5LDEzNSw3Niw4MywxOTcsMTk0XX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTgsMTExLDk4XX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJLZXlQYWNrYWdlIjp7Im5vdF9iZWZvcmUiOjE3MjA2ODg5NDksIm5vdF9hZnRlciI6MTcyNzk1MDE0OX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzI4LDE1NCwxOCw1NCwxMjQsMjMxLDI3LDE3MiwxOTIsMTA0LDE4Nyw5OCwxODUsNDQsMSwxNTgsMjA5LDIxMywyNDAsMTc5LDE4NCwyMDQsMTQ0LDEwNywxMjksMjEsMSw4Nyw2OSwxNTcsMTEyLDIwNywyMTQsMjA1LDEzMSwxMzcsNiwzNSwyMTcsMjI5LDE5NSw1NiwxMDksMTYyLDk2LDg5LDE3NiwyOCwxNzYsMjQsMTgsMTc0LDU5LDE0NSwxMzUsMjQ3LDIzMSwxNzAsMzMsMjA5LDQ3LDI1NSw1Myw3XX19fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOls1LDEzMywyNDUsNDQsMTU0LDE0MiwxNDQsMjQ0LDUsOTIsOTgsMTU3LDI0NSwzLDIwOCwxNzEsMTU0LDQyLDIwOSwxOSwxMDEsMjI4LDI4LDYxLDIyNiwyNDYsMjMxLDE3NCwxODgsMTExLDIyOCw4Nyw3MCwxOTUsMTg2LDE1LDE0MSw2MiwxOTksNDEsMTMsMjMsMjAyLDI0MCw1MCwxNSwxNDgsNTgsMTExLDYwLDIwNSw2MCwyNDEsNDksMzYsMjQzLDYxLDIxNyw1MCwxOTEsMTcxLDI2LDIzOCw1XX19fX19LCJwcm9wb3NhbF9yZWZlcmVuY2UiOnsidmFsdWUiOnsidmVjIjpbMzQsMTY0LDM4LDUyLDI0MSwyMzksMTU0LDg3LDI4LDY2LDc4LDEzOSwxNTksODYsMTg2LDIwNiw0NywyMDQsNDUsMTMyLDE4MiwxMTYsMjksMTIwLDEzOSwxMjYsOTQsMTk4LDEyMSwxLDIzNywxNjZdfX0sInNlbmRlciI6eyJNZW1iZXIiOjB9LCJwcm9wb3NhbF9vcl9yZWZfdHlwZSI6IlByb3Bvc2FsIn1dXX0sInN0YXRlIjp7Ikdyb3VwTWVtYmVyIjp7Imdyb3VwX2Vwb2NoX3NlY3JldHMiOnsiaW5pdF9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzEyMywxNDUsMjE4LDgxLDE2MCwyMjYsNSwyMzgsMTgzLDIwLDExLDQ5LDIyLDkzLDE5Nyw2NywxNzMsMjI1LDE4OSw2NSw0LDU5LDE5Miw3MywyMjIsMTMwLDIxOSwxODIsMTA5LDE4MywxOTAsMjA1XX19fSwiZXhwb3J0ZXJfc2VjcmV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOls0NywyMzIsNDksMTU2LDc3LDE3MywxMzgsMTYyLDI1MywxNzIsMTEzLDI0NiwyMTMsNjEsODIsMjUwLDI3LDksODIsMTM3LDIyNCwxOTUsMjQ1LDIzMywxMDIsNTQsOTIsNzYsOSw1OCwxNDIsMjNdfX19LCJlcG9jaF9hdXRoZW50aWNhdG9yIjp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyMzEsNTksMTg0LDY0LDI5LDExNSwxOTksMTYsNDEsMjA4LDUxLDk0LDEwNSwxODAsMTIyLDE3NywyMjEsMTY5LDcyLDE5OSwxMDIsMTMwLDE3NiwyNTIsMzcsMTI0LDIsMTA3LDIzOSwyMCwyNDYsMjhdfX19LCJleHRlcm5hbF9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzksMTg0LDE1NiwyNSw3MSw5MSwxMzMsMjEwLDg0LDEyNywxNzMsMjE2LDIwOCwyMTgsNTYsMzcsMjEyLDIyLDIwLDIyMSw1NiwxNiwzNCw3NCwxNzksODcsMjI3LDIzNiw5OCw1NiwxMjYsNTVdfX19LCJyZXN1bXB0aW9uX3BzayI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTUsMjIyLDYsMTU1LDc5LDk1LDE0MCwzMiwxNjcsMTY3LDEzMywyMCwxNTQsNiw0Myw0NSwxNTYsMTk0LDIxLDE1MywxMzIsMTk5LDEyNywxNjMsMTM2LDMsMTgwLDE5NSwwLDkzLDIyLDE3Ml19fX19LCJtZXNzYWdlX3NlY3JldHMiOnsic2VuZGVyX2RhdGFfc2VjcmV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMDYsMzYsMTA2LDE2NCwxMDQsMjI3LDE0MywxMzQsMjEwLDEzMCwyMjMsMTQxLDE2MSwxOTMsMTE0LDIzMSwxMjQsMTksMzgsMjQ3LDE4NiwxMjUsMTAxLDE0LDIwMiwxNTYsNTQsMTAsMTMyLDQwLDIxMCwyMzldfX19LCJtZW1iZXJzaGlwX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTI4LDE0Niw4OSwxNDEsOTUsMTQzLDI0OCwxNSw3NCw1MSwxOCwyMjgsODEsMTgxLDIzNyw5OSwyNDQsMTc3LDE3NCwxNzEsMTE0LDk4LDEzNSwzNCwyMzcsMzYsNzEsNDUsMjIwLDgzLDg0LDM3XX19fSwiY29uZmlybWF0aW9uX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbNTQsMjUwLDE3NCwxNjMsMTU0LDIzNiwxOTksMTE5LDE3NCwxMzcsNywyMzMsMjA3LDEzNSwxNDQsMzEsMTM3LDIzNSwyNDMsMTkwLDI0OSwyNiwxMjgsMjI2LDEzMiw4OSwxMjksNzYsMjMwLDE3OCw3Niw4MV19fX0sInNlcmlhbGl6ZWRfY29udGV4dCI6WzAsMSwwLDMsMTYsMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjIsMCwwLDAsMCwwLDAsMCwxLDMyLDQ3LDIzOCwyNiwyNTEsODQsMTIwLDEzNCw5MywxMSw2LDYyLDIsMTYxLDgsMTUxLDU3LDE0MCwxNTgsMTU2LDEwMCwxODQsMTYxLDg1LDI0NCwyMjEsNzEsMTQ1LDIxOCwxMywxMCwxNTYsOTcsMzIsNCwxMDksMzMsMTg5LDE3OCwxNjAsMTAyLDIxMiwyOSwxODUsMTMzLDEwNCwyMzYsMTE1LDE3LDUxLDE3OSwxNzIsMzcsNDAsMTIwLDE0OCw3NCwyNTMsMjU1LDIyNywxMjcsMjA3LDEzMiw5OSwxMzksMTQ5LDBdLCJzZWNyZXRfdHJlZSI6eyJvd25faW5kZXgiOjAsImxlYWZfbm9kZXMiOltudWxsLG51bGxdLCJwYXJlbnRfbm9kZXMiOlt7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNzYsMzMsMjMsMjQ0LDQ3LDE4MywxODMsODksMjE1LDEwMiw1NSwyMjYsMjA5LDQ1LDY2LDI2LDUzLDEzOSwyMzIsMTIyLDUwLDYxLDE4OCw5MywyNSwxMjAsMTkyLDU1LDE4MCw0MCw3Niw4Nl19fX0sbnVsbF0sImhhbmRzaGFrZV9zZW5kZXJfcmF0Y2hldHMiOltudWxsLG51bGxdLCJhcHBsaWNhdGlvbl9zZW5kZXJfcmF0Y2hldHMiOltudWxsLG51bGxdLCJzaXplIjozfX0sInN0YWdlZF9kaWZmIjp7InN0YWdlZF9kaWZmIjp7ImRpZmYiOnsibGVhZl9kaWZmIjp7IjAiOnsibm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxNjYsMjM5LDI1LDE5NCwyMTUsMTE3LDk3LDIzOSwwLDIyNCwxOSw1MiwxMjYsMjAyLDEwOSwyNTQsMjMsMTM2LDE1NiwzOSwxNjEsMTMzLDk1LDM4LDM1LDEyMywxMjQsMTM4LDI1LDIzNiw4OCwxMDBdfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbMTg4LDI5LDI0NywyNDUsODUsMTcxLDE3Niw1NiwxMSw0MSw4OCwxODcsNzEsMjM3LDk4LDEwOCw2LDQwLDE3MiwyMjMsMTI5LDE4OSwxOTIsOTEsMjM2LDI3LDk0LDIyNCwxNzQsMTUyLDExNyw2N119fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJDb21taXQiOnsidmVjIjpbMTM5LDE2OCwyMjcsMTY1LDg0LDM1LDE2NCwxODYsNjcsMjUwLDE4NSw1Myw5Nyw5OCwyMjAsMjI3LDQ1LDc0LDk5LDQxLDM3LDU3LDE3NywxMTgsMjU0LDUxLDM2LDEzMCw2NCwyMiw3Nyw3NF19fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNjgsMTAxLDE2NCwyNDksMTIxLDcyLDUxLDE2MCw5MSwyMSw5MywxNDgsNiw2MCwxMTAsMjEsNjEsMTc4LDk2LDMwLDIwNywxMTIsMjAxLDIwNiwyNDgsMTg5LDE4OSwxMiw2MywxOCwxMywyMzMsMTAxLDIxNyw4NSw4NCwyMzYsNTEsNDgsNDgsOTIsODIsMTE2LDc2LDE1NywyMzUsMjE4LDE4NCw4OSwzLDY5LDQzLDI0NywxMzcsMTUwLDEyNywxMSw5NiwxNzIsMTMwLDE1Miw5OCw2MiwxXX19fX0sIjEiOnsibm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOls3MSwxMCw2OSwyMCwyLDkyLDcwLDg5LDIyNCw0OCwxMjYsNzgsMTI0LDE4NiwxNDgsMTU5LDI0NSwxNzUsMTIyLDE1NSwxNiwyMDksMTUzLDIxNiwyMiwxNDEsMTE3LDc1LDk3LDcyLDI0NywzNl19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMTYsMTEwLDE2LDkxLDk5LDQ0LDE3MCwxMjEsMTY0LDEwMiwxMjMsMTIzLDExNCwyMzksNzIsMTk2LDY5LDUsNTgsODcsMjU0LDQ1LDEwNywyMjksMTgyLDQyLDI5LDEzNSw3Niw4MywxOTcsMTk0XX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTgsMTExLDk4XX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJLZXlQYWNrYWdlIjp7Im5vdF9iZWZvcmUiOjE3MjA2ODg5NDksIm5vdF9hZnRlciI6MTcyNzk1MDE0OX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzI4LDE1NCwxOCw1NCwxMjQsMjMxLDI3LDE3MiwxOTIsMTA0LDE4Nyw5OCwxODUsNDQsMSwxNTgsMjA5LDIxMywyNDAsMTc5LDE4NCwyMDQsMTQ0LDEwNywxMjksMjEsMSw4Nyw2OSwxNTcsMTEyLDIwNywyMTQsMjA1LDEzMSwxMzcsNiwzNSwyMTcsMjI5LDE5NSw1NiwxMDksMTYyLDk2LDg5LDE3NiwyOCwxNzYsMjQsMTgsMTc0LDU5LDE0NSwxMzUsMjQ3LDIzMSwxNzAsMzMsMjA5LDQ3LDI1NSw1Myw3XX19fX19LCJwYXJlbnRfZGlmZiI6eyIwIjp7Im5vZGUiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzEzLDE4MSw2MiwxNTksMjcsMjU1LDI0MywyMTEsMjQ3LDUyLDI0NywxMzgsMzcsMjU1LDYwLDMwLDEyNCw1MCw2NCw3OSwyNDEsMjIxLDE1NSwzNSwyMDYsMjI5LDE0MCw3MywxOCwyNDYsMjQ2LDg1XX19LCJwYXJlbnRfaGFzaCI6eyJ2ZWMiOltdfSwidW5tZXJnZWRfbGVhdmVzIjp7Imxpc3QiOltdfX19fSwic2l6ZSI6M30sIm5ld190cmVlX2hhc2giOls0NywyMzgsMjYsMjUxLDg0LDEyMCwxMzQsOTMsMTEsNiw2MiwyLDE2MSw4LDE1MSw1NywxNDAsMTU4LDE1NiwxMDAsMTg0LDE2MSw4NSwyNDQsMjIxLDcxLDE0NSwyMTgsMTMsMTAsMTU2LDk3XX0sImdyb3VwX2NvbnRleHQiOnsicHJvdG9jb2xfdmVyc2lvbiI6Ik1sczEwIiwiY2lwaGVyc3VpdGUiOiJNTFNfMTI4X0RIS0VNWDI1NTE5X0NIQUNIQTIwUE9MWTEzMDVfU0hBMjU2X0VkMjU1MTkiLCJncm91cF9pZCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fSwiZXBvY2giOjEsInRyZWVfaGFzaCI6eyJ2ZWMiOls0NywyMzgsMjYsMjUxLDg0LDEyMCwxMzQsOTMsMTEsNiw2MiwyLDE2MSw4LDE1MSw1NywxNDAsMTU4LDE1NiwxMDAsMTg0LDE2MSw4NSwyNDQsMjIxLDcxLDE0NSwyMTgsMTMsMTAsMTU2LDk3XX0sImNvbmZpcm1lZF90cmFuc2NyaXB0X2hhc2giOnsidmVjIjpbNCwxMDksMzMsMTg5LDE3OCwxNjAsMTAyLDIxMiwyOSwxODUsMTMzLDEwNCwyMzYsMTE1LDE3LDUxLDE3OSwxNzIsMzcsNDAsMTIwLDE0OCw3NCwyNTMsMjU1LDIyNywxMjcsMjA3LDEzMiw5OSwxMzksMTQ5XX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJpbnRlcmltX3RyYW5zY3JpcHRfaGFzaCI6WzE5MSw0NywzNywxNzAsMTkxLDE4NSwxOTgsOTEsMjUzLDIzMywzMSwzNyw5OCw3MSwxMTQsMjA2LDI2LDE4LDU4LDM1LDI0MCw0NCwxODAsNzIsMTcsMTQyLDIwNSwxMjAsMTk0LDE0NSwyMzQsMjQ4XSwiY29uZmlybWF0aW9uX3RhZyI6eyJtYWNfdmFsdWUiOnsidmVjIjpbMTAwLDk5LDIxMyw5MCw1OCwyNTIsMTcsMTE1LDE3MSwyLDEwMSwyNDMsNDQsMjIxLDg2LDE5Niw4Miw1MiwxNjIsMTY3LDExMiw3Myw2LDEzMyw5MCw4MywyNiwxOSwyMjEsMTUsMjA0LDE5MV19fX0sIm5ld19rZXlwYWlycyI6W3sicHVibGljX2tleSI6eyJrZXkiOnsidmVjIjpbMTY2LDIzOSwyNSwxOTQsMjE1LDExNyw5NywyMzksMCwyMjQsMTksNTIsMTI2LDIwMiwxMDksMjU0LDIzLDEzNiwxNTYsMzksMTYxLDEzMyw5NSwzOCwzNSwxMjMsMTI0LDEzOCwyNSwyMzYsODgsMTAwXX19LCJwcml2YXRlX2tleSI6eyJrZXkiOnsidmVjIjpbMjQ2LDk4LDEzOCw3LDIsMjIsNDQsMTYxLDE1MSwxMjQsNDksMTMwLDE2OCwxOSwxMzEsNzMsMTQ4LDIzMCwxMTAsNTksMTc4LDk3LDIyLDE2NywyNDIsODUsMjM0LDEwMSw2Myw1OCwyMzksMjQ0XX19fSx7InB1YmxpY19rZXkiOnsia2V5Ijp7InZlYyI6WzEzLDE4MSw2MiwxNTksMjcsMjU1LDI0MywyMTEsMjQ3LDUyLDI0NywxMzgsMzcsMjU1LDYwLDMwLDEyNCw1MCw2NCw3OSwyNDEsMjIxLDE1NSwzNSwyMDYsMjI5LDE0MCw3MywxOCwyNDYsMjQ2LDg1XX19LCJwcml2YXRlX2tleSI6eyJrZXkiOnsidmVjIjpbMjcsMjI5LDE0Miw4MywzNCwxNDEsMzAsNjIsMTE1LDEzLDE5MCw3OCw4MSwxNTEsOTgsMTgsMjksNTQsMjE4LDYxLDYwLDIzMCwzMyw3OCwxMzQsMTk5LDExOCw2MiwxOTUsMjQyLDEyNiwyMzNdfX19XSwibmV3X2xlYWZfa2V5cGFpcl9vcHRpb24iOm51bGwsInVwZGF0ZV9wYXRoX2xlYWZfbm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxNjYsMjM5LDI1LDE5NCwyMTUsMTE3LDk3LDIzOSwwLDIyNCwxOSw1MiwxMjYsMjAyLDEwOSwyNTQsMjMsMTM2LDE1NiwzOSwxNjEsMTMzLDk1LDM4LDM1LDEyMywxMjQsMTM4LDI1LDIzNiw4OCwxMDBdfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbMTg4LDI5LDI0NywyNDUsODUsMTcxLDE3Niw1NiwxMSw0MSw4OCwxODcsNzEsMjM3LDk4LDEwOCw2LDQwLDE3MiwyMjMsMTI5LDE4OSwxOTIsOTEsMjM2LDI3LDk0LDIyNCwxNzQsMTUyLDExNyw2N119fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJDb21taXQiOnsidmVjIjpbMTM5LDE2OCwyMjcsMTY1LDg0LDM1LDE2NCwxODYsNjcsMjUwLDE4NSw1Myw5Nyw5OCwyMjAsMjI3LDQ1LDc0LDk5LDQxLDM3LDU3LDE3NywxMTgsMjU0LDUxLDM2LDEzMCw2NCwyMiw3Nyw3NF19fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNjgsMTAxLDE2NCwyNDksMTIxLDcyLDUxLDE2MCw5MSwyMSw5MywxNDgsNiw2MCwxMTAsMjEsNjEsMTc4LDk2LDMwLDIwNywxMTIsMjAxLDIwNiwyNDgsMTg5LDE4OSwxMiw2MywxOCwxMywyMzMsMTAxLDIxNyw4NSw4NCwyMzYsNTEsNDgsNDgsOTIsODIsMTE2LDc2LDE1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ZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzEyMSwxMTEsMTE4LDEyOSwyMDYsNzIsMTQsMjE0LDEyOCwxMjYsMTE4LDIzOSwxNCwxNzMsMjU1LDI1MywxMzgsMzksOSwxMywxNjQsMTQ1LDE2MSwyMzAsMTU0LDMzLDE3MiwyNTIsMjI3LDg5LDU4LDgwXX19fSwiY29uZmlybWF0aW9uX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbNzcsMTMxLDE0MiwyMzIsMTE1LDAsMTE1LDkwLDgwLDI0MywyNTEsMTIsMTI1LDQ3LDExNSwxNDksMTY1LDI0Myw2NCwxMSwxOTksOTUsMTU0LDE0LDE2MywxMjUsMTU3LDIwMiwxNjYsMTg0LDE4OSwxMDZdfX19LCJzZXJpYWxpemVkX2NvbnRleHQiOlswLDEsMCwzLDE2LDIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyLDAsMCwwLDAsMCwwLDAsMCwzMiwxNDQsMjQ0LDY3LDc2LDQzLDE4LDE2OSwxMjEsMjQ0LDIwNywyMDgsODMsMjAwLDQ3LDIyMiwxNzgsMTkzLDE1NCwxMzQsMjE4LDEwNiwyMzQsMTA1LDE5MCwxMjQsMjAwLDM5LDkxLDE2NCwxMzEsMTI4LDExNiwwLDBdLCJzZWNyZXRfdHJlZSI6eyJvd25faW5kZXgiOjAsImxlYWZfbm9kZXMiOltudWxsXSwicGFyZW50X25vZGVzIjpbbnVsbF0sImhhbmRzaGFrZV9zZW5kZXJfcmF0Y2hldHMiOlt7IkVuY3J5cHRpb25SYXRjaGV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlszNywxODEsMTczLDAsMzcsMTU2LDY1LDk1LDE0NSwxNiwxMTQsMTM4LDExNiwyMzEsMzksMTg5LDE0MywzMiw4LDExLDEyLDExNywxNDIsMTYyLDExOCw1MCwxNzQsOTgsMTQyLDEyLDIwNSwxNDNdfX0sImdlbmVyYXRpb24iOjF9fV0sImFwcGxpY2F0aW9uX3NlbmRlcl9yYXRjaGV0cyI6W3siRW5jcnlwdGlvblJhdGNoZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzY2LDEzOCw5MiwxOTAsMTY2LDMwLDIxMyw4MCw4NSwxMTksMjI5LDM1LDEzOCw1OCwxNDMsNjAsMjIwLDg0LDE5Niw1MywxNiwxMSw3LDIxNSwxNTAsMjQxLDEyMiwxODQsMTUwLDExMCwxOTksNDldfX0sImdlbmVyYXRpb24iOjB9fV0sInNpemUiOjF9fX0AAAAAAAAAXgAAAAAAAAABT3duTGVhZk5vZGVJbmRleHsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AATAAAAAAAAAAWgAAAAAAAAGSR3JvdXBDb250ZXh0eyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJwcm90b2NvbF92ZXJzaW9uIjoiTWxzMTAiLCJjaXBoZXJzdWl0ZSI6Ik1MU18xMjhfREhLRU1YMjU1MTlfQ0hBQ0hBMjBQT0xZMTMwNV9TSEEyNTZfRWQyNTUxOSIsImdyb3VwX2lkIjp7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19LCJlcG9jaCI6MCwidHJlZV9oYXNoIjp7InZlYyI6WzE0NCwyNDQsNjcsNzYsNDMsMTgsMTY5LDEyMSwyNDQsMjA3LDIwOCw4MywyMDAsNDcsMjIyLDE3OCwxOTMsMTU0LDEzNCwyMTgsMTA2LDIzNCwxMDUsMTkwLDEyNCwyMDAsMzksOTEsMTY0LDEzMSwxMjgsMTE2XX0sImNvbmZpcm1lZF90cmFuc2NyaXB0X2hhc2giOnsidmVjIjpbXX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19AAAAAAAAAGMAAAAAAAAAeUludGVyaW1UcmFuc2NyaXB0SGFzaHsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAVsyMjUsMTk3LDY3LDU3LDI0MSw3NywxNjgsMjQ1LDkxLDE0MywxNDQsODEsMTc3LDE1NiwxMzEsMTYsOTcsMjEwLDI0MiwxNzQsMTg0LDEyNiwxODAsMTc0LDIxMywyNDUsMTQyLDIyMywyMDYsMjUsMTc4LDEzNV0AAAAAAAAAYAAAAAAAAAEWTWxzR3JvdXBKb2luQ29uZmlneyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJ3aXJlX2Zvcm1hdF9wb2xpY3kiOnsib3V0Z29pbmciOiJBbHdheXNDaXBoZXJ0ZXh0IiwiaW5jb21pbmciOiJBbHdheXNDaXBoZXJ0ZXh0In0sInBhZGRpbmdfc2l6ZSI6MCwibWF4X3Bhc3RfZXBvY2hzIjowLCJudW1iZXJfb2ZfcmVzdW1wdGlvbl9wc2tzIjowLCJ1c2VfcmF0Y2hldF90cmVlX2V4dGVuc2lvbiI6ZmFsc2UsInNlbmRlcl9yYXRjaGV0X2NvbmZpZ3VyYXRpb24iOnsib3V0X29mX29yZGVyX3RvbGVyYW5jZSI6NSwibWF4aW11bV9mb3J3YXJkX2Rpc3RhbmNlIjoxMDAwfX0AAAAAAAAAWgAAAAAAAAM2RXBvY2hTZWNyZXRzeyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJpbml0X3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTQwLDE1MSwyMSwxMTEsNzMsMTE3LDE5NCwxMTMsNjMsMTY2LDIwOSw1NiwxMTEsMzgsMTQyLDEyOCwyMCwxMDQsMjUxLDI0OSw1NywyOSwyMiw5NCwxODQsNDQsMTI5LDEyOCwxODgsMjA3LDExOCwxMzRdfX19LCJleHBvcnRlcl9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE3OCw0MCwyNDAsMTc4LDEsNzMsMTYwLDc4LDEyMiwyMzEsMTYzLDQ3LDc5LDE1Myw3OSwxNDQsMjIsMSwxOTEsMjI5LDc2LDI0MCw2NSw2MCwyNTMsODEsODEsMTM1LDE1NiwyMDEsMTE1LDE0NV19fX0sImVwb2NoX2F1dGhlbnRpY2F0b3IiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE1NSw3NiwxMTQsMjMyLDEzNSwyMjksMzIsMTksMjI0LDE2MiwxMjgsMjM4LDIzMSwxNjIsMTEyLDU2LDk5LDExNSwxMTYsMjU1LDQ2LDkyLDE4MSwyMDAsMTE0LDIzMywxMCwxNTAsNTksMTgzLDI0MCw5OF19fX0sImV4dGVybmFsX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTAwLDQ3LDI0NywyNDEsNjUsMTM5LDI0OCwyMzMsMjA0LDE1OSw4MywxNDMsMTcxLDc5LDI0OCw0NSwxNTEsODgsMjAsMTUzLDE4MiwxNTYsMTgsMTI5LDE5MywyMzUsMTM5LDEyMiwzMywxNDUsODQsMTQ5XX19fSwicmVzdW1wdGlvbl9wc2siOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE2NSw1Myw0MiwyNyw0LDYyLDg1LDEwNCwxNjYsNzMsMTk5LDIxNSwxMzEsMywxNDcsMjUwLDkyLDE0Nyw2MCw4NSwxMzgsMTAwLDEzNywxMzgsNzQsMTQyLDEwNSwyMDgsMTIyLDkyLDEzOSw0NF19fX19AAAAAAAAAOUAAAAAAAABGFNpZ25hdHVyZUtleVBhaXJ7InZhbHVlIjpbMTg4LDI5LDI0NywyNDUsODUsMTcxLDE3Niw1NiwxMSw0MSw4OCwxODcsNzEsMjM3LDk4LDEwOCw2LDQwLDE3MiwyMjMsMTI5LDE4OSwxOTIsOTEsMjM2LDI3LDk0LDIyNCwxNzQsMTUyLDExNyw2Nyw4MiwxMTcsMTE1LDExNiw2NywxMTQsMTIxLDExMiwxMTYsMTExLDgzLDEwNSwxMDMsMTEwLDk3LDExNiwxMTcsMTE0LDEwMSw3NSwxMDEsMTIxLDgsN119AAF7InByaXZhdGUiOls3MCwyMTMsNjksMjI1LDg3LDM5LDE0MSwxMTcsMTEyLDE3LDQyLDU3LDIwNCwxNywxMzgsMzUsNzUsOTEsMTU5LDc1LDE1MiwyMjAsMTE3LDEwLDIxNywyMDAsMTQxLDE3MCwxODQsNzQsMjI4LDIwNl0sInB1YmxpYyI6WzE4OCwyOSwyNDcsMjQ1LDg1LDE3MSwxNzYsNTYsMTEsNDEsODgsMTg3LDcxLDIzNyw5OCwxMDgsNiw0MCwxNzIsMjIzLDEyOSwxODksMTkyLDkxLDIzNiwyNyw5NCwyMjQsMTc0LDE1MiwxMTcsNjddLCJzaWduYXR1cmVfc2NoZW1lIjoiRUQyNTUxOSJ9","AAAAAAAAAA0AAAAAAAAAWwAAAAAAAAFeUmVzdW1wdGlvblBza3sidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsibWF4X251bWJlcl9vZl9zZWNyZXRzIjozMiwicmVzdW1wdGlvbl9wc2siOltbMCx7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNjUsNTMsNDIsMjcsNCw2Miw4NSwxMDQsMTY2LDczLDE5OSwyMTUsMTMxLDMsMTQ3LDI1MCw5MiwxNDcsNjAsODUsMTM4LDEwMCwxMzcsMTM4LDc0LDE0MiwxMDUsMjA4LDEyMiw5MiwxMzksNDRdfX19XSxbMSx7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNSwyMjIsNiwxNTUsNzksOTUsMTQwLDMyLDE2NywxNjcsMTMzLDIwLDE1NCw2LDQzLDQ1LDE1NiwxOTQsMjEsMTUzLDEzMiwxOTksMTI3LDE2MywxMzYsMywxODAsMTk1LDAsOTMsMjIsMTcyXX19fV1dLCJjdXJzb3IiOjJ9AAAAAAAAAF0AAAAAAAAAhUNvbmZpcm1hdGlvblRhZ3sidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsibWFjX3ZhbHVlIjp7InZlYyI6WzEwMCw5OSwyMTMsOTAsNTgsMjUyLDE3LDExNSwxNzEsMiwxMDEsMjQzLDQ0LDIyMSw4NiwxOTYsODIsNTIsMTYyLDE2NywxMTIsNzMsNiwxMzMsOTAsODMsMjYsMTksMjIxLDE1LDIwNCwxOTFdfX0AAAAAAAAAWAAAAAAAAAANR3JvdXBTdGF0ZXsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AASJPcGVyYXRpb25hbCIAAAAAAAAAXQAAAAAAAAJHRXBvY2hLZXlQYWlyc3sidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0xMAABW3sicHVibGljX2tleSI6eyJrZXkiOnsidmVjIjpbMTY2LDIzOSwyNSwxOTQsMjE1LDExNyw5NywyMzksMCwyMjQsMTksNTIsMTI2LDIwMiwxMDksMjU0LDIzLDEzNiwxNTYsMzksMTYxLDEzMyw5NSwzOCwzNSwxMjMsMTI0LDEzOCwyNSwyMzYsODgsMTAwXX19LCJwcml2YXRlX2tleSI6eyJrZXkiOnsidmVjIjpbMjQ2LDk4LDEzOCw3LDIsMjIsNDQsMTYxLDE1MSwxMjQsNDksMTMwLDE2OCwxOSwxMzEsNzMsMTQ4LDIzMCwxMTAsNTksMTc4LDk3LDIyLDE2NywyNDIsODUsMjM0LDEwMSw2Myw1OCwyMzksMjQ0XX19fSx7InB1YmxpY19rZXkiOnsia2V5Ijp7InZlYyI6WzEzLDE4MSw2MiwxNTksMjcsMjU1LDI0MywyMTEsMjQ3LDUyLDI0NywxMzgsMzcsMjU1LDYwLDMwLDEyNCw1MCw2NCw3OSwyNDEsMjIxLDE1NSwzNSwyMDYsMjI5LDE0MCw3MywxOCwyNDYsMjQ2LDg1XX19LCJwcml2YXRlX2tleSI6eyJrZXkiOnsidmVjIjpbMjcsMjI5LDE0Miw4MywzNCwxNDEsMzAsNjIsMTE1LDEzLDE5MCw3OCw4MSwxNTEsOTgsMTgsMjksNTQsMjE4LDYxLDYwLDIzMCwzMyw3OCwxMzQsMTk5LDExOCw2MiwxOTUsMjQyLDEyNiwyMzNdfX19XQAAAAAAAABSAAAAAAAACStUcmVleyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJ0cmVlIjp7ImxlYWZfbm9kZXMiOlt7Im5vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbMTY2LDIzOSwyNSwxOTQsMjE1LDExNyw5NywyMzksMCwyMjQsMTksNTIsMTI2LDIwMiwxMDksMjU0LDIzLDEzNiwxNTYsMzksMTYxLDEzMyw5NSwzOCwzNSwxMjMsMTI0LDEzOCwyNSwyMzYsODgsMTAwXX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6WzE4OCwyOSwyNDcsMjQ1LDg1LDE3MSwxNzYsNTYsMTEsNDEsODgsMTg3LDcxLDIzNyw5OCwxMDgsNiw0MCwxNzIsMjIzLDEyOSwxODksMTkyLDkxLDIzNiwyNyw5NCwyMjQsMTc0LDE1MiwxMTcsNjddfX0sImNyZWRlbnRpYWwiOnsiY3JlZGVudGlhbF90eXBlIjoiQmFzaWMiLCJzZXJpYWxpemVkX2NyZWRlbnRpYWxfY29udGVudCI6eyJ2ZWMiOls5NywxMDgsMTA1LDk5LDEwMV19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiQ29tbWl0Ijp7InZlYyI6WzEzOSwxNjgsMjI3LDE2NSw4NCwzNSwxNjQsMTg2LDY3LDI1MCwxODUsNTMsOTcsOTgsMjIwLDIyNyw0NSw3NCw5OSw0MSwzNyw1NywxNzcsMTE4LDI1NCw1MSwzNiwxMzAsNjQsMjIsNzcsNzRdfX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbMTY4LDEwMSwxNjQsMjQ5LDEyMSw3Miw1MSwxNjAsOTEsMjEsOTMsMTQ4LDYsNjAsMTEwLDIxLDYxLDE3OCw5NiwzMCwyMDcsMTEyLDIwMSwyMDYsMjQ4LDE4OSwxODksMTIsNjMsMTgsMTMsMjMzLDEwMSwyMTcsODUsODQsMjM2LDUxLDQ4LDQ4LDkyLDgyLDExNiw3NiwxNTcsMjM1LDIxOCwxODQsODksMyw2OSw0MywyNDcsMTM3LDE1MCwxMjcsMTEsOTYsMTcyLDEzMCwxNTIsOTgsNjIsMV19fX19LHsibm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOls3MSwxMCw2OSwyMCwyLDkyLDcwLDg5LDIyNCw0OCwxMjYsNzgsMTI0LDE4NiwxNDgsMTU5LDI0NSwxNzUsMTIyLDE1NSwxNiwyMDksMTUzLDIxNiwyMiwxNDEsMTE3LDc1LDk3LDcyLDI0NywzNl19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMTYsMTEwLDE2LDkxLDk5LDQ0LDE3MCwxMjEsMTY0LDEwMiwxMjMsMTIzLDExNCwyMzksNzIsMTk2LDY5LDUsNTgsODcsMjU0LDQ1LDEwNywyMjksMTgyLDQyLDI5LDEzNSw3Niw4MywxOTcsMTk0XX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTgsMTExLDk4XX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJLZXlQYWNrYWdlIjp7Im5vdF9iZWZvcmUiOjE3MjA2ODg5NDksIm5vdF9hZnRlciI6MTcyNzk1MDE0OX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzI4LDE1NCwxOCw1NCwxMjQsMjMxLDI3LDE3MiwxOTIsMTA0LDE4Nyw5OCwxODUsNDQsMSwxNTgsMjA5LDIxMywyNDAsMTc5LDE4NCwyMDQsMTQ0LDEwNywxMjksMjEsMSw4Nyw2OSwxNTcsMTEyLDIwNywyMTQsMjA1LDEzMSwxMzcsNiwzNSwyMTcsMjI5LDE5NSw1NiwxMDksMTYyLDk2LDg5LDE3NiwyOCwxNzYsMjQsMTgsMTc0LDU5LDE0NSwxMzUsMjQ3LDIzMSwxNzAsMzMsMjA5LDQ3LDI1NSw1Myw3XX19fX1dLCJwYXJlbnRfbm9kZXMiOlt7Im5vZGUiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzEzLDE4MSw2MiwxNTksMjcsMjU1LDI0MywyMTEsMjQ3LDUyLDI0NywxMzgsMzcsMjU1LDYwLDMwLDEyNCw1MCw2NCw3OSwyNDEsMjIxLDE1NSwzNSwyMDYsMjI5LDE0MCw3MywxOCwyNDYsMjQ2LDg1XX19LCJwYXJlbnRfaGFzaCI6eyJ2ZWMiOltdfSwidW5tZXJnZWRfbGVhdmVzIjp7Imxpc3QiOltdfX19XSwiZGVmYXVsdF9sZWFmIjp7Im5vZGUiOm51bGx9LCJkZWZhdWx0X3BhcmVudCI6eyJub2RlIjpudWxsfX0sInRyZWVfaGFzaCI6WzQ3LDIzOCwyNiwyNTEsODQsMTIwLDEzNCw5MywxMSw2LDYyLDIsMTYxLDgsMTUxLDU3LDE0MCwxNTgsMTU2LDEwMCwxODQsMTYxLDg1LDI0NCwyMjEsNzEsMTQ1LDIxOCwxMywxMCwxNTYsOTddfQAAAAAAAABcAAAAAAAAAAVVc2VSYXRjaGV0VHJlZXsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAWZhbHNlAAAAAAAAAFwAAAAAAAAEvU1lc3NhZ2VTZWNyZXRzeyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJtYXhfZXBvY2hzIjowLCJwYXN0X2Vwb2NoX3RyZWVzIjpbXSwibWVzc2FnZV9zZWNyZXRzIjp7InNlbmRlcl9kYXRhX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTA2LDM2LDEwNiwxNjQsMTA0LDIyNywxNDMsMTM0LDIxMCwxMzAsMjIzLDE0MSwxNjEsMTkzLDExNCwyMzEsMTI0LDE5LDM4LDI0NywxODYsMTI1LDEwMSwxNCwyMDIsMTU2LDU0LDEwLDEzMiw0MCwyMTAsMjM5XX19fSwibWVtYmVyc2hpcF9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzEyOCwxNDYsODksMTQxLDk1LDE0MywyNDgsMTUsNzQsNTEsMTgsMjI4LDgxLDE4MSwyMzcsOTksMjQ0LDE3NywxNzQsMTcxLDExNCw5OCwxMzUsMzQsMjM3LDM2LDcxLDQ1LDIyMCw4Myw4NCwzN119fX0sImNvbmZpcm1hdGlvbl9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzU0LDI1MCwxNzQsMTYzLDE1NCwyMzYsMTk5LDExOSwxNzQsMTM3LDcsMjMzLDIwNywxMzUsMTQ0LDMxLDEzNywyMzUsMjQzLDE5MCwyNDksMjYsMTI4LDIyNiwxMzIsODksMTI5LDc2LDIzMCwxNzgsNzYsODFdfX19LCJzZXJpYWxpemVkX2NvbnRleHQiOlswLDEsMCwzLDE2LDIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyLDAsMCwwLDAsMCwwLDAsMSwzMiw0NywyMzgsMjYsMjUxLDg0LDEyMCwxMzQsOTMsMTEsNiw2MiwyLDE2MSw4LDE1MSw1NywxNDAsMTU4LDE1NiwxMDAsMTg0LDE2MSw4NSwyNDQsMjIxLDcxLDE0NSwyMTgsMTMsMTAsMTU2LDk3LDMyLDQsMTA5LDMzLDE4OSwxNzgsMTYwLDEwMiwyMTIsMjksMTg1LDEzMywxMDQsMjM2LDExNSwxNyw1MSwxNzksMTcyLDM3LDQwLDEyMCwxNDgsNzQsMjUzLDI1NSwyMjcsMTI3LDIwNywxMzIsOTksMTM5LDE0OSwwXSwic2VjcmV0X3RyZWUiOnsib3duX2luZGV4IjowLCJsZWFmX25vZGVzIjpbbnVsbCxudWxsXSwicGFyZW50X25vZGVzIjpbeyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTc2LDMzLDIzLDI0NCw0NywxODMsMTgzLDg5LDIxNSwxMDIsNTUsMjI2LDIwOSw0NSw2NiwyNiw1MywxMzksMjMyLDEyMiw1MCw2MSwxODgsOTMsMjUsMTIwLDE5Miw1NSwxODAsNDAsNzYsODZdfX19LG51bGxdLCJoYW5kc2hha2Vfc2VuZGVyX3JhdGNoZXRzIjpbbnVsbCxudWxsXSwiYXBwbGljYXRpb25fc2VuZGVyX3JhdGNoZXRzIjpbbnVsbCxudWxsXSwic2l6ZSI6M319fQAAAAAA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YyI6WzE0OCwxMDYsMjUsMTA0LDIwNywxNzMsNTQsODgsMTczLDYwLDE4OCwxODEsMTIsMjUxLDkwLDEzNiwyMTQsMjAyLDIsMTUsMTc4LDUsMTMyLDgsNSw1NywyLDQ1LDY3LDE5NCw3MCw4MV19fV0sInF1ZXVlZF9wcm9wb3NhbHMiOltbeyJ2YWx1ZSI6eyJ2ZWMiOlsxNDgsMTA2LDI1LDEwNCwyMDcsMTczLDU0LDg4LDE3Myw2MCwxODgsMTgxLDEyLDI1MSw5MCwxMzYsMjE0LDIwMiwyLDE1LDE3OCw1LDEzMiw4LDUsNTcsMiw0NSw2NywxOTQsNzAsODFdfX0seyJwcm9wb3NhbCI6eyJHcm91cENvbnRleHRFeHRlbnNpb25zIjp7ImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbeyJSZXF1aXJlZENhcGFiaWxpdGllcyI6eyJleHRlbnNpb25fdHlwZXMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FsX3R5cGVzIjpbXSwiY3JlZGVudGlhbF90eXBlcyI6W119fV19fX0sInByb3Bvc2FsX3JlZmVyZW5jZSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNDgsMTA2LDI1LDEwNCwyMDcsMTczLDU0LDg4LDE3Myw2MCwxODgsMTgxLDEyLDI1MSw5MCwxMzYsMjE0LDIwMiwyLDE1LDE3OCw1LDEzMiw4LDUsNTcsMiw0NSw2NywxOTQsNzAsODFdfX0sInNlbmRlciI6eyJNZW1iZXIiOjB9LCJwcm9wb3NhbF9vcl9yZWZfdHlwZSI6IlByb3Bvc2FsIn1dXX0sInN0YXRlIjp7Ikdyb3VwTWVtYmVyIjp7Imdyb3VwX2Vwb2NoX3NlY3JldHMiOnsiaW5pdF9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzY0LDU0LDE5NCwyMDQsMTY1LDIsMTQwLDExNCwyMTMsNTUsMTc0LDIxOSw1MiwxNzksMywxNzYsMjIwLDYyLDE0OCw1MCwyMjYsNDgsMzEsMTQ0LDI0NCwxMjEsMTM5LDIwNSwxMzcsMTU0LDEyMCwzM119fX0sImV4cG9ydGVyX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTM0LDE2MywzLDI0MSw4MSwxMjksNTIsMTY4LDEzMywyNDIsOTAsMTQwLDEwMSwxNjEsMTgsMywxMzUsMTU5LDUwLDMwLDg3LDI0NSwxOTgsMTk4LDEyOSwyMDIsMTk1LDEzLDksOTIsMjIwLDEzMl19fX0sImVwb2NoX2F1dGhlbnRpY2F0b3IiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzgzLDE5OSwyNiwxMjIsMTYxLDc4LDc4LDI1LDEzMyw2NSw2MiwxMjUsMTksODMsMTE0LDIzNiwxODIsMzksNTIsMjQ1LDQ2LDE3NCwxNDcsMTYxLDQ2LDE4LDIzMywyNDYsNTAsMTEyLDI1MSwxNDldfX19LCJleHRlcm5hbF9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE2Miw0OSwxNDksMTQ2LDE3MCwxNzUsODUsMTE5LDIyOCwyMDAsMTI5LDI0NSwyMTYsMTUzLDE2NSw2MiwxNDcsOTQsMjQ2LDIxMSwxMTIsMjAyLDE2NSwxLDkzLDIzMiw5NSwzMiwyMTcsODEsNjcsM119fX0sInJlc3VtcHRpb25fcHNrIjp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyMywxMDIsMjU1LDcwLDEwLDIwNCwxODMsMjA2LDQ1LDIxMywxOTMsNTksNjMsMjMzLDgwLDgxLDY1LDE5LDExNCw4Nyw2Myw0NywxNzUsMjA2LDQwLDEyNSwxMiwxNTIsMTc0LDc4LDE0NSw0XX19fX0sIm1lc3NhZ2Vfc2VjcmV0cyI6eyJzZW5kZXJfZGF0YV9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE3OCwyMTEsMTM0LDE4Niw0OSwxNDEsNzYsMTcxLDIzOSwxODQsNTMsMzAsNCwxMjEsMjcsODMsMTQyLDgsMjYsMTAxLDE2Miw2OCwxMDUsMTQzLDI4LDU2LDE0LDg5LDIsNTIsMzEsMTBdfX19LCJtZW1iZXJzaGlwX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMiw0MSwyMTAsMjE1LDEyNiwxNzAsMjE3LDU0LDU3LDEzMywxMTcsMTEwLDU4LDIwOSwxOTMsMTU4LDExOSwxMTgsMTUyLDE4LDEwNiw2LDg0LDYyLDIxNywyMywyMjEsNjEsODcsNzcsMTUxLDIyMF19fX0sImNvbmZpcm1hdGlvbl9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzEwNiwyMjAsMTY0LDksMTk3LDgzLDQyLDI1MSw3NywyNTUsNiwxMDEsNCw1OCwyNSw0MCwyLDIyMSwxNTcsNjEsMTQyLDE0MSw1LDQzLDEwMCwyMTQsNzEsOTksMTY5LDEyNiw4MSwxNDZdfX19LCJzZXJpYWxpemVkX2NvbnRleHQiOlswLDEsMCwzLDE2LDIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyLDAsMCwwLDAsMCwwLDAsMiwzMiwxMDcsMjE0LDcyLDE4OSwyMzksMTcsNjksMzAsMjQzLDE5NCw2NCw1NywyMjcsNjEsMTkxLDIzNSwyMzQsMTAyLDEwNSwyMTAsMTQ4LDI0MiwxMjgsMTY5LDExLDI1NCw5OSwzMSwxNzgsMzIsNiwyNDIsMzIsNjgsMTg2LDE3OSwxOTUsMywxNDMsMjI2LDE5NCwxOTQsMjM4LDYyLDI0OSwxNjcsMTE4LDE5OSwxMDksMTEzLDIyMiwxNDUsMjMxLDEsMTA4LDEyNCw1MCwxMTcsNTMsODEsMTIyLDE3NSw5MywyMDYsMjAxLDgsMCwzLDUsMiwyNDAsNjYsMCwwXSwic2VjcmV0X3RyZWUiOnsib3duX2luZGV4IjowLCJsZWFmX25vZGVzIjpbbnVsbCxudWxsXSwicGFyZW50X25vZGVzIjpbeyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbOTksMTExLDI0MCw3OSwyNTMsMjE5LDE2NCwyMiwxNjIsNiwxOTQsNjcsMTkwLDI1LDE5OCwyMjcsMTcwLDIwOSwyNTMsMTEzLDEyOCwxNDMsODQsMTIwLDIyMCwxNTEsMjQ3LDYzLDU0LDEzMSwxMDAsMTkwXX19fSxudWxsXSwiaGFuZHNoYWtlX3NlbmRlcl9yYXRjaGV0cyI6W251bGwsbnVsbF0sImFwcGxpY2F0aW9uX3NlbmRlcl9yYXRjaGV0cyI6W251bGwsbnVsbF0sInNpemUiOjN9fSwic3RhZ2VkX2RpZmYiOnsic3RhZ2VkX2RpZmYiOnsiZGlmZiI6eyJsZWFmX2RpZmYiOnsiMCI6eyJub2RlIjp7InBheWxvYWQiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzE1LDI1Miw3MiwxMTAsOTIsNTQsODksMzIsMjQwLDEzMSw2NiwxNTcsOTgsMTcwLDI0NCw2Niw3MiwxOTEsNDksMjAyLDE5NiwxNjEsMTczLDE3LDIyMiwxNDIsNjQsMjMxLDE4NywxNzIsMTY5LDE3XX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6WzE4OCwyOSwyNDcsMjQ1LDg1LDE3MSwxNzYsNTYsMTEsNDEsODgsMTg3LDcxLDIzNyw5OCwxMDgsNiw0MCwxNzIsMjIzLDEyOSwxODksMTkyLDkxLDIzNiwyNyw5NCwyMjQsMTc0LDE1MiwxMTcsNjddfX0sImNyZWRlbnRpYWwiOnsiY3JlZGVudGlhbF90eXBlIjoiQmFzaWMiLCJzZXJpYWxpemVkX2NyZWRlbnRpYWxfY29udGVudCI6eyJ2ZWMiOls5NywxMDgsMTA1LDk5LDEwMV19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiQ29tbWl0Ijp7InZlYyI6WzI1MCwyMDIsMTk5LDEzNCwxMDEsMTYxLDIzNCwxNzEsNDYsMTI4LDIzMCw0MSwxNjQsMTAzLDQ2LDE0OCwyMTQsNTMsMjQ0LDQsMTU1LDE4LDY5LDE1Miw3MSwzMSwzNiwxNiwxMzEsMTksOTMsMjAxXX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzY0LDE3OCwyMTYsMTQwLDIwNyw1Miw2MCwyNTAsMzEsMTI2LDIwOCw1OSw3NCwxMzksMTA3LDE5NCw1LDI0Miw2Nyw2MSwxMDQsMjcsNTEsMTUsMTk2LDIyOSwyNDQsODEsNTUsMzksOTYsNzIsOTgsMzIsMTU4LDE5OSw2LDE2MywyMjAsMzgsMTM4LDMzLDEwNCwxNiwxNDUsMzAsNjAsNzYsNzEsMTk4LDk5LDQ4LDIwNCwxMDEsMTIxLDE4LDExNSwyMDEsMTk1LDE1LDU4LDU1LDEzOSwxMV19fX19fSwicGFyZW50X2RpZmYiOnsiMCI6eyJub2RlIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxNzEsMTgwLDIyOCwxODgsMTA0LDIwMSwxOTQsMTcxLDM0LDIxNSwyMDcsMjQ3LDI0MCw4NywyMiwxNjIsNTEsMjE2LDEwLDE5NCw0MCw0OSwxNzcsMTk2LDE1NiwyMjMsMTI4LDIwLDIwOCwxMzQsMjE0LDc2XX19LCJwYXJlbnRfaGFzaCI6eyJ2ZWMiOltdfSwidW5tZXJnZWRfbGVhdmVzIjp7Imxpc3QiOltdfX19fSwic2l6ZSI6M30sIm5ld190cmVlX2hhc2giOlsxMDcsMjE0LDcyLDE4OSwyMzksMTcsNjksMzAsMjQzLDE5NCw2NCw1NywyMjcsNjEsMTkxLDIzNSwyMzQsMTAyLDEwNSwyMTAsMTQ4LDI0MiwxMjgsMTY5LDExLDI1NCw5OSwzMSwxNzgsMzIsNiwyNDJdfSwiZ3JvdXBfY29udGV4dCI6eyJwcm90b2NvbF92ZXJzaW9uIjoiTWxzMTAiLCJjaXBoZXJzdWl0ZSI6Ik1MU18xMjhfREhLRU1YMjU1MTlfQ0hBQ0hBMjBQT0xZMTMwNV9TSEEyNTZfRWQyNTUxOSIsImdyb3VwX2lkIjp7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19LCJlcG9jaCI6MiwidHJlZV9oYXNoIjp7InZlYyI6WzEwNywyMTQsNzIsMTg5LDIzOSwxNyw2OSwzMCwyNDMsMTk0LDY0LDU3LDIyNyw2MSwxOTEsMjM1LDIzNCwxMDIsMTA1LDIxMCwxNDgsMjQyLDEyOCwxNjksMTEsMjU0LDk5LDMxLDE3OCwzMiw2LDI0Ml19LCJjb25maXJtZWRfdHJhbnNjcmlwdF9oYXNoIjp7InZlYyI6WzY4LDE4NiwxNzksMTk1LDMsMTQzLDIyNiwxOTQsMTk0LDIzOCw2MiwyNDksMTY3LDExOCwxOTksMTA5LDExMywyMjIsMTQ1LDIzMSwxLDEwOCwxMjQsNTAsMTE3LDUzLDgxLDEyMiwxNzUsOTMsMjA2LDIwMV19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W3siUmVxdWlyZWRDYXBhYmlsaXRpZXMiOnsiZXh0ZW5zaW9uX3R5cGVzIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbF90eXBlcyI6W10sImNyZWRlbnRpYWxfdHlwZXMiOltdfX1dfX0sImludGVyaW1fdHJhbnNjcmlwdF9oYXNoIjpbNjgsMTQyLDIwLDQ3LDIxNywxODUsMTcxLDE3MywxNDksMzIsMTQ4LDExMywxNzcsMTg4LDE1NCwxNjAsNjMsMTAyLDEzNiwyMDcsNjUsNDAsMzYsMjI3LDE3NywyNDYsNzMsMTA5LDExNSw1NywxNywxMDhdLCJjb25maXJtYXRpb25fdGFnIjp7Im1hY192YWx1ZSI6eyJ2ZWMiOlsxOTYsMjAwLDg2LDI1NCwxMDIsMTk1LDgwLDY0LDIwMywyOSwyMjcsMTY5LDIyOSwxOTUsMTgwLDIyMSw3NCw2OCwyNTQsMTU4LDEwNCwxMzMsMTYxLDI0Nyw2MywxMzEsMTgsMjQzLDE4LDk3LDMxLDIyXX19fSwibmV3X2tleXBhaXJzIjpbeyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxNSwyNTIsNzIsMTEwLDkyLDU0LDg5LDMyLDI0MCwxMzEsNjYsMTU3LDk4LDE3MCwyNDQsNjYsNzIsMTkxLDQ5LDIwMiwxOTYsMTYxLDE3MywxNywyMjIsMTQyLDY0LDIzMSwxODcsMTcyLDE2OSwxN119fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6WzE3NCw1OCw4NiwxOTgsMTM2LDIwNiwyMzIsMjUzLDM2LDEyLDMwLDE0NiwxMjksMTA2LDEwOCwxMjEsMjAyLDI1MywyNDIsMTU5LDk3LDE5MywyMTMsMjEsMTcwLDIzNCw2OCwzNSwxNTQsMjI1LDUzLDEwOF19fX0seyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxNzEsMTgwLDIyOCwxODgsMTA0LDIwMSwxOTQsMTcxLDM0LDIxNSwyMDcsMjQ3LDI0MCw4NywyMiwxNjIsNTEsMjE2LDEwLDE5NCw0MCw0OSwxNzcsMTk2LDE1NiwyMjMsMTI4LDIwLDIwOCwxMzQsMjE0LDc2XX19LCJwcml2YXRlX2tleSI6eyJrZXkiOnsidmVjIjpbMCwyNCwxODksMjQwLDMwLDUsMjU1LDIyMSwxMjcsNTgsMTg0LDEwOCwyMDMsMjMwLDE4LDI4LDUxLDQzLDI1MCwxMjcsMTg1LDEyNSwyNTIsMTA0LDI1MiwzMiwxNjcsMjAsOTEsNzIsMzEsMTgxXX19fV0sIm5ld19sZWFmX2tleXBhaXJfb3B0aW9uIjpudWxsLCJ1cGRhdGVfcGF0aF9sZWFmX25vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbMTUsMjUyLDcyLDExMCw5Miw1NCw4OSwzMiwyNDAsMTMxLDY2LDE1Nyw5OCwxNzAsMjQ0LDY2LDcyLDE5MSw0OSwyMDIsMTk2LDE2MSwxNzMsMTcsMjIyLDE0Miw2NCwyMzEsMTg3LDE3MiwxNjksMTddfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbMTg4LDI5LDI0NywyNDUsODUsMTcxLDE3Niw1NiwxMSw0MSw4OCwxODcsNzEsMjM3LDk4LDEwOCw2LDQwLDE3MiwyMjMsMTI5LDE4OSwxOTIsOTEsMjM2LDI3LDk0LDIyNCwxNzQsMTUyLDExNyw2N119fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJDb21taXQiOnsidmVj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dCI6eyJ2ZWMiOlsxMzksMTY4LDIyNywxNjUsODQsMzUsMTY0LDE4Niw2NywyNTAsMTg1LDUzLDk3LDk4LDIyMCwyMjcsNDUsNzQsOTksNDEsMzcsNTcsMTc3LDExOCwyNTQsNTEsMzYsMTMwLDY0LDIyLDc3LDc0XX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzE2OCwxMDEsMTY0LDI0OSwxMjEsNzIsNTEsMTYwLDkxLDIxLDkzLDE0OCw2LDYwLDExMCwyMSw2MSwxNzgsOTYsMzAsMjA3LDExMiwyMDEsMjA2LDI0OCwxODksMTg5LDEyLDYzLDE4LDEzLDIzMywxMDEsMjE3LDg1LDg0LDIzNiw1MSw0OCw0OCw5Miw4MiwxMTYsNzYsMTU3LDIzNSwyMTgsMTg0LDg5LDMsNjksNDMsMjQ3LDEzNywxNTAsMTI3LDExLDk2LDE3MiwxMzAsMTUyLDk4LDYyLDFdfX19fSx7Im5vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbNzEsMTAsNjksMjAsMiw5Miw3MCw4OSwyMjQsNDgsMTI2LDc4LDEyNCwxODYsMTQ4LDE1OSwyNDUsMTc1LDEyMiwxNTUsMTYsMjA5LDE1MywyMTYsMjIsMTQxLDExNyw3NSw5Nyw3MiwyNDcsMzZdfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbMTE2LDExMCwxNiw5MSw5OSw0NCwxNzAsMTIxLDE2NCwxMDIsMTIzLDEyMywxMTQsMjM5LDcyLDE5Niw2OSw1LDU4LDg3LDI1NCw0NSwxMDcsMjI5LDE4Miw0MiwyOSwxMzUsNzYsODMsMTk3LDE5NF19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk4LDExMSw5OF19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93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MV19fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOls2NCwxNzgsMjE2LDE0MCwyMDcsNTIsNjAsMjUwLDMxLDEyNiwyMDgsNTksNzQsMTM5LDEwNywxOTQsNSwyNDIsNjcsNjEsMTA0LDI3LDUxLDE1LDE5NiwyMjksMjQ0LDgxLDU1LDM5LDk2LDcyLDk4LDMyLDE1OCwxOTksNiwxNjMsMjIwLDM4LDEzOCwzMywxMDQsMTYsMTQ1LDMwLDYwLDc2LDcxLDE5OCw5OSw0OCwyMDQsMTAxLDEyMSwxOCwxMTUsMjAxLDE5NSwxNSw1OCw1NSwxMzksMTFdfX19fSx7Im5vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbNzEsMTAsNjksMjAsMiw5Miw3MCw4OSwyMjQsNDgsMTI2LDc4LDEyNCwxODYsMTQ4LDE1OSwyNDUsMTc1LDEyMiwxNTUsMTYsMjA5LDE1MywyMTYsMjIsMTQxLDExNyw3NSw5Nyw3MiwyNDcsMzZdfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbMTE2LDExMCwxNiw5MSw5OSw0NCwxNzAsMTIxLDE2NCwxMDIsMTIzLDEyMywxMTQsMjM5LDcyLDE5Niw2OSw1LDU4LDg3LDI1NCw0NSwxMDcsMjI5LDE4Miw0MiwyOSwxMzUsNzYsODMsMTk3LDE5NF19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk4LDExMSw5OF19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiS2V5UGFja2FnZSI6eyJub3RfYmVmb3JlIjoxNzIwNjg4OTQ5LCJub3RfYWZ0ZXIiOjE3Mjc5NTAxNDl9fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyOCwxNTQsMTgsNTQsMTI0LDIzMSwyNywxNzIsMTkyLDEwNCwxODcsOTgsMTg1LDQ0LDEsMTU4LDIwOSwyMTMsMjQwLDE3OSwxODQsMjA0LDE0NCwxMDcsMTI5LDIxLDEsODcsNjksMTU3LDExMiwyMDcsMjE0LDIwNSwxMzEsMTM3LDYsMzUsMjE3LDIyOSwxOTUsNTYsMTA5LDE2Miw5Niw4OSwxNzYsMjgsMTc2LDI0LDE4LDE3NCw1OSwxNDUsMTM1LDI0NywyMzEsMTcwLDMzLDIwOSw0NywyNTUsNTMsN119fX19XSwicGFyZW50X25vZGVzIjpbeyJub2RlIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxNzEsMTgwLDIyOCwxODgsMTA0LDIwMSwxOTQsMTcxLDM0LDIxNSwyMDcsMjQ3LDI0MCw4NywyMiwxNjIsNTEsMjE2LDEwLDE5NCw0MCw0OSwxNzcsMTk2LDE1NiwyMjMsMTI4LDIwLDIwOCwxMzQsMjE0LDc2XX19LCJwYXJlbnRfaGFzaCI6eyJ2ZWMiOltdfSwidW5tZXJnZWRfbGVhdmVzIjp7Imxpc3QiOltdfX19XSwiZGVmYXVsdF9sZWFmIjp7Im5vZGUiOm51bGx9LCJkZWZhdWx0X3BhcmVudCI6eyJub2RlIjpudWxsfX0sInRyZWVfaGFzaCI6WzEwNywyMTQsNzIsMTg5LDIzOSwxNyw2OSwzMCwyNDMsMTk0LDY0LDU3LDIyNyw2MSwxOTEsMjM1LDIzNCwxMDIsMTA1LDIxMCwxNDgsMjQyLDEyOCwxNjksMTEsMjU0LDk5LDMxLDE3OCwzMiw2LDI0Ml19AAAAAAAAAFwAAAAAAAAABVVzZVJhdGNoZXRUcmVleyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABZmFsc2UAAAAAAAAAXAAAAAAAAATDTWVzc2FnZVNlY3JldHN7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAF7Im1heF9lcG9jaHMiOjAsInBhc3RfZXBvY2hfdHJlZXMiOltdLCJtZXNzYWdlX3NlY3JldHMiOnsic2VuZGVyX2RhdGFfc2VjcmV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNzgsMjExLDEzNCwxODYsNDksMTQxLDc2LDE3MSwyMzksMTg0LDUzLDMwLDQsMTIxLDI3LDgzLDE0Miw4LDI2LDEwMSwxNjIsNjgsMTA1LDE0MywyOCw1NiwxNCw4OSwyLDUyLDMxLDEwXX19fSwibWVtYmVyc2hpcF9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzIsNDEsMjEwLDIxNSwxMjYsMTcwLDIxNyw1NCw1NywxMzMsMTE3LDExMCw1OCwyMDksMTkzLDE1OCwxMTksMTE4LDE1MiwxOCwxMDYsNiw4NCw2MiwyMTcsMjMsMjIxLDYxLDg3LDc3LDE1MSwyMjBdfX19LCJjb25maXJtYXRpb25fa2V5Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMDYsMjIwLDE2NCw5LDE5Nyw4Myw0MiwyNTEsNzcsMjU1LDYsMTAxLDQsNTgsMjUsNDAsMiwyMjEsMTU3LDYxLDE0MiwxNDEsNSw0MywxMDAsMjE0LDcxLDk5LDE2OSwxMjYsODEsMTQ2XX19fSwic2VyaWFsaXplZF9jb250ZXh0IjpbMCwxLDAsMywxNiwyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMiwwLDAsMCwwLDAsMCwwLDIsMzIsMTA3LDIxNCw3MiwxODksMjM5LDE3LDY5LDMwLDI0MywxOTQsNjQsNTcsMjI3LDYxLDE5MSwyMzUsMjM0LDEwMiwxMDUsMjEwLDE0OCwyNDIsMTI4LDE2OSwxMSwyNTQsOTksMzEsMTc4LDMyLDYsMjQyLDMyLDY4LDE4NiwxNzksMTk1LDMsMTQzLDIyNiwxOTQsMTk0LDIzOCw2MiwyNDksMTY3LDExOCwxOTksMTA5LDExMywyMjIsMTQ1LDIzMSwxLDEwOCwxMjQs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MTE3LDY3LDgyLDExNywxMTUsMTE2LDY3LDExNCwxMjEsMTEyLDExNiwxMTEsODMsMTA1LDEwMywxMTAsOTcsMTE2LDExNywxMTQsMTAxLDc1LDEwMSwxMjEsOCw3XX0AAXsicHJpdmF0ZSI6WzcwLDIxMyw2OSwyMjUsODcsMzksMTQxLDExNywxMTIsMTcsNDIsNTcsMjA0LDE3LDEzOCwzNSw3NSw5MSwxNTksNzUsMTUyLDIyMCwxMTcsMTAsMjE3LDIwMCwxNDEsMTcwLDE4NCw3NCwyMjgsMjA2XSwicHVibGljIjpbMTg4LDI5LDI0NywyNDUsODUsMTcxLDE3Niw1NiwxMSw0MSw4OCwxODcsNzEsMjM3LDk4LDEwOCw2LDQwLDE3MiwyMjMsMTI5LDE4OSwxOTIsOTEsMjM2LDI3LDk0LDIyNCwxNzQsMTUyLDExNyw2N10sInNpZ25hdHVyZV9zY2hlbWUiOiJFRDI1NTE5In0=","AAAAAAAAAA8AAAAAAAAAWwAAAAAAAAHvUmVzdW1wdGlvblBza3sidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsibWF4X251bWJlcl9vZl9zZWNyZXRzIjozMiwicmVzdW1wdGlvbl9wc2siOltbMCx7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNjUsNTMsNDIsMjcsNCw2Miw4NSwxMDQsMTY2LDczLDE5OSwyMTUsMTMxLDMsMTQ3LDI1MCw5MiwxNDcsNjAsODUsMTM4LDEwMCwxMzcsMTM4LDc0LDE0MiwxMDUsMjA4LDEyMiw5MiwxMzksNDRdfX19XSxbMSx7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNSwyMjIsNiwxNTUsNzksOTUsMTQwLDMyLDE2NywxNjcsMTMzLDIwLDE1NCw2LDQzLDQ1LDE1NiwxOTQsMjEsMTUzLDEzMiwxOTksMTI3LDE2MywxMzYsMywxODAsMTk1LDAsOTMsMjIsMTcyXX19fV0sWzIseyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMjMsMTAyLDI1NSw3MCwxMCwyMDQsMTgzLDIwNiw0NSwyMTMsMTkzLDU5LDYzLDIzMyw4MCw4MSw2NSwxOSwxMTQsODcsNjMsNDcsMTc1LDIwNiw0MCwxMjUsMTIsMTUyLDE3NCw3OCwxNDUsNF19fX1dXSwiY3Vyc29yIjozfQAAAAAAAABYAAAAAAAAAA1Hcm91cFN0YXRleyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABIk9wZXJhdGlvbmFsIgAAAAAAAABSAAAAAAAACTdUcmVleyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJ0cmVlIjp7ImxlYWZfbm9kZXMiOlt7Im5vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbMTUsMjUyLDcyLDExMCw5Miw1NCw4OSwzMiwyNDAsMTMxLDY2LDE1Nyw5OCwxNzAsMjQ0LDY2LDcyLDE5MSw0OSwyMDIsMTk2LDE2MSwxNzMsMTcsMjIyLDE0Miw2NCwyMzEsMTg3LDE3MiwxNjksMTddfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbMTg4LDI5LDI0NywyNDUsODUsMTcxLDE3Niw1NiwxMSw0MSw4OCwxODcsNzEsMjM3LDk4LDEwOCw2LDQwLDE3MiwyMjMsMTI5LDE4OSwxOTIsOTEsMjM2LDI3LDk0LDIyNCwxNzQsMTUyLDExNyw2N119fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJDb21taXQiOnsidmVjIjpbMjUwLDIwMiwxOTksMTM0LDEwMSwxNjEsMjM0LDE3MSw0NiwxMjgsMjMwLDQxLDE2NCwxMDMsNDYsMTQ4LDIxNCw1MywyNDQsNCwxNTUsMTgsNjksMTUyLDcxLDMxLDM2LDE2LDEzMSwxOSw5MywyMDFdfX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbNjQsMTc4LDIxNiwxNDAsMjA3LDUyLDYwLDI1MCwzMSwxMjYsMjA4LDU5LDc0LDEzOSwxMDcsMTk0LDUsMjQyLDY3LDYxLDEwNCwyNyw1MSwxNSwxOTYsMjI5LDI0NCw4MSw1NSwzOSw5Niw3Miw5OCwzMiwxNTgsMTk5LDYsMTYzLDIyMCwzOCwxMzgsMzMsMTA0LDE2LDE0NSwzMCw2MCw3Niw3MSwxOTgsOTksNDgsMjA0LDEwMSwxMjEsMTgsMTE1LDIwMSwxOTUsMTUsNTgsNTUsMTM5LDExXX19fX0seyJub2RlIjp7InBheWxvYWQiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzcxLDEwLDY5LDIwLDIsOTIsNzAsODksMjI0LDQ4LDEyNiw3OCwxMjQsMTg2LDE0OCwxNTksMjQ1LDE3NSwxMjIsMTU1LDE2LDIwOSwxNTMsMjE2LDIyLDE0MSwxMTcsNzUsOTcsNzIsMjQ3LDM2XX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6WzExNiwxMTAsMTYsOTEsOTksNDQsMTcwLDEyMSwxNjQsMTAyLDEyMywxMjMsMTE0LDIzOSw3MiwxOTYsNjksNSw1OCw4NywyNTQsNDUsMTA3LDIyOSwxODIsNDIsMjksMTM1LDc2LDgzLDE5NywxOTRdfX0sImNyZWRlbnRpYWwiOnsiY3JlZGVudGlhbF90eXBlIjoiQmFzaWMiLCJzZXJpYWxpemVkX2NyZWRlbnRpYWxfY29udGVudCI6eyJ2ZWMiOls5OCwxMTEsOThdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IktleVBhY2thZ2UiOnsibm90X2JlZm9yZSI6MTcyMDY4ODk0OSwibm90X2FmdGVyIjoxNzI3OTUwMTQ5fX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbMjgsMTU0LDE4LDU0LDEyNCwyMzEsMjcsMTcyLDE5MiwxMDQsMTg3LDk4LDE4NSw0NCwxLDE1OCwyMDksMjEzLDI0MCwxNzksMTg0LDIwNCwxNDQsMTA3LDEyOSwyMSwxLDg3LDY5LDE1NywxMTIsMjA3LDIxNCwyMDUsMTMxLDEzNyw2LDM1LDIxNywyMjksMTk1LDU2LDEwOSwxNjIsOTYsODksMTc2LDI4LDE3Niwy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NCw3MSw5OSwxNjksMTI2LDgxLDE0Nl19fX0sInNlcmlhbGl6ZWRfY29udGV4dCI6WzAsMSwwLDMsMTYsMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjIsMCwwLDAsMCwwLDAsMCwyLDMyLDEwNywyMTQsNzIsMTg5LDIzOSwxNyw2OSwzMCwyNDMsMTk0LDY0LDU3LDIyNyw2MSwxOTEsMjM1LDIzNCwxMDIsMTA1LDIxMCwxNDgsMjQyLDEyOCwxNjksMTEsMjU0LDk5LDMxLDE3OCwzMiw2LDI0MiwzMiw2OCwxODYsMTc5LDE5NSwzLDE0MywyMjYsMTk0LDE5NCwyMzgsNjIsMjQ5LDE2NywxMTgsMTk5LDEwOSwxMTMsMjIyLDE0NSwyMzEsMSwxMDgsMTI0LDUwLDExNyw1Myw4MSwxMjIsMTc1LDkzLDIwNiwyMDEsOCwwLDMsNSwyLDI0MCw2NiwwLDBdLCJzZWNyZXRfdHJlZSI6eyJvd25faW5kZXgiOjAsImxlYWZfbm9kZXMiOltudWxsLHsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzUyLDEwMSwxNzUsMTU3LDIwLDEwMywxNiwyMTgsMTcyLDUzLDI0MCwyNSw3OCw5MSwxODgsMzksNTAsMTI1LDE3MSwyMywzNiwxNTYsMjgsNzIsODQsMTY5LDIxMywxMiwxMDIsMTQ2LDE1MSwyMjVdfX19XSwicGFyZW50X25vZGVzIjpbbnVsbCxudWxsXSwiaGFuZHNoYWtlX3NlbmRlcl9yYXRjaGV0cyI6W3siRW5jcnlwdGlvblJhdGNoZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzY5LDIxMCwxMywxMDcsMTY2LDE3MiwxMTAsMTIwLDI1LDE5Miw3NCw2NSw5NCwxMzUsNjAsMjU0LDI5LDExOSw3LDI0NiwxMSwxNjIsMjA1LDIwOSwyMDgsMjE4LDEzNSwxMDQsMTAwLDQ5LDE5OCwxODldfX0sImdlbmVyYXRpb24iOjF9fSxudWxsXSwiYXBwbGljYXRpb25fc2VuZGVyX3JhdGNoZXRzIjpbeyJFbmNyeXB0aW9uUmF0Y2hldCI6eyJzZWNyZXQiOnsidmFs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LDI4LDIxLDE0NCw5MCwxNDgsMTUzLDEzOSwzOCw3MSwzMCwxNTcsMTcwLDE2MCw3LDE5MiwxMTAsMTc3LDIxMF19fV0AAXsicHJvcG9zYWwiOnsiQWRkIjp7ImtleV9wYWNrYWdlIjp7InBheWxvYWQiOnsicHJvdG9jb2xfdmVyc2lvbiI6Ik1sczEwIiwiY2lwaGVyc3VpdGUiOiJNTFNfMTI4X0RIS0VNWDI1NTE5X0NIQUNIQTIwUE9MWTEzMDVfU0hBMjU2X0VkMjU1MTkiLCJpbml0X2tleSI6eyJrZXkiOnsidmVjIjpbODQsMTMwLDU3LDIyNSwyNiwxNzksMjQ4LDIwNyw1NywxOTYsMTQ5LDE2MSwxMzksMTQsMTQ4LDI0NywyLDE0OSw3NSwyMjYsMTEwLDI1MSwxMzIsMTcwLDE2MiwxODcsMTUwLDY0LDI2LDI0MiwyMjksMzddfX0sImxlYWZfbm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxMCw4MywyMzYsMTU1LDE5MiwyMTYsNDUsMTY2LDE3NCwxMDEsMTAyLDQzLDEyOCw5MSwyNCwxMTgsMTQ2LDU3LDE4OCwxMTEsMjIsMjEsNDIsMTQ0LDYyLDIwNSw1OSwxNTIsMzgsMjA2LDE4NSw3N119fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyMDYsMTk2LDExNiw3MCwxOTMsNDksMjM1LDEyMSwxNiw2MiwxNjgsMTM2LDE2LDIwOCwxNjcsMTIsNTgsNTAsMiw1NCwxLDIxNCw3MiwyNTMsMTc5LDIzLDEwNiwxNDMsMTY0LDIwOCw4MiwxMl19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk5LDEwNCw5NywxMTQsMTA4LDEwNSwxMDFdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IktleVBhY2thZ2UiOnsibm90X2JlZm9yZSI6MTcyMDY4ODk0OSwibm90X2FmdGVyIjoxNzI3OTUwMTQ5fX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbMTM0LDI1NCwxNjgsMTA0LDUwLDk3LDcsMjQyLDIzMSwxOTEsMTE0LDEyMywxMzIsMzAsNjcsNTgsNSw1NywxODEsMTY5LDIzMiw4MSwyOCwxMDIsMTgxLDE4OCw5OCw1MywxMDQsMTgzLDI0MywyMSwyMTMsMjQ0LDEyOCwyNDgsMjI5LDE2OCw5MiwxOTYsMTcwLDE1MSwyMzUsMTgzLDQsMjMyLDIsMjA3LDIwNCwyMjUsMjA1LDE5LDIwNCwxNzYsMzEsMTE4LDIwOCwyMjksMTA3LDE4OCwyMywxNjIsMjI0LDVdfX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzE3OSwyOSw4NSwxODcsMTQxLDE4LDk1LDExLDExMSwyNDIsMTY3LDEyOCwxMDQsMjIyLDgxLDY3LDk3LDIwNiwyNTAsMTcxLDIyMCwxMDksNTMsMTc5LDE3MSwyMzQsNDMsMjEzLDAsMTA1LDQ5LDE1OSw5MSwxODIsMjMxLDc0LDc5LDgzLDE5OCwxMTIsMzAsOTksMjE4LDEzNCwxMDksMjQsMjMwLDI0OCw1MSwxNTgsMTAwLDM3LDEwMyw5LDE1MSwxMzgsMTQ1LDksODcsMTU5LDE2MiwxMzgsMjQ2LDFdfX19fX0sInByb3Bvc2FsX3JlZmVyZW5jZSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxLDM3LDk0LDE4MiwzNSw1MywxMjUsMTg3LDE0OCwxNTUsMTQ0LDM1LDE3OSwxODQsMjgsMjEsMTQ0LDkwLDE0OCwxNTMsMTM5LDM4LDcxLDMwLDE1NywxNzAsMTYwLDcsMTkyLDExMCwxNzcsMjEwXX19LCJzZW5kZXIiOnsiTWVtYmVyIjowfSwicHJvcG9zYWxfb3JfcmVmX3R5cGUiOiJSZWZlcmVuY2UifQAAAAAAAADlAAAAAAAAARhTaWduYXR1cmVLZXlQYWlyeyJ2YWx1ZSI6WzE4OCwyOSwyNDcsMjQ1LDg1LDE3MSwxNzYsNTYsMTEsNDEsODgsMTg3LDcxLDIzNyw5OCwxMDgsNiw0MCwxNzIsMjIzLDEyOSwxODksMTkyLDkxLDIzNiwyNyw5NCwyMjQsMTc0LDE1MiwxMTcsNjcsODIsMTE3LDExNSwxMTYsNjcsMTE0LDEyMSwxMTIsMTE2LDExMSw4MywxMDUsMTAzLDExMCw5NywxMTYsMTE3LDExNCwxMDEsNzUsMTAxLDEyMSw4LDddfQABeyJwcml2YXRlIjpbNzAsMjEzLDY5LDIyNSw4NywzOSwxNDEsMTE3LDExMiwxNyw0Miw1NywyMDQsMTcsMTM4LDM1LDc1LDkxLDE1OSw3NSwxNTIsMjIwLDExNywxMCwyMTcsMjAwLDE0MSwxNzAsMTg0LDc0LDIyOCwyMDZdLCJwdWJsaWMiOlsxODgsMjksMjQ3LDI0NSw4NSwxNzEsMTc2LDU2LDExLDQxLDg4LDE4Nyw3MSwyMzcsOTgsMTA4LDYsNDAsMTcyLDIyMywxMjksMTg5LDE5Miw5MSwyMzYsMjcsOTQsMjI0LDE3NCwxNTIsMTE3LDY3XSwic2lnbmF0dXJlX3NjaGVtZSI6IkVEMjU1MTkifQ=="]},"MLS_256_XWING_CHACHA20POLY1305_SHA256_Ed25519":{"group_id":{"value":{"vec":[214,206,173,27,206,87,231,4,172,30,130,210,232,69,61,222]}},"storages":["AAAAAAAAAA0AAAAAAAAAXAAAAAAAAAAFVXNlUmF0Y2hldFRyZWV7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAFmYWxzZQAAAAAAAABaAAAAAAAAAYZHcm91cENvbnRleHR7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAF7InByb3RvY29sX3ZlcnNpb24iOiJNbHMxMCIsImNpcGhlcnN1aXRlIjoiTUxTXzI1Nl9YV0lOR19DSEFDSEEyMFBPTFkxMzA1X1NIQTI1Nl9FZDI1NTE5IiwiZ3JvdXBfaWQiOnsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0sImVwb2NoIjowLCJ0cmVlX2hhc2giOnsidmVjIjpbMTg0LDQxLDEzNCwyMTMsNzIsMjcsMTcxLDEzNCwxNjAsNjQsMTQsODQsNTEsMjM0LDIsMjIxLDEyMyw4MCwxNTUsMTY4LDI0OCwxNTYsMTEzLDIzOSwxLDI1MiwxODcsMTI5LDI4LDU4LDEwMCwyMTFdfSwiY29uZmlybWVkX3RyYW5zY3JpcHRfaGFzaCI6eyJ2ZWMiOltdfSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0AAAAAAAAAXQAAAAAAAACFQ29uZmlybWF0aW9uVGFneyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJtYWNfdmFsdWUiOnsidmVjIjpbNTAsMTUzLDI1NSwxNDAsOTQsNTksNTgsNDEsMjMzLDEyNCw3MSwxMTQsMTg3LDIxNywyOCw3OCw1LDQzLDE1Nyw5LDEzOCw1MSw1LDIxMiwxMDMsMjA3LDIyNCwzNCwxMTQsNDQsMjI4LDE3NF19fQAAAAAAAABcAAAAAAAABDBNZXNzYWdlU2VjcmV0c3sidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsibWF4X2Vwb2NocyI6MCwicGFzdF9lcG9jaF90cmVlcyI6W10sIm1lc3NhZ2Vfc2VjcmV0cyI6eyJzZW5kZXJfZGF0YV9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE2LDMxLDE1LDg5LDIzMyw2OSw3MywxMTcsMjUyLDExNSwxNTAsMTQ5LDEyMiwxMjAsOTYsMTA2LDEzMiwzMiw5NywyLDIwLDI0NywyMTEsMTA0LDIyOCwxOCwyMzMsMTAxLDIxMiwxMzksMTUyLDIzOF19fX0sIm1lbWJlcnNoaXBfa2V5Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxODksMTI2LDE3LDExNiwxNzQsMjQ1LDAsNTEsMjA1LDIwMywyNTQsMTQxLDY0LDEyNSwxNjMsMjAzLDE3MCwwLDI0MywzNSwxNDAsMTE5LDE3Nyw1MiwyMTAsNTQsMjQ0LDI0Miw2MSw1LDI0Myw5NV19fX0sImNvbmZpcm1hdGlvbl9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE4NywyNTEsMTk0LDc2LDU0LDE3NSw4MSwxNDYsNjcsMjA2LDEwMSwyMzksMzIsMTU2LDI1LDE2MywxNTAsNjYsMzMsMTc3LDExMSwxNTMsNDMsMTAxLDE2NCwxMTMsMjMsMjQzLDIzNywyMDksMjIwLDQ2XX19fSwic2VyaWFsaXplZF9jb250ZXh0IjpbMCwxLDAsNzcsMTYsMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjIsMCwwLDAsMCwwLDAsMCwwLDMyLDE4NCw0MSwxMzQsMjEzLDcyLDI3LDE3MSwxMzQsMTYwLDY0LDE0LDg0LDUxLDIzNCwyLDIyMSwxMjMsODAsMTU1LDE2OCwyNDgsMTU2LDExMywyMzksMSwyNTIsMTg3LDEyOSwyOCw1OCwxMDAsMjExLDAsMF0sInNlY3JldF90cmVlIjp7Im93bl9pbmRleCI6MCwibGVhZl9ub2RlcyI6W3sic2VjcmV0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NSw1NCwyMDEsNTEsMjQ4LDE4NCw4NSwxNDksMTgzLDU3LDIwOSwyNSwxMCwzNyw4NCwxNDYsMjE2LDE1MSwxNDEsNDMsNzgsMjIzLDE2NiwxMjAsNjEsMTk2LDEwOCw2NiwyOCwzLDEwNyw2NiwyNywzMywzMiwxNDAsMjIxLDE2NCwxMzEsMiwxNjAsMTM1LDk3LDE2MSwxMjEsODcsOTcsNjAsMTU4LDEwMywxNDEsOTgsMjI4LDIwLDE1MywxMTUsMTAwLDEwOCw4OCw2NCwzNCwxMDYsMTAyLDg4LDMsMTE1LDgsMTM1LDE5MiwxNDAsMjUyLDM5LDg4LDIyMCwxODcsMywzMywxNTcsMjIwLDEyOSw2Nyw2OSwxNzEsMTA0LDQ4LDIxMCwxNzksNiwxNTUsMTAxLDE0OCwxNzgsNzYsMjUwLDUzLDMyLDE5NywxMCwxNTEsNDksNTQsMTgwLDIzMCwxNjUsNzAsMTQ4LDIzMywxODYsODEsNTMsNjcsMjEyLDUsMTk3LDE3NywxMDYsOTAsMTkwLDIyNywxNTIsNjQsMjAwLDE2MywyMjQsMjYsMTgzLDEzMCw1NywxMTYsNTAsMjEwLDUyLDEyMCwxNzYsMTY0LDIwOCwxNzksMTg2LDUwLDk3LDkxLDI1MCwyMTYsMTg1LDMxLDI0OCwxODcsOTIsMTU1LDIwNSwyMzksMzQsMTg2LDI1NCwyOCwzNiw0MCwwLDI4LDIyMyw0MCwyNCwxMzIsMjE0LDEwNSw2LDM0LDg5LDExMiwyMzEsMTEsOSwxMCwxNTksMTUxLDIxNCw4LDEzMSw0MCwxNDksNTIsMTYyLDI3LDM4LDg1LDE3NSw5MywxNDQsNjAsODcsOTIsNCwyMDksMTk4LDExNiwyNywyNTAsODYsMTc2LDEyMCw5OCw0MywxMDQsODksMTMxLDExLDk4LDExMSw2NSw4OCwxNjYsMTA2LDQ5LDgxLDY3LDUsMTE3LDIzNSwxNTEsMTEyLDI4LDY2LDk0LDEzOCwzNiwxMzQsMTY3LDE4MCw5MCwyNDYsMTQ2LDksMTQ4LDEyNywyNTEsMjI3LDEwNSw2NCwzNCwxNDQsMTEyLDE2Myw2MywxMDUsMTcyLDU3LDIyMywyNDIsNDMsMTI3LDgzLDk1LDE0MiwyMTcsMzcsNTQsOTksNzEsMTQsMjE4LDE4OCwyMTIsMTEyLDk5LDMzLDEyMiwxOTgsMjI5LDEyNCwxMjAsMjMwLDY0LDE4OSwyMDUsNDIsMzgsMjAyLDkyLDU3LDczLDY0LDcxLDgxLDEzOCwxMjQsMjksMTE1LDE3MSwzMCwxNjMsMTUsMjQ2LDEyOSwzMiwxMiwzNCwxNTYsOTEsNjYsODQsMTg4LDE2MCwyMDcsNjAsMjE0LDE0MiwxMDMsMTEsMTYxLDE1LDE0NiwxNzQsMTkxLDExNCw1MCwyMjcsMTcwLDc3LDUyLDEzMywxOTYsNiwxNDgsODgsMzAsMTgyLDE5MywxMjQsNjYsMTE2LDQ4LDEyMywxNDgsMjIyLDQ4LDE3NSwyNDQsMTk4LDgwLDU4LDEyMiw4Nyw1OCwxMjAsMTI5LDE4OCwxNzYsMTMsMCwyNTAsMjA0LDgyLDcwLDE4NywyMDQsMTM2LDEwMCwyMTAsMjE0LDE0Myw2LDEyOCwxMzQsMTI1LDI0MCwyMDUsMTkwLDgzLDE2NiwyNCwxNTAsNiwxNzIsMTIzLDk4LDIzOSwyMzYsMTYwLDIxNSw5NywxNywyMjIsMjA0LDE2OCwxMTIsNjcsOTYsMTI3LDE1MiwxMzIsMTkxLDEzNSwxNjksMjI2LDE3NywxNTgsMjIzLDE4NywxOTQsMjEsMTA1LDE4OCwyMzIsMTMxLDE3NSw2NCwyMDksNDUsNjYsMTQ5LDU2LDIyOSw3LDQzLDYzLDk4LDEzNiwxOTQsMjA0LDEyMywyNiw0LDExMCwyMTQsMTMwLDE4NywyMCw5OSw5Myw1Nyw4MywxNzYsMjE0LDEyMywxODYsMTAwLDE2LDc0LDIyNiwyNDIsMTQ1LDEyOCwxNjMsMTUsMTE5LDIwMiw1NiwxMDEsMTY4LDE0MCw1MCwxNTIsMTI0LDEzNiwyMCwwLDU5LDE2Nyw1OCwxMDIsNzAsMTMwLDI0NSw0Myw5NywxMzQsMTc2LDEwNiwxMjMsMjAzLDE0OSwxODksMjIsMTk2LDIxMSw3NCwxNTIsMTYxLDIyNiwxMjYsMjIwLDIzMiwzMCwyMzUsOTksNjEsMTc3LDIxOSwyOCwyMDgsMTU0LDEwNSw0MywxMDEsMjAzLDI0NiwzNSw0Niw3OSwyNTAsMTYxLDQ2LDM1LDg4LDE2LDQzLDIsMTgwLDM0LDExMiwxNjEsODMsMTExLDkyLDE5OSw1NiwyMzAsOCwxMjIsMTY0LDE2OCwzOSwxMjUsMTc3LDE5MSwxMzQsNCw3NywxNzcsMjMyLDExNCwyOSw1MiwxODAsMjQsMywyMDYsMTIsMTg1LDM4LDE5NSwyMzMsMTgxLDEyNiwyMDgsMTYsMjIwLDEyLDg1LDI0LDU1LDMyLDE5NSwxODQsMTAsNDQsMjEwLDc0LDIwNiw0MCwxODEsOTMsOTIsMywxNjYsMjMsMTE4LDQsODUsMzAsMTcsMjE2LDEwNywyMzksMTMzLDExNiw2MiwxOTIsMTMzLDEzNCw0NCw5OSwyNDEsMTM5LDUzLDY5LDk2LDYxLDI0MCwxMzksOTUsOTIsNywxNDksMTMwLDQ0LDE4MywyMiwxODIsMTc1LDIzMiwxODYsMTgwLDE5OSwyNDAsMzUsMjQyLDEyMCwxMDgsNjEsMTg0LDM2LDM0LDE2MCwxODYsNzMsNSwxNzAsMjM2LDIwOCwxODcsMjM5LDIzLDUyLDAsMTk2LDEwMywxODgsNDksOTAsMjE4LDEwNywzMywxMzUsMTY2LDE5LDE4MiwxNTEsMTksOTIsNzEsNDgsMjQ0LDIwMSwxNDgsMjAwLDEyLDMzLDE0Niw1MiwxODIsMTQsMjQ0LDg0LDIxNiwyMTgsNTAsNjEsMjIwLDYsNSwxMTgsMjQsMTEyLDI0MCwxNTUsMjM5LDI0OCwxMzIsMTYsNjksMTI2LDE4OSwxMDYsMTQzLDE5NiwxNywyMDQsMjA5LDIyOSwxMTksNDUsMTE5LDg1LDY0LDIwOSw3OSwxMjIsODksMTQyLDUzLDE0OCwxNTgsMTM0LDE2NiwxMzIsMTM4LDI0NCwxOTQsMTk5LDE3MSwxMDUsNDcsNDEsOTgsNjksMjQ4LDMzLDQ2LDE3OSwxNzIsMjQ3LDEzNiw0NSwxMDcsMjE2LDE4MiwxOTYsOTcsNzksMjQsMjUwLDE3OCwxMDYsMzQsOTIsMTQ0LDQ0LDI2LDI0MCwyNDksMzcsMjEsMjIwLDExNSwzNSwzOSwyMSwyMywxOTUsMTczLDE1OSwyMDgsMTc3LDEwNCw1MSwxNjEsNzksMzUsODYsMTQ5LDE3OSw5MiwyMiwxNjUsOTMsOTAsMTM3LDEyMywxMzQsMTc5LDYzLDE5MCw3MSwxODAsMjQ1LDI0OSw4LDEzOSwxMzcsMTk2LDIzOSwyMDQsMCwxMTgsNjksMTAsNzksMTUzLDExNiwyMzIsMTAsOTksNzMsMTYsMjAwLDgsMTM2LDE1LDE0OCwyNDIsNSw0OCwwLDEwLDI4LDEyNCw3MCw3Myw3LDE2NCwyMjQsNzIsMjA0LDEzNiwyNiw1MSw2NSwxMSw2OCwxODYsMTE4LDE2MCwxNzQsMTE3LDY3LDcyLDksOCw2NSwxODgsNjcsMTUyLDExNCwxNDQsODgsMiwyNiwxNDksNjcsMTksNzgsMzQsMTQ3LDE0LDk3LDE0OCwyNDEsMjMxLDM5LDIyMSwxNzcsMTMxLDIxMiwxNywzMiw4OCwyMTcsNDYsMjA4LDE4LDExOCwyMzgsMjMzLDEwMywxNzcsMTcyLDkxLDMxLDE2NywzMCwyNTEsMTY1LDE2MywxODcsMTQ0LDE1MSwxNzgsMTE5LDk3LDIyNSwyNDQsODEsMTMxLDE4MiwyMDYsNDYsMjUsMjA0LDEyMiw0OSwyMiwxMzMsMzgsMTYzLDI1MSwxMDMsMTE5LDI0NCw4OCw0NCwxNTUsMTAyLDE5MiwxNzUsMTc3LDEyMCwxMzksMzYsMjksMjQsNTksMjUsMjI1LDEzNCwxNDksMzgsNjgsMTc1LDE3MywyMzEsODksMTc1LDM3LDExMyw4MywyNDQsMTY2LDIwNiwyMDgsOTcsMTQ5LDUyLDgwLDMwLDQ4LDEwMSwxNTIsOTcsMTM3LDE4NywyMTQsMTY0LDkwLDE2Miw2NiwxNzcsMzEsMTM4LDI1MCwxMTgsMjUxLDMyLDEzNiwxOTcsMjMxLDQsNTEsMTc1LDE5NCwxODQsMTk4LDcsMjM3LDk0LDIyNCwyMjIsMjUxLDM0LDIsMjMwLDUsMTIwLDE5Nyw0Myw3NSwyNywxNjUsMTIwLDQsNTAsMiwxNzAsMTkxLDc2LDE1Miw3NSwxMTUsMTAyLDE5Nyw0NCwyMjQsMTcyLDEwNSw4MiwxNDQsODMsMTM2LDEwOSw4LDE0MSwyMjgsMTEsMTM3LDIwNiwxNDcsNDhdfX0sInByaXZhdGVfa2V5Ijp7ImtleSI6eyJ2ZWMiOlsyMzcsMjQ3LDIzLDEzMywzOCwyNiwzMyw4NCw4NCwzMSwxNDgsMjYsNzMsMTU2LDc3LDE4MSwxMiw4OSwxMDcsMjEwLDIwMSwyMDAsNjYsMTYwLDQ5LDE0OCwxMDksMjQ0LDM5LDQyLDMsMTgwLDEzMCw1NSwxOTIsMTI1LDIwNCwxMjQsMTUwLDEwMCwxNjIsMjAsMTM1LDE2MCwxMjEsMTg5LDE5Miw5OCw5OCwxNDgsMTI0LDI0NCwyMjQsMTcyLDE0MiwxMjMsMTQ4LDE2NywyNTIsMzAsMzksMTg3LDY3LDE5MiwxMzgsMTg5LDY2LDc2LDE4Niw1LDIyNywxMDksMTIxLDEzNiwxNTMsNTEsMTQ2LDIwNywxMzIsMTMzLDM4LDE2LDIwLDE2MiwyMzMsMjQyLDE2NCw4OSw1Niw0NiwxNjYsMTk3LDk0LDIwOSw5OCw3NiwxODIsMTc4LDExLDE2NCwxOTcsOTUsMTU4LDU5LDI4LDE4NiwyNDYsMTEsMTYwLDEwMywxODUsMTM3LDE1NSwxLDE5MCwyNDIsMjAyLDM3LDIyOSw3NSwxMzIsMjQsMTIwLDMwLDE4LDc1LDE5NywxMzksMjcsMjEyLDExNywxMjksMjEsNDMsMTYzLDEzNSwxNDAsMTMsMTgzLDE2NywyMDIsMjIwLDIxOSwyMSwxODUsNTEsMTMxLDE5MSwyMCwxODEsMTg0LDIwLDExMSw4NSwyMTksMTA5LDkxLDI0LDMxLDc4LDE2NCw1NSwyMDksMjM2LDE3MSw3Nyw5OCw5MSwxNjIsMjA0LDIwNywxOTQsMTY5LDExOCwyMzEsMjA4LDE3OCw5MywxMDcsMzksMjYsNjUsODAsMTM1LDE3LDE3NiwyNTEsMTI0LDEyLDEyOSw4LDE4NiwxNDIsMTcwLDMsNDMsMjI0LDcwLDc2LDMsMzgsMjMzLDk3LDM5LDgwLDczLDEzMiw0NywyMDMsMTI5LDE2MiwxMzEsMTQxLDE5MCwxNjksMTA5LDUsMTM2LDE1NCw0NywxNjIsMjUsMjksMjI4LDE2NSwxNjIsMjMwLDEyMCwxMTQsMTk3LDEwMywyMjYsMjMwLDExMiwyMzUsMTMyLDE3LDIyOSwyMDksMTA1LDksNzIsMTU1LDkwLDIzNiw3MSwyMTgsMTk5LDEyMCwxNjIsMTc5LDEzNSwxOSw4OSwxNjUsMTkxLDY3LDE1NCwzNiwyNDAsMTM3LDYsMTUzLDE4NywxMTQsNiwxOTUsMTUxLDIzLDQ2LDIwMywzNywxOTMsNzUsMTUwLDEyMSw0MCwxNjYsMTc3LDExLDEsNDQsMjE0LDI0NSw4OCw3OCwxOTMsNjEsMjAxLDEwMCwyMCwyMjMsMjMsMTYxLDIyMSw1MiwzNywxNzYsMTgsMTAwLDEyLDE4NiwxNzYsMjMwLDI0MywwLDEzLDk5LDIyLDMxLDE1MSwxNTQsMTYsMTEzLDgsMTQ4LDI0Myw5OSwxMDMsMTAzLDc2LDEzMCwxMzYsMTY2LDIwMCwyMCwxNCwyMzUsMTcsMTk1LDIyMSwxNDcsNTksNTEsMjQ0LDE3LDE2MywzMyw2LDIyNiw3MiwxMDksMTM2LDE5Nyw0MCwzNSw3MCwxNTIsMjM3LDg1LDE2LDI3LDE3MCw5MSwxNTcsNCw1MCw5NywxMDcsMTE2LDY4LDQ5LDE0MSwxMDYsMTI4LDE5MywxNCwyOCwxMjksMjM5LDcyLDYyLDIwMCwyNDYsMTA2LDM2LDUyLDg3LDYzLDE1MywxNDMsMTg0LDIsMTE4LDE1NSw3NiwxMzIsMTY5LDE5LDExMywyMDksMjMyLDE2MiwyMSwyMzIsNTUsMTM4LDM0LDEwNCw4Niw3Miw3NSw2NSw4MCw1MCwxNzQsMTA0LDE4NSwyMzksMjEzLDU5LDQxLDY1LDUxLDE2NywyNSwxODUsODYsMjMwLDcsMTg3LDI1MSw4OSwyNDksMjMyLDcsMTI0LDk5LDE1NSwxNTUsMTk3LDIwMywxMzMsMTA0LDE3NywzMSw5LDEzNiwxNDQsMTEsOSwxLDE3Miw2OSwyNDEsMTE5LDE3OCwzMCwyNDUsMTE5LDM5LDIxOSwyLDE4NSwxMzAsMTY0LDMxLDI1Miw5MCwyMjUsMjI2LDExMSw3MiwxODAsMTM1LDEwMiwxNjgsMTQ1LDEzMSwxNjQsMTIwLDEsMTcyLDE1MCwxNDAsMTc5LDM2LDIwMCwxNDgsMTI3LDEyNyw1OCw5NiwxOTUsODAsMTMyLDIzNiwxOTMsMTU4LDIzLDQyLDcyLDIyMyw5OSw5NCwyMjYsMjI3LDgwLDM4LDE1MywyNSwxNjEsODcsMTMsMTM4LDEzOSwzOCwyNSwxODYsMzQsMTY3LDI0Nyw4OSwyMDYsNjQsNjAsOTYsMTE3LDEwNiwxOTIsMTUxLDE4OCw5NCwxMSw2NSwxOTUsOTAsMTQ4LDE2NCwyMTYsMjA1LDE3NCwxNTYsMTU5LDM1LDYsNTcsMTAwLDE2NSw4Nyw0OSwzNSw4NCwxOCwwLDc5LDE1MCwyNywxMzMsMjI3LDI0NywxMywxLDIzLDcwLDE5NSwxODYsMTkzLDcwLDY3LDE1OSw4LDI0MywxMzQsMTIyLDg5LDE1MSwxMDcsNzUsNDIsMTc2LDEyMiwyMDMsMTkwLDY4LDE2MCwxNjUsMTk2LDU5LDI1LDM4LDExMywxNSwyMTYsMTc1LDIzMCwxMSwxNjMsMzMsMjQ5LDE5NywxMDksMCw0MSwyOSw3Myw5NiwxNCwxNjQsMzUsNDgsMjA5LDk0LDE5NCwxMDIsMjYsMTU5LDI1Miw1LDI2LDI0Myw2OCwxMDEsMzgsMjA0LDE4MCwxMjgsNjgsNjAsNjcsODUsMzksNiwxNiw4Nyw3MywxNDUsMjA4LDIwNCwzMCwxMzYsMjAxLDIwLDk4LDExNCwxMjAsMTY1LDIzNCwxODksMTM3LDE5NSwzMCwxNzEsMjM2LDEwMyw4MSw4MSwxNzgsNDIsOTAsMTYyLDAsMTY5LDEyNCwxNDQsMjQzLDY4LDM3LDk2LDEwNSwxMTQsOCwxODQsMSwxMzgsMTAxLDE1NSwxNjcsMjA1LDE0OCwyMDgsMTUsMTM3LDIsMTMwLDEyOCwyNDEsMTM4LDI0Miw1NywxNDEsMTk5LDEwMiwxMzYsNjcsMjExLDEwNCwyMDAsNzYsMTM3LDQ3LDEwNywxMTcsMTUwLDE4LDc0LDE1OCwxOTQsNzIsMTI3LDEyMiwxNjQsNTgsMTA1LDI5LDEzNywxODQsNzYsNzksODEsMTMzLDI1MCwxODIsMTgzLDExNCwyNTEsMTA0LDQzLDI0NSwxMTIsNiwyMTAsMTYyLDM5LDkwLDE2OCw2MCwyMTAsNzEsMjI5LDIwMiw2NCwyMTYsMTMxLDE0NSwyMTAsMjAyLDE5OCwyMTEsODEsMTI3LDg4LDE1MiwyMDUsODksMjAyLDEyNywxODksMTM4LDUyLDIwNywxMDUsODksMTc5LDksMTA0LDI0NSw1MSw0LDI0MiwyMzQsMTIyLDExMSwxMiwxMzQsMjM0LDEyLDk2LDM0LDE0OSwxNzUsNzksNzMsMzksMTQxLDIxMywxNDUsNzcsMTMxLDEzMSwxMDQsNzMsMTAyLDEyOCwyMTUsNTQsMzUsMjQ2LDM5LDMxLDI0OSw3OSwyMTYsMjAwLDk0LDE0MCwyMjAsMTE4LDQ2LDM1LDIsMTEwLDIxNCwxMiwxMzksMTgxLDkwLDM4LDE2NywxNjcsMTIyLDI3LDE0Miw0OCwxNzIsMjYsODUsMzMsMTE4LDE2MiwxODQsMTA5LDEyMCwxMjAsNjcsNDQsMTIyLDQ4LDQ2LDE5Miw4Niw4MCw5MSwxMyw1MywyNTIsMTA1LDksMzIsMTEzLDIxMSwzLDEyOCwxMjIsODksMTU1LDE0MCwyMTgsMiwxMDIsNjcsMTUzLDE5MCwyMzIsMjYsMzYsMTMxLDIsOTMsMTM3LDcxLDIxNCw4NCwzMywxMSwyMTEsOTYsMTQ0LDUxLDE4NiwyMDksMjI2LDEyMSwxMjQsMTYwLDg4LDg4LDE4MSw5OCwyNTUsOCwxODEsMjIzLDE4NSwxOTcsMTI0LDI4LDIyLDIyMCw5NiwxMjcsMTc5LDEyNCwxNDksMjMyLDY4LDI5LDIwMSw3MCwxMjAsNDksODUsMTE5LDE3LDE3OCwxMiwxNzYsNDAsNDUsMjE2LDExMiwxLDE2OCwxMzUsOTUsMywxMTYsMjAxLDExMCw1MywxOSwzNSwxMjMsMjMsMTgzLDQzLDE4LDExNiw1MiwxNjEsMTIwLDExNiwxMTEsMTk1LDYsMjA0LDEwNywxMzksMTUwLDI0LDEzMywyMiwxNDgsNTMsMTM1LDE1MCwxMTIsODAsMjQ0LDE3LDEwMiwyMTAsMjQzLDIwNSw1Miw2MCw4LDkwLDEyLDE5MCwyNDgsMTAwLDEwNSwzOSwxODMsMTMxLDQ5LDExNCwxODEsMywxMDMsMTk3LDE4OCwxMTUsMTYxLDM2LDEwLDE0NCw5NCw4MSwxNjcsNzMsNCwxOTcsNDMsMTUyLDUwLDE5NywxOTQsNjksMTk1LDE2NiwyMDEsMjEwLDI1MiwxMDYsNzAsMjQ4LDE2LDEwMCwyMzIsMjAxLDE4Nyw1LDE5Miw1Niw3NSw3OSwxMTEsMzMsNSwxNTIsMTAsMjAwLDE5LDUyLDE2MCwxMTYsMTY1LDE0NiwxMSwyNDMsMTA2LDI0OSwyMzYsNzksMTU3LDg1LDk4LDY3LDE2Niw4NCwyMTQsOTgsMTI3LDUyLDU2LDEwMiwxMTksMjExLDIwMywyMDksMjMsMjQsMTM3LDE5Miw2MiwxMzAsMTMwLDEzMiw4MCwxNTYsMTM2LDIyNywxNjIsMTYwLDQzLDI2LDkyLDE4OSwxNzYsNzEsNDksMTk5LDEyNiwyMDEsNjksMTcsNjcsMiwxMTMsMjA1LDEyMiwxNzUsMjA2LDE4OCwxNTcsMiwxOTgsMTEsNjgsMzQsMTIxLDE5Nyw2Nyw4NiwxNTUsMTM0LDE5Miw2OCwxNTQsNzgsNjEsMjUwLDgsMTE5LDEwNywxNTQsMTY5LDUxLDU4LDMyLDE2Niw2MywxMDQsMTg3LDEwMCwxOTIsMjAsMTQ2LDIzOCwyMSwyMCwxMTMsMTMwLDE1LDYsNTIsMTM5LDU2LDIwOCwxMjQsMTg1LDIxMiwyMDcsMzEsNTgsMTcxLDE0NywyMTQsMTE3LDQzLDE1MywxMjcsMjEsMTUyLDU3LDYzLDcxLDE5MywyMTcsMTU2LDE5NywxNjcsMTcxLDE1NCw5MCwxNjQsMTE1LDgxLDE1NCw4OSwyNywxMzMsMTE5LDg5LDE3LDIsMTczLDEzMSwxODYsMjE5LDc0LDk0LDczLDE4NywyMDMsMzEsMjQ0LDE2OSwxOSwxMDMsMTIsMTQsOTksMTY1LDIyNSwxMzgsMzYsMTk3LDEzNSwxODcsNjgsMTU1LDMxLDExMCwxMDgsOTAsMjIsODEsMTM3LDE5MSwxMDUsMTg5LDksMTcyLDgxLDIwNywyMTAsMzQsNzEsMTE1LDE4NCwxMTEsNDEsMTQzLDUzLDM2LDE5NSwxNiw3MSw4NSwyMzIsMTIwLDc1LDE5NywxNTYsMjA0LDE5LDM4LDE3OCwyLDIwLDE1MiwxMDMsMjcsNjYsMjIyLDU4LDIwMiw3OCw0Myw2OCwxMTgsNzEsOTMsMzMsMTU0LDEyNSwyMjcsMTQ2LDU2LDEzMiwxOTMsMTY3LDg3LDE1NiwyMCwyMDMsNDEsMTI2LDExOSwxMCwxOTUsMjgsNCwyMiwxMzEsOCw1Niw4Niw3LDE4NCwzMyw4NCwzMiwxMjgsMjMsMCwyMTMsMTU0LDExOSwzMiwxNjQsNTcsMjQzLDE4MCwxODMsMjIsMzksMTk3LDExMiwxNDgsOTEsMjE4LDE5OCwxNzUsODQsMTEzLDE5OCwyMDcsMzgsMTIxLDE4LDE2Miw0OSwxNDAsMjI0LDU3LDIzNiwzMiwxMiw5NywyMTcsMzcsNDUsMTc2LDc2LDEwOSw4Miw3LDE2OSwyNDgsMTI3LDI2LDU4LDExNSwxMTcsMjA5LDE2NCwxNzAsMTUwLDE2MCw2NCw5MCw1Nyw0OCwzMiw5Myw1NCwyMjAsMTA4LDE4LDI0Myw1MCw3LDI0MiwxMTAsNTEsMzksMTk5LDI1Myw1MSwxODcsNzgsMTM1LDQxLDc4LDE4NiwyMDcsMjAxLDI0Nyw3MSwzMCw5Nyw0MywxMjQsMjMyLDAsNTgsMTQ1LDEwLDI0MiwxNjksMTg4LDI0Myw4Miw1Myw5MywyOCwxMDQsNjUsNTQsMjAxLDUxLDI0OCwxODQsODUsMTQ5LDE4Myw1NywyMDksMjUsMTAsMzcsODQsMTQ2LDIxNiwxNTEsMTQxLDQzLDc4LDIyMywxNjYsMTIwLDYxLDE5NiwxMDgsNjYsMjgsMywxMDcsNjYsMjcsMzMsMzIsMTQwLDIyMSwxNjQsMTMxLDIsMTYwLDEzNSw5NywxNjEsMTIxLDg3LDk3LDYwLDE1OCwxMDMsMTQxLDk4LDIyOCwyMCwxNTMsMTE1LDEwMCwxMDgsODgsNjQsMzQsMTA2LDEwMiw4OCwzLDExNSw4LDEzNSwxOTIsMTQwLDI1MiwzOSw4OCwyMjAsMTg3LDMsMzMsMTU3LDIyMCwxMjksNjcsNjksMTcxLDEwNCw0OCwyMTAsMTc5LDYsMTU1LDEwMSwxNDgsMTc4LDc2LDI1MCw1MywzMiwxOTcsMTAsMTUxLDQ5LDU0LDE4MCwyMzAsMTY1LDcwLDE0OCwyMzMsMTg2LDgxLDUzLDY3LDIxMiw1LDE5NywxNzcsMTA2LDkwLDE5MCwyMjcsMTUyLDY0LDIwMCwxNjMsMjI0LDI2LDE4MywxMzAsNTcsMTE2LDUwLDIxMCw1MiwxMjAsMTc2LDE2NCwyMDgsMTc5LDE4Niw1MCw5Nyw5MSwyNTAsMjE2LDE4NSwzMSwyNDgsMTg3LDkyLDE1NSwyMDUsMjM5LDM0LDE4NiwyNTQsMjgsMzYsNDAsMCwyOCwyMjMsNDAsMjQsMTMyLDIxNCwxMDUsNiwzNCw4OSwxMTIsMjMxLDExLDksMTAsMTU5LDE1MSwyMTQsOCwxMzEsNDAsMTQ5LDUyLDE2MiwyNywzOCw4NSwxNzUsOTMsMTQ0LDYwLDg3LDkyLDQsMjA5LDE5OCwxMTYsMjcsMjUwLDg2LDE3NiwxMjAsOTgsNDMsMTA0LDg5LDEzMSwxMSw5OCwxMTEsNjUsODgsMTY2LDEwNiw0OSw4MSw2Nyw1LDExNywyMzUsMTUxLDExMiwyOCw2Niw5NCwxMzgsMzYsMTM0LDE2NywxODAsOTAsMjQ2LDE0Niw5LDE0OCwxMjcsMjUxLDIyNywxMDUsNjQsMzQsMTQ0LDExMiwxNjMsNjMsMTA1LDE3Miw1NywyMjMsMjQyLDQzLDEyNyw4Myw5NSwxNDIsMjE3LDM3LDU0LDk5LDcxLDE0LDIxOCwxODgsMjEyLDExMiw5OSwzMywxMjIsMTk4LDIyOSwxMjQsMTIwLDIzMCw2NCwxODksMjA1LDQyLDM4LDIwMiw5Miw1Nyw3Myw2NCw3MSw4MSwxMzgsMTI0LDI5LDExNSwxNzEsMzAsMTYzLDE1LDI0NiwxMjksMzIsMTIsMzQsMTU2LDkxLDY2LDg0LDE4OCwxNjAsMjA3LDYwLDIxNCwxNDIsMTAzLDExLDE2MSwxNSwxNDYsMTc0LDE5MSwxMTQsNTAsMjI3LDE3MCw3Nyw1MiwxMzMsMTk2LDYsMTQ4LDg4LDMwLDE4MiwxOTMsMTI0LDY2LDExNiw0OCwxMjMsMTQ4LDIyMiw0OCwxNzUsMjQ0LDE5OCw4MCw1OCwxMjIsODcsNTgsMTIwLDEyOSwxODgsMTc2LDEzLDAsMjUwLDIwNCw4Miw3MCwxODcsMjA0LDEzNiwxMDAsMjEwLDIxNCwxNDMsNiwxMjgsMTM0LDEyNSwyNDAsMjA1LDE5MCw4MywxNjYsMjQsMTUwLDYsMTcyLDEyMyw5OCwyMzksMjM2LDE2MCwyMTUsOTcsMTcsMjIyLDIwNCwxNjgsMTEyLDY3LDk2LDEyNywxNTIsMTMyLDE5MSwxMzUsMTY5LDIyNiwxNzcsMTU4LDIyMywxODcsMTk0LDIxLDEwNSwxODgsMjMyLDEzMSwxNzUsNjQsMjA5LDQ1LDY2LDE0OSw1NiwyMjksNyw0Myw2Myw5OCwxMzYsMTk0LDIwNCwxMjMsMjYsNCwxMTAsMjE0LDEzMCwxODcsMjAsOTksOTMsNTcsODMsMTc2LDIxNCwxMjMsMTg2LDEwMCwxNiw3NCwyMjYsMjQyLDE0NSwxMjgsMTYzLDE1LDExOSwyMDIsNTYsMTAxLDE2OCwxNDAsNTAsMTUyLDEyNCwxMzYsMjAsMCw1OSwxNjcsNTgsMTAyLDcwLDEzMCwyNDUsNDMsOTcsMTM0LDE3NiwxMDYsMTIzLDIwMywxNDksMTg5LDIyLDE5NiwyMTEsNzQsMTUyLDE2MSwyMjYsMTI2LDIyMCwyMzIsMzAsMjM1LDk5LDYxLDE3NywyMTksMjgsMjA4LDE1NCwxMDUsNDMsMTAxLDIwMywyNDYsMzUsNDYsNzksMjUwLDE2MSw0NiwzNSw4OCwxNiw0MywyLDE4MCwzNCwxMTIsMTYxLDgzLDExMSw5MiwxOTksNTYsMjMwLDgsMTIyLDE2NCwxNjgsMzksMTI1LDE3NywxOTEsMTM0LDQsNzcsMTc3LDIzMiwxMTQsMjksNTIsMTgwLDI0LDMsMjA2LDEyLDE4NSwzOCwxOTUsMjMzLDE4MSwxMjYsMjA4LDE2LDIyMCwxMiw4NSwyNCw1NSwzMiwxOTUsMTg0LDEwLDQ0LDIxMCw3NCwyMDYsNDAsMTgxLDkzLDkyLDMsMTY2LDIzLDExOCw0LDg1LDMwLDE3LDIxNiwxMDcsMjM5LDEzMywxMTYsNjIsMTkyLDEzMywxMzQsNDQsOTksMjQxLDEzOSw1Myw2OSw5Niw2MSwyNDAsMTM5LDk1LDkyLDcsMTQ5LDEzMCw0NCwxODMsMjIsMTgyLDE3NSwyMzIsMTg2LDE4MCwxOTksMjQwLDM1LDI0MiwxMjAsMTA4LDYxLDE4NCwzNiwzNCwxNjAsMTg2LDczLDUsMTcwLDIzNiwyMDgsMTg3LDIzOSwyMyw1MiwwLDE5NiwxMDMsMTg4LDQ5LDkwLDIxOCwxMDcsMzMsMTM1LDE2NiwxOSwxODIsMTUxLDE5LDkyLDcxLDQ4LDI0NCwyMDEsMTQ4LDIwMCwxMiwzMywxNDYsNTIsMTgyLDE0LDI0NCw4NCwyMTYsMjE4LDUwLDYxLDIyMCw2LDUsMTE4LDI0LDExMiwyNDAsMTU1LDIzOSwyNDgsMTMyLDE2LDY5LDEyNiwxODksMTA2LDE0MywxOTYsMTcsMjA0LDIwOSwyMjksMTE5LDQ1LDExOSw4NSw2NCwyMDksNzksMTIyLDg5LDE0Miw1MywxNDgsMTU4LDEzNCwxNjYsMTMyLDEzOCwyNDQsMTk0LDE5OSwxNzEsMTA1LDQ3LDQxLDk4LDY5LDI0OCwzMyw0NiwxNzksMTcyLDI0NywxMzYsNDUsMTA3LDIxNiwxODIsMTk2LDk3LDc5LDI0LDI1MCwxNzgsMTA2LDM0LDkyLDE0NCw0NCwyNiwyNDAsMjQ5LDM3LDIxLDIyMCwxMTUsMzUsMzksMjEsMjMsMTk1LDE3MywxNTksMjA4LDE3NywxMDQsNTEsMTYxLDc5LDM1LDg2LDE0OSwxNzksOTIsMjIsMTY1LDkzLDkwLDEzNywxMjMsMTM0LDE3OSw2MywxOTAsNzEsMTgwLDI0NSwyNDksOCwxMzksMTM3LDE5NiwyMzksMjA0LDAsMTE4LDY5LDEwLDc5LDE1MywxMTYsMjMyLDEwLDk5LDczLDE2LDIwMCw4LDEzNiwxNSwxNDgsMjQyLDUsNDgsMCwxMCwyOCwxMjQsNzAsNzMsNywxNjQsMjI0LDcyLDIwNCwxMzYsMjYsNTEsNjUsMTEsNjgsMTg2LDExOCwxNjAsMTc0LDExNyw2Nyw3Miw5LDgsNjUsMTg4LDY3LDE1MiwxMTQsMTQ0LDg4LDIsMjYsMTQ5LDY3LDE5LDc4LDM0LDE0NywxNCw5NywxNDgsMjQxLDIzMSwzOSwyMjEsMTc3LDEzMSwyMTIsMTcsMzIsODgsMjE3LDQ2LDIwOCwxOCwxMTgsMjM4LDIzMywxMDMsMTc3LDE3Miw5MSwzMSwxNjcsMzAsMjUxLDE2NSwxNjMsMTg3LDE0NCwxNTEsMTc4LDExOSw5NywyMjUsMjQ0LDgxLDEzMSwxODIsMjA2LDQ2LDI1LDIwNCwxMjIsNDksMjIsMTMzLDM4LDE2MywyNTEsMTAzLDExOSwyNDQsODgsNDQsMTU1LDEwMiwxOTIsMTc1LDE3NywxMjAsMTM5LDM2LDI5LDI0LDU5LDI1LDIyNSwxMzQsMTQ5LDM4LDY4LDE3NSwxNzMsMjMxLDg5LDE3NSwzNywxMTMsODMsMjQ0LDE2NiwyMDYsMjA4LDk3LDE0OSw1Miw4MCwzMCw0OCwxMDEsMTUyLDk3LDEzNywxODcsMjE0LDE2NCw5MCwxNjIsNjYsMTc3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NSwxMTcsMjA5LDE2NCwxNzAsMTUwLDE2MCw2NCw5MCw1Nyw0OCwzMiw5Myw1NCwyMjAsMTA4LDE4LDI0Myw1MCw3LDI0MiwxMTAsNTEsMzksMTk5LDI1Myw1MSwxODcsNzgsMTM1LDQxLDc4LDE4NiwyMDcsMjAxLDI0Nyw3MSwzMCw5Nyw0MywxMjQsMjMyLDAsNTgsMTQ1LDEwLDI0MiwxNjksMTg4LDI0Myw4Miw1Myw5MywyOCwxMDQsNjUsNTQsMjAxLDUxLDI0OCwxODQsODUsMTQ5LDE4Myw1NywyMDksMjUsMTAsMzcsODQsMTQ2LDIxNiwxNTEsMTQxLDQzLDc4LDIyMywxNjYsMTIwLDYxLDE5NiwxMDgsNjYsMjgsMywxMDcsNjYsMjcsMzMsMzIsMTQwLDIyMSwxNjQsMTMxLDIsMTYwLDEzNSw5NywxNjEsMTIxLDg3LDk3LDYwLDE1OCwxMDMsMTQxLDk4LDIyOCwyMCwxNTMsMTE1LDEwMCwxMDgsODgsNjQsMzQsMTA2LDEwMiw4OCwzLDExNSw4LDEzNSwxOTIsMTQwLDI1MiwzOSw4OCwyMjAsMTg3LDMsMzMsMTU3LDIyMCwxMjksNjcsNjksMTcxLDEwNCw0OCwyMTAsMTc5LDYsMTU1LDEwMSwxNDgsMTc4LDc2LDI1MCw1MywzMiwxOTcsMTAsMTUxLDQ5LDU0LDE4MCwyMzAsMTY1LDcwLDE0OCwyMzMsMTg2LDgxLDUzLDY3LDIxMiw1LDE5NywxNzcsMTA2LDkwLDE5MCwyMjcsMTUyLDY0LDIwMCwxNjMsMjI0LDI2LDE4MywxMzAsNTcsMTE2LDUwLDIxMCw1MiwxMjAsMTc2LDE2NCwyMDgsMTc5LDE4Niw1MCw5Nyw5MSwyNTAsMjE2LDE4NSwzMSwyNDgsMTg3LDkyLDE1NSwyMDUsMjM5LDM0LDE4NiwyNTQsMjgsMzYsNDAsMCwyOCwyMjMsNDAsMjQsMTMyLDIxNCwxMDUsNiwzNCw4OSwxMTIsMjMxLDExLDksMTAsMTU5LDE1MSwyMTQsOCwxMzEsNDAsMTQ5LDUyLDE2MiwyNywzOCw4NSwxNzUsOTMsMTQ0LDYwLDg3LDkyLDQsMjA5LDE5OCwxMTYsMjcsMjUwLDg2LDE3NiwxMjAsOTgsNDMsMTA0LDg5LDEzMSwxMSw5OCwxMTEsNjUsODgsMTY2LDEwNiw0OSw4MSw2Nyw1LDExNywyMzUsMTUxLDExMiwyOCw2Niw5NCwxMzgsMzYsMTM0LDE2NywxODAsOTAsMjQ2LDE0Niw5LDE0OCwxMjcsMjUxLDIyNywxMDUsNjQsMzQsMTQ0LDExMiwxNjMsNjMsMTA1LDE3Miw1NywyMjMsMjQyLDQzLDEyNyw4Myw5NSwxNDIsMjE3LDM3LDU0LDk5LDcxLDE0LDIxOCwxODgsMjEyLDExMiw5OSwzMywxMjIsMTk4LDIyOSwxMjQsMTIwLDIzMCw2NCwxODksMjA1LDQyLDM4LDIwMiw5Miw1Nyw3Myw2NCw3MSw4MSwxMzgsMTI0LDI5LDExNSwxNzEsMzAsMTYzLDE1LDI0NiwxMjksMzIsMTIsMzQsMTU2LDkxLDY2LDg0LDE4OCwxNjAsMjA3LDYwLDIxNCwxNDIsMTAzLDExLDE2MSwxNSwxNDYsMTc0LDE5MSwxMTQsNTAsMjI3LDE3MCw3Nyw1MiwxMzMsMTk2LDYsMTQ4LDg4LDMwLDE4MiwxOTMsMTI0LDY2LDExNiw0OCwxMjMsMTQ4LDIyMiw0OCwxNzUsMjQ0LDE5OCw4MCw1OCwxMjIsODcsNTgsMTIwLDEyOSwxODgsMTc2LDEzLDAsMjUwLDIwNCw4Miw3MCwxODcsMjA0LDEzNiwxMDAsMjEwLDIxNCwxNDMsNiwxMjgsMTM0LDEyNSwyNDAsMjA1LDE5MCw4MywxNjYsMjQsMTUwLDYsMTcyLDEyMyw5OCwyMzksMjM2LDE2MCwyMTUsOTcsMTcsMjIyLDIwNCwxNjgsMTEyLDY3LDk2LDEyNywxNTIsMTMyLDE5MSwxMzUsMTY5LDIyNiwxNzcsMTU4LDIyMywxODcsMTk0LDIxLDEwNSwxODgsMjMyLDEzMSwxNzUsNjQsMjA5LDQ1LDY2LDE0OSw1NiwyMjksNyw0Myw2Myw5OCwxMzYsMTk0LDIwNCwxMjMsMjYsNCwxMTAsMjE0LDEzMCwxODcsMjAsOTksOTMsNTcsODMsMTc2LDIxNCwxMjMsMTg2LDEwMCwxNiw3NCwyMjYsMjQyLDE0NSwxMjgsMTYzLDE1LDExOSwyMDIsNTYsMTAxLDE2OCwxNDAsNTAsMTUyLDEyNCwxMzYsMjAsMCw1OSwxNjcsNTgsMTAyLDcwLDEzMCwyNDUsNDMsOTcsMTM0LDE3NiwxMDYsMTIzLDIwMywxNDksMTg5LDIyLDE5NiwyMTEsNzQsMTUyLDE2MSwyMjYsMTI2LDIyMCwyMzIsMzAsMjM1LDk5LDYxLDE3NywyMTksMjgsMjA4LDE1NCwxMDUsNDMsMTAxLDIwMywyNDYsMzUsNDYsNzksMjUwLDE2MSw0NiwzNSw4OCwxNiw0MywyLDE4MCwzNCwxMTIsMTYxLDgzLDExMSw5MiwxOTksNTYsMjMwLDgsMTIyLDE2NCwxNjgsMzksMTI1LDE3NywxOTEsMTM0LDQsNzcsMTc3LDIzMiwxMTQsMjksNTIsMTgwLDI0LDMsMjA2LDEyLDE4NSwzOCwxOTUsMjMzLDE4MSwxMjYsMjA4LDE2LDIyMCwxMiw4NSwyNCw1NSwzMiwxOTUsMTg0LDEwLDQ0LDIxMCw3NCwyMDYsNDAsMTgxLDkzLDkyLDMsMTY2LDIzLDExOCw0LDg1LDMwLDE3LDIxNiwxMDcsMjM5LDEzMywxMTYsNjIsMTkyLDEzMywxMzQsNDQsOTksMjQxLDEzOSw1Myw2OSw5Niw2MSwyNDAsMTM5LDk1LDkyLDcsMTQ5LDEzMCw0NCwxODMsMjIsMTgyLDE3NSwyMzIsMTg2LDE4MCwxOTksMjQwLDM1LDI0MiwxMjAsMTA4LDYxLDE4NCwzNiwzNCwxNjAsMTg2LDczLDUsMTcwLDIzNiwyMDgsMTg3LDIzOSwyMyw1MiwwLDE5NiwxMDMsMTg4LDQ5LDkwLDIxOCwxMDcsMzMsMTM1LDE2NiwxOSwxODIsMTUxLDE5LDkyLDcxLDQ4LDI0NCwyMDEsMTQ4LDIwMCwxMiwzMywxNDYsNTIsMTgyLDE0LDI0NCw4NCwyMTYsMjE4LDUwLDYxLDIyMCw2LDUsMTE4LDI0LDExMiwyNDAsMTU1LDIzOSwyNDgsMTMyLDE2LDY5LDEyNiwxODksMTA2LDE0MywxOTYsMTcsMjA0LDIwOSwyMjksMTE5LDQ1LDExOSw4NSw2NCwyMDksNzksMTIyLDg5LDE0Miw1MywxNDgsMTU4LDEzNCwxNjYsMTMyLDEzOCwyNDQsMTk0LDE5OSwxNzEsMTA1LDQ3LDQxLDk4LDY5LDI0OCwzMyw0NiwxNzksMTcyLDI0NywxMzYsNDUsMTA3LDIxNiwxODIsMTk2LDk3LDc5LDI0LDI1MCwxNzgsMTA2LDM0LDkyLDE0NCw0NCwyNiwyNDAsMjQ5LDM3LDIxLDIyMCwxMTUsMzUsMzksMjEsMjMsMTk1LDE3MywxNTksMjA4LDE3NywxMDQsNTEsMTYxLDc5LDM1LDg2LDE0OSwxNzksOTIsMjIsMTY1LDkzLDkwLDEzNywxMjMsMTM0LDE3OSw2MywxOTAsNzEsMTgwLDI0NSwyNDksOCwxMzksMTM3LDE5NiwyMzksMjA0LDAsMTE4LDY5LDEwLDc5LDE1MywxMTYsMjMyLDEwLDk5LDczLDE2LDIwMCw4LDEzNiwxNSwxNDgsMjQyLDUsNDgsMCwxMCwyOCwxMjQsNzAsNzMsNywxNjQsMjI0LDcyLDIwNCwxMzYsMjYsNTEsNjUsMTEsNjgsMTg2LDExOCwxNjAsMTc0LDExNyw2Nyw3Miw5LDgsNjUsMTg4LDY3LDE1MiwxMTQsMTQ0LDg4LDIsMjYsMTQ5LDY3LDE5LDc4LDM0LDE0NywxNCw5NywxNDgsMjQxLDIzMSwzOSwyMjEsMTc3LDEzMSwyMTIsMTcsMzIsODgsMjE3LDQ2LDIwOCwxOCwxMTgsMjM4LDIzMywxMDMsMTc3LDE3Miw5MSwzMSwxNjcsMzAsMjUxLDE2NSwxNjMsMTg3LDE0NCwxNTEsMTc4LDExOSw5NywyMjUsMjQ0LDgxLDEzMSwxODIsMjA2LDQ2LDI1LDIwNCwxMjIsNDksMjIsMTMzLDM4LDE2MywyNTEsMTAzLDExOSwyNDQsODgsNDQsMTU1LDEwMiwxOTIsMTc1LDE3NywxMjAsMTM5LDM2LDI5LDI0LDU5LDI1LDIyNSwxMzQsMTQ5LDM4LDY4LDE3NSwxNzMsMjMxLDg5LDE3NSwzNywxMTMsODMsMjQ0LDE2NiwyMDYsMjA4LDk3LDE0OSw1Miw4MCwzMCw0OCwxMDEsMTUyLDk3LDEzNywxODcsMjE0LDE2NCw5MCwxNjIsNjYsMTc3LDMxLDEzOCwyNTAsMTE4LDI1MSwzMiwxMzYsMTk3LDIzMSw0LDUxLDE3NSwxOTQsMTg0LDE5OCw3LDIzNyw5NCwyMjQsMjIyLDI1MSwzNCwyLDIzMCw1LDEyMCwxOTcsNDMsNzUsMjcsMTY1LDEyMCw0LDUwLDIsMTcwLDE5MSw3NiwxNTIsNzUsMTE1LDEwMiwxOTcsNDQsMjI0LDE3MiwxMDUsODIsMTQ0LDgzLDEzNiwxMDksOCwxNDEsMjI4LDExLDEzNywyMDYsMTQ3LDQ4XX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6WzE2NCwxODAsMTI1LDEyNiw3OSwyMjAsMjIxLDI1MywxMjMsNDIsMjAxLDEyMCwxODAsMTY0LDIwMCwyMDgsMTc3LDk5LDgyLDYwLDU1LDE1NiwxMjYsNzcsMTE3LDExNSwyMDMsMjAzLDE0MiwyNTUsMTY2LDM0XX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTcsMTA4LDEwNSw5OSwxMDFdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IktleVBhY2thZ2UiOnsibm90X2JlZm9yZSI6MTcyMDY4ODk1MCwibm90X2FmdGVyIjoxNzI3OTUwMTUwfX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbMzQsOTUsNyw0Myw3Miw4MCwxNSw0OSw0NSwxMzEsMTIwLDExOSwxNzcsMTI0LDkzLDE1MSwxMjMsMTI4LDQ1LDMzLDIxMywyMzMsMjEyLDEwLDIyMiwxNzgsMTY3LDgyLDU3LDUsMjMxLDIsMTIsMTAxLDEwOSwxNzEsMjM3LDk0LDQsMjA5LDcyLDEyNCwxMTAsMTU2LDIxNywyMzMsMjcsNjksMTk3LDIxMCwxNzksMzEsMTIzLDIzNiwyMDksMTkwLDI1MywxMDAsMjA4LDQ3LDU1LDYsMTksOV19fX19XSwicGFyZW50X25vZGVzIjpbXSwiZGVmYXVsdF9s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dmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsibWF4X2Vwb2NocyI6MCwicGFzdF9lcG9jaF90cmVlcyI6W10sIm1lc3NhZ2Vfc2VjcmV0cyI6eyJzZW5kZXJfZGF0YV9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE2LDMxLDE1LDg5LDIzMyw2OSw3MywxMTcsMjUyLDExNSwxNTAsMTQ5LDEyMiwxMjAsOTYsMTA2LDEzMiwzMiw5NywyLDIwLDI0NywyMTEsMTA0LDIyOCwxOCwyMzMsMTAxLDIxMiwxMzksMTUyLDIzOF19fX0sIm1lbWJlcnNoaXBfa2V5Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxODksMTI2LDE3LDExNiwxNzQsMjQ1LDAsNTEsMjA1LDIwMywyNTQsMTQxLDY0LDEyNSwxNjMsMjAzLDE3MCwwLDI0MywzNSwxNDAsMTE5LDE3Nyw1MiwyMTAsNTQsMjQ0LDI0Miw2MSw1LDI0Myw5NV19fX0sImNvbmZpcm1hdGlvbl9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE4NywyNTEsMTk0LDc2LDU0LDE3NSw4MSwxNDYsNjcsMjA2LDEwMSwyMzksMzIsMTU2LDI1LDE2MywxNTAsNjYsMzMsMTc3LDExMSwxNTMsNDMsMTAxLDE2NCwxMTMsMjMsMjQzLDIzNywyMDksMjIwLDQ2XX19fSwic2VyaWFsaXplZF9jb250ZXh0IjpbMCwxLDAsNzcsMTYsMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjIsMCwwLDAsMCwwLDAsMCwwLDMyLDE4NCw0MSwxMzQsMjEzLDcyLDI3LDE3MSwxMzQsMTYwLDY0LDE0LDg0LDUxLDIzNCwyLDIyMSwxMjMsODAsMTU1LDE2OCwyNDgsMTU2LDExMywyMzksMSwyNTIsMTg3LDEyOSwyOCw1OCwxMDAsMjExLDAsMF0sInNlY3JldF90cmVlIjp7Im93bl9pbmRleCI6MCwibGVhZl9ub2RlcyI6W251bGxdLCJw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LDc2LDEwOSw4Miw3LDE2OSwyNDgsMTI3LDI2LDU4LDExNSwxMTcsMjA5LDE2NCwxNzAsMTUwLDE2MCw2NCw5MCw1Nyw0OCwzMiw5Myw1NCwyMjAsMTA4LDE4LDI0Myw1MCw3LDI0MiwxMTAsNTEsMzksMTk5LDI1Myw1MSwxODcsNzgsMTM1LDQxLDc4LDE4NiwyMDcsMjAxLDI0Nyw3MSwzMCw5Nyw0MywxMjQsMjMyLDAsNTgsMTQ1LDEwLDI0MiwxNjksMTg4LDI0Myw4Miw1Myw5MywyOCwxMDQsNjUsNTQsMjAxLDUxLDI0OCwxODQsODUsMTQ5LDE4Myw1NywyMDksMjUsMTAsMzcsODQsMTQ2LDIxNiwxNTEsMTQxLDQzLDc4LDIyMywxNjYsMTIwLDYxLDE5NiwxMDgsNjYsMjgsMywxMDcsNjYsMjcsMzMsMzIsMTQwLDIyMSwxNjQsMTMxLDIsMTYwLDEzNSw5NywxNjEsMTIxLDg3LDk3LDYwLDE1OCwxMDMsMTQxLDk4LDIyOCwyMCwxNTMsMTE1LDEwMCwxMDgsODgsNjQsMzQsMTA2LDEwMiw4OCwzLDExNSw4LDEzNSwxOTIsMTQwLDI1MiwzOSw4OCwyMjAsMTg3LDMsMzMsMTU3LDIyMCwxMjksNjcsNjksMTcxLDEwNCw0OCwyMTAsMTc5LDYsMTU1LDEwMSwxNDgsMTc4LDc2LDI1MCw1MywzMiwxOTcsMTAsMTUxLDQ5LDU0LDE4MCwyMzAsMTY1LDcwLDE0OCwyMzMsMTg2LDgxLDUzLDY3LDIxMiw1LDE5NywxNzcsMTA2LDkwLDE5MCwyMjcsMTUyLDY0LDIwMCwxNjMsMjI0LDI2LDE4MywxMzAsNTcsMTE2LDUwLDIxMCw1MiwxMjAsMTc2LDE2NCwyMDgsMTc5LDE4Niw1MCw5Nyw5MSwyNTAsMjE2LDE4NSwzMSwyNDgsMTg3LDkyLDE1NSwyMDUsMjM5LDM0LDE4NiwyNTQsMjgsMzYsNDAsMCwyOCwyMjMsNDAsMjQsMTMyLDIxNCwxMDUsNiwzNCw4OSwxMTIsMjMxLDExLDksMTAsMTU5LDE1MSwyMTQsOCwxMzEsNDAsMTQ5LDUyLDE2MiwyNywzOCw4NSwxNzUsOTMsMTQ0LDYwLDg3LDkyLDQsMjA5LDE5OCwxMTYsMjcsMjUwLDg2LDE3NiwxMjAsOTgsNDMsMTA0LDg5LDEzMSwxMSw5OCwxMTEsNjUsODgsMTY2LDEwNiw0OSw4MSw2Nyw1LDExNywyMzUsMTUxLDExMiwyOCw2Niw5NCwxMzgsMzYsMTM0LDE2NywxODAsOTAsMjQ2LDE0Niw5LDE0OCwxMjcsMjUxLDIyNywxMDUsNjQsMzQsMTQ0LDExMiwxNjMsNjMsMTA1LDE3Miw1NywyMjMsMjQyLDQzLDEyNyw4Myw5NSwxNDIsMjE3LDM3LDU0LDk5LDcxLDE0LDIxOCwxODgsMjEyLDExMiw5OSwzMywxMjIsMTk4LDIyOSwxMjQsMTIwLDIzMCw2NCwxODksMjA1LDQyLDM4LDIwMiw5Miw1Nyw3Myw2NCw3MSw4MSwxMzgsMTI0LDI5LDExNSwxNzEsMzAsMTYzLDE1LDI0NiwxMjksMzIsMTIsMzQsMTU2LDkxLDY2LDg0LDE4OCwxNjAsMjA3LDYwLDIxNCwxNDIsMTAzLDExLDE2MSwxNSwxNDYsMTc0LDE5MSwxMTQsNTAsMjI3LDE3MCw3Nyw1MiwxMzMsMTk2LDYsMTQ4LDg4LDMwLDE4MiwxOTMsMTI0LDY2LDExNiw0OCwxMjMsMTQ4LDIyMiw0OCwxNzUsMjQ0LDE5OCw4MCw1OCwxMjIsODcsNTgsMTIwLDEyOSwxODgsMTc2LDEzLDAsMjUwLDIwNCw4Miw3MCwxODcsMjA0LDEzNiwxMDAsMjEwLDIxNCwxNDMsNiwxMjgsMTM0LDEyNSwyNDAsMjA1LDE5MCw4MywxNjYsMjQsMTUwLDYsMTcyLDEyMyw5OCwyMzksMjM2LDE2MCwyMTUsOTcsMTcsMjIyLDIwNCwxNjgsMTEyLDY3LDk2LDEyNywxNTIsMTMyLDE5MSwxMzUsMTY5LDIyNiwxNzcsMTU4LDIyMywxODcsMTk0LDIxLDEwNSwxODgsMjMyLDEzMSwxNzUsNjQsMjA5LDQ1LDY2LDE0OSw1NiwyMjksNyw0Myw2Myw5OCwxMzYsMTk0LDIwNCwxMjMsMjYsNCwxMTAsMjE0LDEzMCwxODcsMjAsOTksOTMsNTcsODMsMTc2LDIxNCwxMjMsMTg2LDEwMCwxNiw3NCwyMjYsMjQyLDE0NSwxMjgsMTYzLDE1LDExOSwyMDIsNTYsMTAxLDE2OCwxNDAsNTAsMTUyLDEyNCwxMzYsMjAsMCw1OSwxNjcsNTgsMTAyLDcwLDEzMCwyNDUsNDMsOTcsMTM0LDE3NiwxMDYsMTIzLDIwMywxNDksMTg5LDIyLDE5NiwyMTEsNzQsMTUyLDE2MSwyMjYsMTI2LDIyMCwyMzIsMzAsMjM1LDk5LDYxLDE3NywyMTksMjgsMjA4LDE1NCwxMDUsNDMsMTAxLDIwMywyNDYsMzUsNDYsNzksMjUwLDE2MSw0NiwzNSw4OCwxNiw0MywyLDE4MCwzNCwxMTIsMTYxLDgzLDExMSw5MiwxOTksNTYsMjMwLDgsMTIyLDE2NCwxNjgsMzksMTI1LDE3NywxOTEsMTM0LDQsNzcsMTc3LDIzMiwxMTQsMjksNTIsMTgwLDI0LDMsMjA2LDEyLDE4NSwzOCwxOTUsMjMzLDE4MSwxMjYsMjA4LDE2LDIyMCwxMiw4NSwyNCw1NSwzMiwxOTUsMTg0LDEwLDQ0LDIxMCw3NCwyMDYsNDAsMTgxLDkzLDkyLDMsMTY2LDIzLDExOCw0LDg1LDMwLDE3LDIxNiwxMDcsMjM5LDEzMywxMTYsNjIsMTkyLDEzMywxMzQsNDQsOTksMjQxLDEzOSw1Myw2OSw5Niw2MSwyNDAsMTM5LDk1LDkyLDcsMTQ5LDEzMCw0NCwxODMsMjIsMTgyLDE3NSwyMzIsMTg2LDE4MCwxOTksMjQwLDM1LDI0MiwxMjAsMTA4LDYxLDE4NCwzNiwzNCwxNjAsMTg2LDczLDUsMTcwLDIzNiwyMDgsMTg3LDIzOSwyMyw1MiwwLDE5NiwxMDMsMTg4LDQ5LDkwLDIxOCwxMDcsMzMsMTM1LDE2NiwxOSwxODIsMTUxLDE5LDkyLDcxLDQ4LDI0NCwyMDEsMTQ4LDIwMCwxMiwzMywxNDYsNTIsMTgyLDE0LDI0NCw4NCwyMTYsMjE4LDUwLDYxLDIyMCw2LDUsMTE4LDI0LDExMiwyNDAsMTU1LDIzOSwyNDgsMTMyLDE2LDY5LDEyNiwxODksMTA2LDE0MywxOTYsMTcsMjA0LDIwOSwyMjksMTE5LDQ1LDExOSw4NSw2NCwyMDksNzksMTIyLDg5LDE0Miw1MywxNDgsMTU4LDEzNCwxNjYsMTMyLDEzOCwyNDQsMTk0LDE5OSwxNzEsMTA1LDQ3LDQxLDk4LDY5LDI0OCwzMyw0NiwxNzksMTcyLDI0NywxMzYsNDUsMTA3LDIxNiwxODIsMTk2LDk3LDc5LDI0LDI1MCwxNzgsMTA2LDM0LDkyLDE0NCw0NCwyNiwyNDAsMjQ5LDM3LDIxLDIyMCwxMTUsMzUsMzksMjEsMjMsMTk1LDE3MywxNTksMjA4LDE3NywxMDQsNTEsMTYxLDc5LDM1LDg2LDE0OSwxNzksOTIsMjIsMTY1LDkzLDkwLDEzNywxMjMsMTM0LDE3OSw2MywxOTAsNzEsMTgwLDI0NSwyNDksOCwxMzksMTM3LDE5NiwyMzksMjA0LDAsMTE4LDY5LDEwLDc5LDE1MywxMTYsMjMyLDEwLDk5LDczLDE2LDIwMCw4LDEzNiwxNSwxNDgsMjQyLDUsNDgsMCwxMCwyOCwxMjQsNzAsNzMsNywxNjQsMjI0LDcyLDIwNCwxMzYsMjYsNTEsNjUsMTEsNjgsMTg2LDExOCwxNjAsMTc0LDExNyw2Nyw3Miw5LDgsNjUsMTg4LDY3LDE1MiwxMTQsMTQ0LDg4LDIsMjYsMTQ5LDY3LDE5LDc4LDM0LDE0NywxNCw5NywxNDgsMjQxLDIzMSwzOSwyMjEsMTc3LDEzMSwyMTIsMTcsMzIsODgsMjE3LDQ2LDIwOCwxOCwxMTgsMjM4LDIzMywxMDMsMTc3LDE3Miw5MSwzMSwxNjcsMzAsMjUxLDE2NSwxNjMsMTg3LDE0NCwxNTEsMTc4LDExOSw5NywyMjUsMjQ0LDgxLDEzMSwxODIsMjA2LDQ2LDI1LDIwNCwxMjIsNDksMjIsMTMzLDM4LDE2MywyNTEsMTAzLDExOSwyNDQsODgsNDQsMTU1LDEwMiwxOTIsMTc1LDE3NywxMjAsMTM5LDM2LDI5LDI0LDU5LDI1LDIyNSwxMzQsMTQ5LDM4LDY4LDE3NSwxNzMsMjMxLDg5LDE3NSwzNywxMTMsODMsMjQ0LDE2NiwyMDYsMjA4LDk3LDE0OSw1Miw4MCwzMCw0OCwxMDEsMTUyLDk3LDEzNywxODcsMjE0LDE2NCw5MCwxNjIsNjYsMTc3LDMxLDEzOCwyNTAsMTE4LDI1MSwzMiwxMzYsMTk3LDIzMSw0LDUxLDE3NSwxOTQsMTg0LDE5OCw3LDIzNyw5NCwyMjQsMjIyLDI1MSwzNCwyLDIzMCw1LDEyMCwxOTcsNDMsNzUsMjcsMTY1LDEyMCw0LDUwLDIsMTcwLDE5MSw3NiwxNTIsNzUsMTE1LDEwMiwxOTcsNDQsMjI0LDE3MiwxMDUsODIsMTQ0LDgzLDEzNiwxMDksOCwxNDEsMjI4LDExLDEzNywyMDYsMTQ3LDQ4XX19LCJwcml2YXRlX2tleSI6eyJrZXkiOnsidmVjIjpbMjM3LDI0NywyMywxMzMsMzgsMjYsMzMsODQsODQsMzEsMTQ4LDI2LDczLDE1Niw3NywxODEsMTIsODksMTA3LDIxMCwyMDEsMjAwLDY2LDE2MCw0OSwxNDgsMTA5LDI0NCwzOSw0MiwzLDE4MCwxMzAsNTUsMTkyLDEyNSwyMDQsMTI0LDE1MCwxMDAsMTYyLDIwLDEzNSwxNjAsMTIxLDE4OSwxOTIsOTgsOTgsMTQ4LDEyNCwyNDQsMjI0LDE3MiwxNDIsMTIzLDE0OCwxNjcsMjUyLDMwLDM5LDE4Nyw2NywxOTIsMTM4LDE4OSw2Niw3NiwxODYsNSwyMjcsMTA5LDEyMSwxMzYsMTUzLDUxLDE0NiwyMDcsMTMyLDEzMywzOCwxNiwyMCwxNjIsMjMzLDI0MiwxNjQsODksNTYsNDYsMTY2LDE5Nyw5NCwyMDksOTgsNzYsMTgyLDE3OCwxMSwxNjQsMTk3LDk1LDE1OCw1OSwyOCwxODYsMjQ2LDExLDE2MCwxMDMsMTg1LDEzNywxNTUsMSwxOTAsMjQyLDIwMiwzNywyMjksNzUsMTMyLDI0LDEyMCwzMCwxOCw3NSwxOTcsMTM5LDI3LDIxMiwxMTcsMTI5LDIxLDQzLDE2MywxMzUsMTQwLDEzLDE4MywxNjcsMjAyLDIyMCwyMTksMjEsMTg1LDUxLDEzMSwxOTEsMjAsMTgxLDE4NCwyMCwxMTEsODUsMjE5LDEwOSw5MSwyNCwzMSw3OCwxNjQsNTUsMjA5LDIzNiwxNzEsNzcsOTgsOTEsMTYyLDIwNCwyMDcsMTk0LDE2OSwxMTgsMjMxLDIwOCwxNzgsOTMsMTA3LDM5LDI2LDY1LDgwLDEzNSwxNywxNzYsMjUxLDEyNCwxMiwxMjksOCwxODYsMTQyLDE3MCwzLDQzLDIyNCw3MCw3NiwzLDM4LDIzMyw5NywzOSw4MCw3MywxMzIsNDcsMjAzLDEyOSwxNjIsMTMxLDE0MSwxOTAsMTY5LDEwOSw1LDEzNiwxNTQsNDcsMTYyLDI1LDI5LDIyOCwxNjUsMTYyLDIzMCwxMjAsMTE0LDE5NywxMDMsMjI2LDIzMCwxMTIsMjM1LDEzMiwxNywyMjksMjA5LDEwNSw5LDcyLDE1NSw5MCwyMzYsNzEsMjE4LDE5OSwxMjAsMTYyLDE3OSwxMzUsMTksODksMTY1LDE5MSw2NywxNTQsMzYsMjQwLDEzNyw2LDE1MywxODcsMTE0LDYsMTk1LDE1MSwyMyw0NiwyMDMsMzcsMTkzLDc1LDE1MCwxMjEsNDAsMTY2LDE3NywxMSwxLDQ0LDIxNCwyNDUsODgsNzgsMTkzLDYxLDIwMSwxMDAsMjAsMjIzLDIzLDE2MSwyMjEsNTIsMzcsMTc2LDE4LDEwMCwxMiwxODYsMTc2LDIzMCwyNDMsMCwxMyw5OSwyMiwzMSwxNTEsMTU0LDE2LDExMyw4LDE0OCwyNDMsOTksMTAzLDEwMyw3NiwxMzAsMTM2LDE2NiwyMDAsMjAsMTQsMjM1LDE3LDE5NSwyMjEsMTQ3LDU5LDUxLDI0NCwxNywxNjMsMzMsNiwyMjYsNzIsMTA5LDEzNiwxOTcsNDAsMzUsNzAsMTUyLDIzNyw4NSwxNiwyNywxNzAsOTEsMTU3LDQsNTAsOTcsMTA3LDExNiw2OCw0OSwxNDEsMTA2LDEyOCwxOTMsMTQsMjgsMTI5LDIzOSw3Miw2MiwyMDAsMjQ2LDEwNiwzNiw1Miw4Nyw2MywxNTMsMTQzLDE4NCwyLDExOCwxNTUsNzYsMTMyLDE2OSwxOSwxMTMsMjA5LDIzMiwxNjIsMjEsMjMyLDU1LDEzOCwzNCwxMDQsODYsNzIsNzUsNjUsODAsNTAsMTc0LDEwNCwxODUsMjM5LDIxMyw1OSw0MSw2NSw1MSwxNjcsMjUsMTg1LDg2LDIzMCw3LDE4NywyNTEsODksMjQ5LDIzMiw3LDEyNCw5OSwxNTUsMTU1LDE5NywyMDMsMTMzLDEwNCwxNzcsMzEsOSwxMzYsMTQ0LDExLDksMSwxNzIsNjksMjQxLDExOSwxNzgsMzAsMjQ1LDExOSwzOSwyMTksMiwxODUsMTMwLDE2NCwzMSwyNTIsOTAsMjI1LDIyNiwxMTEsNzIsMTgwLDEzNSwxMDIsMTY4LDE0NSwxMzEsMTY0LDEyMCwxLDE3MiwxNTAsMTQwLDE3OSwzNiwyMDAsMTQ4LDEyNywxMjcsNTgsOTYsMTk1LDgwLDEzMiwyMzYsMTkzLDE1OCwyMyw0Miw3MiwyMjMsOTksOTQsMjI2LDIyNyw4MCwzOCwxNTMsMjUsMTYxLDg3LDEzLDEzOCwxMzksMzgsMjUsMTg2LDM0LDE2NywyNDcsODksMjA2LDY0LDYwLDk2LDExNywxMDYsMTkyLDE1MSwxODgsOTQsMTEsNjUsMTk1LDkwLDE0OCwxNjQsMjE2LDIwNSwxNzQsMTU2LDE1OSwzNSw2LDU3LDEwMCwxNjUsODcsNDksMzUsODQsMTgsMCw3OSwxNTAsMjcsMTMzLDIyNywyNDcsMTMsMSwyMyw3MCwxOTUsMTg2LDE5Myw3MCw2NywxNTksOCwyNDMsMTM0LDEyMiw4OSwxNTEsMTA3LDc1LDQyLDE3NiwxMjIsMjAzLDE5MCw2OCwxNjAsMTY1LDE5Niw1OSwyNSwzOCwxMTMsMTUsMjE2LDE3NSwyMzAsMTEsMTYzLDMzLDI0OSwxOTcsMTA5LDAsNDEsMjksNzMsOTYsMTQsMTY0LDM1LDQ4LDIwOSw5NCwxOTQsMTAyLDI2LDE1OSwyNTIsNSwyNiwyNDMsNjgsMTAxLDM4LDIwNCwxODAsMTI4LDY4LDYwLDY3LDg1LDM5LDYsMTYsODcsNzMsMTQ1LDIwOCwyMDQsMzAsMTM2LDIwMSwyMCw5OCwxMTQsMTIwLDE2NSwyMzQsMTg5LDEzNywxOTUsMzAsMTcxLDIzNiwxMDMsODEsODEsMTc4LDQyLDkwLDE2MiwwLDE2OSwxMjQsMTQ0LDI0Myw2OCwzNyw5NiwxMDUsMTE0LDgsMTg0LDEsMTM4LDEwMSwxNTUsMTY3LDIwNSwxNDgsMjA4LDE1LDEzNywyLDEzMCwxMjgsMjQxLDEzOCwyNDIsNTcsMTQxLDE5OSwxMDIsMTM2LDY3LDIxMSwxMDQsMjAwLDc2LDEzNyw0NywxMDcsMTE3LDE1MCwxOCw3NCwxNTgsMTk0LDcyLDEyNywxMjIsMTY0LDU4LDEwNSwyOSwxMzcsMTg0LDc2LDc5LDgxLDEzMywyNTAsMTgyLDE4MywxMTQsMjUxLDEwNCw0MywyNDUsMTEyLDYsMjEwLDE2MiwzOSw5MCwxNjgsNjAsMjEwLDcxLDIyOSwyMDIsNjQsMjE2LDEzMSwxNDUsMjEwLDIwMiwxOTgsMjExLDgxLDEyNyw4OCwxNTIsMjA1LDg5LDIwMiwxMjcsMTg5LDEzOCw1MiwyMDcsMTA1LDg5LDE3OSw5LDEwNCwyNDUsNTEsNCwyNDIsMjM0LDEyMiwxMTEsMTIsMTM0LDIzNCwxMiw5NiwzNCwxNDksMTc1LDc5LDczLDM5LDE0MSwyMTMsMTQ1LDc3LDEzMSwxMzEsMTA0LDczLDEwMiwxMjgsMjE1LDU0LDM1LDI0NiwzOSwzMSwyNDksNzksMjE2LDIwMCw5NCwxNDAsMjIwLDExOCw0NiwzNSwyLDExMCwyMTQsMTIsMTM5LDE4MSw5MCwzOCwxNjcsMTY3LDEyMiwyNywxNDIsNDgsMTcyLDI2LDg1LDMzLDExOCwxNjIsMTg0LDEwOSwxMjAsMTIwLDY3LDQ0LDEyMiw0OCw0NiwxOTIsODYsODAsOTEsMTMsNTMsMjUyLDEwNSw5LDMyLDExMywyMTEsMywxMjgsMTIyLDg5LDE1NSwxNDAsMjE4LDIsMTAyLDY3LDE1MywxOTAsMjMyLDI2LDM2LDEzMSwyLDkzLDEzNyw3MSwyMTQsODQsMzMsMTEsMjExLDk2LDE0NCw1MSwxODYsMjA5LDIyNiwxMjEsMTI0LDE2MCw4OCw4OCwxODEsOTgsMjU1LDgsMTgxLDIyMywxODUsMTk3LDEyNCwyOCwyMiwyMjAsOTYsMTI3LDE3OSwxMjQsMTQ5LDIzMiw2OCwyOSwyMDEsNzAsMTIwLDQ5LDg1LDExOSwxNywxNzgsMTIsMTc2LDQwLDQ1LDIxNiwxMTIsMSwxNjgsMTM1LDk1LDMsMTE2LDIwMSwxMTAsNTMsMTksMzUsMTIzLDIzLDE4Myw0MywxOCwxMTYsNTIsMTYxLDEyMCwxMTYsMTExLDE5NSw2LDIwNCwxMDcsMTM5LDE1MCwyNCwxMzMsMjIsMTQ4LDUzLDEzNSwxNTAsMTEyLDgwLDI0NCwxNywxMDIsMjEwLDI0MywyMDUsNTIsNjAsOCw5MCwxMiwxOTAsMjQ4LDEwMCwxMDUsMzksMTgzLDEzMSw0OSwxMTQsMTgxLDMsMTAzLDE5NywxODgsMTE1LDE2MSwzNiwxMCwxNDQsOTQsODEsMTY3LDczLDQsMTk3LDQzLDE1Miw1MCwxOTcsMTk0LDY5LDE5NSwxNjYsMjAxLDIxMCwyNTIsMTA2LDcwLDI0OCwxNiwxMDAsMjMyLDIwMSwxODcsNSwxOTIsNTYsNzUsNzksMTExLDMzLDUsMTUyLDEwLDIwMCwxOSw1MiwxNjAsMTE2LDE2NSwxNDYsMTEsMjQzLDEwNiwyNDksMjM2LDc5LDE1Nyw4NSw5OCw2NywxNjYsODQsMjE0LDk4LDEyNyw1Miw1NiwxMDIsMTE5LDIxMSwyMDMsMjA5LDIzLDI0LDEzNywxOTIsNjIsMTMwLDEzMCwxMzIsODAsMTU2LDEzNiwyMjcsMTYyLDE2MCw0MywyNiw5MiwxODksMTc2LDcxLDQ5LDE5OSwxMjYsMjAxLDY5LDE3LDY3LDIsMTEzLDIwNSwxMjIsMTc1LDIwNiwxODgsMTU3LDIsMTk4LDExLDY4LDM0LDEyMSwxOTcsNjcsODYsMTU1LDEzNCwxOTIsNjgsMTU0LDc4LDYxLDI1MCw4LDExOSwxMDcsMTU0LDE2OSw1MSw1OCwzMiwxNjYsNjMsMTA0LDE4NywxMDAsMTkyLDIwLDE0NiwyMzgsMjEsMjAsMTEzLDEzMCwxNSw2LDUyLDEzOSw1NiwyMDgsMTI0LDE4NSwyMTIsMjA3LDMxLDU4LDE3MSwxNDcsMjE0LDExNyw0MywxNTMsMTI3LDIxLDE1Miw1Nyw2Myw3MSwxOTMsMjE3LDE1NiwxOTcsMTY3LDE3MSwxNTQsOTAsMTY0LDExNSw4MSwxNTQsODksMjcsMTMzLDExOSw4OSwxNywyLDE3MywxMzEsMTg2LDIxOSw3NCw5NCw3MywxODcsMjAzLDMxLDI0NCwxNjksMTksMTAzLDEyLDE0LDk5LDE2NSwyMjUsMTM4LDM2LDE5NywxMzUsMTg3LDY4LDE1NSwzMSwxMTAsMTA4LDkwLDIyLDgxLDEzNywxOTEsMTA1LDE4OSw5LDE3Miw4MSwyMDcsMjEwLDM0LDcxLDExNSwxODQsMTExLDQxLDE0Myw1MywzNiwxOTUsMTYsNzEsODUsMjMyLDEyMCw3NSwxOTcsMTU2LDIwNCwxOSwzOCwxNzgsMiwyMCwxNTIsMTAzLDI3LDY2LDIyMiw1OCwyMDIsNzgsNDMsNjgsMTE4LDcxLDkzLDMzLDE1NCwxMjUsMjI3LDE0Niw1NiwxMzIsMTkzLDE2Nyw4NywxNTYsMjAsMjAzLDQxLDEyNiwxMTksMTAsMTk1LDI4LDQsMjIsMTMxLDgsNTYsODYsNywxODQsMzMsODQsMzIsMTI4LDIzLDAsMjEzLDE1NCwxMTksMzIsMTY0LDU3LDI0MywxODAsMTgzLDIyLDM5LDE5NywxMTIsMTQ4LDkxLDIxOCwxOTgsMTc1LDg0LDExMywxOTgsMjA3LDM4LDEyMSwxOCwxNjIsNDksMTQwLDIyNCw1NywyMzYsMzIsMTIsOTcsMjE3LDM3LDQ1LDE3Niw3NiwxMDksODIsNywxNjksMjQ4LDEyNywyNiw1OCwxMTUsMTE3LDIwOSwxNjQsMTcwLDE1MCwxNjAsNjQsOTAsNTcsNDgsMzIsOTMsNTQsMjIwLDEwOCwxOCwyNDMsNTAsNywyNDIsMTEwLDUxLDM5LDE5OSwyNTMsNTEsMTg3LDc4LDEzNSw0MSw3OCwxODYsMjA3LDIwMSwyNDcsNzEsMzAsOTcsNDMsMTI0LDIzMiwwLDU4LDE0NSwxMCwyNDIsMTY5LDE4OCwyNDMsODIsNTMsOTMsMjgsMTA0LDY1LDU0LDIwMSw1MSwyNDgsMTg0LDg1LDE0OSwxODMsNTcsMjA5LDI1LDEwLDM3LDg0LDE0NiwyMTYsMTUxLDE0MSw0Myw3OCwyMjMsMTY2LDEyMCw2MSwxOTYsMTA4LDY2LDI4LDMsMTA3LDY2LDI3LDMzLDMyLDE0MCwyMjEsMTY0LDEzMSwyLDE2MCwxMzUsOTcsMTYxLDEyMSw4Nyw5Nyw2MCwxNTgsMTAzLDE0MSw5OCwyMjgsMjAsMTUzLDExNSwxMDAsMTA4LDg4LDY0LDM0LDEwNiwxMDIsODgsMywxMTUsOCwxMzUsMTkyLDE0MCwyNTIsMzksODgsMjIwLDE4NywzLDMzLDE1NywyMjAsMTI5LDY3LDY5LDE3MSwxMDQsNDgsMjEwLDE3OSw2LDE1NSwxMDEsMTQ4LDE3OCw3NiwyNTAsNTMsMzIsMTk3LDEwLDE1MSw0OSw1NCwxODAsMjMwLDE2NSw3MCwxNDgsMjMzLDE4Niw4MSw1Myw2NywyMTIsNSwxOTcsMTc3LDEwNiw5MCwxOTAsMjI3LDE1Miw2NCwyMDAsMTYzLDIyNCwyNiwxODMsMTMwLDU3LDExNiw1MCwyMTAsNTIsMTIwLDE3NiwxNjQsMjA4LDE3OSwxODYsNTAsOTcsOTEsMjUwLDIxNiwxODUsMzEsMjQ4LDE4Nyw5MiwxNTUsMjA1LDIzOSwzNCwxODYsMjU0LDI4LDM2LDQwLDAsMjgsMjIzLDQwLDI0LDEzMiwyMTQsMTA1LDYsMzQsODksMTEyLDIzMSwxMSw5LDEwLDE1OSwxNTEsMjE0LDgsMTMxLDQwLDE0OSw1MiwxNjIsMjcsMzgsODUsMTc1LDkzLDE0NCw2MCw4Nyw5Miw0LDIwOSwxOTgsMTE2LDI3LDI1MCw4NiwxNzYsMTIwLDk4LDQzLDEwNCw4OSwxMzEsMTEsOTgsMTExLDY1LDg4LDE2NiwxMDYsNDksODEsNjcsNSwxMTcsMjM1LDE1MSwxMTIsMjgsNjYsOTQsMTM4LDM2LDEzNCwxNjcsMTgwLDkwLDI0NiwxNDYsOSwxNDgsMTI3LDI1MSwyMjcsMTA1LDY0LDM0LDE0NCwxMTIsMTYzLDYzLDEwNSwxNzIsNTcsMjIzLDI0Miw0MywxMjcsODMsOTUsMTQyLDIxNywzNyw1NCw5OSw3MSwxNCwyMTgsMTg4LDIxMiwxMTIsOTksMzMsMTIyLDE5OCwyMjksMTI0LDEyMCwyMzAsNjQsMTg5LDIwNSw0MiwzOCwyMDIsOTIsNTcsNzMsNjQsNzEsODEsMTM4LDEyNCwyOSwxMTUsMTcxLDMwLDE2MywxNSwyNDYsMTI5LDMyLDEyLDM0LDE1Niw5MSw2Niw4NCwxODgsMTYwLDIwNyw2MCwyMTQsMTQyLDEwMywxMSwxNjEsMTUsMTQ2LDE3NCwxOTEsMTE0LDUwLDIyNywxNzAsNzcsNTIsMTMzLDE5Niw2LDE0OCw4OCwzMCwxODIsMTkzLDEyNCw2NiwxMTYsNDgsMTIzLDE0OCwyMjIsNDgsMTc1LDI0NCwxOTgsODAsNTgsMTIyLDg3LDU4LDEyMCwxMjksMTg4LDE3NiwxMywwLDI1MCwyMDQsODIsNzAsMTg3LDIwNCwxMzYsMTAwLDIxMCwyMTQsMTQzLDYsMTI4LDEzNCwxMjUsMjQwLDIwNSwxOTAsODMsMTY2LDI0LDE1MCw2LDE3MiwxMjMsOTgsMjM5LDIzNiwxNjAsMjE1LDk3LDE3LDIyMiwyMDQsMTY4LDExMiw2Nyw5NiwxMjcsMTUyLDEzMiwxOTEsMTM1LDE2OSwyMjYsMTc3LDE1OCwyMjMsMTg3LDE5NCwyMSwxMDUsMTg4LDIzMiwxMzEsMTc1LDY0LDIwOSw0NSw2NiwxNDksNTYsMjI5LDcsNDMsNjMsOTgsMTM2LDE5NCwyMDQsMTIzLDI2LDQsMTEwLDIxNCwxMzAsMTg3LDIwLDk5LDkzLDU3LDgzLDE3NiwyMTQsMTIzLDE4NiwxMDAsMTYsNzQsMjI2LDI0MiwxNDUsMTI4LDE2MywxNSwxMTksMjAyLDU2LDEwMSwxNjgsMTQwLDUwLDE1MiwxMjQsMTM2LDIwLDAsNTksMTY3LDU4LDEwMiw3MCwxMzAsMjQ1LDQzLDk3LDEzNCwxNzYsMTA2LDEyMywyMDMsMTQ5LDE4OSwyMiwxOTYsMjExLDc0LDE1MiwxNjEsMjI2LDEyNiwyMjAsMjMyLDMwLDIzNSw5OSw2MSwxNzcsMjE5LDI4LDIwOCwxNTQsMTA1LDQzLDEwMSwyMDMsMjQ2LDM1LDQ2LDc5LDI1MCwxNjEsNDYsMzUsODgsMTYsNDMsMiwxODAsMzQsMTEyLDE2MSw4MywxMTEsOTIsMTk5LDU2LDIzMCw4LDEyMiwxNjQsMTY4LDM5LDEyNSwxNzcsMTkxLDEzNCw0LDc3LDE3NywyMzIsMTE0LDI5LDUyLDE4MCwyNCwzLDIwNiwxMiwxODUsMzgsMTk1LDIzMywxODEsMTI2LDIwOCwxNiwyMjAsMTIsODUsMjQsNTUsMzIsMTk1LDE4NCwxMCw0NCwyMTAsNzQsMjA2LDQwLDE4MSw5Myw5MiwzLDE2NiwyMywxMTgsNCw4NSwzMCwxNywyMTYsMTA3LDIzOSwxMzMsMTE2LDYyLDE5MiwxMzMsMTM0LDQ0LDk5LDI0MSwxMzksNTMsNjksOTYsNjEsMjQwLDEzOSw5NSw5Miw3LDE0OSwxMzAsNDQsMTgzLDIyLDE4MiwxNzUsMjMyLDE4NiwxODAsMTk5LDI0MCwzNSwyNDIsMTIwLDEwOCw2MSwxODQsMzYsMzQsMTYwLDE4Niw3Myw1LDE3MCwyMzYsMjA4LDE4NywyMzksMjMsNTIsMCwxOTYsMTAzLDE4OCw0OSw5MCwyMTgsMTA3LDMzLDEzNSwxNjYsMTksMTgyLDE1MSwxOSw5Miw3MSw0OCwyNDQsMjAxLDE0OCwyMDAsMTIsMzMsMTQ2LDUyLDE4MiwxNCwyNDQsODQsMjE2LDIxOCw1MCw2MSwyMjAsNiw1LDExOCwyNCwxMTIsMjQwLDE1NSwyMzksMjQ4LDEzMiwxNiw2OSwxMjYsMTg5LDEwNiwxNDMsMTk2LDE3LDIwNCwyMDksMjI5LDExOSw0NSwxMTksODUsNjQsMjA5LDc5LDEyMiw4OSwxNDIsNTMsMTQ4LDE1OCwxMzQsMTY2LDEzMiwxMzgsMjQ0LDE5NCwxOTksMTcxLDEwNSw0Nyw0MSw5OCw2OSwyNDgsMzMsNDYsMTc5LDE3MiwyNDcsMTM2LDQ1LDEwNywyMTYsMTgyLDE5Niw5Nyw3OSwyNCwyNTAsMTc4LDEwNiwzNCw5MiwxNDQsNDQsMjYsMjQwLDI0OSwzNywyMSwyMjAsMTE1LDM1LDM5LDIxLDIzLDE5NSwxNzMsMTU5LDIwOCwxNzcsMTA0LDUxLDE2MSw3OSwzNSw4NiwxNDksMTc5LDkyLDIyLDE2NSw5Myw5MCwxMzcsMTIzLDEzNCwxNzksNjMsMTkwLDcxLDE4MCwyNDUsMjQ5LDgsMTM5LDEzNywxOTYsMjM5LDIwNCwwLDExOCw2OSwxMCw3OSwxNTMsMTE2LDIzMiwxMCw5OSw3MywxNiwyMDAsOCwxMzYsMTUsMTQ4LDI0Miw1LDQ4LDAsMTAsMjgsMTI0LDcwLDczLDcsMTY0LDIyNCw3MiwyMDQsMTM2LDI2LDUxLDY1LDExLDY4LDE4NiwxMTgsMTYwLDE3NCwxMTcsNjcsNzIsOSw4LDY1LDE4OCw2NywxNTIsMTE0LDE0NCw4OCwyLDI2LDE0OSw2NywxOSw3OCwzNCwxNDcsMTQsOTcsMTQ4LDI0MSwyMzEsMzksMjIxLDE3NywxMzEsMjEyLDE3LDMyLDg4LDIxNyw0NiwyMDgsMTgsMTE4LDIzOCwyMzMsMTAzLDE3NywxNzIsOTEsMzEsMTY3LDMwLDI1MSwxNjUsMTYzLDE4NywxNDQsMTUxLDE3OCwxMTksOTcsMjI1LDI0NCw4MSwxMzEsMTgy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MTczLDI3LDEwNCwzMiw3OSwzNiwyMDUsNjYsODMsMTYzLDE0OCwxMzYsMTczLDI0OSwxNzcsNTgsNiwxMTksMTMyLDE4MCw1OSw0LDEyLDEyMSwxNDMsNDYsNDAsMTQ5LDQzLDEzOSwxNCwxMzYsMTU0LDE0OSwzOCwxMDgsMTg3LDE4NCwxMTIsNDgsMjE2LDEwOCwxMDksNTcsMTE0LDc5LDUwLDcsNiwyMjAsMTA0LDEwNywzOCw4OSwxNDgsNjQsMTE1LDE0MSw1OCw3MCwxNTgsMTYzLDIxMywxNDgsMjQ0LDM2LDIwNCwyMzAsMjAxLDAsNjEsMTAsMzAsMjEyLDE5MywxMzIsODgsODQsMTk1LDExMywyMjgsNDMsMjE2LDEwNywyNSwyMzMsMSw3NiwxMzIsMjA5LDAsMjI5LDE3LDkxLDEzLDExNiwxMTcsMjYsOTksMTUsNzYsMTA1LDEwMywxMDksMjMyLDEzNCw4MiwyMTUsMTg5LDEzLDExMiwzMyw2OSwxNTYsMTAxLDk3LDI0NSwxOTIsMTIzLDU5LDE3MCwyMDUsMTIwLDg4LDE2MywxMTMsNDMsMTkwLDEzMSwxMzksMTQwLDIxMSwxNjgsNzcsMTg2LDEwMSw3NSw1Niw4Myw4NywxNTUsMTMyLDE3Niw5MCw4OSw0NSw5MCwyMSwzNywyNyw1MiwzMyw4OCw1NywxNTQsNTksMTMxLDE0MiwyMTksNzAsMTYyLDEzNSwxNDEsMTU1LDU2LDE5LDE1NSwxNTIsMjMsMjQzLDEwOCwxNTYsMTEyLDE3Nyw2MywxMyw4NCwzMCw2Nyw0MywzMSwxMjMsODIsNTEsMjAzLDEzOSw5MiwyMjEsMjQxLDE0MywyMzQsMjAsMTg5LDI4LDYwLDE5NywxMjQsMTY4LDc2LDYyLDk5LDEzLDgyLDIwOSwxMzAsMiw3Miw0NSwxMTYsOTgsMjgsODEsNTMsNyw0LDU3LDQ0LDIwLDUsNDgsMjQzLDE2MiwzNywxOTksMTkzLDE1NiwyMjIsMTgzLDE3MywxNDcsMjE5LDE3NCwxMDcsOTYsMTk5LDQ1LDE3NywzNSw2LDEwMywxNjMsNTcsMTAwLDEyMSwyNSwxMzksNywxMywxODQsMTY2LDE5OSw1OCwyNSw5LDEzNiwxNTEsMTI4LDAsMTExLDAsOTksNDYsMjQ1LDIyNiwyLDE1LDEzNywxMDksMTY5LDE4MSwxNjIsNjQsMjExLDEwNSwxMDMsMTEzLDE0MywyMjYsODIsOTAsMTM2LDIwMSwxMjUsMTEwLDI0MywxNDMsMTY1LDEsMTA0LDE1MCwxMDgsMzcsMzAsMTAxLDgsMCw5OCwxOTIsMjU1LDE3LDE2OSwyMTksMjQsNTUsNCw0MCw2NSwxNDIsMTM1LDE3NiwxMDQsMTAwLDE3NywxODYsMTkzLDEyNiwyMjQsMTY3LDU1LDIxNywxMTcsMTgxLDc4LDQsMTkyLDUzLDEsNzQsOTgsMjUwLDE1NSw3Miw4NCwxNTksNzgsMTc5LDI2LDMxLDE5NCw0MCwxNjgsNjQsNTgsMTkzLDk3LDY4LDI1MCwxNjEsNDksNDAsMTkyLDIwLDIwOSwxLDE4MiwxNzIsMjMsMTY5LDIxOSwxNTAsNDQsMTIxLDE0NSwxODUsMzMsMTMwLDE1MCwxMTEsMTk0LDE0NCwxNzAsMjQsMTg5LDIzNCw1MCwxMTQsMzcsMTcwLDExMCwyNDYsMTY0LDM3LDIyNCwxMzAsMTYzLDE5MiwxNDUsOTgsMTI4LDIwOCw1MSwyMzIsMTY4LDE0MCw1NCwxOTcsMTI4LDIzOSwyNDksMTE3LDQ4LDgyLDE2MSwxMTMsMTU1LDE5Nyw2NCw4NiwxOTYsODksNywyMywyNTUsNCwxNjUsMTQ5LDEsNTksMTYwLDIxNCw5OCwyMDMsMTk3LDU5LDEwMyw2NiwxOTMsMTMzLDI1LDIwNiwyNDMsMjMyLDEyNSw3MSwyMzUsNzksMTQyLDY2LDU0LDg0LDQ5LDQzLDIwLDE3MiwxMSwyNDMsMjQxLDEzNiw5NCwxMDMsMTQsMTgxLDQwLDMyLDIzNCwyNiw0MSw0MSwyMjAsMTczLDc2LDE0Niw1NiwxMTcsMTA4LDEyOSwxMzgsMTU0LDE2MiwxMjAsMTYwLDE3NiwxNjcsMTU2LDM2LDE5OSw5LDM0LDIyNyw3MiwxOTEsMTE3LDIzMyw1MSwxMDIsMTY0LDE3NiwxNCw0MCw3MCwyMzksMTY4LDE5MywyMjcsMTk4LDE1MSwxNDEsMTIxLDE0MywyMjIsMjQ5LDE2LDE4OSwyNTAsNTYsMjU0LDcsMzIsMjEwLDEzOCwxNjcsNCw3Niw3NSwxMzQsMjE1LDU0LDEzOSwyMTMsNjgsMTIxLDE0NiwxOTYsNDIsMjE2LDExMiw3NiwxMzgsNDEsMjM4LDcsMTg3LDIxOSwzLDE5OSwxOTMsNTgsMTIsMzMsMjUyLDcxLDIwNyw3Miw0OCw3LDczLDE1MCwyOCwxMzgsNDMsNTksMTMwLDEyMywxMDYsMTM4LDY2LDExMSwxMTcsMTc3LDEzMiw5MCw5NCw1MCwwLDExMSw1NCw0LDE1NCw5MywxNzYsMTQ2LDIwOSwyNTIsMTAyLDExNyw2MCwxMzQsMTU4LDE4MCwyMDcsMjA2LDEyNCwzMywxNTgsMTEyLDczLDc1LDE2OSwxNzMsMTM1LDE0NCwxNDAsMTM3LDYwLDM5LDEwOCwxMSwxMTgsNDksMTE2LDc2LDE3MSw4MywxNjIsMTc2LDIzMiwyNiwyNywxNzAsMTI0LDEyMywyMiwxMDgsNzYsMTksMTUxLDE4LDE3MCw4OSw1NywyMzAsMjAzLDIwMCwyNDQsMTcxLDM5LDEwMywxMDAsMjMyLDIzMCw2Myw5MSwxMCw3NiwxMDcsMTc2LDg0LDEzOCwxNzIsNDcsMTI1LDE4NCwxMjYsMSwxMjIsNDYsNjUsMTk3LDM1LDIyOSw1LDExOCwyMjksNDEsNjksNTYsMTE1LDE0NiwxODYsNDIsMTUsMTAsNzIsMTE4LDE5Myw5NywxNDUsMTQ1LDI0MSwxODUsMjEyLDIwNCwzNiw5MiwxMDMsMTM0LDE5OSwxMjAsMzYsMTIyLDE5Miw0Niw0MywyMzEsMTY0LDQ3LDIyLDgyLDcxLDEwMSwxODgsMjA0LDEwMCwyMDcsMTgxLDIzNSwxNSwxNjEsNiwxMjcsMTUxLDI0MiwxODksMTY3LDE2MCwxMzAsMTkwLDIzMCw1Nyw4NSw4LDE0LDIyNCwxLDE4MywxNTcsMjAzLDY5LDIwNiwzMiwxMDQsMTMyLDE2MiwxNzcsMjgsMTY0LDEyLDIyMiwyMzEsOTIsMTQ1LDIzNiwzOSwxMDEsNiwxODksMTUsMTk1LDE1MCw3NSwxMDcsNjQsMTIyLDIwOCwxMiwxOTEsNjUsNzAsODUsMjAwLDE5LDEzNiw5LDk5LDI0NiwyMjUsOTEsMjQ0LDEyNCwxMTksMjM1LDE2MiwzMCwxNzksOTIsOTQsMCwyNDIsMTU2LDIzOSw3NiwxNDUsMzEsMTQ3LDUxLDEzMCwyMTIsMTAyLDE5LDMzLDUwLDk4LDIxMCw0OCwxNTMsOTAsMTI5LDI0NCw3NCwxNDMsMTQ2LDEwNSw5Nyw3MSwxMTQsMjA1LDEwOSwyNDgsNjMsMjQ4LDEzMywxMTAsMTc5LDU3LDQsNzEsNDIsMzcsMjI5LDEwMyw1MiwxMzYsNjksNTYsMTMzLDIzMyw1MCwxNTQsMjE1LDI5LDY2LDE2NCwxMDksMjcsOTEsMTgyLDEzNiwxNDksOTIsMjgsMTA1LDEyOCwyNDUsNzMsMTEsNzAsMTM5LDM5LDE0OSwxOCwyMDAsMTI4LDE0NiwyNiw1Myw4NSwxMjYsMzQsMjAyLDE3OSwxMzgsMTY1LDc0LDMxLDE3OSwyMDEsMTEzLDI3LDU3LDU1LDE1NiwxMTEsNjksNTYsNzQsMywxMzAsMTc3LDIyNSw4LDIwMSwyNDgsMzQsNjEsNCw5NywxMzcsMTMwLDE5NCwxNjcsMTU1LDE4MiwxMiwxODcsNDMsNzcsMTE3LDIxMiwxNjgsMjQ5LDg2LDE0OCw3MywxNjEsMTYyLDIyLDUyLDEyOCwyOSw0OCw0MiwyMTEsMTAwLDEwMCwyMDIsMTkzLDg3LDE3OCwyMzUsNTQsMjI0LDE2LDAsMTAwLDExLDE3NCwxNjEsMjAyLDEyOCwxMTAsMTgwLDE5NCwxOCwxNDksNTQsMTc3LDEwNSwxODgsMTM2LDE2OSw5OCwxOTgsMzgsMTI3LDEzNCwyMTYsNDMsMjM4LDIxNCwxMTgsMTU0LDM1LDYzLDQ4LDE3MCw4NCwyMTgsOTAsNDcsNzcsMTI5LDE5OCwyMzUsNTcsMTU0LDIyNiwxNywxNDUsMTY1LDIxNiw4NywxNzUsMTgzLDE3LDI0MCw0LDc4LDIzNyw0Myw4NSwyMCwyMjYsMTY5LDE0NywxMTQsNDYsMTE0LDExNiw2NiwzNywxNTQsMTE5LDE3MCw1MywxMTQsMjMzLDE2MSwxNTAsMjI5LDE0MCwxNTYsMTMzLDEyMSwxOTQsMTM3LDIsMTQ1LDE4NiwxMTgsMTI5LDI4LDIyNSwxNywxNTcsMjMxLDYwLDIwNiwyMzIsMjgsMjQ4LDM0LDY1LDE5NCwxOTIsMTA5LDEwNSw5NiwxNDYsMiwyNDksMjA0LDE4LDEzOCwxNjIsMjMwLDc0LDEyNiwyMjAsMTAzLDExMywxODgsMzUsMTE4LDE0OSwyNCwxMzAsMzYsMjAsMTcsODAsMjQ3LDY4LDE2NywyMTEsMTMsMTYxLDYsMjEsMTE1LDM1LDE4Niw1MSwyLDg2LDE0LDE2Nyw2MCwyMzQsMTcxLDE4Miw2Miw1OCwxOTgsNzUsMjAzLDEwNCwyNTAsMTI4LDg0LDczLDQ0LDE1NiwyMDMsMTI4LDE3NywyNTQsNzMsNTcsMjI0LDcsMTI5LDI2LDIyOCw3MSwxODEsMTQ4LDEwMywxNzksMTI0LDEyOSwzMiwxMSw3Miw0LDM3LDE2NCwxNzUsMTE5LDk3LDIwMSw5MSwxOTEsMTU5LDIxMSwxNzUsNywyMzQsODgsMjE1LDI0NCwxNDMsMjQ4LDEzNywxMSwxNzUsMTM0LDExNSwxMjEsMTQ2LDE5MSw0MSw3NSwxNDQsMTI0LDEyLDEwNiw3NCwxMjAsMTkxLDU3LDg2LDQ4LDEwNywyMTgsNTgsODEsOTEsMTE1LDQyLDIxOSw3MiwxMjYsODEsMTg5LDIwOCwxNzYsNDQsMjQzLDEzMSw4Miw3MSwxNjAsOTUsMTQ0LDIzNCwxNTIsOSwxNDYsMTIzLDIwMiwxOTYsMTEwLDEzNCwxNjYsMTA5LDEyNiw4OSwxNDMsMjEyLDEzMywyMCwxNzUsMjMwLDI1LDAsNDYsNzUsMTQwLDIyOSwxOTcsMTgwLDE5Miw3NywxMzcsODAsOTksMTMwLDIyOSwyMjYsMjEsMjU0LDE5OCw3MywxNTEsMTMzLDE1NSw1MywyNTUsMTQzLDE5MiwxMDYsMTI0LDE1Miw1NywxMjYsNzYsMTgzLDIwNCw3NywyMDIsODcsMjM2LDEwMyw5Nl19fSwibGVhZl9ub2RlIjp7InBheWxvYWQiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzcwLDE4MCwxMzgsNzEsMjQyLDEwOCw2MywyNDAsMTg5LDE5OSw0MSwxMTAsODksODksMTk1LDE0NSw4OSw3NCwzMywyMTMsMTQsMTY3LDkxLDEwMywxNjMsNjYsNywyMTAsMjM2LDksNTAsMjQwLDEwMCwxNTMsMTAxLDI4LDg1LDksMTYsMTYzLDE3NywxMjAsNjQsMjQ3LDExLDksMTMzLDk1LDE1OCw4OCw2MiwxNDUsMjUyLDEwOSwxMzQsMjMwLDkyLDIzMiwyMDQsMTAxLDIxNyw2MCwxNjksMTI2LDkyLDIwMywyMzgsODYsMjEsMjMzLDg0LDQ1LDE1NSwxMjksNDIsMTM3LDE1MCw1OCwxMDgsNDEsMTYxLDExMywxNDgsMTc1LDg2LDE1NiwxNiw5OCw3NSwxMzgsMTIyLDcsMzMsMTM1LDkxLDc3LDI0MiwyMywxOTEsMjQzLDQ4LDksMjUsMTAwLDQ0LDI0OCw3MywxMjQsNzEsNzQsMTQ3LDIyMCw0OSw0MywyMjgsNTEsMTg2LDEyMCw5NiwxODksMTc1LDM4LDExNSwxMDgsMTEyLDE2MiwxMDMsNTgsNDcsOTQsMjQ2LDQ4LDI0Niw2NiwxMDksMCw2Nyw2NywyMjksMTQ3LDY0LDEzNywzLDE2MywxMTksMTc5LDYzLDEwNSwyMzEsNDYsMTgwLDk4LDEzMSw4OCw0OCwxNDYsMTA0LDIwOCwxMzQsNiwyMCw1LDcsMjMzLDE0NiwyNDgsMTM1LDExNSwxNjcsODEsNzMsMTE5LDEzNyw4MSw5MCwxNzcsNDMsMTY3LDIyLDQ5LDIxLDI1LDExNiwzMywxMzAsNjIsMTEwLDIxNywxOTUsMTU2LDEwLDE3MiwxMzAsODYsNTgsMjEzLDU4LDEyOCw1Miw2NywzMywxNiwyMTksODMsOCw0LDE4MCwxMTksMTc2LDE5NywxMDcsMyw3OSwyMTYsMjQ0LDEwOCwyNDIsMzksNjQsMTY3LDI0OSw0NiwyMzksMTM2LDE2MSwxODAsMjI4LDE2NywxOTMsNSw0MSwxNTYsMTQ5LDEzOCwyMjAsMTQ3LDE0NywxMDcsMTI4LDY1LDgzLDE4MiwxMzIsMjUxLDIzNSwxNjAsMTk0LDIyOCw3OSwxNTIsMTQ1LDE3MCwxNDYsMTIyLDE2LDIwNiwxNzgsNjEsODQsMjE5LDIxLDksMjUxLDE4OCwyMTcsNjcsMzUsMTQ3LDIzMiwyNyw4NiwxNiwxMTAsMTMzLDE1Myw2MywzMCwxOTMsMjAxLDg4LDIzNSw3MiwyNTQsMTY3LDIxLDkzLDg1LDUsNjIsMjQ3LDc2LDE0LDg3LDEwNCwxNzYsMTY0LDEzLDE1NCwyMTUsMTA0LDEzNiwxMzIsMTQyLDU2LDIzMSw5NiwxNTksMTY4LDI0LDE2NywxMDEsMTQyLDEyNyw5MiwxMywyMzYsNjUsNTUsMTAwLDE3NiwxNDAsMTY5LDY3LDY4LDY4LDcyLDExNCwxOTcsMjExLDExOSw5MiwxMzgsMTk3LDIxMCwxOTksMTMyLDE2Niw1MCw1NCwxNDYsMTE1LDQwLDM4LDE3LDY4LDIzNiw0Myw4NSwxOCw4OCwxNDksMjQyLDgyLDgyLDIwMCw5NywxODAsOTcsNTEsOCwxMTcsMTk4LDExNywyMDEsMTYwLDU1LDExNiwxOTMsMTQwLDE0OCwxNyw0LDYyLDUzLDExNywyMTgsNTQsNzcsMTY3LDIxNCwxMSwyMDEsNDEsMSwxNSwxODYsMTcxLDIyNyw0NCwzNiwxMSwxOTksMjA0LDM2LDI0LDE3OSwyMjAsNTMsOTksMTgwLDEzNCwxNiwxNzgsMjI4LDQyLDE3OCw2OSwxNTEsMjA3LDEyMCw4MSwyMDIsMTE4LDE2MywxMDUsMjA0LDU0LDU5LDE5MywxMDQsMjAwLDE2OCwxNzYsNzMsMjUwLDY3LDI0NSwxNzIsMjksNzMsMTAxLDExMCwzOSwxMDQsMjUsNTksMTMzLDkyLDc1LDEwMSw4NSwxMzksMTE4LDE3NSwzNSw3LDEwNywyMTQsMTIsMTU0LDI0Niw1NiwyMCwxMDksNTMsNDgsNzksNzIsMTEyLDE1Niw4LDkxLDI1MiwzMiw3MSwxNzcsMjQzLDEzOSwxODQsMTk2LDEzNSw3Miw2NywxMjEsNDYsMjQ0LDEzMCwxMjEsMjQ4LDE1NSwyMjUsMiwxMDgsMTY4LDUwLDEwOCwxLDEwMiw1Nyw1OCwxNTAsMTI2LDEyMCwxMDUsNDgsOCwxOTksMTAsMTYwLDE4MSwxMzIsMywxMjMsNTMsMTYyLDE3LDE5MywyMDIsMTg4LDE0OSwyMjUsMjYsODMsMTMyLDExNSwxMDcsMTg2LDExMyw5OSwyOSwyNTIsNTQsMjQ3LDE1MywxNjUsMTQ4LDE0NywzOSwzMCw0OSw2Niw5NywxNjIsMTMwLDQsMTA1LDE2MywyMDAsNzMsMjA2LDc0LDE4Myw2Miw4NiwxNjYsMTg4LDEwMywyMjAsNTgsMTgwLDE2Miw1MCwxMTksMjA5LDExNSwxNjksNjQsMTMwLDEwLDkwLDQ3LDc0LDgsMTYwLDM3LDY0LDExOCwxOTMsMTUwLDEyLDQxLDI1MSwxMSw3NSwxNjQsMTMyLDE5NywyMzYsMTQ2LDIzNiwxMzQsMTMyLDI0MCwzOSwxMDYsMjQ0LDI0NSwyMCwxMzQsMjI1LDgxLDI1LDE0MCw3MiwyNTIsMTM3LDI4LDUyLDEzMSwxNjUsMTcyLDEwOCwyMDMsMjgsMjA4LDc3LDIyMCwxODMsNzYsMjA4LDczLDM4LDIzNiwxODAsMCwxOTksMTE5LDM4LDM5LDQ5LDYwLDQzLDIxNywyOCwxNiwzNiwxODAsMjM1LDExOSwxMjksMTcwLDcxLDE4OSwxNzcsMTM5LDcxLDE1MiwxMjAsMTc2LDEyNiw1OCwxMTQsMTMyLDczLDUwLDE5Niw3LDE3NCw0NSw4NCwxMDMsNzAsOTEsMTgyLDEzNSw2OSw5NSwxODUsMjUwLDEzNSwxNjYsMTYyLDE0NywxOTQsMTk3LDExNCw5MiwyNyw5OCwyMzQsMjMyLDE0MywxMDAsMTQ4LDEzNCwyMDgsMjI3LDMwLDUzLDI0OCwxMTAsMTc1LDI0NCwxODYsMzIsMTI0LDcsMTY4LDI0MCw1MSwyMDMsMjQ5LDIyLDYsMTk0LDcwLDExMSwyMSwxMTgsMywxOTIsNDIsMTc3LDI0MCwxNiwxMTcsMTgxLDI3LDQxLDIwMiwxNSwzOSw2NiwxODEsMjAxLDY2LDg3LDE3OSwxMjksMTAwLDExNCwxNDQsNzcsMTI2LDkyLDIwMiwyMjAsNjQsMTE3LDE0MiwyOCwxMzIsMjE2LDI0OSwxNzcsNTEsMTUwLDEwMiwyMzksMTIzLDMwLDE5LDgwLDIwNCwxNjAsMjMsMTM3LDExNiwxNTYsMTI1LDEyOCwxMzEsOTksMTg4LDYsMjAsMTQ0LDE1MywyNCwyMjcsMjEzLDgwLDI0OSw0MSw2Nyw2NSwxLDQyLDI0NCwxNDYsMTI5LDE4Myw4MywxLDE5NCwxNjQsMTQsMTcxLDE4NCwxMjQsMTI4LDExNyw3MywxMTQsNDksMTc3LDE5Myw4NCwxNTUsMTUyLDAsNTgsNTksMjQ1LDEyMSwxMjcsMjEzLDEzMCwxMDYsMTc5LDcsMjE5LDE2OSwyOCw3MiwxMTcsNSwxOCw5MCwxODQsMjQwLDgyLDE3MCwyNTAsMjQ1LDYzLDQwLDE4Miw2OCw4NCwxNTUsMTc0LDUxLDE3NiwxMjgsMTAwLDExLDE1MSw4NSwyNTAsMTg2LDExNiwyNywyNSwxNTYsMTcxLDUxLDE2NCwxOTcsMjAzLDE4NywxODAsNDYsMTQ3LDIxNSw2NCw3MCwxMTYsMTYsMjE3LDIyOSw5OCw1MSwxNTAsMTQ3LDIxNiwxNzcsMTQ2LDE5MSwxNTMsMTQzLDM2LDIzLDMxLDIxOCwxOTksMTYyLDIwLDIxMiwxMCw3MCwxNjQsNTQsMTYsNjUsMjQsMTE5LDE3Niw0LDIwOCwxNTEsMTg4LDUxLDcxLDE4OSwxMDksMTY2LDE1NiwyMTEsMTU2LDE4NywxOTgsMTM4LDUzLDEzOSwxNTQsNDMsODcsMTUwLDQ5LDE3OSwyNDAsNTEsMTEwLDExOCwxMzIsMjEwLDkwLDEzMCwxNTQsNjQsMTMwLDIxMywyMjcsMTg2LDUxLDEwNywxOTEsOTEsMTU0LDQ3LDEzNCwyMDgsMjA1LDIxMywyMTIsMjA2LDUsMTI4LDE4NywxMDcsMTMzLDEwMSwxOTEsMTE1LDE4LDEzOCwxMDUsMjcsOTgsMjI1LDEzMywyMTgsODEsMzgsMTE5LDIxNyw0OCwxMzYsMjEwLDIwNCwxMjAsMTY3LDcyLDk3LDEzNSwxMDYsMjAzLDM0LDE2LDQ1LDE1NCwxOTAsOTIsNTEsNDYsMjA5LDk2LDE4MCwxNjgsMTAwLDQwLDI1MCwxOTIsMTQ3LDIxOSwxMDUsMTgzLDg3LDQzLDE1OSwxODUsMjQ3LDUzLDIzOCw0NCwxODAsNDYsMTgsMjgsMjE2LDE2NSwxMDEsMTYwLDIzMSw1Myw2MywxMTIsMTAzLDIxNywxODYsMTAyLDEyOSwxOCwxNDEsNzYsMTE5LDczLDIxMiw4MCwxNDcsMTU3LDk4LDEyNSwxMjIsMjAzLDU3LDI1LDE5NywxNSwxODcsMjE5LDMsMTI1LDgyLDEwMyw0MCwwLDQ3LDIyOSwyNSwxMTcsMjQ2LDIwLDE5MiwzLDIwMCwxLDE4MCwxNTAsMjA1LDIwMSw1NCwxMDYsMTgxLDExMyw0Myw4Myw0Myw1NCw3MiwxMDUsODAsMjUsNTksMzcsMTc1LDIxNCwxMjMsMzMsMTUzLDExLDIyMSwxOSwxMzEsMTMyLDI0MCw4MCw5NSwyNTEsNCwyNTQsMjUwLDgwLDEzMywxODcsMTgyLDExMiwyNDUsNzUsMTI0LDEwNywxMjEsNCwyNDAsMTk4LDI0MCwxNjIsNzIsMjI4LDI1MiwxMjAsNzcsMCw3MiwxODEsMTk4LDI5LDEwMiwzNywxODEsNDUsMTk3LDk3LDE1LDIzLDE4NCwxNjgsMTAyLDUxLDY0LDExNSwxMTMsMjM3LDIyNSwxMzgsODksMiwxMjgsMjM5LDE4MSwxNzUsMTAyLDIxMSwxNjAsNTQsMTgyLDM1LDIzMyw1MCw5LDEwNCwxMDAsMTMxLDI2LDg1LDQ4LDE1Nyw2Nyw2OSw3MywyMDMsMTI4LDQsMTcyLDE1OSwyNDMsNzQsMTQyLDE5NiwxNjksMTksNzksMTUyLDIsNiwzMCwxMzIsMTcxLDEwMywyMjEsNywyMTEsMTY5LDc4LDIzNSwyMDYsNjksMjgsMjUyLDEzLDY5LDEyNSw2NCwyNTQsMjQ3LDE3LDE2MCwyMCwyMDIsMTQ2LDAsMjMyLDAsMTIsMTcxLDk2LDc2LDEzMywxMzQsMjQzLDU5LDI0MCwxNTAsMTQ5LDk1LDIwOSwyMTksMTk5LDczLDE4OCwxMDUsMTAzLDEwMSwxODUsMjQ1LDEzLDk1LDIyMiwyMDQsMTYyLDQ1LDEzOSwzMiwxMDUsNV19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyMzksMjM3LDI1MSwxNTIsMjMxLDE0MCwyNTIsMzMsMjM3LDE3NCwyNDIsMjQxLDEyNCwxMDMsMTMwLDI0LDc2LDEwNiwxNDUsMjI3LDAsNTEsNjgsMTEyLDE2MCw0Niw0Miw0OSw4MiwyMzMsNzcsMTE3XX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTgsMTExLDk4XX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJLZXlQYWNrYWdlIjp7Im5vdF9iZWZvcmUiOjE3MjA2ODg5NTAsIm5vdF9hZnRlciI6MTcyNzk1MDE1MH19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzIyMiwxNzksMywzMiw5NCwxMjcsNjYsMjQ5LDE4OCwxMDcsNzcsMTg2LDEyNiwxODksMTM1LDUyLDY4LDQwLDE3MiwxMTAsMTM1LDI0NCwyMDgsOTUsMTY3LDIyMywxNzcsMTgyLDE2MCw0NiwxLDQ1LDEwOCwxOTEsNzIsMTE5LDE5NiwyMiwxNTAsMTk0LDUzLDIyLDIwMyw5MSwyMjMsMjA0LDE1MSwxNDQsMTI2LDIwMywyNDksMTIxLDYyLDQ1LDQsMTQ0LDg5LDI3LDE4MCw4NCwyMzYsNjYsNTksMV19fX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbMTEzLDUwLDEzMSwxNzUsMTU5LDEyNSwzLDIzOSwxMjUsMjA2LDE4LDg4LDU0LDMxLDIzNywxNzYsMjMwLDI0MCw3MywxMjQsNDIsNjksMTg2LDI0OCwyMCwxMTQsMjksNTEsMTEwLDEyMSwxMDksMjQ0LDQ3LDM0LDEzOSw4OCwxNyw1NiwxMjIsMjUwLDIxMSwyNTMsMjUxLDEwOSwyMjgsMTQzLDE5LDkwLDE5NSw2MywxMjIsMjQzLDEwNCwxMjUsNjQsMjUwLDgyLDI5LDEwLDE2MiwxOTksMTYsMTY1LDE0XX19fX19LCJwcm9wb3NhbF9yZWZlcmVuY2UiOnsidmFsdWUiOnsidmVjIjpbMjA1LDExNiwxNjQsMjA2LDI0MCwzNCwyMTQsNjAsMjQzLDE3NiwxMTgsMzEsMjAzLDE1NywxNCwxNTUsMjMxLDI1MywxNjUsMjE0LDcsMTE2LDc5LDMwLDYwLDIxNSw2LDIxMSwyMSwxMDIsOTIsODldfX0sInNlbmRlciI6eyJNZW1iZXIiOjB9LCJwcm9wb3NhbF9vcl9yZWZfdHlwZSI6IlByb3Bvc2FsIn1dXX0sInN0YXRlIjp7Ikdyb3VwTWVtYmVyIjp7Imdyb3VwX2Vwb2NoX3NlY3JldHMiOnsiaW5pdF9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzIzOSw4MiwyNDYsMTc2LDI5LDc4LDU3LDE1MiwyMiw5NiwxMjksMywyMjksNDIsMTUyLDE3MiwyMDcsNzEsMjM1LDIwMiw2NCwxNjAsMjM2LDE4OSwyNTAsMTMsMTE0LDEyOCwxNjUsNzIsMTExLDE2Ml19fX0sImV4cG9ydGVyX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbNzEsNzksMjEyLDE2MiwxNDgsMTcyLDE3NSw1MiwxMTYsMjE5LDEyMCw5MiwyMDAsMjQxLDEwNyw3OCwxMDMsOTUsMjA4LDM2LDQsMTA3LDE1NiwyNSwyMzIsMjU1LDExMCwyMjAsNTEsMTY1LDQwLDE2NF19fX0sImVwb2NoX2F1dGhlbnRpY2F0b3IiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzY5LDUzLDE3LDc4LDE5NCwxMzAsMjM1LDMxLDE2NywxMTUsMTA4LDExNywyMjUsMjYsMTUsMzEsODIsMTgwLDY5LDEwNCwyOSwxMjEsMTIwLDk5LDE5MCwyMDAsMjQwLDI0LDE3NSw3MSw1OSwxMDVdfX19LCJleHRlcm5hbF9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzEwOCwxNDQsMTg4LDIyMCwyMjUsMjM3LDIyNCw4NywxMzMsMTc5LDg3LDIyMiwyOCwxNzQsMTQxLDE2OSw0NiwyNDgsMjQsMTQ0LDIwOCwyMTIsMCwxODEsMTk2LDkxLDE0LDExOCwxMzksNDEsMTk5LDddfX19LCJyZXN1bXB0aW9uX3BzayI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTE4LDEzLDg5LDcxLDM0LDE4MSw4NiwyMSwxNDYsMTQ4LDM0LDc1LDE3NCwxNTksMjEwLDE1MCw0MSw1MiwxNTksMTMwLDI1NCwyNDcsMjQ2LDUsMTg5LDE3MywxODEsMTM4LDEzNywxMTgsNDAsODddfX19fSwibWVzc2FnZV9zZWNyZXRzIjp7InNlbmRlcl9kYXRhX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTk1LDE0NiwyMTIsNjksNDQsMTUyLDc0LDEzNSw3OSwxNDQsMTQ0LDIxMCwxNDAsNzIsMjQzLDE0MSw2NSw3OCwxMjMsNzUsMTUxLDE2OCwxNDEsMTU3LDEyMCwyMTYsMjEwLDI0MCwyOSw0MiwyMDYsNjFdfX19LCJtZW1iZXJzaGlwX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTQ2LDE0NiwxMDgsMjA5LDc5LDEyOSw4NywzMywzMywxMzcsMTcwLDIwLDU2LDI0NywxNDMsMTk4LDI0NSwxMDEsODEsMTcxLDY2LDEwOCwyMTgsMjQzLDE1NywxMDQsMjE1LDQ2LDIyNSwyMjYsMTYxLDEzNF19fX0sImNvbmZpcm1hdGlvbl9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6Wzg3LDk2LDExOSw3NSw2MiwyNDcsMTAyLDM1LDQ4LDUxLDI1MSwyMSwxOTgsMTEyLDI1MSwyMTgsMTY1LDIwMywxODIsMTY0LDE5NiwyMCw5Myw4Myw1MywxNjksMTQ1LDY5LDIyOSwxMjYsMzQsNzVdfX19LCJzZXJpYWxpemVkX2NvbnRleHQiOlswLDEsMCw3NywxNiwyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMiwwLDAsMCwwLDAsMCwwLDEsMzIsMTI1LDExNSwyNDQsMTM3LDIzNiwxNTcsMjQsMTM0LDEzMCw3MywxMDEsMjE0LDYwLDg2LDE4OCw5MiwxLDI0Myw3NSw0Niw4NSw2MCwyMjAsMTkwLDEyNywxMjEsNTQsMTU2LDE3LDI1MSwyMzUsMTM1LDMyLDE3Miw2NCwxNTAsNTMsMTcsMTk1LDI1Myw2OSw3LDE2NCwxODcsMTA3LDE2OCwxNzUsMjQxLDkxLDIxMCwyMDUsMTcyLDM1LDEzLDYwLDE4LDI3LDgyLDIxMSwxMTQsMiwyNTEsMTY1LDEzNCwyMjksMF0sInNlY3JldF90cmVlIjp7Im93bl9pbmRleCI6MCwibGVhZl9ub2RlcyI6W251bGwsbnVsbF0sInBhcmVudF9ub2RlcyI6W3sic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE3Myw4NywxNDUsMjEwLDIyOSw1Nyw3MCw5OCwxOTcsNzYsMTQyLDIzMywxNTcsNSwxNzMsNjcsMjAzLDEyNSwyOSwxNzksMjQzLDQsNTgsMTg1LDIwMiw5NSwxLDU1LDE0MSwxNTgsNSwxNDddfX19LG51bGxdLCJoYW5kc2hha2Vfc2VuZGVyX3JhdGNoZXRzIjpbbnVsbCxudWxsXSwiYXBwbGljYXRpb25fc2VuZGVyX3JhdGNoZXRzIjpbbnVsbCxudWxsXSwic2l6ZSI6M319LCJzdGFnZWRfZGlmZiI6eyJzdGFnZWRfZGlmZiI6eyJkaWZmIjp7ImxlYWZfZGlmZiI6eyIwIjp7Im5vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbMTM0LDE2OSwxMDQsMjA3LDEzNCwxNDUsMjAsMjcsOTgsMjE0LDY3LDY0LDEwMCw5Miw5MSw3OSwxNjgsMTY4LDI4LDIwOCw3NCwyMzIsMTEsMTc3LDg3LDI1MSwyNSwxLDI1MCwxNzEsMjA5LDE2LDE2MywxNzUsMTQwLDQxLDkyLDE1MiwyMiw4MCw4MCwxMDcsNjgsMjUxLDMsMTU5LDIwOSwxMjUsNDgsMTY1LDEwOCwyMzYsMjAsMTEsNTQsMTAwLDE4OCwyMjgsMTQ0LDE3NiwxODYsMjIwLDE0NywxMDgsMTYsOTMsOTMsMTc2LDQzLDIxMiw2NSwzOCwxNDcsMTYwLDgsNzIsMjcsMTA0LDIyNCwyNDMsMTMzLDE0MiwxMDEsMjA2LDIwNCwxOTcsNjYsODgsMjQsMTQzLDEwNSwxMzcsMTAzLDAsMTk2LDQ5LDI0MSwyMDQsNTMsODcsMjIsMTI3LDE4OCwxMzIsMzgsMTEyLDE2OCw1MCw5Niw0NCw2NywyNDQsMTM5LDExMSwxNjUsNTQsNTMsMTg2LDIxOSw4NCwxMzEsMTEsODIsMTkwLDk2LDE4LDIzMCwxOTMsOTcsMjA5LDgwLDg1LDY0LDczLDU0LDkzLDE1NSwxODgsMTQsNiwzNSwxODIsMTMyLDE3MCwxMTYsMjMwLDQyLDMzLDIzNSw4NSwxMjYsMzksMTA1LDEzOSw5Miw1Nyw2LDE4Niw4OSwxNTcsODMsNDAsMjA3LDE3OSwxNjEsNjAsMTQwLDIwNiwxOTgsMTcxLDExOCwyMzIsMTM0LDg4LDY5LDE0MCw4OSwxMzUsMTE3LDYyLDE1NSwyNTAsOTUsMTUyLDIyNiwzMCwzMCwxMTQsMTkyLDk4LDIxNywxMTYsNzYsMTY4LDAsMjI1LDEsMTU3LDE5MCwxNzIsMTAzLDE0MSw5MiwxNTUsMTgsMTE3LDU4LDEzMCwxODEsMTk2LDI3LDU4LDc5LDk5LDg0LDgsMTg5LDE5NCwxMjgsNSwxMTQsMjEsMTUsOTIsMTg5LDk1LDEzMywxODIsMTQ5LDE4Niw1MiwyNDksMzksNzIsOCwyMSwxMDksMTQsNTMsMzcsMTc4LDE5NiwxMTQsMTc5LDE3MSw2OSwxODksNDEsMTU1LDE0LDgzLDE1NywxNzAsMjQ0LDM5LDE0OCwyNDQsMTcwLDgwLDE4NiwxNTUsMTAwLDI0MywxODksNTAsMTc3LDE0NSwyMjUsODQsMTgsMiw3LDE0OSwyMTgsODQsMTc2LDE5Miw1MCwxMTksNzYsMTAwLDAsNjcsMjgsMjA2LDIyOCwxNDksMTAxLDE3NywyNDcsMTk5LDk4LDE1NCw4LDI0NiwyMjAsNTAsMSwxMTgsMTY3LDYwLDcyLDE1MCwyMjksNTgsMTg5LDQ1LDIyMCwxMTksMjE4LDQwLDI4LDE4NiwxOCwxNzQsMCwyMDksMTQwLDE3MSwxNjMsMTQsOTQsOTIsMTM4LDIxNyw3NSwxNDAsMTcwLDIyNywyMDAsMTI3LDE1NSw0OCwxODEsMTIsMTMzLDIyNSwyNDksMTYwLDQxLDIwNCwyNiwxMDEsMjE5LDAsMTg0LDE1NCwyMDUsMjMzLDE5NiwxNDIsMjMyLDEyMywzMCwyMzcsMjEwLDkzLDY0LDgzLDg2LDE1MCwyMCwxODksMTA3LDU1LDI0LDE2LDg0LDIzLDExNSwxNDUsOCwxMTEsMjcsNCwxODQsNTYsNDQsMjQ2LDIwOCwxMDYsMTE1LDkxLDE1OSwyNDQsMTIzLDE5NiwyNywyMTYsOTcsMTUwLDIwOCwyLDI1Miw2MCwxNzgsMTkwLDM5LDYsMjIsMTQ3LDE2MCwzMywyNDUsMjEsMTYzLDIxNiw1LDE5LDEzNiwxNTYsMTA2LDE1NiwxMjcsMjMxLDEwMiwyMDcsMzUsOTYsMTI5LDExNCwyMDgsODYsMTgwLDExNiwxMTksMTI2LDc0LDEyLDY3LDYsMTMzLDQxLDExOCw3NiwwLDI2LDIwNiw2LDUsMTAzLDE1MSwyMDQsMTM2LDE2NCwzOCw2NiwxNCw5MiwxMjUsMTYzLDUzLDE1MSwxMzAsMjM1LDE4NCwxNTgsMTQ5LDE2MSwyMzgsMTk5LDcxLDI1MSwxODcsMzUsMTg4LDI0LDMxLDE2MywyMzUsMTYzLDYwLDYwLDEzMCw3OSwxNTQsMjUsMjE3LDY0LDE5NSwxNzQsMTM5LDg1LDE5NSwyMDgsMTM5LDczLDYwLDE5NiwxMjksNjQsMjAzLDE2NiwxMjgsMTM5LDIwNCwxOCwxMjcsMTM4LDIyOSw3NywxNjgsMTYxLDE5MywyMDcsMTA1LDAsMTgwLDEwNywxNzIsNjUsMTE3LDYzLDc0LDM2LDE2NSwxNCw1MSwxMjQsMTYsMTA3LDIzLDgyLDE0NSwxMDYsMjQ3LDE0NCw0NCwxOTMsMTIwLDMsMTA0LDE2OCw0MSwxODgsMzQsMjA2LDI1MSwxNzAsMjA1LDIwMywxMTIsMTcxLDE2MSwxMzMsNzYsMTQ4LDEzOCwzNCw4MCw0MSwxNjgsMTI4LDIzLDIwMyw4MSwxNDcsNTAsNTEsMTQ1LDE5OCwxNTIsMjM0LDk2LDcyLDE4NSw1MCwyMzEsMjcsMTQ1LDIwNywyMTEsNDIsNDAsODYsMzEsMjUwLDg2LDg4LDIzNiwxOTcsMTY5LDE3NiwxNjUsMTMwLDIzNCwyNDQsMTg0LDE1NSwxODYsMiwxOTksNTUsNjksNTcsMjAwLDEyOCwxNSwxOSw3OCwyMzEsMjEzLDE3MiwyMCwyMTQsMzQsMTg5LDIxMiwxODMsNCwxMSwxNDIsMTg4LDE2MCw0OSwxNTcsMjcsMjEsMTU0LDE2NCwxNzksMjIwLDE2NiwxNzQsMjA2LDEzMSwxMSw2NCw4MCwyOCwzMSwxMjEsMTEwLDE4MSwxMjIsMTMzLDIyNSwxNDcsMTc5LDk4LDg5LDE3OSw2NiwxNjgsNDIsMjQwLDg3LDIwNSwxODcsMTk1LDExMCwxOTksMjIwLDEzLDE4Myw0NCwxOSwxLDE1MSw1OSwxODAsMTYxLDE5MSwxMDMsMTIzLDEzLDI1NSwxNjgsNzAsODQsMjYsMjA0LDEzMCw4NiwzOCwxMzYsMjMsMTM0LDE1OCwxMDEsMTI4LDI1MywyMDIsMTM5LDE2MiwyMTQsMzAsMTkxLDExMiwxMjAsMjAyLDE1MCwxNzcsMywxNjUsODMsMjQwLDE2NCwxNjYsMjQ2LDE1MiwxNDcsMTk5LDg0LDE1LDIwMiwyMzQsMzAsNzUsMzgsNzMsOTgsNjcsMTY0LDEyMCw1NCw3LDEyMiw1Myw3MSwzNywyNSwxOTcsNzUsMTg3LDEyLDE4OSwxOTcsNDEsMTkwLDMyLDEyMywyMTQsMTM5LDIwNSwxNzIsMjQ3LDEzMywxNTAsNywxOTUsMTI2LDgwLDEyMCwyMDEsOTgsMTQyLDIxNSw4NSwyMDAsMjM0LDc1LDUwLDIxNCw0OSwxMDYsMjE2LDU4LDE5LDY4LDIxMyw3MywzNywxNDgsMTM0LDIwMSwyMzUsMTAyLDE5MSw3NSwxODAsMjE0LDU1LDE4NywxOTksODYsMjksMCw3LDIwMCwxMzMsMTM1LDQyLDE4OSwxODAsMTc4LDE0MiwzNywxMjAsMTI4LDM2LDcwLDIzNCwxMzIsNTksNDYsMjE3LDE0Miw4Myw4Niw2NiwxOTMsMTY4LDE0MiwxOTgsMTAzLDY1LDEzOSwyNDMsMTUxLDI5LDEzOSw2Myw2MywxODgsMTIyLDQyLDM1LDY5LDE1MCw5OSwxMTEsMTQ2LDE4NCwyNSwzOSw5MCwzMywxMjYsMjQ5LDE4OSwxMjcsMTc2LDYxLDExNSwxMDUsOTgsOTEsNTMsMTM1LDExNCwxMjIsMTYwLDgyLDczLDE2NSw1Nyw2OCwxMTAsMjA4LDEyNCwxMjUsMiwxNjksMTE4LDExOSw4NCwzNywxMjgsODYsMTUwLDUxLDEwNSw4NywyNTUsMzMsMjAzLDIwMCwyMzEsMTAzLDEyOSw1Miw2NCwxODgsODIsNTgsNjYsMTYzLDU3LDIxMSwxMjAsMTEwLDE4NiwxOCw4NSwxMzEsMjE4LDE5LDE3LDgsNzgsMjA1LDE3Nyw1NiwyMjMsMTIwLDkyLDQzLDE5Niw3LDEyNywxNTYsNDIsODMsMTA3LDEwLDIyMywxMzAsMTAsMjQwLDIzMywxODksMTUsMTk4LDQwLDI0MCwxMTgsNSw0NSw2NSwyMSw5NSwxODcsMTc5LDEwNiwxMzIsMTEzLDE5MiwxMCwzMCwxMzMsMTY0LDIxLDkzLDkyLDE1OCwxNzAsMTM5LDEyNiwyNDgsMjQ4LDEzMSwyMjcsMTgyLDk0LDE1OSw0LDM3LDU0LDE5OSwxODcsMTQ1LDExNywxMzMsMTcsNTcsNTUsMjEyLDM1LDExMiwxODUsMTMxLDksMjA5LDY0LDc0LDE0NiwyMTcsNTIsMjIsMjI0LDQ5LDE5NSw4NywxNzQsNjAsMjEsODgsNzYsMjA4LDg3LDE5NSwyMjYsNzMsMjAxLDIyOSwxMjgsNjgsMjM2LDg0LDIyNywyNDIsMTY0LDc5LDE5NiwxMzQsMTE4LDY3LDEyOCwyLDEwLDE3LDIyNiwyMCwxMjYsMTM3LDMsMTg2LDEwMSwxNDQsMjAwLDE4OSwxNTMsMTE0LDE2MSwxOTksNSw5MiwxNDgsMTEyLDU0LDIsMTQ0LDYwLDIxOCwwLDIzLDIzMiw2MCwyNDMsMjEyLDE3NSwwLDM3LDI1LDQ3LDIxMiwxMTAsMjE2LDQ4LDQsMTQ3LDIyNCw1NCwxNCw3MCwyMDAsMjMzLDIxMiw1NiwxNCwyMTQsMTM1LDc5LDgxLDE1MCwxMTYsMTMzLDMsNzUsMjMyLDE4OCwyNTMsMjIwLDEzOSwyMDIsMTQ0LDU2LDgyLDUyLDMsMjUsMjI4LDk3LDk4LDI1MiwyMDEsNzYsMTQwLDE5LDE0NCw5OCwxMDIsMjAyLDEzNiwxODcsNTAsMTkyLDEwMyw0NCw4Niw5NywxMjcsMTIwLDEyLDg4LDIzNiwxNjMsODAsMjE0LDE4NCwyMjAsMjE1LDQwLDEzOSwxMTcsNzEsMjE5LDE4MSwxMTcsNTEsMjEyLDEyNCwxMDIsMTEzLDEwMSwzMSwxNDYsNDYsMTkxLDIwMSw5OSw2LDIyOCwxMjIsMjI4LDcxLDIwNyw5MCw5Miw1NCw3MCwyNTAsMTYxLDIyMSwxMzksMTExLDQ2LDg1LDE4MCwxNjUsNyw1NiwxMjUsMjEsMzQsNjcsMTE5LDExMiwxNjUsMTEsMTk3LDEwMCw2NSw2NywyMjEsNTksMjM0LDE4OSwxOTUsMjAzLDE2MiwxNTksMjAzLDE5OSwxNTgsMTgyLDE2NSwxLDE5MiwxNTUsMTE1LDI5LDE3OSwyMzMsMzUsMjE1LDk1LDE5LDIyNCwyLDE5LDgzLDIxNiwxMiw4MSwxOTgsMTgzLDE4MCwwLDU4LDI0OCwzOSwzOSwyNTMsODQsNTAsOTQsMjU0LDIyNSwyMTIsMTUsMTAsODgsMjUzLDIxMCw5LDI0NiwzNywyMjQsMTY1LDE4NSw5LDYsMzMsMF19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNjQsMTgwLDEyNSwxMjYsNzksMjIwLDIyMSwyNTMsMTIzLDQyLDIwMSwxMjAsMTgwLDE2NCwyMDAsMjA4LDE3Nyw5OSw4Miw2MCw1NSwxNTYsMTI2LDc3LDExNywxMTUsMjAzLDIwMywxNDIsMjU1LDE2NiwzNF19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJDb21taXQiOnsidmVjIjpbMTY1LDI0MCwyMjIsMTQ1LDE5MSwxOTksMjAxLDIwOCw3NiwyMDMsMTYyLDE3OSwxNDIsMjM1LDExNywyMjcsMTM0LDU2LDExNSwzOSw4Miw1MywxNTQsNDksMTc3LDIxOSw4OSwyMDksMTg0LDMsMTM5LDIwOV19fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMzIsMzAsMzksODMsNjksMTA3LDE4OSwzNiwxMDEsMTA0LDE3MCwyMjAsMTM0LDI1MSw0MSw0NSwxNjQsOTYsMzksMjQyLDU3LDU5LDE2OCw4Myw4NCwxNjMsMTM5LDE4OSwyMzEsMTI4LDEyNywxOTUsMTkwLDE1NCwxMjIsNTQsMTI2LDE1NywxMzAsNTksNzAsMTQ0LDEwMSwzMiwxNzAsMjUsMjA4LDIwNCwyNDcsMTM0LDE1NSwyMDksOTksMTE1LDU0LDEzNywyMywxMjksMjE5LDE0MywxNTIsMTU2LDEwMCwxM119fX19LCIxIjp7Im5vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbNzAsMTgwLDEzOCw3MSwyNDIsMTA4LDYzLDI0MCwxODksMTk5LDQxLDExMCw4OSw4OSwxOTUsMTQ1LDg5LDc0LDMzLDIxMywxNCwxNjcsOTEsMTAzLDE2Myw2Niw3LDIxMCwyMzYsOSw1MCwyNDAsMTAwLDE1MywxMDEsMjgsODUsOSwxNiwxNjMsMTc3LDEyMCw2NCwyNDcsMTEsOSwxMzMsOTUsMTU4LDg4LDYyLDE0NSwyNTIsMTA5LDEzNCwyMzAsOTIsMjMyLDIwNCwxMDEsMjE3LDYwLDE2OSwxMjYsOTIsMjAzLDIzOCw4NiwyMSwyMzMsODQsNDUsMTU1LDEyOSw0MiwxMzcsMTUwLDU4LDEwOCw0MSwxNjEsMTEzLDE0OCwxNzUsODYsMTU2LDE2LDk4LDc1LDEzOCwxMjIsNywzMywxMzUsOTEsNzcsMjQyLDIzLDE5MSwyNDMsNDgsOSwyNSwxMDAsNDQsMjQ4LDczLDEyNCw3MSw3NCwxNDcsMjIwLDQ5LDQzLDIyOCw1MSwxODYsMTIwLDk2LDE4OSwxNzUsMzgsMTE1LDEwOCwxMTIsMTYyLDEwMyw1OCw0Nyw5NCwyNDYsNDgsMjQ2LDY2LDEwOSwwLDY3LDY3LDIyOSwxNDcsNjQsMTM3LDMsMTYzLDExOSwxNzksNjMsMTA1LDIzMSw0NiwxODAsOTgsMTMxLDg4LDQ4LDE0NiwxMDQsMjA4LDEzNCw2LDIwLDUsNywyMzMsMTQ2LDI0OCwxMzUsMTE1LDE2Nyw4MSw3MywxMTksMTM3LDgxLDkwLDE3Nyw0MywxNjcsMjIsNDksMjEsMjUsMTE2LDMzLDEzMCw2MiwxMTAsMjE3LDE5NSwxNTYsMTAsMTcyLDEzMCw4Niw1OCwyMTMsNTgsMTI4LDUyLDY3LDMzLDE2LDIxOSw4Myw4LDQsMTgwLDExOSwxNzYsMTk3LDEwNywzLDc5LDIxNiwyNDQsMTA4LDI0MiwzOSw2NCwxNjcsMjQ5LDQ2LDIzOSwxMzYsMTYxLDE4MCwyMjgsMTY3LDE5Myw1LDQxLDE1NiwxNDksMTM4LDIyMCwxNDcsMTQ3LDEwNywxMjgsNjUsODMsMTgyLDEzMiwyNTEsMjM1LDE2MCwxOTQsMjI4LDc5LDE1MiwxNDUsMTcwLDE0NiwxMjIsMTYsMjA2LDE3OCw2MSw4NCwyMTksMjEsOSwyNTEsMTg4LDIxNyw2NywzNSwxNDcsMjMyLDI3LDg2LDE2LDExMCwxMzMsMTUzLDYzLDMwLDE5MywyMDEsODgsMjM1LDcyLDI1NCwxNjcsMjEsOTMsODUsNSw2MiwyNDcsNzYsMTQsODcsMTA0LDE3NiwxNjQsMTMsMTU0LDIxNSwxMDQsMTM2LDEzMiwxNDIsNTYsMjMxLDk2LDE1OSwxNjgsMjQsMTY3LDEwMSwxNDIsMTI3LDkyLDEzLDIzNiw2NSw1NSwxMDAsMTc2LDE0MCwxNjksNjcsNjgsNjgsNzIsMTE0LDE5NywyMTEsMTE5LDkyLDEzOCwxOTcsMjEwLDE5OSwxMzIsMTY2LDUwLDU0LDE0NiwxMTUsNDAsMzgsMTcsNjgsMjM2LDQzLDg1LDE4LDg4LDE0OSwyNDIsODIsODIsMjAwLDk3LDE4MCw5Nyw1MSw4LDExNywxOTgsMTE3LDIwMSwxNjAsNTUsMTE2LDE5MywxNDAsMTQ4LDE3LDQsNjIsNTMsMTE3LDIxOCw1NCw3NywxNjcsMjE0LDExLDIwMSw0MSwxLDE1LDE4NiwxNzEsMjI3LDQ0LDM2LDExLDE5OSwyMDQsMzYsMjQsMTc5LDIyMCw1Myw5OSwxODAsMTM0LDE2LDE3OCwyMjgsNDIsMTc4LDY5LDE1MSwyMDcsMTIwLDgxLDIwMiwxMTgsMTYzLDEwNSwyMDQsNTQsNTksMTkzLDEwNCwyMDAsMTY4LDE3Niw3MywyNTAsNjcsMjQ1LDE3MiwyOSw3MywxMDEsMTEwLDM5LDEwNCwyNSw1OSwxMzMsOTIsNzUsMTAxLDg1LDEzOSwxMTgsMTc1LDM1LDcsMTA3LDIxNCwxMiwxNTQsMjQ2LDU2LDIwLDEwOSw1Myw0OCw3OSw3MiwxMTIsMTU2LDgsOTEsMjUyLDMyLDcxLDE3NywyNDMsMTM5LDE4NCwxOTYsMTM1LDcyLDY3LDEyMSw0NiwyNDQsMTMwLDEyMSwyNDgsMTU1LDIyNSwyLDEwOCwxNjgsNTAsMTA4LDEsMTAyLDU3LDU4LDE1MCwxMjYsMTIwLDEwNSw0OCw4LDE5OSwxMCwxNjAsMTgxLDEzMiwzLDEyMyw1MywxNjIsMTcsMTkzLDIwMiwxODgsMTQ5LDIyNSwyNiw4MywxMzIsMTE1LDEwNywxODYsMTEzLDk5LDI5LDI1Miw1NCwyNDcsMTUzLDE2NSwxNDgsMTQ3LDM5LDMwLDQ5LDY2LDk3LDE2MiwxMzAsNCwxMDUsMTYzLDIwMCw3MywyMDYsNzQsMTgzLDYyLDg2LDE2NiwxODgsMTAzLDIyMCw1OCwxODAsMTYyLDUwLDExOSwyMDksMTE1LDE2OSw2NCwxMzAsMTAsOTAsNDcsNzQsOCwxNjAsMzcsNjQsMTE4LDE5MywxNTAsMTIsNDEsMjUxLDExLDc1LDE2NCwxMzIsMTk3LDIzNiwxNDYsMjM2LDEzNCwxMzIsMjQwLDM5LDEwNiwyNDQsMjQ1LDIwLDEzNCwyMjUsODEsMjUsMTQwLDcyLDI1MiwxMzcsMjgsNTIsMTMxLDE2NSwxNzIsMTA4LDIwMywyOCwyMDgsNzcsMjIwLDE4Myw3NiwyMDgsNzMsMzgsMjM2LDE4MCwwLDE5OSwxMTksMzgsMzksNDksNjAsNDMsMjE3LDI4LDE2LDM2LDE4MCwyMzUsMTE5LDEyOSwxNzAsNzEsMTg5LDE3NywxMzksNzEsMTUyLDEyMCwxNzYsMTI2LDU4LDExNCwxMzIsNzMsNTAsMTk2LDcsMTc0LDQ1LDg0LDEwMyw3MCw5MSwxODIsMTM1LDY5LDk1LDE4NSwyNTAsMTM1LDE2NiwxNjIsMTQ3LDE5NCwxOTcsMTE0LDkyLDI3LDk4LDIzNCwyMzIsMTQzLDEwMCwxNDgsMTM0LDIwOCwyMjcsMzAsNTMsMjQ4LDExMCwxNzUsMjQ0LDE4NiwzMiwxMjQsNywxNjgsMjQwLDUxLDIwMywyNDksMjIsNiwxOTQsNzAsMTExLDIxLDExOCwzLDE5Miw0MiwxNzcsMjQwLDE2LDExNywxODEsMjcsNDEsMjAyLDE1LDM5LDY2LDE4MSwyMDEsNjYsODcsMTc5LDEyOSwxMDAsMTE0LDE0NCw3NywxMjYsOTIsMjAyLDIyMCw2NCwxMTcsMTQyLDI4LDEzMiwyMTYsMjQ5LDE3Nyw1MSwxNTAsMTAyLDIzOSwxMjMsMzAsMTksODAsMjA0LDE2MCwyMywxMzcsMTE2LDE1NiwxMjUsMTI4LDEzMSw5OSwxODgsNiwyMCwxNDQsMTUzLDI0LDIyNywyMTMsODAsMjQ5LDQxLDY3LDY1LDEsNDIsMjQ0LDE0NiwxMjksMTgzLDgzLDEsMTk0LDE2NCwxNCwxNzEsMTg0LDEyNCwxMjgsMTE3LDczLDExNCw0OSwxNzcsMTkzLDg0LDE1NSwxNTIsMCw1OCw1OSwyNDUsMTIxLDEyNywyMTMsMTMwLDEwNiwxNzksNywyMTksMTY5LDI4LDcyLDExNyw1LDE4LDkwLDE4NCwyNDAsODIsMTcwLDI1MCwyNDUsNjMsNDAsMTgyLDY4LDg0LDE1NSwxNzQsNTEsMTc2LDEyOCwxMDAsMTEsMTUxLDg1LDI1MCwxODYsMTE2LDI3LDI1LDE1NiwxNzEsNTEsMTY0LDE5NywyMDMsMTg3LDE4MCw0NiwxNDcsMjE1LDY0LDcwLDExNiwxNiwyMTcsMjI5LDk4LDUxLDE1MCwxNDcsMjE2LDE3NywxNDYsMTkxLDE1MywxNDMsMzYsMjMsMzEsMjE4LDE5OSwxNjIsMjAsMjEyLDEwLDcwLDE2NCw1NCwxNiw2NSwyNCwxMTksMTc2LDQsMjA4LDE1MSwxODgsNTEsNzEsMTg5LDEwOSwxNjYsMTU2LDIxMSwxNTYsMTg3LDE5OCwxMzgsNTMsMTM5LDE1NCw0Myw4NywxNTAsNDksMTc5LDI0MCw1MSwxMTAsMTE4LDEzMiwyMTAsOTAsMTMwLDE1NCw2NCwxMzAsMjEzLDIyNywxODYsNTEsMTA3LDE5MSw5MSwxNTQsNDcsMTM0LDIwOCwyMDUsMjEzLDIxMiwyMDYsNSwxMjgsMTg3LDEwNywxMzMsMTAxLDE5MSwxMTUsMTgsMTM4LDEwNSwyNyw5OCwyMjUsMTMzLDIxOCw4MSwzOCwxMTksMjE3LDQ4LDEzNiwyMTAsMjA0LDEyMCwxNjcsNzIsOTcsMTM1LDEwNiwyMDMsMzQsMTYsNDUsMTU0LDE5MCw5Miw1MSw0NiwyMDksOTYsMTgwLDE2OCwxMDAsNDAsMjUwLDE5MiwxNDcsMjE5LDEwNSwxODMsODcsNDMsMTU5LDE4NSwyNDcsNTMsMjM4LDQ0LDE4MCw0NiwxOCwyOCwyMTYsMTY1LDEwMSwxNjAsMjMxLDUzLDYzLDExMiwxMDMsMjE3LDE4NiwxMDIsMTI5LDE4LDE0MSw3NiwxMTksNzMsMjEyLDgwLDE0NywxNTcsOTgsMTI1LDEyMiwyMDMsNTcsMjUsMTk3LDE1LDE4NywyMTksMywxMjUsODIsMTAzLDQwLDAsNDcsMjI5LDI1LDExNywyNDYsMjAsMTkyLDMsMjAwLDEsMTgwLDE1MCwyMDUsMjAxLDU0LDEwNiwxODEsMTEzLDQzLDgzLDQzLDU0LDcyLDEwNSw4MCwyNSw1OSwzNywxNzUsMjE0LDEyMywzMywxNTMsMTEsMjIxLDE5LDEzMSwxMzIsMjQwLDgwLDk1LDI1MSw0LDI1NCwyNTAsODAsMTMzLDE4NywxODIsMTEyLDI0NSw3NSwxMjQsMTA3LDEyMSw0LDI0MCwxOTgsMjQwLDE2Miw3MiwyMjgsMjUyLDEyMCw3NywwLDcyLDE4MSwxOTgsMjksMTAyLDM3LDE4MSw0NSwxOTcsOTcsMTUsMjMsMTg0LDE2OCwxMDIsNTEsNjQsMTE1LDExMywyMzcsMjI1LDEzOCw4OSwyLDEyOCwyMzksMTgxLDE3NSwxMDIsMjExLDE2MCw1NCwxODIsMzUsMjMzLDUwLDksMTA0LDEwMCwxMzEsMjYsODUsNDgsMTU3LDY3LDY5LDczLDIwMywxMjgsNCwxNzIsMTU5LDI0Myw3NCwxNDIsMTk2LDE2OSwxOSw3OSwxNTIsMiw2LDMwLDEzMiwxNzEsMTAzLDIyMSw3LDIxMSwxNjksNzgsMjM1LDIwNiw2OSwyOCwyNTIsMTMsNjksMTI1LDY0LDI1NCwyNDcsMTcsMTYwLDIwLDIwMiwxNDYsMCwyMzIsMCwxMiwxNzEsOTYsNzYsMTMzLDEzNCwyNDMsNTksMjQwLDE1MCwxNDksOTUsMjA5LDIxOSwxOTksNzMsMTg4LDEwNSwxMDMsMTAxLDE4NSwyNDUsMTMsOTUsMjIyLDIwNCwxNjIsNDUsMTM5LDMyLDEwNSw1XX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6WzIzOSwyMzcsMjUxLDE1MiwyMzEsMTQwLDI1MiwzMywyMzcsMTc0LDI0MiwyNDEsMTI0LDEwMywxMzAsMjQsNzYsMTA2LDE0NSwyMjcsMCw1MSw2OCwxMTIsMTYwLDQ2LDQyLDQ5LDgyLDIzMyw3NywxMTddfX0sImNyZWRlbnRpYWwiOnsiY3JlZGVudGlhbF90eXBlIjoiQmFzaWMiLCJzZXJpYWxpemVkX2NyZWRlbnRpYWxfY29udGVudCI6eyJ2ZWMiOls5OCwxMTEsOThdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IktleVBhY2thZ2UiOnsibm90X2JlZm9yZSI6MTcyMDY4ODk1MCwibm90X2FmdGVyIjoxNzI3OTUwMTUwfX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbMjIyLDE3OSwzLDMyLDk0LDEyNyw2NiwyNDksMTg4LDEwNyw3NywxODYsMTI2LDE4OSwxMzUsNTIsNjgsNDAsMTcyLDExMCwxMzUsMjQ0LDIwOCw5NSwxNjcsMjIzLDE3NywxODIsMTYwLDQ2LDEsNDUsMTA4LDE5MSw3MiwxMTksMTk2LDIyLDE1MCwxOTQsNTMsMjIsMjAzLDkxLDIyMywyMDQsMTUxLDE0NCwxMjYsMjAzLDI0OSwxMjEsNjIsNDUsNCwxNDQsODksMjcsMTgwLDg0LDIzNiw2Niw1OSwxXX19fX19LCJwYXJlbnRfZGlmZiI6eyIwIjp7Im5vZGUiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzExNiwxNjYsNjIsMTI5LDE3NywxNjMsMTI0LDIxNCwxMDgsODAsODYsMTQ1LDI4LDE0NCw2NCwxODUsNCw4OSw2MCwxMTYsMzMsMTksMjI1LDE1Nyw3MCwxMjMsMTMzLDUzLDE4MCw4OSw2NywxNDksNDMsNjYsMTgzLDE0Myw0NywzNCwxODAsODcsMTYsMTEsMTEwLDI1MSw2MSwyMDIsMjMzLDE1Myw4LDEwMiw5MSwxOTgsNDksNTksMTYwLDE5OCw4Niw1OCwyNDAsMTU4LDE1OSw4MSwyMDcsOTQsMjA5LDEyMCwyMjgsODQsNTUsMjM5LDIyLDE5NywxMDMsMjM0LDc3LDE5OCwyNDEsNDcsOSw4MCwxNjIsMTg2LDE1NCwxODIsMjYsMTM5LDg2LDI0MSwyMCwxMDQsMTY5LDIxOSwxMzcsMjA3LDgsMTgsMTU0LDE2LDI1LDExOSwxNDYsMTg2LDE1Myw4OSwyLDksMTA0LDQyLDM2LDE2LDM3LDIxLDE5NSw5NSwzOSwxOTYsMTU0LDE4NSw3NCwxMzIsMjQ2LDg5LDE0NSwxMjAsMjI3LDIxLDYyLDE4MiwxMDIsMjMyLDI1MiwyLDE3OSwxNjksNDIsMTQ1LDEwMywxOTEsMjA1LDIzNCwxMTYsMTkwLDEwOCwxNDIsOTksNTksNDUsMTAxLDEyMSw5LDYzLDE2NywxOTQsODQsMTAyLDQ4LDIzLDIxMCwxMTgsMjI3LDE1MiwxMzUsMTYzLDQzLDQyLDg0LDI0NCwzNywyMDUsMTM1LDE1MSwxMTUsMTUwLDg4LDE4MCwyMzMsMTQ2LDY5LDE5LDIwNyw2Niw0MiwxMjMsMTcyLDI0OCw4OCwxODMsMTY5LDMwLDM1LDUyLDc2LDg1LDE1MywxNTgsOSwxMTUsOTAsMjUxLDk5LDE1LDE2NCwxNjIsMjMsODYsMTUwLDE3Miw4NSwxMDEsMTI5LDI0MSwxMzQsMTk5LDEyNCwyNSwwLDE5MCwxNDYsMzQsNzEsMjQsOTYsMzgsMjEsNjAsMTkxLDE0MCwxNzMsMjUyLDExMyw5NSw2MCw3NSw0OSw1OSwyNDQsMjAzLDI0MSwxMjksNjksMjM1LDIyLDMyLDE1LDIzNiwxOTAsMTIyLDEwMSw2NCwxMTEsNywxNzEsMjI4LDU3LDEyMSwxMTQsMjAzLDEzLDEwMyw5LDM0LDE1LDM2LDI5LDIyMiwyMjcsMTk4LDE1NCwzMywxMTEsMTM3LDE2OCwxMTgsMTA1LDIzMSwxMDEsNjEsMzUsMTgwLDc4LDg5LDQzLDE0MCw5MCwyNiw1MCwyMSwxNDMsMjQxLDIxMiw3NywxMyw0OCwxNzEsMzMsMTYzLDIwMywyMDgsMTgxLDE5NCwxMDgsODIsMTI1LDExNyw4Miw2OSwxMywxNDgsODMsNDUsNjUsNjcsMTExLDE5Nyw4NiwxMDMsMTY2LDMwLDI1MywyNTIsNDksMzUsNTcsMTgzLDc1LDkxLDE0MSwxODYsOTEsMTcwLDE0NywyNTEsMTYzLDQyLDE4MSwxNzQsMjI4LDI0LDIzLDE3NywyMTUsNzYsMjA2LDIxOSw1MiwyNTIsODYsOTIsNjQsMTY4LDIyLDc4LDE4NywxNDQsNzgsODgsMTAxLDIxOCwxNDYsMTA1LDE2Niw2LDEzNCwxNTYsNjYsMTkxLDE4NSwxOTksMTg2LDEyLDUsOTYsMTI1LDY0LDQ0LDE0MiwxMiwxNzEsMTI5LDg0LDc2LDcxLDIxNiw5NiwzMywxNDUsNTIsMjU1LDE0Niw5MSwxMzUsNTUsMTk3LDMzLDI0NCwxNjIsNjgsOTcsNDgsNjcsODksMTMzLDIwMywxODYsMTAwLDgzLDE4NSw3MCwxMTgsNTksMTg5LDI0OCwyMTMsMTQyLDk1LDE5NiwxMTIsMTc5LDE0OCwxODcsNywxMDgsMjgsMjM1LDEzMiwxLDIwMCwyMjgsMTgzLDE2NCwxMzUsMTYsODIsMjgsMTY2LDMwLDIzMSwxMzMsODUsMjUwLDEzOCw4OSwxOTYsMTE4LDE3Miw2NSwxOTAsMjMyLDgsMTMsNTgsODMsNzIsMjM5LDEwMyw0Niw5NiwzNiw1NSw4OSwxODcsMzYsMjUsMjE2LDEwNCwyMDAsMzQsNzUsMjIwLDIzNCwxMTIsMjIzLDAsMTI2LDEwNiwyMTYsMTkyLDE0OSw0Myw4NiwyMCwxNzEsMTE1LDgzLDIwMywxMiw0OSwxODQsODIsMjM4LDIxMywxNDAsNTQsMTUxLDksOTMsMTc3LDgyLDU0LDEyMSwzMiwxMjUsMzIsMTExLDExOSwxODUsMTAxLDEzNCwyNDEsMTQ0LDIyNywyMTYsMjgsMzgsMjI4LDUsMzQsMTE0LDExMSwyOSwyMDksMjA3LDEyNSw0OCwzOSwyMzEsMTI5LDc4LDIyOSw5MSw3NCw1LDI1MiwxNjAsMTY2LDE0OCwyMCw0OCwxNDcsMjAyLDE5OSwyNDcsMTcwLDIzMSwxMjksODMsMjI0LDE2Nyw0OSwyMzQsMTM2LDE2MywzNCwyMjgsMTE5LDE1MCwxNiw1OCwxODYsMTk4LDEzMyw0LDY4LDE1OSwxNzUsODEsMTQwLDI0MywyNCw4MCw3OSwyNDQsMTA4LDgwLDEwMywxNDMsMTYxLDg4LDIwMywyMjUsMTYzLDE2NCwxOTcsNSw4MiwyNywxMzgsNjksMjQwLDE4Niw5MSwyMzMsMTMxLDE1OCwyMDIsNDAsOTAsODEsMTYwLDgyLDE0MywxMzcsMTY0LDEzMSwyMCwxNzMsMTUzLDI1LDk1LDgwLDI2LDE4MSwzOCwxNDgsNTQsMTk2LDEwNCwyMywyMzcsMTM2LDE2MywyMTgsMTcsMjcsNjYsMjI4LDEyNywyMTEsMjUwLDE0OSwxNjQsODUsMTA5LDE2OSwxODYsMjAwLDEsMjUxLDIwMSwxMDMsMTIzLDE4MywxNTUsODcsOTQsMTg3LDIzNSwxNzgsOTgsOTcsMjA2LDI1LDEwNSwxNjEsMjAyLDIzMSwxMjMsNjYsMTM4LDE0LDE3NywxMTQsMTYxLDU5LDE3Nyw0MCwxMywzOSwzMCw4NCw0OCwxODcsMjMzLDEzMSwxODYsMjA0LDE2Nyw5MSwyMjMsMjQzLDE5Myw5MiwyMTMsMTkxLDE0LDE0NywxNywxMzcsNCwzNiw5Niw1Niw0NSwyNywzNSwyMDEsMTkwLDE5MywyNCwxNzcsMTU0LDg2LDE5NywxNTYsMTY4LDE2OCwxMTUsMzEsMTI1LDIyOSwzNSw4MCw4OSw5OSwyMzcsMjUxLDE5MCw4MiwxLDEzMywxNTAsMjE0LDIwNSw4Nyw5LDE5NCwyMzQsMjM0LDg2LDE2OCwxNDQsMTkwLDIwMSw5NywxMTIsMTQxLDc0LDc2LDE0MCw5Niw1LDExNyw2Niw3LDI1NSw0MCwxNTksNDIsNDMsMTE5LDg0LDUsOTcsMSwyMTYsNzEsMTEsMTY3LDE0NSw2NSwyNTEsNTAsMTAwLDUyLDE3MCw0LDE5LDE5LDExOSwxNDAsMTAsMTAsODUsMTcsODQsMzcsMTA5LDI0MCwxOTQsMjMsMTY2LDIzNSwxMzEsNzYsMTg2LDM3LDEwNCwyMTcsMjksMjI3LDE1NSw2MCwxMDksNzUsMTAyLDE3LDEyOSwxNTQsMjI1LDIyLDk5LDE4MiwxNzAsNTYsMjUsMjMxLDE1MSw3OSwxNjEsNTAsMTAsMjI5LDMsNDAsMTk2LDI2LDE3OCwxMzQsMTQ1LDE3LDE1NSwxMTYsMTQxLDIwLDE3MiwxNDEsMTY5LDUsNDAsMjA5LDYyLDM1LDM2LDE0LDc2LDIzNiwxOTQsMjQyLDExNiwxODAsMjM2LDQyLDg0LDkxLDExOCwxMzksMjI1LDE3OSwxODgsMCwxMDUsMTMsOTksMTgzLDUzLDIyMiwyMTMsMTMxLDIzMiwyMjUsOTYsMTkzLDcxLDQsMTA0LDYsMTY1LDE3OSwyMzUsNDksMjA3LDExNSwzOCwxMjMsMTg1LDI5LDY1LDE4MSwxNzYsMTg1LDcwLDE2OSwxODEsMjQxLDIyLDQxLDkwLDY2LDEyMyw4OSwxNjEsMzAsMTQ4LDExNSwxMjQsMTk4LDY0LDY2LDEwMywxMDEsNTIsMTk3LDE5MCwxMzMsMTAwLDEzOSwxNDIsODMsOTcsMjUyLDEsMTMyLDIzMCwyMzQsMTgyLDIyMSwyMSw4OSwxMDUsMTI0LDEwOCwyMjAsMTkzLDE5NiwxNTUsMTU2LDE2MSwxNTEsMjQxLDExNyw2NCwxMjAsMjA2LDM4LDI0MSw5MywxMDYsMjEyLDI1LDE0MCwxNTQsMjcsMTgxLDI0MSwxMDEsMjEyLDM0LDEzOSw1MSw3LDk5LDM0LDE2Niw2MCw1MywxODIsNzgsMTkxLDczLDE1NSwyNTEsNTYsMTcxLDUzLDE5NywzNiw0MiwxOTksMTQ4LDI1MCwxOTYsMTkyLDEzNSwxMzQsMTAyLDI1NCwyOCwxMTcsMTI2LDg2LDUsMTU3LDUzLDE2NSwyMzgsMTM1LDE3OCwxODEsMzksNzYsMTQsMzQsODAsNiwyMjcsMTYyLDEyMCwxMzAsMTAzLDE3LDE4OCwxNzcsNTQsOTgsMTQwLDE5NSwxNzgsNjcsMTYwLDE2NywxNCwxNTIsNDksMTYzLDY3LDI1MCwxNTIsMjA4LDExNiwzMywyNDcsMTgyLDEyMiwxMTYsMTIzLDE2OSwxOTQsMTY0LDExMiwxNTYsNzQsMTQ4LDE0OCw2NywxMjUsMTE5LDM5LDExOSwxMjQsNTUsMTMzLDIxMCw1OSwxMjUsOTEsMTg3LDExNCwxNDUsNzEsMTcyLDE4MSw1MSw5MSwxNjEsNTcsNTUsMTQ4LDgxLDQ5LDE3NCwxMDgsMTUzLDIwNiwyNDIsNzgsMjM5LDE4LDEzMCwzMiwyMTEsMTI5LDIyMiw2NCw4LDEyOCwxOTMsMTI4LDE2LDEwNiw4NSwxNTAsMywyMDIsNzQsMTYzLDIwMiw4LDE5Nyw2MywxMzMsMjA0LDE4NCwxNDgsMTUzLDE4OSw2MiwxNjgsMjYsMTgzLDIxOSwxNTAsMjAwLDIxMSw1NCwyNDgsNzUsMTExLDIzNywyMDIsMTYsMTkzLDIyNSwxOTIsMTgyLDU5LDIwMiwzNiwyMzIsMTgwLDE5NywxMzAsMTIzLDE1OSwxNTQsMTIzLDIxNiwyNDAsMTYxLDIxMiwxNDUsMTEwLDE1MCw4MCwxMTgsMjA4LDkwLDEwNiw4MSw3MiwyMCw2OSw2MCwyOCwxNzcsOTAsMTY0LDE4OSwzOSwwLDgzLDgyLDk4LDEzMCw4MCw0NSwxNzcsNzksMTc3LDIzNSw0MSwxNDQsMjUsMzIsMjIsMTIyLDMxLDE0NSwyMTcsMTYzLDEwMSwyMjAsMSw5OCwxMDgsMTk2LDE3MSwxODYsMTMyLDI5LDI0MCwyMjUsMTEyLDQsNjYsOTYsMTQ4LDE4NCwxNjQsMzYsMjIzLDMwLDExLDY5LDEwNSw3NywxOTYsMTY3LDE2LDE0OSwxODUsMjQ2LDE1MywxMjksMTgwLDEyMCwyNDQsMTU2LDEyLDEzMSw5NywyNDIsMjI3LDc0LDE0NSw3OSw3XX19LCJwYXJlbnRfaGFzaCI6eyJ2ZWMiOltdfSwidW5tZXJnZWRfbGVhdmVzIjp7Imxpc3QiOltdfX19fSwic2l6ZSI6M30sIm5ld190cmVlX2hhc2giOlsxMjUsMTE1LDI0NCwxMzcsMjM2LDE1NywyNCwxMzQsMTMwLDczLDEwMSwyMTQsNjAsODYsMTg4LDkyLDEsMjQzLDc1LDQ2LDg1LDYwLDIyMCwxOTAsMTI3LDEyMSw1NCwxNTYsMTcsMjUxLDIzNSwxMzVdfSwiZ3JvdXBfY29udGV4dCI6eyJwcm90b2NvbF92ZXJzaW9uIjoiTWxzMTAiLCJjaXBoZXJzdWl0ZSI6Ik1MU18yNTZfWFdJTkdfQ0hBQ0hBMjBQT0xZMTMwNV9TSEEyNTZfRWQyNTUxOSIsImdyb3VwX2lkIjp7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19LCJlcG9jaCI6MSwidHJlZV9oYXNoIjp7InZlYyI6WzEyNSwxMTUsMjQ0LDEzNywyMzYsMTU3LDI0LDEzNCwxMzAsNzMsMTAxLDIxNCw2MCw4NiwxODgsOTIsMSwyNDMsNzUsNDYsODUsNjAsMjIwLDE5MCwxMjcsMTIxLDU0LDE1NiwxNywyNTEsMjM1LDEzNV19LCJjb25maXJtZWRfdHJhbnNjcmlwdF9oYXNoIjp7InZlYyI6WzE3Miw2NCwxNTAsNTMsMTcsMTk1LDI1Myw2OSw3LDE2NCwxODcsMTA3LDE2OCwxNzUsMjQxLDkxLDIxMCwyMDUsMTcyLDM1LDEzLDYwLDE4LDI3LDgyLDIxMSwxMTQsMiwyNTEsMTY1LDEzNCwyMjldfSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sImludGVyaW1fdHJhbnNjcmlwdF9oYXNoIjpbMjUsNzAsMTAzLDEwNSwxOTMsMTk4LDE1NCwxOTcsMjM1LDk1LDMyLDE1NiwyMDksMjUxLDQ2LDU5LDE4MSwyNDUsNDgsNjQsMjE5LDcxLDYyLDg2LDEyLDcwLDkyLDQyLDI0NCwzNywxMjcsMjAzXSwiY29uZmlybWF0aW9uX3RhZyI6eyJtYWNfdmFsdWUiOnsidmVjIjpbMjA4LDEsMTgsMjI3LDc0LDE4MiwxMTAsOTEsMTk5LDE2OCwyNDEsMTQ4LDQ5LDExNSwxMSwyNDMsODAsMjEzLDAsMjA3LDEzNyw2NywyMDcsNzEsMjExLDExMSwyNTQsMTczLDc0LDExNCw2OCw4MV19fX0sIm5ld19rZXlwYWlycyI6W3sicHVibGljX2tleSI6eyJrZXkiOnsidmVjIjpbMTM0LDE2OSwxMDQsMjA3LDEzNCwxNDUsMjAsMjcsOTgsMjE0LDY3LDY0LDEwMCw5Miw5MSw3OSwxNjgsMTY4LDI4LDIwOCw3NCwyMzIsMTEsMTc3LDg3LDI1MSwyNSwxLDI1MCwxNzEsMjA5LDE2LDE2MywxNzUsMTQwLDQxLDkyLDE1MiwyMiw4MCw4MCwxMDcsNjgsMjUxLDMsMTU5LDIwOSwxMjUsNDgsMTY1LDEwOCwyMzYsMjAsMTEsNTQsMTAwLDE4OCwyMjgsMTQ0LDE3NiwxODYsMjIwLDE0NywxMDgsMTYsOTMsOTMsMTc2LDQzLDIxMiw2NSwzOCwxNDcsMTYwLDgsNzIsMjcsMTA0LDIyNCwyNDMsMTMzLDE0MiwxMDEsMjA2LDIwNCwxOTcsNjYsODgsMjQsMTQzLDEwNSwxMzcsMTAzLDAsMTk2LDQ5LDI0MSwyMDQsNTMsODcsMjIsMTI3LDE4OCwxMzIsMzgsMTEyLDE2OCw1MCw5Niw0NCw2NywyNDQsMTM5LDExMSwxNjUsNTQsNTMsMTg2LDIxOSw4NCwxMzEsMTEsODIsMTkwLDk2LDE4LDIzMCwxOTMsOTcsMjA5LDgwLDg1LDY0LDczLDU0LDkzLDE1NSwxODgsMTQsNiwzNSwxODIsMTMyLDE3MCwxMTYsMjMwLDQyLDMzLDIzNSw4NSwxMjYsMzksMTA1LDEzOSw5Miw1Nyw2LDE4Niw4OSwxNTcsODMsNDAsMjA3LDE3OSwxNjEsNjAsMTQwLDIwNiwxOTgsMTcxLDExOCwyMzIsMTM0LDg4LDY5LDE0MCw4OSwxMzUsMTE3LDYyLDE1NSwyNTAsOTUsMTUyLDIyNiwzMCwzMCwxMTQsMTkyLDk4LDIxNywxMTYsNzYsMTY4LDAsMjI1LDEsMTU3LDE5MCwxNzIsMTAzLDE0MSw5MiwxNTUsMTgsMTE3LDU4LDEzMCwxODEsMTk2LDI3LDU4LDc5LDk5LDg0LDgsMTg5LDE5NCwxMjgsNSwxMTQsMjEsMTUsOTIsMTg5LDk1LDEzMywxODIsMTQ5LDE4Niw1MiwyNDksMzksNzIsOCwyMSwxMDksMTQsNTMsMzcsMTc4LDE5NiwxMTQsMTc5LDE3MSw2OSwxODksNDEsMTU1LDE0LDgzLDE1NywxNzAsMjQ0LDM5LDE0OCwyNDQsMTcwLDgwLDE4NiwxNTUsMTAwLDI0MywxODksNTAsMTc3LDE0NSwyMjUsODQsMTgsMiw3LDE0OSwyMTgsODQsMTc2LDE5Miw1MCwxMTksNzYsMTAwLDAsNjcsMjgsMjA2LDIyOCwxNDksMTAxLDE3NywyNDcsMTk5LDk4LDE1NCw4LDI0NiwyMjAsNTAsMSwxMTgsMTY3LDYwLDcyLDE1MCwyMjksNTgsMTg5LDQ1LDIyMCwxMTksMjE4LDQwLDI4LDE4NiwxOCwxNzQsMCwyMDksMTQwLDE3MSwxNjMsMTQsOTQsOTIsMTM4LDIxNyw3NSwxNDAsMTcwLDIyNywyMDAsMTI3LDE1NSw0OCwxODEsMTIsMTMzLDIyNSwyNDksMTYwLDQxLDIwNCwyNiwxMDEsMjE5LDAsMTg0LDE1NCwyMDUsMjMzLDE5NiwxNDIsMjMyLDEyMywzMCwyMzcsMjEwLDkzLDY0LDgzLDg2LDE1MCwyMCwxODksMTA3LDU1LDI0LDE2LDg0LDIzLDExNSwxNDUsOCwxMTEsMjcsNCwxODQsNTYsNDQsMjQ2LDIwOCwxMDYsMTE1LDkxLDE1OSwyNDQsMTIzLDE5NiwyNywyMTYsOTcsMTUwLDIwOCwyLDI1Miw2MCwxNzgsMTkwLDM5LDYsMjIsMTQ3LDE2MCwzMywyNDUsMjEsMTYzLDIxNiw1LDE5LDEzNiwxNTYsMTA2LDE1NiwxMjcsMjMxLDEwMiwyMDcsMzUsOTYsMTI5LDExNCwyMDgsODYsMTgwLDExNiwxMTksMTI2LDc0LDEyLDY3LDYsMTMzLDQxLDExOCw3NiwwLDI2LDIwNiw2LDUsMTAzLDE1MSwyMDQsMTM2LDE2NCwzOCw2NiwxNCw5MiwxMjUsMTYzLDUzLDE1MSwxMzAsMjM1LDE4NCwxNTgsMTQ5LDE2MSwyMzgsMTk5LDcxLDI1MSwxODcsMzUsMTg4LDI0LDMxLDE2MywyMzUsMTYzLDYwLDYwLDEzMCw3OSwxNTQsMjUsMjE3LDY0LDE5NSwxNzQsMTM5LDg1LDE5NSwyMDgsMTM5LDczLDYwLDE5NiwxMjksNjQsMjAzLDE2NiwxMjgsMTM5LDIwNCwxOCwxMjcsMTM4LDIyOSw3NywxNjgsMTYxLDE5MywyMDcsMTA1LDAsMTgwLDEwNywxNzIsNjUsMTE3LDYzLDc0LDM2LDE2NSwxNCw1MSwxMjQsMTYsMTA3LDIzLDgyLDE0NSwxMDYsMjQ3LDE0NCw0NCwxOTMsMTIwLDMsMTA0LDE2OCw0MSwxODgsMzQsMjA2LDI1MSwxNzAsMjA1LDIwMywxMTIsMTcxLDE2MSwxMzMsNzYsMTQ4LDEzOCwzNCw4MCw0MSwxNjgsMTI4LDIzLDIwMyw4MSwxNDcsNTAsNTEsMTQ1LDE5OCwxNTIsMjM0LDk2LDcyLDE4NSw1MCwyMzEsMjcsMTQ1LDIwNywyMTEsNDIsNDAsODYsMzEsMjUwLDg2LDg4LDIzNiwxOTcsMTY5LDE3NiwxNjUsMTMwLDIzNCwyNDQsMTg0LDE1NSwxODYsMiwxOTksNTUsNjksNTcsMjAwLDEyOCwxNSwxOSw3OCwyMzEsMjEzLDE3MiwyMCwyMTQsMzQsMTg5LDIxMiwxODMsNCwxMSwxNDIsMTg4LDE2MCw0OSwxNTcsMjcsMjEsMTU0LDE2NCwxNzksMjIwLDE2NiwxNzQsMjA2LDEzMSwxMSw2NCw4MCwyOCwzMSwxMjEsMTEwLDE4MSwxMjIsMTMzLDIyNSwxNDcsMTc5LDk4LDg5LDE3OSw2NiwxNjgsNDIsMjQwLDg3LDIwNSwxODcsMTk1LDExMCwxOTksMjIwLDEzLDE4Myw0NCwxOSwxLDE1MSw1OSwxODAsMTYxLDE5MSwxMDMsMTIzLDEzLDI1NSwxNjgsNzAsODQsMjYsMjA0LDEzMCw4NiwzOCwxMzYsMjMsMTM0LDE1OCwxMDEsMTI4LDI1MywyMDIsMTM5LDE2MiwyMTQsMzAsMTkxLDExMiwxMjAsMjAyLDE1MCwxNzcsMywxNjUsODMsMjQwLDE2NCwxNjYsMjQ2LDE1MiwxNDcsMTk5LDg0LDE1LDIwMiwyMzQsMzAsNzUsMzgsNzMsOTgsNjcsMTY0LDEyMCw1NCw3LDEyMiw1Myw3MSwzNywyNSwxOTcsNzUsMTg3LDEyLDE4OSwxOTcsNDEsMTkwLDMyLDEyMywyMTQsMTM5LDIwNSwxNzIsMjQ3LDEzMywxNTAsNywxOTUsMTI2LDgwLDEyMCwyMDEsOTgsMTQyLDIxNSw4NSwyMDAsMjM0LDc1LDUwLDIxNCw0OSwxMDYsMjE2LDU4LDE5LDY4LDIxMyw3MywzNywxNDgsMTM0LDIwMSwyMzUsMTAyLDE5MSw3NSwxODAsMjE0LDU1LDE4NywxOTksODYsMjksMCw3LDIwMCwxMzMsMTM1LDQyLDE4OSwxODAsMTc4LDE0MiwzNywxMjAsMTI4LDM2LDcwLDIzNCwxMzIsNTksNDYsMjE3LDE0Miw4Myw4Niw2NiwxOTMsMTY4LDE0MiwxOTgsMTAzLDY1LDEzOSwyNDMsMTUxLDI5LDEzOSw2Myw2MywxODgsMTIyLDQyLDM1LDY5LDE1MCw5OSwxMTEsMTQ2LDE4NCwyNSwzOSw5MCwzMywxMjYsMjQ5LDE4OSwxMjcsMTc2LDYxLDExNSwxMDUsOTgsOTEsNTMsMTM1LDExNCwxMjIsMTYwLDgyLDczLDE2NSw1Nyw2OCwxMTAsMjA4LDEyNCwxMjUsMiwxNjksMTE4LDExOSw4NCwzNywxMjgsODYsMTUwLDUxLDEwNSw4NywyNTUsMzMsMjAzLDIwMCwyMzEsMTAzLDEyOSw1Miw2NCwxODgsODIsNTgsNjYsMTYzLDU3LDIxMSwxMjAsMTEwLDE4NiwxOCw4NSwxMzEsMjE4LDE5LDE3LDgsNzgsMjA1LDE3Nyw1NiwyMjMsMTIwLDkyLDQzLDE5Niw3LDEyNywxNTYsNDIsODMsMTA3LDEwLDIyMywxMzAsMTAsMjQwLDIzMywxODksMTUsMTk4LDQwLDI0MCwxMTgsNSw0NSw2NSwyMSw5NSwxODcsMTc5LDEwNiwxMzIsMTEzLDE5MiwxMCwzMCwxMzMsMTY0LDIxLDkzLDkyLDE1OCwxNzAsMTM5LDEyNiwyNDgsMjQ4LDEzMSwyMjcsMTgyLDk0LDE1OSw0LDM3LDU0LDE5OSwxODcsMTQ1LDExNywxMzMsMTcsNTcsNTUsMjEyLDM1LDExMiwxODUsMTMxLDksMjA5LDY0LDc0LDE0NiwyMTcsNTIsMjIsMjI0LDQ5LDE5NSw4NywxNzQsNjAsMjEsODgsNzYsMjA4LDg3LDE5NSwyMjYsNzMsMjAxLDIyOSwxMjgsNjgsMjM2LDg0LDIyNywyNDIsMTY0LDc5LDE5NiwxMzQsMTE4LDY3LDEyOCwyLDEwLDE3LDIyNiwyMCwxMjYsMTM3LDMsMTg2LDEwMSwxNDQsMjAwLDE4OSwxNTMsMTE0LDE2MSwxOTksNSw5MiwxNDgsMTEyLDU0LDIsMTQ0LDYwLDIxOCwwLDIzLDIzMiw2MCwyNDMsMjEyLDE3NSwwLDM3LDI1LDQ3LDIxMiwxMTAsMjE2LDQ4LDQsMTQ3LDIyNCw1NCwxNCw3MCwyMDAsMjMzLDIxMiw1NiwxNCwyMTQsMTM1LDc5LDgxLDE1MCwxMTYsMTMzLDMsNzUsMjMyLDE4OCwyNTMsMjIwLDEzOSwyMDIsMTQ0LDU2LDgyLDUyLDMsMjUsMjI4LDk3LDk4LDI1MiwyMDEsNzYsMTQwLDE5LDE0NCw5OCwxMDIsMjAyLDEzNiwxODcsNTAsMTkyLDEwMyw0NCw4Niw5NywxMjcsMTIwLDEyLDg4LDIzNiwxNjMsODAsMjE0LDE4NCwyMjAsMjE1LDQwLDEzOSwxMTcsNzEsMjE5LDE4MSwxMTcsNTEsMjEyLDEyNCwxMDIsMTEzLDEwMSwzMSwxNDYsNDYsMTkxLDIwMSw5OSw2LDIyOCwxMjIsMjI4LDcxLDIwNyw5MCw5Miw1NCw3MCwyNTAsMTYxLDIyMSwxMzksMTExLDQ2LDg1LDE4MCwxNjUsNyw1NiwxMjUsMjEsMzQsNjcsMTE5LDExMiwxNjUsMTEsMTk3LDEwMCw2NSw2NywyMjEsNTksMjM0LDE4OSwxOTUsMjAzLDE2MiwxNTksMjAzLDE5OSwxNTgsMTgyLDE2NSwxLDE5MiwxNTUsMTE1LDI5LDE3OSwyMzMsMzUsMjE1LDk1LDE5LDIyNCwyLDE5LDgzLDIxNiwxMiw4MSwxOTgsMTgzLDE4MCwwLDU4LDI0OCwzOSwzOSwyNTMsODQsNTAsOTQsMjU0LDIyNSwyMTIsMTUsMTAsODgsMjUzLDIxMCw5LDI0NiwzNywyMjQsMTY1LDE4NSw5LDYsMzMsMF19fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6WzEzNCwxNTEsMTcsMjIyLDU3LDE2LDkzLDIzMyw4NywxMjAsMTcxLDE2MywxNTYsMTM5LDEyMywxODIsMjA5LDE1MiwxMDEsMTM4LDE5Myw2NiwxMzgsMTE3LDIyOCwxMzgsNCw2MywxMjIsMSwxNjgsODEsMyw0OSwyMjcsODksMjAzLDI0NSw4MCwyNDMsMTk0LDE4OSwxMTQsNDMsMTIyLDEzLDU4LDE3Niw0MSwxODAsNTUsNDQsMjI1LDE4NiwxMzcsMTAyLDY2LDc4LDMyLDEzMywyMDUsOSwyMiwyMzIsMTUxLDE4MSwxOTQsMTQ0LDI3LDIyMCwxNjcsMTY3LDE2MSwxMzMsMTgyLDc1LDE5OSwxMDQsMyw2OSwxNjAsMjgsNDQsMTU4LDUyLDIzLDMsNTUsMjIsNzMsMjI1LDIyNSwyMDAsNzAsODEsMjUsMjQ4LDE2MiwxMTUsOTksMjE3LDI1LDE4Niw4NywxODYsODcsMjUyLDYzLDEzMSwxNjMsMTg1LDgzLDM3LDE5NSwxNTIsMTI0LDE4MCwxMjQsOTgsNTAsMTU2LDIxOSw2OCw3MywxNzAsNCw0NCwxMjksMTY2LDIyNiwxMDQsMTgwLDI1MCwzNCwxNzAsMjIxLDIxNyw3OSwxOCwyNTIsMTY0LDc0LDI1MiwxNTksMTEzLDM5LDE4MCw0MiwxNywxOTEsMjQ2LDcyLDE5Nyw4MywxOTUsMTQ3LDYzLDIxNSw1NiwyMSw1MCwxMzQsMjI4LDIxNSwxMzUsMjU1LDEzOSw0MSwxNDcsOTAsMjAxLDEzNyw4NiwxMTEsMTEwLDkyLDE1MCwxNTAsMTkyLDE4MSwyNDUsMTMwLDEwNSwxOCw0OSwxNjIsMjUyLDcwLDE1LDI1NSw4MSwxOTQsMTEwLDIzNSw3NCwxOTUsODMsNCwxOTYsMTMyLDE4MywxNDYsMTYsNjgsMTQ2LDk2LDE3MSw5NywwLDI2LDc4LDI4LDE0NSwxMSw1MSwxNjMsMTA0LDcyLDUzLDEzNyw0NCwxNiwyMjEsODgsMjMsMTY5LDY2LDE0Myw2MywyMDMsODEsMjA2LDI0MSwxODcsMjcsMTMxLDE4Myw4Myw0LDEwMCwxODEsNiwxMzUsMjA0LDIyMCw4MywxODcsNTYsODIsNzcsNzMsMTA4LDE2LDE2MywxNTYsOTEsOTgsMTA3LDI4LDMsMTgzLDIxNiw1OSwxNjYsMTgxLDM0LDE1OSwwLDIxMiw0MSwyMDMsMTM1LDEyNiwxOTUsODMsMTg3LDEyMSw4LDExOSwxNDgsMzgsMTM4LDM5LDE3MCwxMTcsMjIwLDE3OSwxMjksNTAsMzUsOTMsMTY5LDY0LDEwMCwxNTYsMjMyLDE3MSwzNiwxNDcsMTM1LDg5LDg5LDE5MiwxNyw5MiwxNDIsMTYwLDE3OCwxMDcsMTQxLDE2OSwxMiwxMzgsMzUsNzEsMTQwLDIyOCwzOCwxMCwyMTUsNzQsMjksMTUwLDI2LDE1NywyMTQsMTkxLDQ4LDIwLDE2OSw0Miw1MiwxOTUsMywxMDgsMTkwLDEwNCwyMTIsMTc0LDIyNSwyNDMsMyw3NCwyMDAsMTY2LDMsMTI5LDEwOSwxNTIsMTk2LDg5LDExMSwxNjcsNjUsMTg4LDkyLDc4LDE5MywyNyw5Nyw4LDE0NywxNCwxNDMsMjQyLDIwNywyMzQsMTEyLDE4MSw4Niw1MywxMjcsOTIsMTk1LDE2MywyMzYsOCwxMDAsMjA1LDE0NiwxMzksMTQzLDk2LDE5MywyMTYsNTgsMTAwLDE2MSw1MiwxMzEsMzYsMTI5LDEzMSwyMzMsNjksMzEsOTcsMTE2LDE3OSwxMTUsMTUxLDgzLDEwMSwxNzIsMjIsMTU1LDIyNyw2NCw5MiwxMTksOTUsNzgsNzUsMTMzLDY5LDk3LDE5MywyOCwyMDMsMTI4LDI0OSwyNDYsMTI4LDIyNCwyMzMsMTM2LDE3OSwxMzQsMTM1LDEyNiwyNiw5NSwyNDMsMTk4LDExLDExMCwxNjQsMjcsMCwyMTUsMjA0LDI1MiwxNTQsMjA3LDEwOCw4MywxMTIsMTIwLDE5NSwzOSwxNDMsNzQsMTM0LDEzNyw0Myw4NSwxNDgsMTUxLDc1LDk0LDI1Miw2OCw3OCwxODQsODUsMjIxLDE3LDEyOSwxOTEsMTY0LDc1LDIxNCwzLDUwLDc3LDg0LDE2NCwyMzMsMjExLDE0OCwyMTcsMjI4LDE0MCwxODQsMjM1LDY1LDEwMSw0LDE1LDEyOSw4MywxNzEsMjQwLDEyMCwxNTIsOTIsOTEsNTIsNTksOTcsOTksMjMsMjE0LDE4NSw3NSwyMjgsMTIsNjQsNjUsNjgsMjYsOTksMTg0LDE3MSwxMTQsMTAsNjAsMjMwLDE4NSwyMzksMTc2LDIwNCwxMDMsMjUwLDEyMyw3NSwxOTUsNjksMjM0LDIyNSwwLDE5OSwyNTEsMTEzLDY2LDU4LDEyMywyNTQsMjE3LDE1OSwxNjQsMTgwLDE2LDg5LDIzLDMwLDExMSwxNzgsMjA1LDEyMCwyMjksMTA3LDExOCwyMjYsODAsMjIsODYsMzEsMTAyLDE2MywxNzgsNzEsMTc2LDUsMTA1LDg5LDE4MSwyMjksNDQsMTgzLDUsMTYwLDEyMSwxMDksNTQsMTc3LDIwMCwyNDYsMTYxLDE3MiwxNDQsMjAzLDIyNiwxOTksMzgsMTExLDI2LDIwNCwxMzEsMjQyLDE5LDEzNSwyNDAsMTg1LDUsMTUzLDE5OCwyMzQsMTEyLDE4NSwyLDE0NiwzMCwyMTIsMjQ5LDgyLDIzOSwyNDEsMTI2LDExNiwyMDgsMTA0LDE2MywyMzAsMywxMzQsMTA0LDE2LDIxNyw3MCwxNjYsMTAzLDUsMTgzLDg4LDEzNiwxMDEsMTkxLDczLDcxLDI1MSwxNjcsNDcsMjE3LDg5LDQzLDExMiwyMTEsMTE1LDE0OCwyNTIsMjgsNzIsMTk5LDEzOSwyMjAsMTcyLDE3NywxMDAsNTUsMTE4LDgsMTQwLDg0LDE0MywyMiwzMyw0Nyw4MSw5OSwzNSwyMDEsMjYsMTk1LDI0MCwxNTAsNTQsMjM0LDIyLDcxLDU0LDIwMCwyMDMsMTYxLDE3NCwyNDYsMjQ5LDQwLDE2OCwyMjYsMTYyLDE4MSwxNTUsMTc0LDIyNiwxMjksODUsMjIwLDg2LDE2OCwxMzUsMTYxLDY4LDY3LDY2LDM4LDE3LDE5LDYsNzYsMTE4LDgwLDI0Nyw5MSw5Nyw0MiwyMTQsMzEsMjA1LDExNCw5NCwxNzQsMjQzLDExLDI1NCwxMzcsMzYsNTksMzQsMTM3LDE4MCw2LDEzNCw1MiwxMTIsMTc1LDE2OSwyMzQsODQsMjYsMjYsMTk0LDIyMSwxOTcsMzMsMjUzLDE5NiwyNiwyOCwxMzEsNDcsMTI0LDIyNyw3NywyNDEsNTcsNjAsMTUwLDE4NiwxNDgsMTg1LDk3LDExMyw3OSwyMzYsMTE1LDIzNyw0LDEwNCwxMTEsMjQsNDksMTg4LDY5LDksOTcsODMsOTEsMjQ0LDEyOCwxODQsMjMyLDIwMywyNSwyMTksMTQ4LDEsMTMyLDIxMCwxNTAsODEsNTMsMjIsMTQzLDE3OSwyMDUsMjE5LDIxMCwxNzIsMTAyLDE5NCwxMDMsMTA2LDE4OCwxOTQsMTM1LDExNiwxNDUsNiw1MCw5LDgwLDIxMCwzMiw4MCw1Nyw1MiwxMzYsMSwxNTIsMTM1LDE4OCw1OCw3MiwxODYsMTYwLDY0LDk3LDE4NiwxOTcsMjA4LDU5LDI1LDk2LDE1OSw3LDE3OSw0Miw2MSwyMTcsODQsMTk5LDE0NywyLDM5LDIzMCw2MywxMzUsMTg3LDE1MSwyMTQsNTAsMTQsMTQ3LDE5MiwyMDQsMTI4LDEwNywxODksMzIsMjI4LDEyNCwxNTgsMTM2LDI4LDEyNSwxNjksMTQ3LDU0LDEwMSwxMTcsMTE0LDExOCwxNTcsNTIsMjA5LDgyLDIyMCw5Nyw3MSwxMiwyMTAsMTE0LDEyMiwyMDMsMTkzLDEyMywxODAsMTE0LDgyLDE1MywxODAsMjIyLDI2LDE2MSwxLDIwLDE4Myw2MCwyMTgsMTU3LDI4LDQ4LDE4NywxOTMsMjQxLDEsMjU0LDEyMSwzNCwxNzUsMTY2LDE1OSwxNDksMTE0LDMzLDc0LDAsNDMsMjM2LDg3LDQ0LDIwMywxNTQsOTAsMjA2LDEzMiw2MSwxMTAsNDEsMzEsMjQ2LDUsOCwyMjEsMTgyLDE0OCwyMTksMTk3LDkyLDE0MSwyMDgsMTE2LDEwMSwxMDgsNzcsMjIzLDE3NiwxNSwxNjEsMjI4LDYyLDUwLDExNCwxMTQsNzIsNzIsNTksMTgwLDE2NCwxMzgsMTM4LDE4Myw4LDkwLDI0LDE3MiwyMjcsMTcxLDI5LDI0NiwzOSwxMzUsNzEsMTMzLDExMywxMDEsMjI0LDU2LDEzNCwyOCwyMDAsMjI2LDI0NCwxMjEsMTgzLDE0OSw5Myw2MCwyMTAsMjA2LDIzMiwxMiwxMjMsMzgsNTcsMTc1LDIzMywxMjEsODQsNTcsMTg3LDQ4LDIyNiwwLDIwNywyOSwyMTksNDcsMTMwLDkyLDYwLDI1NCwxMzIsMTA5LDkwLDEwOCwxNTAsMSw2MCwxMzIsNzYsNTcsNzgsOTEsMTc3LDIwMiwxODAsMTk2LDc4LDM3LDE4MCw0MiwxNTEsMzcsMTU0LDE4MSw5Miw3MiwyNDUsOCwyNCwxNzcsMSwxMjMsMTQyLDEyMCwxMzMsMTc3LDIyOCw3NSw3NSwyMjgsMTM4LDIxNiwyMzMsMTQxLDY1LDIwMiwxODEsMTE3LDU3LDE0MSwyNTAsMjQ0LDEwLDE0OSw1NCwxNzMsMTA0LDM2LDE1NiwzNSwyNTEsMTYsMjExLDE0NCwzMCwxNDEsOTEsMTc2LDMyLDc2LDE2MiwxNTIsMjA4LDEwOCw4NSwyMSwxNTksODksNywxNTMsMjA4LDExMiwxOTUsMjE3LDEwNywxNDksNzMsMTgwLDg0LDEyLDQwLDEzMiwxNTYsODQsMTkwLDE5NCwxNTIsMTQ1LDQwLDEwNCw4LDEsMTEzLDcyLDY5LDI0NywxNTEsMjE3LDI0OSw4Miw1OCwxMTksMTk3LDEzMCwxNjMsMTEwLDk2LDg1LDI3LDEzMiw4Nyw1OSwxMDYsOCwxMDcsMTEyLDU1LDk3LDEwMCwxMTksMTEyLDEzNiwyMTAsNDQsMTk5LDM4LDIwNywyMjAsMTM5LDk2LDcsODYsMTMsNCwxNDQsMTUyLDE4Niw2LDkxLDEzNCwxNjksMTA0LDIwNywxMzQsMTQ1LDIwLDI3LDk4LDIxNCw2Nyw2NCwxMDAsOTIsOTEsNzksMTY4LDE2OCwyOCwyMDgsNzQsMjMyLDExLDE3Nyw4NywyNTEsMjUsMSwyNTAsMTcxLDIwOSwxNiwxNjMsMTc1LDE0MCw0MSw5MiwxNTIsMjIsODAsODAsMTA3LDY4LDI1MSwzLDE1OSwyMDksMTI1LDQ4LDE2NSwxMDgsMjM2LDIwLDExLDU0LDEwMCwxODgsMjI4LDE0NCwxNzYsMTg2LDIyMCwxNDcsMTA4LDE2LDkzLDkzLDE3Niw0MywyMTIsNjUsMzgsMTQ3LDE2MCw4LDcyLDI3LDEwNCwyMjQsMjQzLDEzMywxNDIsMTAxLDIwNiwyMDQsMTk3LDY2LDg4LDI0LDE0MywxMDUsMTM3LDEwMywwLDE5Niw0OSwyNDEsMjA0LDUzLDg3LDIyLDEyNywxODgsMTMyLDM4LDExMiwxNjgsNTAsOTYsNDQsNjcsMjQ0LDEzOSwxMTEsMTY1LDU0LDUzLDE4NiwyMTksODQsMTMxLDExLDgyLDE5MCw5NiwxOCwyMzAsMTkzLDk3LDIwOSw4MCw4NSw2NCw3Myw1NCw5MywxNTUsMTg4LDE0LDYsMzUsMTgyLDEzMiwxNzAsMTE2LDIzMCw0MiwzMywyMzUsODUsMTI2LDM5LDEwNSwxMzksOTIsNTcsNiwxODYsODksMTU3LDgzLDQwLDIwNywxNzksMTYxLDYwLDE0MCwyMDYsMTk4LDE3MSwxMTgsMjMyLDEzNCw4OCw2OSwxNDAsODksMTM1LDExNyw2MiwxNTUsMjUwLDk1LDE1MiwyMjYsMzAsMzAsMTE0LDE5Miw5OCwyMTcsMTE2LDc2LDE2OCwwLDIyNSwxLDE1NywxOTAsMTcyLDEwMywxNDEsOTIsMTU1LDE4LDExNyw1OCwxMzAsMTgxLDE5NiwyNyw1OCw3OSw5OSw4NCw4LDE4OSwxOTQsMTI4LDUsMTE0LDIxLDE1LDkyLDE4OSw5NSwxMzMsMTgyLDE0OSwxODYsNTIsMjQ5LDM5LDcyLDgsMjEsMTA5LDE0LDUzLDM3LDE3OCwxOTYsMTE0LDE3OSwxNzEsNjksMTg5LDQxLDE1NSwxNCw4MywxNTcsMTcwLDI0NCwzOSwxNDgsMjQ0LDE3MCw4MCwxODYsMTU1LDEwMCwyNDMsMTg5LDUwLDE3NywxNDUsMjI1LDg0LDE4LDIsNywxNDksMjE4LDg0LDE3NiwxOTIsNTAsMTE5LDc2LDEwMCwwLDY3LDI4LDIwNiwyMjgsMTQ5LDEwMSwxNzcsMjQ3LDE5OSw5OCwxNTQsOCwyNDYsMjIwLDUwLDEsMTE4LDE2Nyw2MCw3MiwxNTAsMjI5LDU4LDE4OSw0NSwyMjAsMTE5LDIxOCw0MCwyOCwxODYsMTgsMTc0LDAsMjA5LDE0MCwxNzEsMTYzLDE0LDk0LDkyLDEzOCwyMTcsNzUsMTQwLDE3MCwyMjcsMjAwLDEyNywxNTUsNDgsMTgxLDEyLDEzMywyMjUsMjQ5LDE2MCw0MSwyMDQsMjYsMTAxLDIxOSwwLDE4NCwxNTQsMjA1LDIzMywxOTYsMTQyLDIzMiwxMjMsMzAsMjM3LDIxMCw5Myw2NCw4Myw4NiwxNTAsMjAsMTg5LDEwNyw1NSwyNCwxNiw4NCwyMywxMTUsMTQ1LDgsMTExLDI3LDQsMTg0LDU2LDQ0LDI0NiwyMDgsMTA2LDExNSw5MSwxNTksMjQ0LDEyMywxOTYsMjcsMjE2LDk3LDE1MCwyMDgsMiwyNTIsNjAsMTc4LDE5MCwzOSw2LDIyLDE0NywxNjAsMzMsMjQ1LDIxLDE2MywyMTYsNSwxOSwxMzYsMTU2LDEwNiwxNTYsMTI3LDIzMSwxMDIsMjA3LDM1LDk2LDEyOSwxMTQsMjA4LDg2LDE4MCwxMTYsMTE5LDEyNiw3NCwxMiw2Nyw2LDEzMyw0MSwxMTgsNzYsMCwyNiwyMDYsNiw1LDEwMywxNTEsMjA0LDEzNiwxNjQsMzgsNjYsMTQsOTIsMTI1LDE2Myw1MywxNTEsMTMwLDIzNSwxODQsMTU4LDE0OSwxNjEsMjM4LDE5OSw3MSwyNTEsMTg3LDM1LDE4OCwyNCwzMSwxNjMsMjM1LDE2Myw2MCw2MCwxMzAsNzksMTU0LDI1LDIxNyw2NCwxOTUsMTc0LDEzOSw4NSwxOTUsMjA4LDEzOSw3Myw2MCwxOTYsMTI5LDY0LDIwMywxNjYsMTI4LDEzOSwyMDQsMTgsMTI3LDEzOCwyMjksNzcsMTY4LDE2MSwxOTMsMjA3LDEwNSwwLDE4MCwxMDcsMTcyLDY1LDExNyw2Myw3NCwzNiwxNjUsMTQsNTEsMTI0LDE2LDEwNywyMyw4MiwxNDUsMTA2LDI0NywxNDQsNDQsMTkzLDEyMCwzLDEwNCwxNjgsNDEsMTg4LDM0LDIwNiwyNTEsMTcwLDIwNSwyMDMsMTEyLDE3MSwxNjEsMTMzLDc2LDE0OCwxMzgsMzQsODAsNDEsMTY4LDEyOCwyMywyMDMsODEsMTQ3LDUwLDUxLDE0NSwxOTgsMTUyLDIzNCw5Niw3MiwxODUsNTAsMjMxLDI3LDE0NSwyMDcsMjExLDQyLDQwLDg2LDMxLDI1MCw4Niw4OCwyMzYsMTk3LDE2OSwxNzYsMTY1LDEzMCwyMzQsMjQ0LDE4NCwxNTUsMTg2LDIsMTk5LDU1LDY5LDU3LDIwMCwxMjgsMTUsMTksNzgsMjMxLDIxMywxNzIsMjAsMjE0LDM0LDE4OSwyMTIsMTgzLDQsMTEsMTQyLDE4OCwxNjAsNDksMTU3LDI3LDIxLDE1NCwxNjQsMTc5LDIyMCwxNjYsMTc0LDIwNiwxMzEsMTEsNjQsODAsMjgsMzEsMTIxLDExMCwxODEsMTIyLDEzMywyMjUsMTQ3LDE3OSw5OCw4OSwxNzksNjYsMTY4LDQyLDI0MCw4NywyMDUsMTg3LDE5NSwxMTAsMTk5LDIyMCwxMywxODMsNDQsMTksMSwxNTEsNTksMTgwLDE2MSwxOTEsMTAzLDEyMywxMywyNTUsMTY4LDcwLDg0LDI2LDIwNCwxMzAsODYsMzgsMTM2LDIzLDEzNCwxNTgsMTAxLDEyOCwyNTMsMjAyLDEzOSwxNjIsMjE0LDMwLDE5MSwxMTIsMTIwLDIwMiwxNTAsMTc3LDMsMTY1LDgzLDI0MCwxNjQsMTY2LDI0NiwxNTIsMTQ3LDE5OSw4NCwxNSwyMDIsMjM0LDMwLDc1LDM4LDczLDk4LDY3LDE2NCwxMjAsNTQsNywxMjIsNTMsNzEsMzcsMjUsMTk3LDc1LDE4NywxMiwxODksMTk3LDQxLDE5MCwzMiwxMjMsMjE0LDEzOSwyMDUsMTcyLDI0NywxMzMsMTUwLDcsMTk1LDEyNiw4MCwxMjAsMjAxLDk4LDE0MiwyMTUsODUsMjAwLDIzNCw3NSw1MCwyMTQsNDksMTA2LDIxNiw1OCwxOSw2OCwyMTMsNzMsMzcsMTQ4LDEzNCwyMDEsMjM1LDEwMiwxOTEsNzUsMTgwLDIxNCw1NSwxODcsMTk5LDg2LDI5LDAsNywyMDAsMTMzLDEzNSw0MiwxODksMTgwLDE3OCwxNDIsMzcsMTIwLDEyOCwzNiw3MCwyMzQsMTMyLDU5LDQ2LDIxNywxNDIsODMsODYsNjYsMTkzLDE2OCwxNDIsMTk4LDEwMyw2NSwxMzksMjQzLDE1MSwyOSwxMzksNjMsNjMsMTg4LDEyMiw0MiwzNSw2OSwxNTAsOTksMTExLDE0NiwxODQsMjUsMzksOTAsMzMsMTI2LDI0OSwxODksMTI3LDE3Niw2MSwxMTUsMTA1LDk4LDkxLDUzLDEzNSwxMTQsMTIyLDE2MCw4Miw3MywxNjUsNTcsNjgsMTEwLDIwOCwxMjQsMTI1LDIsMTY5LDExOCwxMTksODQsMzcsMTI4LDg2LDE1MCw1MSwxMDUsODcsMjU1LDMzLDIwMywyMDAsMjMxLDEwMywxMjksNTIsNjQsMTg4LDgyLDU4LDY2LDE2Myw1NywyMTEsMTIwLDExMCwxODYsMTgsODUsMTMxLDIxOCwxOSwxNyw4LDc4LDIwNSwxNzcsNTYsMjIzLDEyMCw5Miw0MywxOTYsNywxMjcsMTU2LDQyLDgzLDEwNywxMCwyMjMsMTMwLDEwLDI0MCwyMzMsMTg5LDE1LDE5OCw0MCwyNDAsMTE4LDUsNDUsNjUsMjEsOTUsMTg3LDE3OSwxMDYsMTMyLDExMywxOTIsMTAsMzAsMTMzLDE2NCwyMSw5Myw5MiwxNTgsMTcwLDEzOSwxMjYsMjQ4LDI0OCwxMzEsMjI3LDE4Miw5NCwxNTksNCwzNyw1NCwxOTksMTg3LDE0NSwxMTcsMTMzLDE3LDU3LDU1LDIxMiwzNSwxMTIsMTg1LDEzMSw5LDIwOSw2NCw3NCwxNDYsMjE3LDUyLDIyLDIyNCw0OSwxOTUsODcsMTc0LDYwLDIxLDg4LDc2LDIwOCw4NywxOTUsMjI2LDczLDIwMSwyMjksMTI4LDY4LDIzNiw4NCwyMjcsMjQyLDE2NCw3OSwxOTYsMTM0LDExOCw2NywxMjgsMiwxMCwxNywyMjYsMjAsMTI2LDEzNywzLDE4NiwxMDEsMTQ0LDIwMCwxODksMTUzLDExNCwxNjEsMTk5LDUsOTIsMTQ4LDExMiw1NCwyLDE0NCw2MCwyMTgsMCwyMywyMzIsNjAsMjQzLDIxMiwxNzUsMCwzNywyNSw0NywyMTIsMTEwLDIxNiw0OCw0LDE0NywyMjQsNTQsMTQsNzAsMjAwLDIzMywyMTIsNTYsMTQsMjE0LDEzNSw3OSw4MSwxNTAsMTE2LDEzMywzLDc1LDIzMiwxODgsMjUzLDIyMCwxMzksMjAyLDE0NCw1Niw4Miw1MiwzLDI1LDIyOCw5Nyw5OCwyNTIsMjAxLDc2LDE0MCwxOSwxNDQsOTgsMTAyLDIwMiwxMzYsMTg3LDUwLDE5MiwxMDMsNDQsODYsOTcsMTI3LDEyMCwxMiw4OCwyMzYsMTYzLDgwLDIxNCwxODQsMjIwLDIxNSw0MCwxMzksMTE3LDcxLDIxOSwxODEsMTE3LDUxLDIxMiwxMjQsMTAyLDExMywxMDEsMzEsMTQ2LDQ2LDE5MSwyMDEsOTksNiwyMjgsMTIyLDIyOCw3MSwyMDcsOTAsOTIsNTQsNzAsMjUwLDE2MSwyMjEsMTM5LDExMSw0Niw4NSwxODAsMTY1LDcsNTYsMTI1LDIxLDM0LDY3LDExOSwxMTIsMTY1LDExLDE5NywxMDAsNjUsNjcsMjIxLDU5LDIzNCwxODksMTk1LDIwMywxNjIsMTU5LDIwMywxOTksMTU4LDE4MiwxNjUsMSwxOTIsMTU1LDExNSwyOSwxNzksMjMzLDM1LDIxNSw5NSwxOSwyMjQsMiwxOSw4MywyMTYsMTQzLDE0MiwxMzQsMTUyLDYyLDI1MSwxNTQsMzUsMjAsMTA3LDEyLDE0NywxNTEsNzgsMTUzLDkzLDg3LDE0NSwzOCwyNiwxODUsMTQzLDk0LDY2LDIxMSw1LDIyLDE1NiwzOCwxMjUsMTY4LDUyLDU0LDIwNywxNzEsMTExLDU5LDk1LDIwOCwyMTksMjM1LDksMzAsNTcsMTQyLDE4LDI1NCw2MywxODksMTYwLDc4LDExNiw1MCwyMDQsMjM2LDIwLDE1NywxMzksMTA1LDE0LDI1MCwyMjQsMTk5LDQ5LDgyLDY2LDE2MCwxODEsMzIsMTQxLDEyNiwyMjAsMjEzLDc3LDE4MywyNDYsMjUzLDE5NSwyMTQsMzcsMTk0LDE4NSw5OCwxNDUsMTI0LDYyLDE4LDUyLDQ2LDIyNSwxLDEwLDQ0LDEyMCwxNDMsMjQwLDEyLDgxLDE5OCwxODMsMTgwLDAsNTgsMjQ4LDM5LDM5LDI1Myw4NCw1MCw5NCwyNTQsMjI1LDIxMiwxNSwxMCw4OCwyNTMsMjEwLDksMjQ2LDM3LDIyNCwxNjUsMTg1LDksNiwzMywwXX19fSx7InB1YmxpY19rZXkiOnsia2V5Ijp7InZlYyI6WzExNiwxNjYsNjIsMTI5LDE3NywxNjMsMTI0LDIxNCwxMDgsODAsODYsMTQ1LDI4LDE0NCw2NCwxODUsNCw4OSw2MCwxMTYsMzMsMTksMjI1LDE1Nyw3MCwxMjMsMTMzLDUzLDE4MCw4OSw2NywxNDksNDMsNjYsMTgzLDE0Myw0NywzNCwxODAsODcsMTYsMTEsMTEwLDI1MSw2MSwyMDIsMjMzLDE1Myw4LDEwMiw5MSwxOTgsNDksNTksMTYwLDE5OCw4Niw1OCwyNDAsMTU4LDE1OSw4MSwyMDcsOTQsMjA5LDEyMCwyMjgsODQsNTUsMjM5LDIyLDE5NywxMDMsMjM0LDc3LDE5OCwyNDEsNDcsOSw4MCwxNjIsMTg2LDE1NCwxODIsMjYsMTM5LDg2LDI0MSwyMCwxMDQsMTY5LDIxOSwxMzcsMjA3LDgsMTgsMTU0LDE2LDI1LDExOSwxNDYsMTg2LDE1Myw4OSwyLDksMTA0LDQyLDM2LDE2LDM3LDIxLDE5NSw5NSwzOSwxOTYsMTU0LDE4NSw3NCwxMzIsMjQ2LDg5LDE0NSwxMjAsMjI3LDIxLDYyLDE4MiwxMDIsMjMyLDI1MiwyLDE3OSwxNjksNDIsMTQ1LDEwMywxOTEsMjA1LDIzNCwxMTYsMTkwLDEwOCwxNDIsOTksNTksNDUsMTAxLDEyMSw5LDYzLDE2NywxOTQsODQsMTAyLDQ4LDIzLDIxMCwxMTgsMjI3LDE1MiwxMzUsMTYzLDQzLDQyLDg0LDI0NCwzNywyMDUsMTM1LDE1MSwxMTUsMTUwLDg4LDE4MCwyMzMsMTQ2LDY5LDE5LDIwNyw2Niw0MiwxMjMsMTcyLDI0OCw4OCwxODMsMTY5LDMwLDM1LDUyLDc2LDg1LDE1MywxNTgsOSwxMTUsOTAsMjUxLDk5LDE1LDE2NCwxNjIsMjMsODYsMTUwLDE3Miw4NSwxMDEsMTI5LDI0MSwxMzQsMTk5LDEyNCwyNSwwLDE5MCwxNDYsMzQsNzEsMjQsOTYsMzgsMjEsNjAsMTkxLDE0MCwxNzMsMjUyLDExMyw5NSw2MCw3NSw0OSw1OSwyNDQsMjAzLDI0MSwxMjksNjksMjM1LDIyLDMyLDE1LDIzNiwxOTAsMTIyLDEwMSw2NCwxMTEsNywxNzEsMjI4LDU3LDEyMSwxMTQsMjAzLDEzLDEwMyw5LDM0LDE1LDM2LDI5LDIyMiwyMjcsMTk4LDE1NCwzMywxMTEsMTM3LDE2OCwxMTgsMTA1LDIzMSwxMDEsNjEsMzUsMTgwLDc4LDg5LDQzLDE0MCw5MCwyNiw1MCwyMSwxNDMsMjQxLDIxMiw3NywxMyw0OCwxNzEsMzMsMTYzLDIwMywyMDgsMTgxLDE5NCwxMDgsODIsMTI1LDExNyw4Miw2OSwxMywxNDgsODMsNDUsNjUsNjcsMTExLDE5Nyw4NiwxMDMsMTY2LDMwLDI1MywyNTIsNDksMzUsNTcsMTgzLDc1LDkxLDE0MSwxODYsOTEsMTcwLDE0NywyNTEsMTYzLDQyLDE4MSwxNzQsMjI4LDI0LDIzLDE3NywyMTUsNzYsMjA2LDIxOSw1MiwyNTIsODYsOTIsNjQsMTY4LDIyLDc4LDE4NywxNDQsNzgsODgsMTAxLDIxOCwxNDYsMTA1LDE2Niw2LDEzNCwxNTYsNjYsMTkxLDE4NSwxOTksMTg2LDEyLDUsOTYsMTI1LDY0LDQ0LDE0MiwxMiwxNzEsMTI5LDg0LDc2LDcxLDIxNiw5NiwzMywxNDUsNTIsMjU1LDE0Niw5MSwxMzUsNTUsMTk3LDMzLDI0NCwxNjIsNjgsOTcsNDgsNjcsODksMTMzLDIwMywxODYsMTAwLDgzLDE4NSw3MCwxMTgsNTksMTg5LDI0OCwyMTMsMTQyLDk1LDE5NiwxMTIsMTc5LDE0OCwxODcsNywxMDgsMjgsMjM1LDEzMiwxLDIwMCwyMjgsMTgzLDE2NCwxMzUsMTYsODIsMjgsMTY2LDMwLDIzMSwxMzMsODUsMjUwLDEzOCw4OSwxOTYsMTE4LDE3Miw2NSwxOTAsMjMyLDgsMTMsNTgsODMsNzIsMjM5LDEwMyw0Niw5NiwzNiw1NSw4OSwxODcsMzYsMjUsMjE2LDEwNCwyMDAsMzQsNzUsMjIwLDIzNCwxMTIsMjIzLDAsMTI2LDEwNiwyMTYsMTkyLDE0OSw0Myw4NiwyMCwxNzEsMTE1LDgzLDIwMywxMiw0OSwxODQsODIsMjM4LDIxMywxNDAsNTQsMTUxLDksOTMsMTc3LDgyLDU0LDEyMSwzMiwxMjUsMzIsMTExLDExOSwxODUsMTAxLDEzNCwyNDEsMTQ0LDIyNywyMTYsMjgsMzgsMjI4LDUsMzQsMTE0LDExMSwyOSwyMDksMjA3LDEyNSw0OCwzOSwyMzEsMTI5LDc4LDIyOSw5MSw3NCw1LDI1MiwxNjAsMTY2LDE0OCwyMCw0OCwxNDcsMjAyLDE5OSwyNDcsMTcwLDIzMSwxMjksODMsMjI0LDE2Nyw0OSwyMzQsMTM2LDE2MywzNCwyMjgsMTE5LDE1MCwxNiw1OCwxODYsMTk4LDEzMyw0LDY4LDE1OSwxNzUsODEsMTQwLDI0MywyNCw4MCw3OSwyNDQsMTA4LDgwLDEwMywxNDMsMTYxLDg4LDIwMywyMjUsMTYzLDE2NCwxOTcsNSw4MiwyNywxMzgsNjksMjQwLDE4Niw5MSwyMzMsMTMxLDE1OCwyMDIsNDAsOTAsODEsMTYwLDgyLDE0MywxMzcsMTY0LDEzMSwyMCwxNzMsMTUzLDI1LDk1LDgwLDI2LDE4MSwzOCwxNDgsNTQsMTk2LDEwNCwyMywyMzcsMTM2LDE2MywyMTgsMTcsMjcsNjYsMjI4LDEyNywyMTEsMjUwLDE0OSwxNjQsODUsMTA5LDE2OSwxODYsMjAwLDEsMjUxLDIwMSwxMDMsMTIzLDE4MywxNTUsODcsOTQsMTg3LDIzNSwxNzgsOTgsOTcsMjA2LDI1LDEwNSwxNjEsMjAyLDIzMSwxMjMsNjYsMTM4LDE0LDE3NywxMTQsMTYxLDU5LDE3Nyw0MCwxMywzOSwzMCw4NCw0OCwxODcsMjMzLDEzMSwxODYsMjA0LDE2Nyw5MSwyMjMsMjQzLDE5Myw5MiwyMTMsMTkxLDE0LDE0NywxNywxMzcsNCwzNiw5Niw1Niw0NSwyNywzNSwyMDEsMTkwLDE5MywyNCwxNzcsMTU0LDg2LDE5NywxNTYsMTY4LDE2OCwxMTUsMzEsMTI1LDIyOSwzNSw4MCw4OSw5OSwyMzcsMjUxLDE5MCw4MiwxLDEzMywxNTAsMjE0LDIwNSw4Nyw5LDE5NCwyMzQsMjM0LDg2LDE2OCwxNDQsMTkwLDIwMSw5NywxMTIsMTQxLDc0LDc2LDE0MCw5Niw1LDExNyw2Niw3LDI1NSw0MCwxNTksNDIsNDMsMTE5LDg0LDUsOTcsMSwyMTYsNzEsMTEsMTY3LDE0NSw2NSwyNTEsNTAsMTAwLDUyLDE3MCw0LDE5LDE5LDExOSwxNDAsMTAsMTAsODUsMTcsODQsMzcsMTA5LDI0MCwxOTQsMjMsMTY2LDIzNSwxMzEsNzYsMTg2LDM3LDEwNCwyMTcsMjksMjI3LDE1NSw2MCwxMDksNzUsMTAyLDE3LDEyOSwxNTQsMjI1LDIyLDk5LDE4MiwxNzAsNTYsMjUsMjMxLDE1MSw3OSwxNjEsNTAsMTAsMjI5LDMsNDAsMTk2LDI2LDE3OCwxMzQsMTQ1LDE3LDE1NSwxMTYsMTQxLDIwLDE3MiwxNDEsMTY5LDUsNDAsMjA5LDYyLDM1LDM2LDE0LDc2LDIzNiwxOTQsMjQyLDExNiwxODAsMjM2LDQyLDg0LDkxLDExOCwxMzksMjI1LDE3OSwxODgsMCwxMDUsMTMsOTksMTgzLDUzLDIyMiwyMTMsMTMxLDIzMiwyMjUsOTYsMTkzLDcxLDQsMTA0LDYsMTY1LDE3OSwyMzUsNDksMjA3LDExNSwzOCwxMjMsMTg1LDI5LDY1LDE4MSwxNzYsMTg1LDcwLDE2OSwxODEsMjQxLDIyLDQxLDkwLDY2LDEyMyw4OSwxNjEsMzAsMTQ4LDExNSwxMjQsMTk4LDY0LDY2LDEwMywxMDEsNTIsMTk3LDE5MCwxMzMsMTAwLDEzOSwxNDIsODMsOTcsMjUyLDEsMTMyLDIzMCwyMzQsMTgyLDIyMSwyMSw4OSwxMDUsMTI0LDEwOCwyMjAsMTkzLDE5NiwxNTUsMTU2LDE2MSwxNTEsMjQxLDExNyw2NCwxMjAsMjA2LDM4LDI0MSw5MywxMDYsMjEyLDI1LDE0MCwxNTQsMjcsMTgxLDI0MSwxMDEsMjEyLDM0LDEzOSw1MSw3LDk5LDM0LDE2Niw2MCw1MywxODIsNzgsMTkxLDczLDE1NSwyNTEsNTYsMTcxLDUzLDE5NywzNiw0MiwxOTksMTQ4LDI1MCwxOTYsMTkyLDEzNSwxMzQsMTAyLDI1NCwyOCwxMTcsMTI2LDg2LDUsMTU3LDUzLDE2NSwyMzgsMTM1LDE3OCwxODEsMzksNzYsMTQsMzQsODAsNiwyMjcsMTYyLDEyMCwxMzAsMTAzLDE3LDE4OCwxNzcsNTQsOTgsMTQwLDE5NSwxNzgsNjcsMTYwLDE2NywxNCwxNTIsNDksMTYzLDY3LDI1MCwxNTIsMjA4LDExNiwzMywyNDcsMTgyLDEyMiwxMTYsMTIzLDE2OSwxOTQsMTY0LDExMiwxNTYsNzQsMTQ4LDE0OCw2NywxMjUsMTE5LDM5LDExOSwxMjQsNTUsMTMzLDIxMCw1OSwxMjUsOTEsMTg3LDExNCwxNDUsNzEsMTcyLDE4MSw1MSw5MSwxNjEsNTcsNTUsMTQ4LDgxLDQ5LDE3NCwxMDgsMTUzLDIwNiwyNDIsNzgsMjM5LDE4LDEzMCwzMiwyMTEsMTI5LDIyMiw2NCw4LDEyOCwxOTMsMTI4LDE2LDEwNiw4NSwxNTAsMywyMDIsNzQsMTYzLDIwMiw4LDE5Nyw2MywxMzMsMjA0LDE4NCwxNDgsMTUzLDE4OSw2MiwxNjgsMjYsMTgzLDIxOSwxNTAsMjAwLDIxMSw1NCwyNDgsNzUsMTExLDIzNywyMDIsMTYsMTkzLDIyNSwxOTIsMTgyLDU5LDIwMiwzNiwyMzIsMTgwLDE5NywxMzAsMTIzLDE1OSwxNTQsMTIzLDIxNiwyNDAsMTYxLDIxMiwxNDUsMTEwLDE1MCw4MCwxMTgsMjA4LDkwLDEwNiw4MSw3MiwyMCw2OSw2MCwyOCwxNzcsOTAsMTY0LDE4OSwzOSwwLDgzLDgyLDk4LDEzMCw4MCw0NSwxNzcsNzksMTc3LDIzNSw0MSwxNDQsMjUsMzIsMjIsMTIyLDMxLDE0NSwyMTcsMTYzLDEwMSwyMjAsMSw5OCwxMDgsMTk2LDE3MSwxODYsMTMyLDI5LDI0MCwyMjUsMTEyLDQsNjYsOTYsMTQ4LDE4NCwxNjQsMzYsMjIzLDMwLDExLDY5LDEwNSw3NywxOTYsMTY3LDE2LDE0OSwxODUsMjQ2LDE1MywxMjksMTgwLDEyMCwyNDQsMTU2LDEyLDEzMSw5NywyNDIsMjI3LDc0LDE0NSw3OSw3XX19LCJwcml2YXRlX2tleSI6eyJrZXkiOnsidmVjIjpbNzUsOTgsNDMsNTYsMTY2LDYyLDE0OCw2MCwxNTUsMjA5LDE5NSwxNjksNDEsMjQ5LDE5NiwxOTcsNywxNDksMTU0LDQxLDEyLDEwOSwyMTUsNDIsMTkzLDUyLDEwNCwxNTUsNzIsNDEsMjksNTYsNzksMTcyLDE5NCwxOTAsMTY5LDI0MCw0OSwxODQsMTYxLDI0LDM5LDQ5LDM4LDQ4LDEyMSwxNTEsMzMsNjQsODMsMTE5LDIzNiwzNywxOTUsMTAyLDEwNCwyMTIsMTIwLDE4OSw2MywxNTEsNDIsNzEsMjI2LDE4MCwxMzcsNDEsOCwzOSwxMDEsMTU4LDE0LDE5Nyw2NCw5MCw3MCw2NiwyNSwyMDMsMTY1LDM1LDE1NCw1Niw0Myw4NywxMTIsMTk5LDU4LDE1NSwyNywxNDcsMTEyLDk1LDE3OSwxMTIsNzcsMTcyLDY2LDMyLDEzNiw2LDE1LDEzNSwxNDMsNzUsMTIyLDE5NCwyMDksNDEsMjA3LDksNyw5NiwxMTQsMjMwLDEzOCwxNDAsMjUwLDcyLDE2NCwxNTQsMTM5LDE3NiwxMDQsNDksMTAzLDI3LDI4LDE0MCwyLDEzMywxMjIsMTA1LDEwOCw2MCw1NCwxNjIsMTcwLDE3OSwxOTIsMjMyLDE4NSwxNDYsMzksMjI4LDMwLDIwMiwxNDgsMTQzLDQ5LDI3LDExNywxOTMsMjI5LDEzMiwyNTAsMTA4LDE1MSw3MSwyNDAsMTYwLDM3LDEyNCwxOTQsMjA3LDI0MSwxMTAsMTY4LDIyNyw1LDE5MSwxMDMsODgsMjQ5LDkwLDExMiwyNDcsMTM4LDY2LDQ1LDYsMTEsMTU1LDEyMiw1NSwxNzIsMjE4LDE1MiwzNSw4MiwxMjksMTExLDI0OCwxMTgsOTUsMTk4LDEzNywyMzYsMjcsMzQsMjEzLDc1LDEzOSwyMCwyMjksMTIsOTMsMTUwLDEyNSw3Miw5NiwxMjgsMjAwLDEwNywyNyw0NCwyMjAsMTg1LDQ0LDExNCw4NywxLDEzNiw1MywxMzUsNTIsMTQsOTUsMTY1LDEzNiwyMjYsMTcwLDEwNiwxNzAsMTU1LDEwNCwyMTEsMTksNjUsNTYsMTQ1LDE2NSwyNTMsMTQ4LDk2LDE0LDE4NCwxOTQsMjU1LDcxLDIwLDEzMyw3NSwyMCw3OCwxNTQsMTUwLDE0OCwxMzMsMTA0LDkxLDg4LDEzMCwxMTksNDIsNTEsMjcsMjQxLDEzMCwyNDQsMjMwLDExMCw3MSw1MCwxMjAsMjMwLDU3LDI4LDE1NCwxNjMsMTksNDksMjMyLDE0OSw1MSwxNDksMjUsMTcyLDI0LDE3OSw2NCw3Niw3LDM2LDIyNCwxMzAsMTI1LDE5Myw5NywxNDUsMSwyMSwzMywxODAsMjksMjI0LDE1NCwxNzYsMTE3LDEwMiwxNjAsODUsMjQ3LDExMSwyNTAsMjM0LDIwNSwyMzAsODYsMjA3LDI1MSwzOCw4LDYzLDE2OCwxNjQsMjUyLDEzNCwxMzYsMTgyLDcwLDEyNiw2NywxMTIsMTM0LDE4OSw0MywxODcsMjI2LDE4OCw5Nyw4NCwxNjQsMjA0LDkwLDcwLDY3LDI0NiwxNDAsMTIxLDE5NCw2OCw0Niw4MSwyMzAsMTM2LDE2NywxNzcsNjcsMjM2LDE2MCwxNzAsMTMyLDExNywxNTIsMTQxLDExNCwxODUsMjAwLDEzNCwxNywyMiwyMTUsNjMsMjM3LDEzOCwxMywxNjQsMTE3LDgwLDE1NywxNjIsMTA0LDE5LDIxNSwxNDAsOCw1MCwxOTMsNDksMjQ4LDY5LDE5NSwxNzksMTU2LDE0NywyNywzNiwxNDcsMTk3LDc3LDIwMywyNTEsMTUyLDYxLDIzNSw0MywxOTcsMTAsMTkwLDIyOCw1OCwxNzAsMTY5LDI0Nyw2OCwxMjMsMjI1LDE3MywxNTIsMTcwLDE2MywyNTIsMTMwLDYsMzksMTkzLDE4MywyMDcsMTYsMTY4LDEwMSwwLDUwLDIxMSwyMzYsMjUsMTMxLDE1NCw0Miw1NiwyNDksOTEsMTM0LDUwLDksMTQzLDIwOSwyNSwxMDksMTA0LDE4MywyMDksNjksNDcsMTM0LDk4LDg1LDE0MCwxMzgsMTk5LDIyMSwyMTcsMTAyLDI5LDE1NSw1NSw4OCwxNDUsMSwxMjQsMjExLDE3OSwxMzYsMjE1LDE0NCwxNjAsMjM0LDEyMiw3OSwxODQsMTYxLDEzNSwzNSwxNzMsMTAwLDgsMTU0LDczLDEyNCwxMzIsMTUwLDEwMSw0NiwyMTgsMjA0LDE5NCwxNzksNTYsNjIsMTIwLDE0NiwxNzYsMjM3LDUzLDExOSw5MCw2OCwxOSwyMzcsMjAsMTY2LDIwLDk5LDExMywxODYsOTYsNjQsMjQ4LDIzNSwxNCwyMDUsMTM4LDEwOCwzMSwxMCwxMjUsMjQ0LDM4LDE1NSwxMTAsNzQsNDQsOTksODcsOTYsMTM0LDM2LDEyLDE1MSw3MywxOSwxMzUsMTkyLDIwNCwyMDIsMTM3LDE3NiwzNyw1NywxNzIsMTAzLDIxMyw5NSw2OSwxNDQsMTg4LDM3LDI0LDI0LDQzLDE0NSwxODMsMTcwLDYsMjgsMTQwLDcsMTEyLDE1NiwxMjAsMTIwLDE4MywxMiwxOTEsMjI5LDgzLDMzLDE2OSwxMTYsMzQsMTI2LDEwMiw1NiwxNTcsMTIxLDQ0LDE5LDIwMCwyMSwxMCw1MywxODMsMjYsMjE5LDExNiwyMDUsMTY4LDE2NywyNTUsNywxNzcsMTk3LDQwLDEzLDI1NSwxODcsNTcsMTEsMTg4LDE3NSw1OSwyNDgsODYsMjUwLDEyLDE1LDE2MywyMTcsMTU2LDE4LDE2Myw0OCwxMjcsMTM5LDEwMiwxOTAsMTcwLDE5MiwxLDE4MCwxNjYsMTA2LDE5OCwzMiwxNzcsOTksOTAsMTgyLDI0Miw2MCwxNTIsMTYsMTc2LDE1MCwxODQsMTAxLDc3LDcwLDE3NiwyOCwxNzcsOTAsMTAsMjUwLDYwLDI0MywxOSwxMjMsMTY5LDkwLDQ4LDI1MiwyNDIsMTgwLDE1NywxNyw1NywxMzMsNzAsMTE4LDE2MiwxNjcsOSwxNzMsMTM2LDE3NSwxMTcsMjI0LDIzLDQ2LDQyLDE3MiwxNTIsMTYwLDk2LDE2MCwyMDAsMTUsNTYsMTM0LDUxLDcxLDg0LDkwLDk1LDc1LDI3LDE4LDE0Nyw0OCwxMjMsODgsMTk2LDE4MCw4Nyw1Nyw2NywxODEsOCwyMjcsODAsMTAsMjAwLDE1NiwyMSwyMTksMjUyLDEwOSwxNTAsMTAwLDIzLDQ1LDE4NiwxOTYsMjM3LDIyOCw2MCwyMDIsMTY3LDIzLDc2LDE4Miw5NywyMywxMzYsNTAsODUsMTY5LDExNywyMTUsODMsMjEsMTMwLDE1MSwyMDEsMTY2LDE2NSwxNzYsMTAwLDIxMiw1Myw5MiwxNDUsMTExLDY5LDE2NiwzOCwyNDgsMjMsMjYsMjUwLDIxNiwxODEsMjQ3LDE5MywyMDYsMTE0LDIxNiwxMzIsMTMzLDEwOCw1MCwxNTYsNTksMjksMTg1LDEyLDE2MSw4MSwxMzEsMjAxLDE2NCwxNTEsMTgsMTQ5LDc2LDEyMywxMzIsMjUsOTUsMTQsMTE0LDE1OSwxOTMsMjUwLDEwMCwxMTUsMTcxLDE0MCwxMjYsODksODYsMTU1LDIxOCwxNzIsMTYxLDIxMSw0Myw2NSwxMDEsOSwxNDEsMjQ2LDIwNSw1MiwyNDcsMTUxLDkzLDczLDE0OSwxMzAsMjI4LDIwNSw1MiwxLDI4LDc3LDcyLDIwNywyMjYsMTE0LDM0LDE3NywxODcsOTgsOCwxODcsMTQzLDE0LDE5OCw4Niw0NywxMDIsMTIxLDIwOCwxNDgsNzYsOTcsNzQsNDcsMTM1LDE1MSwxNjEsMTg0LDM4LDEzNiwyMjQsMTA2LDE3NiwxNzIsMTE0LDE0NSwyMzMsMTU2LDk4LDE0MywxODgsMTIwLDE0OSw1Nyw3LDE5NiwxOTMsMzQsMTc4LDkxLDQ1LDgxLDIzMiw0NCwxMTgsMjQ2LDc1LDE3NCwxNzgsOTUsNzksMTIyLDExNCwyNTQsNjAsMTU3LDg5LDI2LDE5MiwxMjAsMTAsNzMsMjA1LDExNywxNTEsMTI2LDE5Nyw5MywxMzMsMjA4LDE3OSw1MiwzNiw3MSwyMTAsMjQ3LDEyNiwxMjksNTIsMzEsOTQsMTcwLDgsMTYxLDIyNSwxMDIsMTcxLDIsMjIsMTM5LDk2LDcsMTA0LDE4Niw0MCwxMTEsMjcsMTAzLDI1Miw0MiwxNzcsOTIsNzEsMTI4LDIyOCwyNTIsMTkzLDE1OCwxMSw2MCwxMzMsNDAsMTAyLDE3NCw0OSwxODksMTU0LDE3OSw5MSw1OCwxNTYsMTEsMjQ0LDE1MywxMDEsNzMsMSwzMiwxNTQsMTg4LDExNSw3NiwxNDQsMTA4LDE3LDIxMyw5MiwyMTYsMjEsOTEsMjM5LDIzMSwxODYsOTksNDgsMTcxLDExMyw5MSw1NSwyMDIsMTMyLDE0MSwxNDUsMTA0LDE0OCwzOSwzOSwxMyw0MywyNDYsMTQxLDE1NSwyMzUsMTIsNCwyMTgsMTg2LDk3LDIsMTgsMjI4LDEzMiwxNTQsMTcsMjIwLDEyMywyMDgsMzgsMjA0LDM4LDg5LDE4MSw1LDIzMyw3MiwyNDgsMTU2LDgyLDIxMywxNzEsMiwxNTIsNTksMTExLDgyLDE2NSw1NiwxOTEsOSw1MCwyNDksMTY2LDk3LDMyLDQ4LDEyOCwyMTUsODgsODMsMTE4LDM3LDEyNiw4NywxNjgsMTY4LDgzLDIzNCwxOTMsMTYyLDIxLDY5LDEwMywxMzMsMTgsOTcsMTAyLDQxLDE5NSwxODcsNzcsNjQsMTYyLDI4LDIxLDgsNTAsOTQsMTAxLDE2MCwxNDMsMTM4LDEsMTA3LDExNywxMTcsMTY5LDIwLDY3LDMwLDIzMCwxMTUsMjMyLDE4OCw0Niw4MywxMDIsMjAyLDIzNywxNjUsNTcsMTE5LDcsMTUsMTkyLDI1MSw3MiwyMTksNDAsNTIsMTY2LDUwLDkzLDM2LDE1MiwyMDEsMjQ2LDgxLDExMyw3NCw3NCwxMzAsNiwxNjQsMTIsMTE4LDIzMywzNywzOCwyNDYsNTgsMzcsMTIxLDEwMiw3OCwwLDIyLDM3LDE5Myw0MSwxMzksMTAwLDE4OSw0NiwxOTksMTg1LDIwNyw1NiwxMzAsMTIxLDgsMCwyMDksNzIsNjEsMTE2LDE2Niw2MiwxMjksMTc3LDE2MywxMjQsMjE0LDEwOCw4MCw4NiwxNDUsMjgsMTQ0LDY0LDE4NSw0LDg5LDYwLDExNiwzMywxOSwyMjUsMTU3LDcwLDEyMywxMzMsNTMsMTgwLDg5LDY3LDE0OSw0Myw2NiwxODMsMTQzLDQ3LDM0LDE4MCw4NywxNiwxMSwxMTAsMjUxLDYxLDIwMiwyMzMsMTUzLDgsMTAyLDkxLDE5OCw0OSw1OSwxNjAsMTk4LDg2LDU4LDI0MCwxNTgsMTU5LDgxLDIwNyw5NCwyMDksMTIwLDIyOCw4NCw1NSwyMzksMjIsMTk3LDEwMywyMzQsNzcsMTk4LDI0MSw0Nyw5LDgwLDE2MiwxODYsMTU0LDE4MiwyNiwxMzksODYsMjQxLDIwLDEwNCwxNjksMjE5LDEzNywyMDcsOCwxOCwxNTQsMTYsMjUsMTE5LDE0NiwxODYsMTUzLDg5LDIsOSwxMDQsNDIsMzYsMTYsMzcsMjEsMTk1LDk1LDM5LDE5NiwxNTQsMTg1LDc0LDEzMiwyNDYsODksMTQ1LDEyMCwyMjcsMjEsNjIsMTgyLDEwMiwyMzIsMjUyLDIsMTc5LDE2OSw0MiwxNDUsMTAzLDE5MSwyMDUsMjM0LDExNiwxOTAsMTA4LDE0Miw5OSw1OSw0NSwxMDEsMTIxLDksNjMsMTY3LDE5NCw4NCwxMDIsNDgsMjMsMjEwLDExOCwyMjcsMTUyLDEzNSwxNjMsNDMsNDIsODQsMjQ0LDM3LDIwNSwxMzUsMTUxLDExNSwxNTAsODgsMTgwLDIzMywxNDYsNjksMTksMjA3LDY2LDQyLDEyMywxNzIsMjQ4LDg4LDE4MywxNjksMzAsMzUsNTIsNzYsODUsMTUzLDE1OCw5LDExNSw5MCwyNTEsOTksMTUsMTY0LDE2MiwyMyw4NiwxNTAsMTcyLDg1LDEwMSwxMjksMjQxLDEzNCwxOTksMTI0LDI1LDAsMTkwLDE0NiwzNCw3MSwyNCw5NiwzOCwyMSw2MCwxOTEsMTQwLDE3MywyNTIsMTEzLDk1LDYwLDc1LDQ5LDU5LDI0NCwyMDMsMjQxLDEyOSw2OSwyMzUsMjIsMzIsMTUsMjM2LDE5MCwxMjIsMTAxLDY0LDExMSw3LDE3MSwyMjgsNTcsMTIxLDExNCwyMDMsMTMsMTAzLDksMzQsMTUsMzYsMjksMjIyLDIyNywxOTgsMTU0LDMzLDExMSwxMzcsMTY4LDExOCwxMDUsMjMxLDEwMSw2MSwzNSwxODAsNzgsODksNDMsMTQwLDkwLDI2LDUwLDIxLDE0MywyNDEsMjEyLDc3LDEzLDQ4LDE3MSwzMywxNjMsMjAzLDIwOCwxODEsMTk0LDEwOCw4MiwxMjUsMTE3LDgyLDY5LDEzLDE0OCw4Myw0NSw2NSw2NywxMTEsMTk3LDg2LDEwMywxNjYsMzAsMjUzLDI1Miw0OSwzNSw1NywxODMsNzUsOTEsMTQxLDE4Niw5MSwxNzAsMTQ3LDI1MSwxNjMsNDIsMTgxLDE3NCwyMjgsMjQsMjMsMTc3LDIxNSw3NiwyMDYsMjE5LDUyLDI1Miw4Niw5Miw2NCwxNjgsMjIsNzgsMTg3LDE0NCw3OCw4OCwxMDEsMjE4LDE0NiwxMDUsMTY2LDYsMTM0LDE1Niw2NiwxOTEsMTg1LDE5OSwxODYsMTIsNSw5NiwxMjUsNjQsNDQsMTQyLDEyLDE3MSwxMjksODQsNzYsNzEsMjE2LDk2LDMzLDE0NSw1MiwyNTUsMTQ2LDkxLDEzNSw1NSwxOTcsMzMsMjQ0LDE2Miw2OCw5Nyw0OCw2Nyw4OSwxMzMsMjAzLDE4NiwxMDAsODMsMTg1LDcwLDExOCw1OSwxODksMjQ4LDIxMywxNDIsOTUsMTk2LDExMiwxNzksMTQ4LDE4Nyw3LDEwOCwyOCwyMzUsMTMyLDEsMjAwLDIyOCwxODMsMTY0LDEzNSwxNiw4MiwyOCwxNjYsMzAsMjMxLDEzMyw4NSwyNTAsMTM4LDg5LDE5NiwxMTgsMTcyLDY1LDE5MCwyMzIsOCwxMyw1OCw4Myw3MiwyMzksMTAzLDQ2LDk2LDM2LDU1LDg5LDE4NywzNiwyNSwyMTYsMTA0LDIwMCwzNCw3NSwyMjAsMjM0LDExMiwyMjMsMCwxMjYsMTA2LDIxNiwxOTIsMTQ5LDQzLDg2LDIwLDE3MSwxMTUsODMsMjAzLDEyLDQ5LDE4NCw4MiwyMzgsMjEzLDE0MCw1NCwxNTEsOSw5MywxNzcsODIsNTQsMTIxLDMyLDEyNSwzMiwxMTEsMTE5LDE4NSwxMDEsMTM0LDI0MSwxNDQsMjI3LDIxNiwyOCwzOCwyMjgsNSwzNCwxMTQsMTExLDI5LDIwOSwyMDcsMTI1LDQ4LDM5LDIzMSwxMjksNzgsMjI5LDkxLDc0LDUsMjUyLDE2MCwxNjYsMTQ4LDIwLDQ4LDE0NywyMDIsMTk5LDI0NywxNzAsMjMxLDEyOSw4MywyMjQsMTY3LDQ5LDIzNCwxMzYsMTYzLDM0LDIyOCwxMTksMTUwLDE2LDU4LDE4NiwxOTgsMTMzLDQsNjgsMTU5LDE3NSw4MSwxNDAsMjQzLDI0LDgwLDc5LDI0NCwxMDgsODAsMTAzLDE0MywxNjEsODgsMjAzLDIyNSwxNjMsMTY0LDE5Nyw1LDgyLDI3LDEzOCw2OSwyNDAsMTg2LDkxLDIzMywxMzEsMTU4LDIwMiw0MCw5MCw4MSwxNjAsODIsMTQzLDEzNywxNjQsMTMxLDIwLDE3MywxNTMsMjUsOTUsODAsMjYsMTgxLDM4LDE0OCw1NCwxOTYsMTA0LDIzLDIzNywxMzYsMTYzLDIxOCwxNywyNyw2NiwyMjgsMTI3LDIxMSwyNTAsMTQ5LDE2NCw4NSwxMDksMTY5LDE4NiwyMDAsMSwyNTEsMjAxLDEwMywxMjMsMTgzLDE1NSw4Nyw5NCwxODcsMjM1LDE3OCw5OCw5NywyMDYsMjUsMTA1LDE2MSwyMDIsMjMxLDEyMyw2NiwxMzgsMTQsMTc3LDExNCwxNjEsNTksMTc3LDQwLDEzLDM5LDMwLDg0LDQ4LDE4NywyMzMsMTMxLDE4NiwyMDQsMTY3LDkxLDIyMywyNDMsMTkzLDkyLDIxMywxOTEsMTQsMTQ3LDE3LDEzNyw0LDM2LDk2LDU2LDQ1LDI3LDM1LDIwMSwxOTAsMTkzLDI0LDE3NywxNTQsODYsMTk3LDE1NiwxNjgsMTY4LDExNSwzMSwxMjUsMjI5LDM1LDgwLDg5LDk5LDIzNywyNTEsMTkwLDgyLDEsMTMzLDE1MCwyMTQsMjA1LDg3LDksMTk0LDIzNCwyMzQsODYsMTY4LDE0NCwxOTAsMjAxLDk3LDExMiwxNDEsNzQsNzYsMTQwLDk2LDUsMTE3LDY2LDcsMjU1LDQwLDE1OSw0Miw0MywxMTksODQsNSw5NywxLDIxNiw3MSwxMSwxNjcsMTQ1LDY1LDI1MSw1MCwxMDAsNTIsMTcwLDQsMTksMTksMTE5LDE0MCwxMCwxMCw4NSwxNyw4NCwzNywxMDksMjQwLDE5NCwyMywxNjYsMjM1LDEzMSw3NiwxODYsMzcsMTA0LDIxNywyOSwyMjcsMTU1LDYwLDEwOSw3NSwxMDIsMTcsMTI5LDE1NCwyMjUsMjIsOTksMTgyLDE3MCw1NiwyNSwyMzEsMTUxLDc5LDE2MSw1MCwxMCwyMjksMyw0MCwxOTYsMjYsMTc4LDEzNCwxNDUsMTcsMTU1LDExNiwxNDEsMjAsMTcyLDE0MSwxNjksNSw0MCwyMDksNjIsMzUsMzYsMTQsNzYsMjM2LDE5NCwyNDIsMTE2LDE4MCwyMzYsNDIsODQsOTEsMTE4LDEzOSwyMjUsMTc5LDE4OCwwLDEwNSwxMyw5OSwxODMsNTMsMjIyLDIxMywxMzEsMjMyLDIyNSw5NiwxOTMsNzEsNCwxMDQsNiwxNjUsMTc5LDIzNSw0OSwyMDcsMTE1LDM4LDEyMywxODUsMjksNjUsMTgxLDE3NiwxODUsNzAsMTY5LDE4MSwyNDEsMjIsNDEsOTAsNjYsMTIzLDg5LDE2MSwzMCwxNDgsMTE1LDEyNCwxOTgsNjQsNjYsMTAzLDEwMSw1MiwxOTcsMTkwLDEzMywxMDAsMTM5LDE0Miw4Myw5NywyNTIsMSwxMzIsMjMwLDIzNCwxODIsMjIxLDIxLDg5LDEwNSwxMjQsMTA4LDIyMCwxOTMsMTk2LDE1NSwxNTYsMTYxLDE1MSwyNDEsMTE3LDY0LDEyMCwyMDYsMzgsMjQxLDkzLDEwNiwyMTIsMjUsMTQwLDE1NCwyNywxODEsMjQxLDEwMSwyMTIsMzQsMTM5LDUxLDcsOTksMzQsMTY2LDYwLDUzLDE4Miw3OCwxOTEsNzMsMTU1LDI1MSw1NiwxNzEsNTMsMTk3LDM2LDQyLDE5OSwxNDgsMjUwLDE5NiwxOTIsMTM1LDEzNCwxMDIsMjU0LDI4LDExNywxMjYsODYsNSwxNTcsNTMsMTY1LDIzOCwxMzUsMTc4LDE4MSwzOSw3NiwxNCwzNCw4MCw2LDIyNywxNjIsMTIwLDEzMCwxMDMsMTcsMTg4LDE3Nyw1NCw5OCwxNDAsMTk1LDE3OCw2NywxNjAsMTY3LDE0LDE1Miw0OSwxNjMsNjcsMjUwLDE1MiwyMDgsMTE2LDMzLDI0NywxODIsMTIyLDExNiwxMjMsMTY5LDE5NCwxNjQsMTEyLDE1Niw3NCwxNDgsMTQ4LDY3LDEyNSwxMTksMzksMTE5LDEyNCw1NSwxMzMsMjEwLDU5LDEyNSw5MSwxODcsMTE0LDE0NSw3MSwxNzIsMTgxLDUxLDkxLDE2MSw1Nyw1NSwxNDgsODEsNDksMTc0LDEwOCwxNTMsMjA2LDI0Miw3OCwyMzksMTgsMTMwLDMyLDIxMSwxMjksMjIyLDY0LDgsMTI4LDE5MywxMjgsMTYsMTA2LDg1LDE1MCwzLDIwMiw3NCwxNjMsMjAyLDgsMTk3LDYzLDEzMywyMDQsMTg0LDE0OCwxNTMsMTg5LDYyLDE2OCwyNiwxODMsMjE5LDE1MCwyMDAsMjExLDU0LDI0OCw3NSwxMTEsMjM3LDIwMiwxNiwxOTMsMjI1LDE5MiwxODIsNTksMjAyLDM2LDIzMiwxODAsMTk3LDEzMCwxMjMsMTU5LDE1NCwxMjMsMjE2LDI0MCwxNjEsMjEyLDE0NSwxMTAsMTUwLDgwLDExOCwyMDgsOTAsMTA2LDgxLDcyLDIwLDY5LDYwLDI4LDE3Nyw5MCwxNjQsMTg5LDM5LDAsODMsODIsOTgsMTMwLDgwLDQ1LDE3Nyw3OSwxNzcsMjM1LDQxLDE0NCwyNSwzMiwyMiwxMjIsMzEsMTQ1LDIxNywxNjMsMTAxLDIyMCwxLDk4LDEwOCwxOTYsMTcxLDE4NiwxMzIsMjksMjQwLDIyNSwxMTIsNCw2NiwxMDIsMTE5LDE0MiwyMjYsMjQzLDQwLDE4NCwyNTEsMTM4LDkzLDIwOSwyMjIsMjE1LDIwOCwxMTAsMjQyLDE2LDI5LDI1Miw1MiwyMjIsOTEsODUsMTQ2LDU2LDY5LDY2LDIxOCw0Niw5MSwzOSwyNCwyNDUsNTcsMjQ4LDIxNCw2LDM4LDc4LDY0LDkwLDEzNyw2Myw3MiwyOSwyMjQsMTIwLDEzOSwzOCwyOSwyMjQsMzUsMTAwLDEwNiw3MCwxMzMsMTMsMTEsMTM3LDI0NCwxNDAsMjM1LDI0LDIyMSwxNDEsMTcsMTU2LDQ2LDEwLDE5MywyMjgsMTY4LDEzMCwxODEsMjMzLDE3LDE0MywxMjksNTUsMTA5LDIwLDM1LDIyNiw0OSwxNjgsMTM3LDE0Nyw5NSwxNzAsMTMwLDI0MCw2MCwxMzksMTAzLDE3NCwxMTYsOTYsMTQ4LDE4NCwxNjQsMzYsMjIzLDMwLDExLDY5LDEwNSw3NywxOTYsMTY3LDE2LDE0OSwxODUsMjQ2LDE1MywxMjksMTgwLDEyMCwyNDQsMTU2LDEyLDEzMSw5NywyNDIsMjI3LDc0LDE0NSw3OSw3XX19fV0sIm5ld19sZWFmX2tleXBhaXJfb3B0aW9uIjpudWxsLCJ1cGRhdGVfcGF0aF9sZWFmX25vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbMTM0LDE2OSwxMDQsMjA3LDEzNCwxNDUsMjAsMjcsOTgsMjE0LDY3LDY0LDEwMCw5Miw5MSw3OSwxNjgsMTY4LDI4LDIwOCw3NCwyMzIsMTEsMTc3LDg3LDI1MSwyNSwxLDI1MCwxNzEsMjA5LDE2LDE2MywxNzUsMTQwLDQxLDkyLDE1MiwyMiw4MCw4MCwxMDcsNjgsMjUxLDMsMTU5LDIwOSwxMjUsNDgsMTY1LDEwOCwyMzYsMjAsMTEsNTQsMTAwLDE4OCwyMjgsMTQ0LDE3NiwxODYsMjIwLDE0NywxMDgsMTYsOTMsOTMsMTc2LDQzLDIxMiw2NSwzOCwxNDcsMTYwLDgsNzIsMjcsMTA0LDIyNCwyNDMsMTMzLDE0MiwxMDEsMjA2LDIwNCwxOTcsNjYsODgsMjQsMTQzLDEwNSwxMzcsMTAzLDAsMTk2LDQ5LDI0MSwyMDQsNTMsODcsMjIsMTI3LDE4OCwxMzIsMzgsMTEyLDE2OCw1MCw5Niw0NCw2NywyNDQsMTM5LDExMSwxNjUsNTQsNTMsMTg2LDIxOSw4NCwxMzEsMTEsODIsMTkwLDk2LDE4LDIzMCwxOTMsOTcsMjA5LDgwLDg1LDY0LDczLDU0LDkzLDE1NSwxODgsMTQsNiwzNSwxODIsMTMyLDE3MCwxMTYsMjMwLDQyLDMzLDIzNSw4NSwxMjYsMzksMTA1LDEzOSw5Miw1Nyw2LDE4Niw4OSwxNTcsODMsNDAsMjA3LDE3OSwxNjEsNjAsMTQwLDIwNiwxOTgsMTcxLDExOCwyMzIsMTM0LDg4LDY5LDE0MCw4OSwxMzUsMTE3LDYyLDE1NSwyNTAsOTUsMTUyLDIyNiwzMCwzMCwxMTQsMTkyLDk4LDIxNywxMTYsNzYsMTY4LDAsMjI1LDEsMTU3LDE5MCwxNzIsMTAzLDE0MSw5MiwxNTUsMTgsMTE3LDU4LDEzMCwxODEsMTk2LDI3LDU4LDc5LDk5LDg0LDgsMTg5LDE5NCwxMjgsNSwxMTQsMjEsMTUsOTIsMTg5LDk1LDEzMywxODIsMTQ5LDE4Niw1MiwyNDksMzksNzIsOCwyMSwxMDksMTQsNTMsMzcsMTc4LDE5NiwxMTQsMTc5LDE3MSw2OSwxODksNDEsMTU1LDE0LDgzLDE1NywxNzAsMjQ0LDM5LDE0OCwyNDQsMTcwLDgwLDE4NiwxNTUsMTAwLDI0MywxODksNTAsMTc3LDE0NSwyMjUsODQsMTgsMiw3LDE0OSwyMTgsODQsMTc2LDE5Miw1MCwxMTksNzYsMTAwLDAsNjcsMjgsMjA2LDIyOCwxNDksMTAxLDE3NywyNDcsMTk5LDk4LDE1NCw4LDI0NiwyMjAsNTAsMSwxMTgsMTY3LDYwLDcyLDE1MCwyMjksNTgsMTg5LDQ1LDIyMCwxMTksMjE4LDQwLDI4LDE4NiwxOCwxNzQsMCwyMDksMTQwLDE3MSwxNjMsMTQsOTQsOTIsMTM4LDIxNyw3NSwxNDAsMTcwLDIyNywyMDAsMTI3LDE1NSw0OCwxODEsMTIsMTMzLDIyNSwyNDksMTYwLDQxLDIwNCwyNiwxMDEsMjE5LDAsMTg0LDE1NCwyMDUsMjMzLDE5NiwxNDIsMjMyLDEyMywzMCwyMzcsMjEwLDkzLDY0LDgzLDg2LDE1MCwyMCwxODksMTA3LDU1LDI0LDE2LDg0LDIzLDExNSwxNDUsOCwxMTEsMjcsNCwxODQsNTYsNDQsMjQ2LDIwOCwxMDYsMTE1LDkxLDE1OSwyNDQsMTIzLDE5NiwyNywyMTYsOTcsMTUwLDIwOCwyLDI1Miw2MCwxNzgsMTkwLDM5LDYsMjIsMTQ3LDE2MCwzMywyNDUsMjEsMTYzLDIxNiw1LDE5LDEzNiwxNTYsMTA2LDE1NiwxMjcsMjMxLDEwMiwyMDcsMzUsOTYsMTI5LDExNCwyMDgsODYsMTgwLDExNiwxMTksMTI2LDc0LDEyLDY3LDYsMTMzLDQxLDExOCw3NiwwLDI2LDIwNiw2LDUsMTAzLDE1MSwyMDQsMTM2LDE2NCwzOCw2NiwxNCw5MiwxMjUsMTYzLDUzLDE1MSwxMzAsMjM1LDE4NCwxNTgsMTQ5LDE2MSwyMzgsMTk5LDcxLDI1MSwxODcsMzUsMTg4LDI0LDMxLDE2MywyMzUsMTYzLDYwLDYwLDEzMCw3OSwxNTQsMjUsMjE3LDY0LDE5NSwxNzQsMTM5LDg1LDE5NSwyMDgsMTM5LDczLDYwLDE5NiwxMjksNjQsMjAzLDE2NiwxMjgsMTM5LDIwNCwxOCwxMjcsMTM4LDIyOSw3NywxNjgsMTYxLDE5MywyMDcsMTA1LDAsMTgwLDEwNywxNzIsNjUsMTE3LDYzLDc0LDM2LDE2NSwxNCw1MSwxMjQsMTYsMTA3LDIzLDgyLDE0NSwxMDYsMjQ3LDE0NCw0NCwxOTMsMTIwLDMsMTA0LDE2OCw0MSwxODgsMzQsMjA2LDI1MSwxNzAsMjA1LDIwMywxMTIsMTcxLDE2MSwxMzMsNzYsMTQ4LDEzOCwzNCw4MCw0MSwxNjgsMTI4LDIzLDIwMyw4MSwxNDcsNTAsNTEsMTQ1LDE5OCwxNTIsMjM0LDk2LDcyLDE4NSw1MCwyMzEsMjcsMTQ1LDIwNywyMTEsNDIsNDAsODYsMzEsMjUwLDg2LDg4LDIzNiwxOTcsMTY5LDE3NiwxNjUsMTMwLDIzNCwyNDQsMTg0LDE1NSwxODYsMiwxOTksNTUsNjksNTcsMjAwLDEyOCwxNSwxOSw3OCwyMzEsMjEzLDE3MiwyMCwyMTQsMzQsMTg5LDIxMiwxODMsNCwxMSwxNDIsMTg4LDE2MCw0OSwxNTcsMjcsMjEsMTU0LDE2NCwxNzksMjIwLDE2NiwxNzQsMjA2LDEzMSwxMSw2NCw4MCwyOCwzMSwxMjEsMTEwLDE4MSwxMjIsMTMzLDIyNSwxNDcsMTc5LDk4LDg5LDE3OSw2NiwxNjgsNDIsMjQwLDg3LDIwNSwxODcsMTk1LDExMCwxOTksMjIwLDEzLDE4Myw0NCwxOSwxLDE1MSw1OSwxODAsMTYxLDE5MSwxMDMsMTIzLDEzLDI1NSwxNjgsNzAsODQsMjYsMjA0LDEzMCw4NiwzOCwxMzYsMjMsMTM0LDE1OCwxMDEsMTI4LDI1MywyMDIsMTM5LDE2MiwyMTQsMzAsMTkxLDExMiwxMjAsMjAyLDE1MCwxNzcsMywxNjUsODMsMjQwLDE2NCwxNjYsMjQ2LDE1MiwxNDcsMTk5LDg0LDE1LDIwMiwyMzQsMzAsNzUsMzgsNzMsOTgsNjcsMTY0LDEyMCw1NCw3LDEyMiw1Myw3MSwzNywyNSwxOTcsNzUsMTg3LDEyLDE4OSwxOTcsNDEsMTkwLDMyLDEyMywyMTQsMTM5LDIwNSwxNzIsMjQ3LDEzMywxNTAsNywxOTUsMTI2LDgwLDEyMCwyMDEsOTgsMTQyLDIxNSw4NSwyMDAsMjM0LDc1LDUwLDIxNCw0OSwxMDYsMjE2LDU4LDE5LDY4LDIxMyw3MywzNywxNDgsMTM0LDIwMSwyMzUsMTAyLDE5MSw3NSwxODAsMjE0LDU1LDE4NywxOTksODYsMjksMCw3LDIwMCwxMzMsMTM1LDQyLDE4OSwxODAsMTc4LDE0MiwzNywxMjAsMTI4LDM2LDcwLDIzNCwxMzIsNTksNDYsMjE3LDE0Miw4Myw4Niw2NiwxOTMsMTY4LDE0MiwxOTgsMTAzLDY1LDEzOSwyNDMsMTUxLDI5LDEzOSw2Myw2MywxODgsMTIyLDQyLDM1LDY5LDE1MCw5OSwxMTEsMTQ2LDE4NCwyNSwzOSw5MCwzMywxMjYsMjQ5LDE4OSwxMjcsMTc2LDYxLDExNSwxMDUsOTgsOTEsNTMsMTM1LDExNCwxMjIsMTYwLDgyLDczLDE2NSw1Nyw2OCwxMTAsMjA4LDEyNCwxMjUsMiwxNjksMTE4LDExOSw4NCwzNywxMjgsODYsMTUwLDUxLDEwNSw4NywyNTUsMzMsMjAzLDIwMCwyMzEsMTAzLDEyOSw1Miw2NCwxODgsODIsNTgsNjYsMTYzLDU3LDIxMSwxMjAsMTEwLDE4NiwxOCw4NSwxMzEsMjE4LDE5LDE3LDgsNzgsMjA1LDE3Nyw1NiwyMjMsMTIwLDkyLDQzLDE5Niw3LDEyNywxNTYsNDIsODMsMTA3LDEwLDIyMywxMzAsMTAsMjQwLDIzMywxODksMTUsMTk4LDQwLDI0MCwxMTgsNSw0NSw2NSwyMSw5NSwxODcsMTc5LDEwNiwxMzIsMTEzLDE5MiwxMCwzMCwxMzMsMTY0LDIxLDkzLDkyLDE1OCwxNzAsMTM5LDEyNiwyNDgsMjQ4LDEzMSwyMjcsMTgyLDk0LDE1OSw0LDM3LDU0LDE5OSwxODcsMTQ1LDExNywxMzMsMTcsNTcsNTUsMjEyLDM1LDExMiwxODUsMTMxLDksMjA5LDY0LDc0LDE0NiwyMTcsNTIsMjIsMjI0LDQ5LDE5NSw4NywxNzQsNjAsMjEsODgsNzYsMjA4LDg3LDE5NSwyMjYsNzMsMjAxLDIyOSwxMjgsNjgsMjM2LDg0LDIyNywyNDIsMTY0LDc5LDE5NiwxMzQsMTE4LDY3LDEyOCwyLDEwLDE3LDIyNiwyMCwxMjYsMTM3LDMsMTg2LDEwMSwxNDQsMjAwLDE4OSwxNTMsMTE0LDE2MSwxOTksNSw5MiwxNDgsMTEyLDU0LDIsMTQ0LDYwLDIxOCwwLDIzLDIzMiw2MCwyNDMsMjEyLDE3NSwwLDM3LDI1LDQ3LDIxMiwxMTAsMjE2LDQ4LDQsMTQ3LDIyNCw1NCwxNCw3MCwyMDAsMjMzLDIxMiw1NiwxNCwyMTQsMTM1LDc5LDgxLDE1MCwxMTYsMTMzLDMsNzUsMjMyLDE4OCwyNTMsMjIwLDEzOSwyMDIsMTQ0LDU2LDgyLDUyLDMsMjUsMjI4LDk3LDk4LDI1MiwyMDEsNzYsMTQwLDE5LDE0NCw5OCwxMDIsMjAyLDEzNiwxODcsNTAsMTkyLDEwMyw0NCw4Niw5NywxMjcsMTIwLDEyLDg4LDIzNiwxNjMsODAsMjE0LDE4NCwyMjAsMjE1LDQwLDEzOSwxMTcsNzEsMjE5LDE4MSwxMTcsNTEsMjEyLDEyNCwxMDIsMTEzLDEwMSwzMSwxNDYsNDYsMTkxLDIwMSw5OSw2LDIyOCwxMjIsMjI4LDcxLDIwNyw5MCw5Miw1NCw3MCwyNTAsMTYxLDIyMSwxMzksMTExLDQ2LDg1LDE4MCwxNjUsNyw1NiwxMjUsMjEsMzQsNjcsMTE5LDExMiwxNjUsMTEsMTk3LDEwMCw2NSw2NywyMjEsNTksMjM0LDE4OSwxOTUsMjAzLDE2MiwxNTksMjAzLDE5OSwxNTgsMTgyLDE2NSwxLDE5MiwxNTUsMTE1LDI5LDE3OSwyMzMsMzUsMjE1LDk1LDE5LDIyNCwyLDE5LDgzLDIxNiwxMiw4MSwxOTgsMTgzLDE4MCwwLDU4LDI0OCwzOSwzOSwyNTMsODQsNTAsOTQsMjU0LDIyNSwyMTIsMTUsMTAsODgsMjUzLDIxMCw5LDI0NiwzNywyMjQsMTY1LDE4NSw5LDYsMzMsMF19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNjQsMTgwLDEyNSwxMjYsNzksMjIwLDIyMSwyNTMsMTIzLDQyLDIwMSwxMjAsMTgwLDE2NCwyMDAsMjA4LDE3Nyw5OSw4Miw2MCw1NSwxNTYsMTI2LDc3LDExNywxMTUsMjAzLDIwMywxNDIsMjU1LDE2NiwzNF19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJDb21taXQiOnsidmVjIjpbMTY1LDI0MCwyMjIsMTQ1LDE5MSwxOTksMjAxLDIwOCw3NiwyMDMsMTYyLDE3OSwxNDIsMjM1LDExNywyMjcsMTM0LDU2LDExNSwzOSw4Miw1MywxNTQsNDksMTc3LDIxOSw4OSwyMDksMTg0LDMsMTM5LDIwOV19fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMzIsMzAsMzksODMsNjksMTA3LDE4OSwzNiwxMDEsMTA0LDE3MCwyMjAsMTM0LDI1MSw0MSw0NSwxNjQsOTYsMzksMjQyLDU3LDU5LDE2OCw4Myw4NCwxNjMsMTM5LDE4OSwyMzEsMTI4LDEyNywxOTUsMTkwLDE1NCwxMjIsNTQsMTI2LDE1NywxMzAsNTksNzAsMTQ0LDEwMSwzMiwxNzAsMjUsMjA4LDIwNCwyNDcsMTM0LDE1NSwyMDksOTksMTE1LDU0LDEzNywyMywxMjksMjE5LDE0MywxNTIsMTU2LDEwMCwxM119fX19fX19fQAAAAAAAABSAAAAAAAAFM1UcmVleyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJ0cmVlIjp7ImxlYWZfbm9kZXMiOlt7Im5vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbMjcsMTMzLDExOSw4OSwxNywyLDE3MywxMzEsMTg2LDIxOSw3NCw5NCw3MywxODcsMjAzLDMxLDI0NCwxNjksMTksMTAzLDEyLDE0LDk5LDE2NSwyMjUsMTM4LDM2LDE5NywxMzUsMTg3LDY4LDE1NSwzMSwxMTAsMTA4LDkwLDIyLDgxLDEzNywxOTEsMTA1LDE4OSw5LDE3Miw4MSwyMDcsMjEwLDM0LDcxLDExNSwxODQsMTExLDQxLDE0Myw1MywzNiwxOTUsMTYsNzEsODUsMjMyLDEyMCw3NSwxOTcsMTU2LDIwNCwxOSwzOCwxNzgsMiwyMCwxNTIsMTAzLDI3LDY2LDIyMiw1OCwyMDIsNzgsNDMsNjgsMTE4LDcxLDkzLDMzLDE1NCwxMjUsMjI3LDE0Niw1NiwxMzIsMTkzLDE2Nyw4NywxNTYsMjAsMjAzLDQxLDEyNiwxMTksMTAsMTk1LDI4LDQsMjIsMTMxLDgsNTYsODYsNywxODQsMzMsODQsMzIsMTI4LDIzLDAsMjEzLDE1NCwxMTksMzIsMTY0LDU3LDI0MywxODAsMTgzLDIyLDM5LDE5NywxMTIsMTQ4LDkxLDIxOCwxOTgsMTc1LDg0LDExMywxOTgsMjA3LDM4LDEyMSwxOCwxNjIsNDksMTQwLDIyNCw1NywyMzYsMzIsMTIsOTcsMjE3LDM3LDQ1LDE3Niw3NiwxMDksODIsNywxNjksMjQ4LDEyNywyNiw1OCwxMTUsMTE3LDIwOSwxNjQsMTcwLDE1MCwxNjAsNjQsOTAsNTcsNDgsMzIsOTMsNTQsMjIwLDEwOCwxOCwyNDMsNTAsNywyNDIsMTEwLDUxLDM5LDE5OSwyNTMsNTEsMTg3LDc4LDEzNSw0MSw3OCwxODYsMjA3LDIwMSwyNDcsNzEsMzAsOTcsNDMsMTI0LDIzMiwwLDU4LDE0NSwxMCwyNDIsMTY5LDE4OCwyNDMsODIsNTMsOTMsMjgsMTA0LDY1LDU0LDIwMSw1MSwyNDgsMTg0LDg1LDE0OSwxODMsNTcsMjA5LDI1LDEwLDM3LDg0LDE0NiwyMTYsMTUxLDE0MSw0Myw3OCwyMjMsMTY2LDEyMCw2MSwxOTYsMTA4LDY2LDI4LDMsMTA3LDY2LDI3LDMzLDMyLDE0MCwyMjEsMTY0LDEzMSwyLDE2MCwxMzUsOTcsMTYxLDEyMSw4Nyw5Nyw2MCwxNTgsMTAzLDE0MSw5OCwyMjgsMjAsMTUzLDExNSwxMDAsMTA4LDg4LDY0LDM0LDEwNiwxMDIsODgsMywxMTUsOCwxMzUsMTkyLDE0MCwyNTIsMzksODgsMjIwLDE4NywzLDMzLDE1NywyMjAsMTI5LDY3LDY5LDE3MSwxMDQsNDgsMjEwLDE3OSw2LDE1NSwxMDEsMTQ4LDE3OCw3NiwyNTAsNTMsMzIsMTk3LDEwLDE1MSw0OSw1NCwxODAsMjMwLDE2NSw3MCwxNDgsMjMzLDE4Niw4MSw1Myw2NywyMTIsNSwxOTcsMTc3LDEwNiw5MCwxOTAsMjI3LDE1Miw2NCwyMDAsMTYzLDIyNCwyNiwxODMsMTMwLDU3LDExNiw1MCwyMTAsNTIsMTIwLDE3NiwxNjQsMjA4LDE3OSwxODYsNTAsOTcsOTEsMjUwLDIxNiwxODUsMzEsMjQ4LDE4Nyw5MiwxNTUsMjA1LDIzOSwzNCwxODYsMjU0LDI4LDM2LDQwLDAsMjgsMjIzLDQwLDI0LDEzMiwyMTQsMTA1LDYsMzQsODksMTEyLDIzMSwxMSw5LDEwLDE1OSwxNTEsMjE0LDgsMTMxLDQwLDE0OSw1MiwxNjIsMjcsMzgsODUsMTc1LDkzLDE0NCw2MCw4Nyw5Miw0LDIwOSwxOTgsMTE2LDI3LDI1MCw4NiwxNzYsMTIwLDk4LDQzLDEwNCw4OSwxMzEsMTEsOTgsMTExLDY1LDg4LDE2NiwxMDYsNDksODEsNjcsNSwxMTcsMjM1LDE1MSwxMTIsMjgsNjYsOTQsMTM4LDM2LDEzNCwxNjcsMTgwLDkwLDI0NiwxNDYsOSwxNDgsMTI3LDI1MSwyMjcsMTA1LDY0LDM0LDE0NCwxMTIsMTYzLDYzLDEwNSwxNzIsNTcsMjIzLDI0Miw0MywxMjcsODMsOTUsMTQyLDIxNywzNyw1NCw5OSw3MSwxNCwyMTgsMTg4LDIxMiwxMTIsOTksMzMsMTIyLDE5OCwyMjksMTI0LDEyMCwyMzAsNjQsMTg5LDIwNSw0MiwzOCwyMDIsOTIsNTcsNzMsNjQsNzEsODEsMTM4LDEyNCwyOSwxMTUsMTcxLDMwLDE2MywxNSwyNDYsMTI5LDMyLDEyLDM0LDE1Niw5MSw2Niw4NCwxODgsMTYwLDIwNyw2MCwyMTQsMTQyLDEwMywxMSwxNjEsMTUsMTQ2LDE3NCwxOTEsMTE0LDUwLDIyNywxNzAsNzcsNTIsMTMzLDE5Niw2LDE0OCw4OCwzMCwxODIsMTkzLDEyNCw2NiwxMTYsNDgsMTIzLDE0OCwyMjIsNDgsMTc1LDI0NCwxOTgsODAsNTgsMTIyLDg3LDU4LDEyMCwxMjksMTg4LDE3NiwxMywwLDI1MCwyMDQsODIsNzAsMTg3LDIwNCwxMzYsMTAwLDIxMCwyMTQsMTQzLDYsMTI4LDEzNCwxMjUsMjQwLDIwNSwxOTAsODMsMTY2LDI0LDE1MCw2LDE3MiwxMjMsOTgsMjM5LDIzNiwxNjAsMjE1LDk3LDE3LDIyMiwyMDQsMTY4LDExMiw2Nyw5NiwxMjcsMTUyLDEzMiwxOTEsMTM1LDE2OSwyMjYsMTc3LDE1OCwyMjMsMTg3LDE5NCwyMSwxMDUsMTg4LDIzMiwxMzEsMTc1LDY0LDIwOSw0NSw2NiwxNDksNTYsMjI5LDcsNDMsNjMsOTgsMTM2LDE5NCwyMDQsMTIzLDI2LDQsMTEwLDIxNCwxMzAsMTg3LDIwLDk5LDkzLDU3LDgzLDE3NiwyMTQsMTIzLDE4NiwxMDAsMTYsNzQsMjI2LDI0MiwxNDUsMTI4LDE2MywxNSwxMTksMjAyLDU2LDEwMSwxNjgsMTQwLDUwLDE1MiwxMjQsMTM2LDIwLDAsNTksMTY3LDU4LDEwMiw3MCwxMzAsMjQ1LDQzLDk3LDEzNCwxNzYsMTA2LDEyMywyMDMsMTQ5LDE4OSwyMiwxOTYsMjExLDc0LDE1MiwxNjEsMjI2LDEyNiwyMjAsMjMyLDMwLDIzNSw5OSw2MSwxNzcsMjE5LDI4LDIwOCwxNTQsMTA1LDQzLDEwMSwyMDMsMjQ2LDM1LDQ2LDc5LDI1MCwxNjEsNDYsMzUsODgsMTYsNDMsMiwxODAsMzQsMTEyLDE2MSw4MywxMTEsOTIsMTk5LDU2LDIzMCw4LDEyMiwxNjQsMTY4LDM5LDEyNSwxNzcsMTkxLDEzNCw0LDc3LDE3NywyMzIsMTE0LDI5LDUyLDE4MCwyNCwzLDIwNiwxMiwxODUsMzgsMTk1LDIzMywxODEsMTI2LDIwOCwxNiwyMjAsMTIsODUsMjQsNTUsMzIsMTk1LDE4NCwxMCw0NCwyMTAsNzQsMjA2LDQwLDE4MSw5Myw5MiwzLDE2NiwyMywxMTgsNCw4NSwzMCwxNywyMTYsMTA3LDIzOSwxMzMsMTE2LDYyLDE5MiwxMzMsMTM0LDQ0LDk5LDI0MSwxMzksNTMsNjksOTYsNjEsMjQwLDEzOSw5NSw5Miw3LDE0OSwxMzAsNDQsMTgzLDIyLDE4MiwxNzUsMjMyLDE4NiwxODAsMTk5LDI0MCwzNSwyNDIsMTIwLDEwOCw2MSwxODQsMzYsMzQsMTYwLDE4Niw3Myw1LDE3MCwyMzYsMjA4LDE4NywyMzksMjMsNTIsMCwxOTYsMTAzLDE4OCw0OSw5MCwyMTgsMTA3LDMzLDEzNSwxNjYsMTksMTgyLDE1MSwxOSw5Miw3MSw0OCwyNDQsMjAxLDE0OCwyMDAsMTIsMzMsMTQ2LDUyLDE4MiwxNCwyNDQsODQsMjE2LDIxOCw1MCw2MSwyMjAsNiw1LDExOCwyNCwxMTIsMjQwLDE1NSwyMzksMjQ4LDEzMiwxNiw2OSwxMjYsMTg5LDEwNiwxNDMsMTk2LDE3LDIwNCwyMDksMjI5LDExOSw0NSwxMTksODUsNjQsMjA5LDc5LDEyMiw4OSwxNDIsNTMsMTQ4LDE1OCwxMzQsMTY2LDEzMiwxMzgsMjQ0LDE5NCwxOTksMTcxLDEwNSw0Nyw0MSw5OCw2OSwyNDgsMzMsNDYsMTc5LDE3MiwyNDcsMTM2LDQ1LDEwNywyMTYsMTgyLDE5Niw5Nyw3OSwyNCwyNTAsMTc4LDEwNiwzNCw5MiwxNDQsNDQsMjYsMjQwLDI0OSwzNywyMSwyMjAsMTE1LDM1LDM5LDIxLDIzLDE5NSwxNzMsMTU5LDIwOCwxNzcsMTA0LDUxLDE2MSw3OSwzNSw4NiwxNDksMTc5LDkyLDIyLDE2NSw5Myw5MCwxMzcsMTIzLDEzNCwxNzksNjMsMTkwLDcxLDE4MCwyNDUsMjQ5LDgsMTM5LDEzNywxOTYsMjM5LDIwNCwwLDExOCw2OSwxMCw3OSwxNTMsMTE2LDIzMiwxMCw5OSw3MywxNiwyMDAsOCwxMzYsMTUsMTQ4LDI0Miw1LDQ4LDAsMTAsMjgsMTI0LDcwLDczLDcsMTY0LDIyNCw3MiwyMDQsMTM2LDI2LDUxLDY1LDExLDY4LDE4NiwxMTgsMTYwLDE3NCwxMTcsNjcsNzIsOSw4LDY1LDE4OCw2NywxNTIsMTE0LDE0NCw4OCwyLDI2LDE0OSw2NywxOSw3OCwzNCwxNDcsMTQsOTcsMTQ4LDI0MSwyMzEsMzksMjIxLDE3NywxMzEsMjEyLDE3LDMyLDg4LDIxNyw0NiwyMDgsMTgsMTE4LDIzOCwyMzMsMTAzLDE3NywxNzIsOTEsMzEsMTY3LDMwLDI1MSwxNjUsMTYzLDE4NywxNDQsMTUxLDE3OCwxMTksOTcsMjI1LDI0NCw4MSwxMzEsMTgyLDIwNiw0NiwyNSwyMDQsMTIyLDQ5LDIyLDEzMywzOCwxNjMsMjUxLDEwMywxMTksMjQ0LDg4LDQ0LDE1NSwxMDIsMTkyLDE3NSwxNzcsMTIwLDEzOSwzNiwyOSwyNCw1OSwyNSwyMjUsMTM0LDE0OSwzOCw2OCwxNzUsMTczLDIzMSw4OSwxNzUsMzcsMTEzLDgzLDI0NCwxNjYsMjA2LDIwOCw5NywxNDksNTIsODAsMzAsNDgsMTAxLDE1Miw5NywxMzcsMTg3LDIxNCwxNjQsOTAsMTYyLDY2LDE3NywzMSwxMzgsMjUwLDExOCwyNTEsMzIsMTM2LDE5NywyMzEsNCw1MSwxNzUsMTk0LDE4NCwxOTgsNywyMzcsOTQsMjI0LDIyMiwyNTEsMzQsMiwyMzAsNSwxMjAsMTk3LDQzLDc1LDI3LDE2NSwxMjAsNCw1MCwyLDE3MCwxOTEsNzYsMTUyLDc1LDExNSwxMDIsMTk3LDQ0LDIyNCwxNzIsMTA1LDgyLDE0NCw4MywxMzYsMTA5LDgsMTQxLDIyOCwxMSwxMzcsMjA2LDE0Nyw0OF19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNjQsMTgwLDEyNSwxMjYsNzksMjIwLDIyMSwyNTMsMTIzLDQyLDIwMSwxMjAsMTgwLDE2NCwyMDAsMjA4LDE3Nyw5OSw4Miw2MCw1NSwxNTYsMTI2LDc3LDExNywxMTUsMjAzLDIwMywxNDIsMjU1LDE2NiwzNF19fSwiY3JlZGVudGlhbCI6eyJjcmVk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MiwyMDEsMTIwLDE4MCwxNjQsMjAwLDIwOCwxNzcsOTksODIsNjAsNTUsMTU2LDEyNiw3NywxMTcsMTE1LDIwMywyMDMsMTQyLDI1NSwxNjYsMzQsODIsMTE3LDExNSwxMTYsNjcsMTE0LDEyMSwxMTIsMTE2LDExMSw4MywxMDUsMTAzLDExMCw5NywxMTYsMTE3LDExNCwxMDEsNzUsMTAxLDEyMSw4LDddfQABeyJwcml2YXRlIjpbMTgwLDg0LDcyLDI0MiwxMzUsOCwxNTksMTQ3LDk5LDE1LDExLDE3NywxNDYsMTg1LDIyOSwxNiwxNTQsMjAzLDc1LDEzNCw1MiwyMTgsMTc2LDQxLDI1MSwxNywxODcsNjgsMTksMTI0LDMxLDIyMF0sInB1YmxpYyI6WzE2NCwxODAsMTI1LDEyNiw3OSwyMjAsMjIxLDI1MywxMjMsNDIsMjAxLDEyMCwxODAsMTY0LDIwMCwyMDgsMTc3LDk5LDgyLDYwLDU1LDE1NiwxMjYsNzcsMTE3LDExNSwyMDMsMjAzLDE0MiwyNTUsMTY2LDM0XSwic2lnbmF0dXJlX3NjaGVtZSI6IkVEMjU1MTkifQ==","AAAAAAAAAA0AAAAAAAAAXAAAAAAAAAAFVXNlUmF0Y2hldFRyZWV7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAFmYWxzZQAAAAAAAABaAAAAAAAAAfdHcm91cENvbnRleHR7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAF7InByb3RvY29sX3ZlcnNpb24iOiJNbHMxMCIsImNpcGhlcnN1aXRlIjoiTUxTXzI1Nl9YV0lOR19DSEFDSEEyMFBPTFkxMzA1X1NIQTI1Nl9FZDI1NTE5IiwiZ3JvdXBfaWQiOnsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0sImVwb2NoIjoxLCJ0cmVlX2hhc2giOnsidmVjIjpbMTI1LDExNSwyNDQsMTM3LDIzNiwxNTcsMjQsMTM0LDEzMCw3MywxMDEsMjE0LDYwLDg2LDE4OCw5MiwxLDI0Myw3NSw0Niw4NSw2MCwyMjAsMTkwLDEyNywxMjEsNTQsMTU2LDE3LDI1MSwyMzUsMTM1XX0sImNvbmZpcm1lZF90cmFuc2NyaXB0X2hhc2giOnsidmVjIjpbMTcyLDY0LDE1MCw1MywxNywxOTUsMjUzLDY5LDcsMTY0LDE4NywxMDcsMTY4LDE3NSwyNDEsOTEsMjEwLDIwNSwxNzIsMzUsMTMsNjAsMTgsMjcsODIsMjExLDExNCwyLDI1MSwxNjUsMTM0LDIyOV19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fQAAAAAAAABdAAAAAAAAAIhDb25maXJtYXRpb25UYWd7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAF7Im1hY192YWx1ZSI6eyJ2ZWMiOlsyMDgsMSwxOCwyMjcsNzQsMTgyLDExMCw5MSwxOTksMTY4LDI0MSwx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AVt7InB1YmxpY19rZXkiOnsia2V5Ijp7InZlYyI6WzEzNCwxNjksMTA0LDIwNywxMzQsMTQ1LDIwLDI3LDk4LDIxNCw2Nyw2NCwxMDAsOTIsOTEsNzksMTY4LDE2OCwyOCwyMDgsNzQsMjMyLDExLDE3Nyw4NywyNTEsMjUsMSwyNTAsMTcxLDIwOSwxNiwxNjMsMTc1LDE0MCw0MSw5MiwxNTIsMjIsODAsODAsMTA3LDY4LDI1MSwzLDE1OSwyMDksMTI1LDQ4LDE2NSwxMDgsMjM2LDIwLDExLDU0LDEwMCwxODgsMjI4LDE0NCwxNzYsMTg2LDIyMCwxNDcsMTA4LDE2LDkzLDkzLDE3Niw0MywyMTIsNjUsMzgsMTQ3LDE2MCw4LDcyLDI3LDEwNCwyMjQsMjQzLDEzMywxNDIsMTAxLDIwNiwyMDQsMTk3LDY2LDg4LDI0LDE0MywxMDUsMTM3LDEwMywwLDE5Niw0OSwyNDEsMjA0LDUzLDg3LDIyLDEyNywxODgsMTMyLDM4LDExMiwxNjgsNTAsOTYsNDQsNjcsMjQ0LDEzOSwxMTEsMTY1LDU0LDUzLDE4NiwyMTksODQsMTMxLDExLDgyLDE5MCw5NiwxOCwyMzAsMTkzLDk3LDIwOSw4MCw4NSw2NCw3Myw1NCw5MywxNTUsMTg4LDE0LDYsMzUsMTgyLDEzMiwxNzAsMTE2LDIzMCw0MiwzMywyMzUsODUsMTI2LDM5LDEwNSwxMzksOTIsNTcsNiwxODYsODksMTU3LDgzLDQwLDIwNywxNzksMTYxLDYwLDE0MCwyMDYsMTk4LDE3MSwxMTgsMjMyLDEzNCw4OCw2OSwxNDAsODksMTM1LDExNyw2MiwxNTUsMjUwLDk1LDE1MiwyMjYsMzAsMzAsMTE0LDE5Miw5OCwyMTcsMTE2LDc2LDE2OCwwLDIyNSwxLDE1NywxOTAsMTcyLDEwMywxNDEsOTIsMTU1LDE4LDExNyw1OCwxMzAsMTgxLDE5NiwyNyw1OCw3OSw5OSw4NCw4LDE4OSwxOTQsMTI4LDUsMTE0LDIxLDE1LDkyLDE4OSw5NSwxMzMsMTgyLDE0OSwxODYsNTIsMjQ5LDM5LDcyLDgsMjEsMTA5LDE0LDUzLDM3LDE3OCwxOTYsMTE0LDE3OSwxNzEsNjksMTg5LDQxLDE1NSwxNCw4MywxNTcsMTcwLDI0NCwzOSwxNDgsMjQ0LDE3MCw4MCwxODYsMTU1LDEwMCwyNDMsMTg5LDUwLDE3NywxNDUsMjI1LDg0LDE4LDIsNywxNDksMjE4LDg0LDE3NiwxOTIsNTAsMTE5LDc2LDEwMCwwLDY3LDI4LDIwNiwyMjgsMTQ5LDEwMSwxNzcsMjQ3LDE5OSw5OCwxNTQsOCwyNDYsMjIwLDUwLDEsMTE4LDE2Nyw2MCw3MiwxNTAsMjI5LDU4LDE4OSw0NSwyMjAsMTE5LDIxOCw0MCwyOCwxODYsMTgsMTc0LDAsMjA5LDE0MCwxNzEsMTYzLDE0LDk0LDkyLDEzOCwyMTcsNzUsMTQwLDE3MCwyMjcsMjAwLDEyNywxNTUsNDgsMTgxLDEyLDEzMywyMjUsMjQ5LDE2MCw0MSwyMDQsMjYsMTAxLDIxOSwwLDE4NCwxNTQsMjA1LDIzMywxOTYsMTQyLDIzMiwxMjMsMzAsMjM3LDIxMCw5Myw2NCw4Myw4NiwxNTAsMjAsMTg5LDEwNyw1NSwyNCwxNiw4NCwyMywxMTUsMTQ1LDgsMTExLDI3LDQsMTg0LDU2LDQ0LDI0NiwyMDgsMTA2LDExNSw5MSwxNTksMjQ0LDEyMywxOTYsMjcsMjE2LDk3LDE1MCwyMDgsMiwyNTIsNjAsMTc4LDE5MCwzOSw2LDIyLDE0NywxNjAsMzMsMjQ1LDIxLDE2MywyMTYsNSwxOSwxMzYsMTU2LDEwNiwxNTYsMTI3LDIzMSwxMDIsMjA3LDM1LDk2LDEyOSwxMTQsMjA4LDg2LDE4MCwxMTYsMTE5LDEyNiw3NCwxMiw2Nyw2LDEzMyw0MSwxMTgsNzYsMCwyNiwyMDYsNiw1LDEwMywxNTEsMjA0LDEzNiwxNjQsMzgsNjYsMTQsOTIsMTI1LDE2Myw1MywxNTEsMTMwLDIzNSwxODQsMTU4LDE0OSwxNjEsMjM4LDE5OSw3MSwyNTEsMTg3LDM1LDE4OCwyNCwzMSwxNjMsMjM1LDE2Myw2MCw2MCwxMzAsNzksMTU0LDI1LDIxNyw2NCwxOTUsMTc0LDEzOSw4NSwxOTUsMjA4LDEzOSw3Myw2MCwxOTYsMTI5LDY0LDIwMywxNjYsMTI4LDEzOSwyMDQsMTgsMTI3LDEzOCwyMjksNzcsMTY4LDE2MSwxOTMsMjA3LDEwNSwwLDE4MCwxMDcsMTcyLDY1LDExNyw2Myw3NCwzNiwxNjUsMTQsNTEsMTI0LDE2LDEwNywyMyw4MiwxNDUsMTA2LDI0NywxNDQsNDQsMTkzLDEyMCwzLDEwNCwxNjgsNDEsMTg4LDM0LDIwNiwyNTEsMTcwLDIwNSwyMDMsMTEyLDE3MSwxNjEsMTMzLDc2LDE0OCwxMzgsMzQsODAsNDEsMTY4LDEyOCwyMywyMDMsODEsMTQ3LDUwLDUxLDE0NSwxOTgsMTUyLDIzNCw5Niw3MiwxODUsNTAsMjMxLDI3LDE0NSwyMDcsMjExLDQyLDQwLDg2LDMxLDI1MCw4Niw4OCwyMzYsMTk3LDE2OSwxNzYsMTY1LDEzMCwyMzQsMjQ0LDE4NCwxNTUsMTg2LDIsMTk5LDU1LDY5LDU3LDIwMCwxMjgsMTUsMTksNzgsMjMxLDIxMywxNzIsMjAsMjE0LDM0LDE4OSwyMTIsMTgzLDQsMTEsMTQyLDE4OCwxNjAsNDksMTU3LDI3LDIxLDE1NCwxNjQsMTc5LDIyMCwxNjYsMTc0LDIwNiwxMzEsMTEsNjQsODAsMjgsMzEsMTIxLDExMCwxODEsMTIyLDEzMywyMjUsMTQ3LDE3OSw5OCw4OSwxNzksNjYsMTY4LDQyLDI0MCw4NywyMDUsMTg3LDE5NSwxMTAsMTk5LDIyMCwxMywxODMsNDQsMTksMSwxNTEsNTksMTgwLDE2MSwxOTEsMTAzLDEyMywxMywyNTUsMTY4LDcwLDg0LDI2LDIwNCwxMzAsODYsMzgsMTM2LDIzLDEzNCwxNTgsMTAxLDEyOCwyNTMsMjAyLDEzOSwxNjIsMjE0LDMwLDE5MSwxMTIsMTIwLDIwMiwxNTAsMTc3LDMsMTY1LDgzLDI0MCwxNjQsMTY2LDI0NiwxNTIsMTQ3LDE5OSw4NCwxNSwyMDIsMjM0LDMwLDc1LDM4LDczLDk4LDY3LDE2NCwxMjAsNTQsNywxMjIsNTMsNzEsMzcsMjUsMTk3LDc1LDE4NywxMiwxODksMTk3LDQxLDE5MCwzMiwxMjMsMjE0LDEzOSwyMDUsMTcyLDI0NywxMzMsMTUwLDcsMTk1LDEyNiw4MCwxMjAsMjAxLDk4LDE0MiwyMTUsODUsMjAwLDIzNCw3NSw1MCwyMTQsNDksMTA2LDIxNiw1OCwxOSw2OCwyMTMsNzMsMzcsMTQ4LDEzNCwyMDEsMjM1LDEwMiwxOTEsNzUsMTgwLDIxNCw1NSwxODcsMTk5LDg2LDI5LDAsNywyMDAsMTMzLDEzNSw0MiwxODksMTgwLDE3OCwxNDIsMzcsMTIwLDEyOCwzNiw3MCwyMzQsMTMyLDU5LDQ2LDIxNywxNDIsODMsODYsNjYsMTkzLDE2OCwxNDIsMTk4LDEwMyw2NSwxMzksMjQzLDE1MSwyOSwxMzksNjMsNjMsMTg4LDEyMiw0MiwzNSw2OSwxNTAsOTksMTExLDE0NiwxODQsMjUsMzksOTAsMzMsMTI2LDI0OSwxODksMTI3LDE3Niw2MSwxMTUsMTA1LDk4LDkxLDUzLDEzNSwxMTQsMTIyLDE2MCw4Miw3MywxNjUsNTcsNjgsMTEwLDIwOCwxMjQsMTI1LDIsMTY5LDExOCwxMTksODQsMzcsMTI4LDg2LDE1MCw1MSwxMDUsODcsMjU1LDMzLDIwMywyMDAsMjMxLDEwMywxMjksNTIsNjQsMTg4LDgyLDU4LDY2LDE2Myw1NywyMTEsMTIwLDExMCwxODYsMTgsODUsMTMxLDIxOCwxOSwxNyw4LDc4LDIwNSwxNzcsNTYsMjIzLDEyMCw5Miw0MywxOTYsNywxMjcsMTU2LDQyLDgzLDEwNywxMCwyMjMsMTMwLDEwLDI0MCwyMzMsMTg5LDE1LDE5OCw0MCwyNDAsMTE4LDUsNDUsNjUsMjEsOTUsMTg3LDE3OSwxMDYsMTMyLDExMywxOTIsMTAsMzAsMTMzLDE2NCwyMSw5Myw5MiwxNTgsMTcwLDEzOSwxMjYsMjQ4LDI0OCwxMzEsMjI3LDE4Miw5NCwxNTksNCwzNyw1NCwxOTksMTg3LDE0NSwxMTcsMTMzLDE3LDU3LDU1LDIxMiwzNSwxMTIsMTg1LDEzMSw5LDIwOSw2NCw3NCwxNDYsMjE3LDUyLDIyLDIyNCw0OSwxOTUsODcsMTc0LDYwLDIxLDg4LDc2LDIwOCw4NywxOTUsMjI2LDczLDIwMSwyMjksMTI4LDY4LDIzNiw4NCwyMjcsMjQyLDE2NCw3OSwxOTYsMTM0LDExOCw2NywxMjgsMiwxMCwxNywyMjYsMjAsMTI2LDEzNywzLDE4NiwxMDEsMTQ0LDIwMCwxODksMTUzLDExNCwxNjEsMTk5LDUsOTIsMTQ4LDExMiw1NCwyLDE0NCw2MCwyMTgsMCwyMywyMzIsNjAsMjQzLDIxMiwxNzUsMCwzNywyNSw0NywyMTIsMTEwLDIxNiw0OCw0LDE0NywyMjQsNTQsMTQsNzAsMjAwLDIzMywyMTIsNTYsMTQsMjE0LDEzNSw3OSw4MSwxNTAsMTE2LDEzMywzLDc1LDIzMiwxODgsMjUzLDIyMCwxMzksMjAyLDE0NCw1Niw4Miw1MiwzLDI1LDIyOCw5Nyw5OCwyNTIsMjAxLDc2LDE0MCwxOSwxNDQsOTgsMTAyLDIwMiwxMzYsMTg3LDUwLDE5MiwxMDMsNDQsODYsOTcsMTI3LDEyMCwxMiw4OCwyMzYsMTYzLDgwLDIxNCwxODQsMjIwLDIxNSw0MCwxMzksMTE3LDcxLDIxOSwxODEsMTE3LDUxLDIxMiwxMjQsMTAyLDExMywxMDEsMzEsMTQ2LDQ2LDE5MSwyMDEsOTksNiwyMjgsMTIyLDIyOCw3MSwyMDcsOTAsOTIsNTQsNzAsMjUwLDE2MSwyMjEsMTM5LDExMSw0Niw4NSwxODAsMTY1LDcsNTYsMTI1LDIxLDM0LDY3LDExOSwxMTIsMTY1LDExLDE5NywxMDAsNjUsNjcsMjIxLDU5LDIzNCwxODksMTk1LDIwMywxNjIsMTU5LDIwMywxOTksMTU4LDE4MiwxNjUsMSwxOTIsMTU1LDExNSwyOSwxNzksMjMzLDM1LDIxNSw5NSwxOSwyMjQsMiwxOSw4MywyMTYsMTIsODEsMTk4LDE4MywxODAsMCw1OCwyNDgsMzksMzksMjUzLDg0LDUwLDk0LDI1NCwyMjUsMjEyLDE1LDEwLDg4LDI1MywyMTAsOSwyNDYsMzcsMjI0LDE2NSwxODUsOSw2LDMzLDBdfX0sInByaXZhdGVfa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxMzQsMTUxLDE3LDIyMiw1NywxNiw5MywyMzMsODcsMTIwLDE3MSwxNjMsMTU2LDEzOSwxMjMsMTgyLDIwOSwxNTIsMTAxLDEzOCwxOTMsNjYsMTM4LDExNywyMjgsMTM4LDQsNjMsMTIyLDEsMTY4LDgxLDMsNDksMjI3LDg5LDIwMywyNDUsODAsMjQzLDE5NCwxODksMTE0LDQzLDEyMiwxMyw1OCwxNzYsNDEsMTgwLDU1LDQ0LDIyNSwxODYsMTM3LDEwMiw2Niw3OCwzMiwxMzMsMjA1LDksMjIsMjMyLDE1MSwxODEsMTk0LDE0NCwyNywyMjAsMTY3LDE2NywxNjEsMTMzLDE4Miw3NSwxOTksMTA0LDMsNjksMTYwLDI4LDQ0LDE1OCw1MiwyMywzLDU1LDIyLDczLDIyNSwyMjUsMjAwLDcwLDgxLDI1LDI0OCwxNjIsMTE1LDk5LDIxNywyNSwxODYsODcsMTg2LDg3LDI1Miw2MywxMzEsMTYzLDE4NSw4MywzNywxOTUsMTUyLDEyNCwxODAsMTI0LDk4LDUwLDE1NiwyMTksNjgsNzMsMTcwLDQsNDQsMTI5LDE2NiwyMjYsMTA0LDE4MCwyNTAsMzQsMTcwLDIyMSwyMTcsNzksMTgsMjUyLDE2NCw3NCwyNTIsMTU5LDExMywzOSwxODAsNDIsMTcsMTkxLDI0Niw3MiwxOTcsODMsMTk1LDE0Nyw2MywyMTUsNTYsMjEsNTAsMTM0LDIyOCwyMTUsMTM1LDI1NSwxMzksNDEsMTQ3LDkwLDIwMSwxMzcsODYsMTExLDExMCw5MiwxNTAsMTUwLDE5MiwxODEsMjQ1LDEzMCwxMDUsMTgsNDksMTYyLDI1Miw3MCwxNSwyNTUsODEsMTk0LDExMCwyMzUsNzQsMTk1LDgzLDQsMTk2LDEzMiwxODMsMTQ2LDE2LDY4LDE0Niw5NiwxNzEsOTcsMCwyNiw3OCwyOCwxNDUsMTEsNTEsMTYzLDEwNCw3Miw1MywxMzcsNDQsMTYsMjIxLDg4LDIzLDE2OSw2NiwxNDMsNjMsMjAzLDgxLDIwNiwyNDEsMTg3LDI3LDEzMSwxODMsODMsNCwxMDAsMTgxLDYsMTM1LDIwNCwyMjAsODMsMTg3LDU2LDgyLDc3LDczLDEwOCwxNiwxNjMsMTU2LDkxLDk4LDEwNywyOCwzLDE4MywyMTYsNTksMTY2LDE4MSwzNCwxNTksMCwyMTIsNDEsMjAzLDEzNSwxMjYsMTk1LDgzLDE4NywxMjEsOCwxMTksMTQ4LDM4LDEzOCwzOSwxNzAsMTE3LDIyMCwxNzksMTI5LDUwLDM1LDkzLDE2OSw2NCwxMDAsMTU2LDIzMiwxNzEsMzYsMTQ3LDEzNSw4OSw4OSwxOTIsMTcsOTIsMTQyLDE2MCwxNzgsMTA3LDE0MSwxNjksMTIsMTM4LDM1LDcxLDE0MCwyMjgsMzgsMTAsMjE1LDc0LDI5LDE1MCwyNiwxNTcsMjE0LDE5MSw0OCwyMCwxNjksNDIsNTIsMTk1LDMsMTA4LDE5MCwxMDQsMjEyLDE3NCwyMjUsMjQzLDMsNzQsMjAwLDE2NiwzLDEyOSwxMDksMTUyLDE5Niw4OSwxMTEsMTY3LDY1LDE4OCw5Miw3OCwxOTMsMjcsOTcsOCwxNDcsMTQsMTQzLDI0MiwyMDcsMjM0LDExMiwxODEsODYsNTMsMTI3LDkyLDE5NSwxNjMsMjM2LDgsMTAwLDIwNSwxNDYsMTM5LDE0Myw5NiwxOTMsMjE2LDU4LDEwMCwxNjEsNTIsMTMxLDM2LDEyOSwxMzEsMjMzLDY5LDMxLDk3LDExNiwxNzksMTE1LDE1MSw4MywxMDEsMTcyLDIyLDE1NSwyMjcsNjQsOTIsMTE5LDk1LDc4LDc1LDEzMyw2OSw5NywxOTMsMjgsMjAzLDEyOCwyNDksMjQ2LDEyOCwyMjQsMjMzLDEzNiwxNzksMTM0LDEzNSwxMjYsMjYsOTUsMjQzLDE5OCwxMSwxMTAsMTY0LDI3LDAsMjE1LDIwNCwyNTIsMTU0LDIwNywxMDgsODMsMTEyLDEyMCwxOTUsMzksMTQzLDc0LDEzNCwxMzcsNDMsODUsMTQ4LDE1MSw3NSw5NCwyNTIsNjgsNzgsMTg0LDg1LDIyMSwxNywxMjksMTkxLDE2NCw3NSwyMTQsMyw1MCw3Nyw4NCwxNjQsMjMzLDIxMSwxNDgsMjE3LDIyOCwxNDAsMTg0LDIzNSw2NSwxMDEsNCwxNSwxMjksODMsMTcxLDI0MCwxMjAsMTUyLDkyLDkxLDUyLDU5LDk3LDk5LDIzLDIxNCwxODUsNzUsMjI4LDEyLDY0LDY1LDY4LDI2LDk5LDE4NCwxNzEsMTE0LDEwLDYwLDIzMCwxODUsMjM5LDE3NiwyMDQsMTAzLDI1MCwxMjMsNzUsMTk1LDY5LDIzNCwyMjUsMCwxOTksMjUxLDExMyw2Niw1OCwxMjMsMjU0LDIxNywxNTksMTY0LDE4MCwxNiw4OSwyMywzMCwxMTEsMTc4LDIwNSwxMjAsMjI5LDEwNywxMTgsMjI2LDgwLDIyLDg2LDMxLDEwMiwxNjMsMTc4LDcxLDE3Niw1LDEwNSw4OSwxODEsMjI5LDQ0LDE4Myw1LDE2MCwxMjEsMTA5LDU0LDE3NywyMDAsMjQ2LDE2MSwxNzIsMTQ0LDIwMywyMjYsMTk5LDM4LDExMSwyNiwyMDQsMTMxLDI0MiwxOSwxMzUsMjQwLDE4NSw1LDE1MywxOTgsMjM0LDExMiwxODUsMiwxNDYsMzAsMjEyLDI0OSw4MiwyMzksMjQxLDEyNiwxMTYsMjA4LDEwNCwxNjMsMjMwLDMsMTM0LDEwNCwxNiwyMTcsNzAsMTY2LDEwMyw1LDE4Myw4OCwxMzYsMTAxLDE5MSw3Myw3MSwyNTEsMTY3LDQ3LDIxNyw4OSw0MywxMTIsMjExLDExNSwxNDgsMjUyLDI4LDcyLDE5OSwxMzksMjIwLDE3MiwxNzcsMTAwLDU1LDExOCw4LDE0MCw4NCwxNDMsMjIsMzMsNDcsODEsOTksMzUsMjAxLDI2LDE5NSwyNDAsMTUwLDU0LDIzNCwyMiw3MSw1NCwyMDAsMjAzLDE2MSwxNzQsMjQ2LDI0OSw0MCwxNjgsMjI2LDE2MiwxODEsMTU1LDE3NCwyMjYsMTI5LDg1LDIyMCw4NiwxNjgsMTM1LDE2MSw2OCw2Nyw2NiwzOCwxNywxOSw2LDc2LDExOCw4MCwyNDcsOTEsOTcsNDIsMjE0LDMxLDIwNSwxMTQsOTQsMTc0LDI0MywxMSwyNTQsMTM3LDM2LDU5LDM0LDEzNywxODAsNiwxMzQsNTIsMTEyLDE3NSwxNjksMjM0LDg0LDI2LDI2LDE5NCwyMjEsMTk3LDMzLDI1MywxOTYsMjYsMjgsMTMxLDQ3LDEyNCwyMjcsNzcsMjQxLDU3LDYwLDE1MCwxODYsMTQ4LDE4NSw5NywxMTMsNzksMjM2LDExNSwyMzcsNCwxMDQsMTExLDI0LDQ5LDE4OCw2OSw5LDk3LDgzLDkxLDI0NCwxMjgsMTg0LDIzMiwyMDMsMjUsMjE5LDE0OCwxLDEzMiwyMTAsMTUwLDgxLDUzLDIyLDE0MywxNzksMjA1LDIxOSwyMTAsMTcyLDEwMiwxOTQsMTAzLDEwNiwxODgsMTk0LDEzNSwxMTYsMTQ1LDYsNTAsOSw4MCwyMTAsMzIsODAsNTcsNTIsMTM2LDEsMTUyLDEzNSwxODgsNTgsNzIsMTg2LDE2MCw2NCw5NywxODYsMTk3LDIwOCw1OSwyNSw5NiwxNTksNywxNzksNDIsNjEsMjE3LDg0LDE5OSwxNDcsMiwzOSwyMzAsNjMsMTM1LDE4NywxNTEsMjE0LDUwLDE0LDE0NywxOTIsMjA0LDEyOCwxMDcsMTg5LDMyLDIyOCwxMjQsMTU4LDEzNiwyOCwxMjUsMTY5LDE0Nyw1NCwxMDEsMTE3LDExNCwxMTgsMTU3LDUyLDIwOSw4MiwyMjAsOTcsNzEsMTIsMjEwLDExNCwxMjIsMjAzLDE5MywxMjMsMTgwLDExNCw4MiwxNTMsMTgwLDIyMiwyNiwxNjEsMSwyMCwxODMsNjAsMjE4LDE1NywyOCw0OCwxODcsMTkzLDI0MSwxLDI1NCwxMjEsMzQsMTc1LDE2NiwxNTksMTQ5LDExNCwzMyw3NCwwLDQzLDIzNiw4Nyw0NCwyMDMsMTU0LDkwLDIwNiwxMzIsNjEsMTEwLDQxLDMxLDI0Niw1LDgsMjIxLDE4MiwxNDgsMjE5LDE5Nyw5MiwxNDEsMjA4LDExNiwxMDEsMTA4LDc3LDIyMywxNzYsMTUsMTYxLDIyOCw2Miw1MCwxMTQsMTE0LDcyLDcyLDU5LDE4MCwxNjQsMTM4LDEzOCwxODMsOCw5MCwyNCwxNzIsMjI3LDE3MSwyOSwyNDYsMzksMTM1LDcxLDEzMywxMTMsMTAxLDIyNCw1NiwxMzQsMjgsMjAwLDIyNiwyNDQsMTIxLDE4MywxNDksOTMsNjAsMjEwLDIwNiwyMzIsMTIsMTIzLDM4LDU3LDE3NSwyMzMsMTIxLDg0LDU3LDE4Nyw0OCwyMjYsMCwyMDcsMjksMjE5LDQ3LDEzMCw5Miw2MCwyNTQsMTMyLDEwOSw5MCwxMDgsMTUwLDEsNjAsMTMyLDc2LDU3LDc4LDkxLDE3NywyMDIsMTgwLDE5Niw3OCwzNywxODAsNDIsMTUxLDM3LDE1NCwxODEsOTIsNzIsMjQ1LDgsMjQsMTc3LDEsMTIzLDE0MiwxMjAsMTMzLDE3NywyMjgsNzUsNzUsMjI4LDEzOCwyMTYsMjMzLDE0MSw2NSwyMDIsMTgxLDExNyw1NywxNDEsMjUwLDI0NCwxMCwxNDksNTQsMTczLDEwNCwzNiwxNTYsMzUsMjUxLDE2LDIxMSwxNDQsMzAsMTQxLDkxLDE3NiwzMiw3NiwxNjIsMTUyLDIwOCwxMDgsODUsMjEsMTU5LDg5LDcsMTUzLDIwOCwxMTIsMTk1LDIxNywxMDcsMTQ5LDczLDE4MCw4NCwxMiw0MCwxMzIsMTU2LDg0LDE5MCwxOTQsMTUyLDE0NSw0MCwxMDQsOCwxLDExMyw3Miw2OSwyNDcsMTUxLDIxNywyNDksODIsNTgsMTE5LDE5NywxMzAsMTYzLDExMCw5Niw4NSwyNywxMzIsODcsNTksMTA2LDgsMTA3LDExMiw1NSw5NywxMDAsMTE5LDExMiwxMzYsMjEwLDQ0LDE5OSwzOCwyMDcsMjIwLDEzOSw5Niw3LDg2LDEzLDQsMTQ0LDE1MiwxODYsNiw5MSwxMzQsMTY5LDEwNCwyMDcsMTM0LDE0NSwyMCwyNyw5OCwyMTQsNjcsNjQsMTAwLDkyLDkxLDc5LDE2OCwxNjgsMjgsMjA4LDc0LDIzMiwxMSwxNzcsODcsMjUxLDI1LDEsMjUwLDE3MSwyMDksMTYsMTYzLDE3NSwxNDAsNDEsOTIsMTUyLDIyLDgwLDgwLDEwNyw2OCwyNTEsMywxNTksMjA5LDEyNSw0OCwxNjUsMTA4LDIzNiwyMCwxMSw1NCwxMDAsMTg4LDIyOCwxNDQsMTc2LDE4NiwyMjAsMTQ3LDEwOCwxNiw5Myw5MywxNzYsNDMsMjEyLDY1LDM4LDE0NywxNjAsOCw3MiwyNywxMDQsMjI0LDI0MywxMzMsMTQyLDEwMSwyMDYsMjA0LDE5Nyw2Niw4OCwyNCwxNDMsMTA1LDEzNywxMDMsMCwxOTYsNDksMjQxLDIwNCw1Myw4NywyMiwxMjcsMTg4LDEzMiwzOCwxMTIsMTY4LDUwLDk2LDQ0LDY3LDI0NCwxMzksMTExLDE2NSw1NCw1MywxODYsMjE5LDg0LDEzMSwxMSw4MiwxOTAsOTYsMTgsMjMwLDE5Myw5NywyMDksODAsODUsNjQsNzMsNTQsOTMsMTU1LDE4OCwxNCw2LDM1LDE4MiwxMzIsMTcwLDExNiwyMzAsNDIsMzMsMjM1LDg1LDEyNiwzOSwxMDUsMTM5LDkyLDU3LDYsMTg2LDg5LDE1Nyw4Myw0MCwyMDcsMTc5LDE2MSw2MCwxNDAsMjA2LDE5OCwxNzEsMTE4LDIzMiwxMzQsODgsNjksMTQwLDg5LDEzNSwxMTcsNjIsMTU1LDI1MCw5NSwxNTIsMjI2LDMwLDMwLDExNCwxOTIsOTgsMjE3LDExNiw3NiwxNjgsMCwyMjUsMSwxNTcsMTkwLDE3MiwxMDMsMTQxLDkyLDE1NSwxOCwxMTcsNTgsMTMwLDE4MSwxOTYsMjcsNTgsNzksOTksODQsOCwxODksMTk0LDEyOCw1LDExNCwyMSwxNSw5MiwxODksOTUsMTMzLDE4MiwxNDksMTg2LDUyLDI0OSwzOSw3Miw4LDIxLDEwOSwxNCw1MywzNywxNzgsMTk2LDExNCwxNzksMTcxLDY5LDE4OSw0MSwxNTUsMTQsODMsMTU3LDE3MCwyNDQsMzksMTQ4LDI0NCwxNzAsODAsMTg2LDE1NSwxMDAsMjQzLDE4OSw1MCwxNzcsMTQ1LDIyNSw4NCwxOCwyLDcsMTQ5LDIxOCw4NCwxNzYsMTkyLDUwLDExOSw3NiwxMDAsMCw2NywyOCwyMDYsMjI4LDE0OSwxMDEsMTc3LDI0NywxOTksOTgsMTU0LDgsMjQ2LDIyMCw1MCwxLDExOCwxNjcsNjAsNzIsMTUwLDIyOSw1OCwxODksNDUsMjIwLDExOSwyMTgsNDAsMjgsMTg2LDE4LDE3NCwwLDIwOSwxNDAsMTcxLDE2MywxNCw5NCw5MiwxMzgsMjE3LDc1LDE0MCwxNzAsMjI3LDIwMCwxMjcsMTU1LDQ4LDE4MSwxMiwxMzMsMjI1LDI0OSwxNjAsNDEsMjA0LDI2LDEwMSwyMTksMCwxODQsMTU0LDIwNSwyMzMsMTk2LDE0MiwyMzIsMTIzLDMwLDIzNywyMTAsOTMsNjQsODMsODYsMTUwLDIwLDE4OSwxMDcsNTUsMjQsMTYsODQsMjMsMTE1LDE0NSw4LDExMSwyNyw0LDE4NCw1Niw0NCwyNDYsMjA4LDEwNiwxMTUsOTEsMTU5LDI0NCwxMjMsMTk2LDI3LDIxNiw5NywxNTAsMjA4LDIsMjUyLDYwLDE3OCwxOTAsMzksNiwyMiwxNDcsMTYwLDMzLDI0NSwyMSwxNjMsMjE2LDUsMTksMTM2LDE1NiwxMDYsMTU2LDEyNywyMzEsMTAyLDIwNywzNSw5NiwxMjksMTE0LDIwOCw4NiwxODAsMTE2LDExOSwxMjYsNzQsMTIsNjcsNiwxMzMsNDEsMTE4LDc2LDAsMjYsMjA2LDYsNSwxMDMsMTUxLDIwNCwxMzYsMTY0LDM4LDY2LDE0LDkyLDEyNSwxNjMsNTMsMTUxLDEzMCwyMzUsMTg0LDE1OCwxNDksMTYxLDIzOCwxOTksNzEsMjUxLDE4NywzNSwxODgsMjQsMzEsMTYzLDIzNSwxNjMsNjAsNjAsMTMwLDc5LDE1NCwyNSwyMTcsNjQsMTk1LDE3NCwxMzksODUsMTk1LDIwOCwxMzksNzMsNjAsMTk2LDEyOSw2NCwyMDMsMTY2LDEyOCwxMzksMjA0LDE4LDEyNywxMzgsMjI5LDc3LDE2OCwxNjEsMTkzLDIwNywxMDUsMCwxODAsMTA3LDE3Miw2NSwxMTcsNjMsNzQsMzYsMTY1LDE0LDUxLDEyNCwxNiwxMDcsMjMsODIsMTQ1LDEwNiwyNDcsMTQ0LDQ0LDE5MywxMjAsMywxMDQsMTY4LDQxLDE4OCwzNCwyMDYsMjUxLDE3MCwyMDUsMjAzLDExMiwxNzEsMTYxLDEzMyw3NiwxNDgsMTM4LDM0LDgwLDQxLDE2OCwxMjgsMjMsMjAzLDgxLDE0Nyw1MCw1MSwxNDUsMTk4LDE1MiwyMzQsOTYsNzIsMTg1LDUwLDIzMSwyNywxNDUsMjA3LDIxMSw0Miw0MCw4NiwzMSwyNTAsODYsODgsMjM2LDE5NywxNjksMTc2LDE2NSwxMzAsMjM0LDI0NCwxODQsMTU1LDE4NiwyLDE5OSw1NSw2OSw1NywyMDAsMTI4LDE1LDE5LDc4LDIzMSwyMTMsMTcyLDIwLDIxNCwzNCwxODksMjEyLDE4Myw0LDExLDE0MiwxODgsMTYwLDQ5LDE1NywyNywyMSwxNTQsMTY0LDE3OSwyMjAsMTY2LDE3NCwyMDYsMTMxLDExLDY0LDgwLDI4LDMxLDEyMSwxMTAsMTgxLDEyMiwxMzMsMjI1LDE0NywxNzksOTgsODksMTc5LDY2LDE2OCw0MiwyNDAsODcsMjA1LDE4NywxOTUsMTEwLDE5OSwyMjAsMTMsMTgzLDQ0LDE5LDEsMTUxLDU5LDE4MCwxNjEsMTkxLDEwMywxMjMsMTMsMjU1LDE2OCw3MCw4NCwyNiwyMDQsMTMwLDg2LDM4LDEzNiwyMywxMzQsMTU4LDEwMSwxMjgsMjUzLDIwMiwxMzksMTYyLDIxNCwzMCwxOTEsMTEyLDEyMCwyMDIsMTUwLDE3NywzLDE2NSw4MywyNDAsMTY0LDE2NiwyNDYsMTUyLDE0NywxOTksODQsMTUsMjAyLDIzNCwzMCw3NSwzOCw3Myw5OCw2NywxNjQsMTIwLDU0LDcsMTIyLDUzLDcxLDM3LDI1LDE5Nyw3NSwxODcsMTIsMTg5LDE5Nyw0MSwxOTAsMzIsMTIzLDIxNCwxMzksMjA1LDE3MiwyNDcsMTMzLDE1MCw3LDE5NSwxMjYsODAsMTIwLDIwMSw5OCwxNDIsMjE1LDg1LDIwMCwyMzQsNzUsNTAsMjE0LDQ5LDEwNiwyMTYsNTgsMTksNjgsMjEzLDczLDM3LDE0OCwxMzQsMjAxLDIzNSwxMDIsMTkxLDc1LDE4MCwyMTQsNTUsMTg3LDE5OSw4NiwyOSwwLDcsMjAwLDEzMywxMzUsNDIsMTg5LDE4MCwxNzgsMTQyLDM3LDEyMCwxMjgsMzYsNzAsMjM0LDEzMiw1OSw0NiwyMTcsMTQyLDgzLDg2LDY2LDE5MywxNjgsMTQyLDE5OCwxMDMsNjUsMTM5LDI0MywxNTEsMjksMTM5LDYzLDYzLDE4OCwxMjIsNDIsMzUsNjksMTUwLDk5LDExMSwxNDYsMTg0LDI1LDM5LDkwLDMzLDEyNiwyNDksMTg5LDEyNywxNzYsNjEsMTE1LDEwNSw5OCw5MSw1MywxMzUsMTE0LDEyMiwxNjAsODIsNzMsMTY1LDU3LDY4LDExMCwyMDgsMTI0LDEyNSwyLDE2OSwxMTgsMTE5LDg0LDM3LDEyOCw4NiwxNTAsNTEsMTA1LDg3LDI1NSwzMywyMDMsMjAwLDIzMSwxMDMsMTI5LDUyLDY0LDE4OCw4Miw1OCw2NiwxNjMsNTcsMjExLDEyMCwxMTAsMTg2LDE4LDg1LDEzMSwyMTgsMTksMTcsOCw3OCwyMDUsMTc3LDU2LDIyMywxMjAsOTIsNDMsMTk2LDcsMTI3LDE1Niw0Miw4MywxMDcsMTAsMjIzLDEzMCwxMCwyNDAsMjMzLDE4OSwxNSwxOTgsNDAsMjQwLDExOCw1LDQ1LDY1LDIxLDk1LDE4NywxNzksMTA2LDEzMiwxMTMsMTkyLDEwLDMwLDEzMywxNjQsMjEsOTMsOTIsMTU4LDE3MCwxMzksMTI2LDI0OCwyNDgsMTMxLDIyNywxODIsOTQsMTU5LDQsMzcsNTQsMTk5LDE4NywxNDUsMTE3LDEzMywxNyw1Nyw1NSwyMTIsMzUsMTEyLDE4NSwxMzEsOSwyMDksNjQsNzQsMTQ2LDIxNyw1MiwyMiwyMjQsNDksMTk1LDg3LDE3NCw2MCwyMSw4OCw3NiwyMDgsODcsMTk1LDIyNiw3MywyMDEsMjI5LDEyOCw2OCwyMzYsODQsMjI3LDI0MiwxNjQsNzksMTk2LDEzNCwxMTgsNjcsMTI4LDIsMTAsMTcsMjI2LDIwLDEyNiwxMzcsMywxODYsMTAxLDE0NCwyMDAsMTg5LDE1MywxMTQsMTYxLDE5OSw1LDkyLDE0OCwxMTIsNTQsMiwxNDQsNjAsMjE4LDAsMjMsMjMyLDYwLDI0MywyMTIsMTc1LDAsMzcsMjUsNDcsMjEyLDExMCwyMTYsNDgsNCwxNDcsMjI0LDU0LDE0LDcwLDIwMCwyMzMsMjEyLDU2LDE0LDIxNCwxMzUsNzksODEsMTUwLDExNiwxMzMsMyw3NSwyMzIsMTg4LDI1MywyMjAsMTM5LDIwMiwxNDQsNTYsODIsNTIsMywyNSwyMjgsOTcsOTgsMjUyLDIwMSw3NiwxNDAsMTksMTQ0LDk4LDEwMiwyMDIsMTM2LDE4Nyw1MCwxOTIsMTAzLDQ0LDg2LDk3LDEyNywxMjAsMTIsODgsMjM2LDE2Myw4MCwyMTQsMTg0LDIyMCwyMTUsNDAsMTM5LDExNyw3MSwyMTksMTgxLDExNyw1MSwyMTIsMTI0LDEwMiwxMTMsMTAxLDMxLDE0Niw0NiwxOTEsMjAxLDk5LDYsMjI4LDEyMiwyMjgsNzEsMjA3LDkwLDkyLDU0LDcwLDI1MCwxNjEsMjIxLDEzOSwxMTEsNDYsODUsMTgwLDE2NSw3LDU2LDEyNSwyMSwzNCw2NywxMTksMTEyLDE2NSwxMSwxOTcsMTAwLDY1LDY3LDIyMSw1OSwyMzQsMTg5LDE5NSwyMDMsMTYyLDE1OSwyMDMsMTk5LDE1OCwxODIsMTY1LDEsMTkyLDE1NSwxMTUsMjksMTc5LDIzMywzNSwyMTUsOTUsMTksMjI0LDIsMTksODMsMjE2LDE0MywxNDIsMTM0LDE1Miw2MiwyNTEsMTU0LDM1LDIwLDEwNywxMiwxNDcsMTUxLDc4LDE1Myw5Myw4NywxNDUsMzgsMjYsMTg1LDE0Myw5NCw2NiwyMTEsNSwyMiwxNTYsMzgsMTI1LDE2OCw1Miw1NCwyMDcsMTcxLDExMSw1OSw5NSwyMDgsMjE5LDIzNSw5LDMwLDU3LDE0MiwxOCwyNTQsNjMsMTg5LDE2MCw3OCwxMTYsNTAsMjA0LDIzNiwyMCwxNTcsMTM5LDEwNSwxNCwyNTAsMjI0LDE5OSw0OSw4Miw2NiwxNjAsMTgxLDMyLDE0MSwxMjYsMjIwLDIxMyw3NywxODMsMjQ2LDI1MywxOTUsMjE0LDM3LDE5NCwxODUsOTgsMTQ1LDEyNCw2MiwxOCw1Miw0NiwyMjUsMSwxMCw0NCwxMjAsMTQzLDI0MCwxMiw4MSwxOTgsMTgzLDE4MCwwLDU4LDI0OCwzOSwzOSwyNTMsODQsNTAsOTQsMjU0LDIyNSwyMTIsMTUsMTAsODgsMjUzLDIxMCw5LDI0NiwzNywyMjQsMTY1LDE4NSw5LDYsMzMsMF19fX0seyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxMTYsMTY2LDYyLDEyOSwxNzcsMTYzLDEyNCwyMTQsMTA4LDgwLDg2LDE0NSwyOCwxNDQsNjQsMTg1LDQsODksNjAsMTE2LDMzLDE5LDIyNSwxNTcsNzAsMTIzLDEzMyw1MywxODAsODksNjcsMTQ5LDQzLDY2LDE4MywxNDMsNDcsMzQsMTgwLDg3LDE2LDExLDExMCwyNTEsNjEsMjAyLDIzMywxNTMsOCwxMDIsOTEsMTk4LDQ5LDU5LDE2MCwxOTgsODYsNTgsMjQwLDE1OCwxNTksODEsMjA3LDk0LDIwOSwxMjAsMjI4LDg0LDU1LDIzOSwyMiwxOTcsMTAzLDIzNCw3NywxOTgsMjQxLDQ3LDksODAsMTYyLDE4NiwxNTQsMTgyLDI2LDEzOSw4NiwyNDEsMjAsMTA0LDE2OSwyMTksMTM3LDIwNyw4LDE4LDE1NCwxNiwyNSwxMTksMTQ2LDE4NiwxNTMsODksMiw5LDEwNCw0MiwzNiwxNiwzNywyMSwxOTUsOTUsMzksMTk2LDE1NCwxODUsNzQsMTMyLDI0Niw4OSwxNDUsMTIwLDIyNywyMSw2MiwxODIsMTAyLDIzMiwyNTIsMiwxNzksMTY5LDQyLDE0NSwxMDMsMTkxLDIwNSwyMzQsMTE2LDE5MCwxMDgsMTQyLDk5LDU5LDQ1LDEwMSwxMjEsOSw2MywxNjcsMTk0LDg0LDEwMiw0OCwyMywyMTAsMTE4LDIyNywxNTIsMTM1LDE2Myw0Myw0Miw4NCwyNDQsMzcsMjA1LDEzNSwxNTEsMTE1LDE1MCw4OCwxODAsMjMzLDE0Niw2OSwxOSwyMDcsNjYsNDIsMTIzLDE3MiwyNDgsODgsMTgzLDE2OSwzMCwzNSw1Miw3Niw4NSwxNTMsMTU4LDksMTE1LDkwLDI1MSw5OSwxNSwxNjQsMTYyLDIzLDg2LDE1MCwxNzIsODUsMTAxLDEyOSwyNDEsMTM0LDE5OSwxMjQsMjUsMCwxOTAsMTQ2LDM0LDcxLDI0LDk2LDM4LDIxLDYwLDE5MSwxNDAsMTczLDI1MiwxMTMsOTUsNjAsNzUsNDksNTksMjQ0LDIwMywyNDEsMTI5LDY5LDIzNSwyMiwzMiwxNSwyMzYsMTkwLDEyMiwxMDEsNjQsMTExLDcsMTcxLDIyOCw1NywxMjEsMTE0LDIwMywxMywxMDMsOSwzNCwxNSwzNiwyOSwyMjIsMjI3LDE5OCwxNTQsMzMsMTExLDEzNywxNjgsMTE4LDEwNSwyMzEsMTAxLDYxLDM1LDE4MCw3OCw4OSw0MywxNDAsOTAsMjYsNTAsMjEsMTQzLDI0MSwyMTIsNzcsMTMsNDgsMTcxLDMzLDE2MywyMDMsMjA4LDE4MSwxOTQsMTA4LDgyLDEyNSwxMTcsODIsNjksMTMsMTQ4LDgzLDQ1LDY1LDY3LDExMSwxOTcsODYsMTAzLDE2NiwzMCwyNTMsMjUyLDQ5LDM1LDU3LDE4Myw3NSw5MSwxNDEsMTg2LDkxLDE3MCwxNDcsMjUxLDE2Myw0MiwxODEsMTc0LDIyOCwyNCwyMywxNzcsMjE1LDc2LDIwNiwyMTksNTIsMjUyLDg2LDkyLDY0LDE2OCwyMiw3OCwxODcsMTQ0LDc4LDg4LDEwMSwyMTgsMTQ2LDEwNSwxNjYsNiwxMzQsMTU2LDY2LDE5MSwxODUsMTk5LDE4NiwxMiw1LDk2LDEyNSw2NCw0NCwxNDIsMTIsMTcxLDEyOSw4NCw3Niw3MSwyMTYsOTYsMzMsMTQ1LDUyLDI1NSwxNDYsOTEsMTM1LDU1LDE5NywzMywyNDQsMTYyLDY4LDk3LDQ4LDY3LDg5LDEzMywyMDMsMTg2LDEwMCw4MywxODUsNzAsMTE4LDU5LDE4OSwyNDgsMjEzLDE0Miw5NSwxOTYsMTEyLDE3OSwxNDgsMTg3LDcsMTA4LDI4LDIzNSwxMzIsMSwyMDAsMjI4LDE4MywxNjQsMTM1LDE2LDgyLDI4LDE2NiwzMCwyMzEsMTMzLDg1LDI1MCwxMzgsODksMTk2LDExOCwxNzIsNjUsMTkwLDIzMiw4LDEzLDU4LDgzLDcyLDIzOSwxMDMsNDYsOTYsMzYsNTUsODksMTg3LDM2LDI1LDIxNiwxMDQsMjAwLDM0LDc1LDIyMCwyMzQsMTEyLDIyMywwLDEyNiwxMDYsMjE2LDE5MiwxNDksNDMsODYsMjAsMTcxLDExNSw4MywyMDMsMTIsNDksMTg0LDgyLDIzOCwyMTMsMTQwLDU0LDE1MSw5LDkzLDE3Nyw4Miw1NCwxMjEsMzIsMTI1LDMyLDExMSwxMTksMTg1LDEwMSwxMzQsMjQxLDE0NCwyMjcsMjE2LDI4LDM4LDIyOCw1LDM0LDExNCwxMTEsMjksMjA5LDIwNywxMjUsNDgsMzksMjMxLDEyOSw3OCwyMjksOTEsNzQsNSwyNTIsMTYwLDE2NiwxNDgsMjAsNDgsMTQ3LDIwMiwxOTksMjQ3LDE3MCwyMzEsMTI5LDgzLDIyNCwxNjcsNDksMjM0LDEzNiwxNjMsMzQsMjI4LDExOSwxNTAsMTYsNTgsMTg2LDE5OCwxMzMsNCw2OCwxNTksMTc1LDgxLDE0MCwyNDMsMjQsODAsNzksMjQ0LDEwOCw4MCwxMDMsMTQzLDE2MSw4OCwyMDMsMjI1LDE2MywxNjQsMTk3LDUsODIsMjcsMTM4LDY5LDI0MCwxODYsOTEsMjMzLDEzMSwxNTgsMjAyLDQwLDkwLDgxLDE2MCw4MiwxNDMsMTM3LDE2NCwxMzEsMjAsMTczLDE1MywyNSw5NSw4MCwyNiwxODEsMzgsMTQ4LDU0LDE5NiwxMDQsMjMsMjM3LDEzNiwxNjMsMjE4LDE3LDI3LDY2LDIyOCwxMjcsMjExLDI1MCwxNDksMTY0LDg1LDEwOSwxNjksMTg2LDIwMCwxLDI1MSwyMDEsMTAzLDEyMywxODMsMTU1LDg3LDk0LDE4NywyMzUsMTc4LDk4LDk3LDIwNiwyNSwxMDUsMTYxLDIwMiwyMzEsMTIzLDY2LDEzOCwxNCwxNzcsMTE0LDE2MSw1OSwxNzcsNDAsMTMsMzksMzAsODQsNDgsMTg3LDIzMywxMzEsMTg2LDIwNCwxNjcsOTEsMjIzLDI0MywxOTMsOTIsMjEzLDE5MSwxNCwxNDcsMTcsMTM3LDQsMzYsOTYsNTYsNDUsMjcsMzUsMjAxLDE5MCwxOTMsMjQsMTc3LDE1NCw4NiwxOTcsMTU2LDE2OCwxNjgsMTE1LDMxLDEyNSwyMjksMzUsODAsODksOTksMjM3LDI1MSwxOTAsODIsMSwxMzMsMTUwLDIxNCwyMDUsODcsOSwxOTQsMjM0LDIzNCw4NiwxNjgsMTQ0LDE5MCwyMDEsOTcsMTEyLDE0MSw3NCw3NiwxNDAsOTYsNSwxMTcsNjYsNywyNTUsNDAsMTU5LDQyLDQzLDExOSw4NCw1LDk3LDEsMjE2LDcxLDExLDE2NywxNDUsNjUsMjUxLDUwLDEwMCw1MiwxNzAsNCwxOSwxOSwxMTksMTQwLDEwLDEwLDg1LDE3LDg0LDM3LDEwOSwyNDAsMTk0LDIzLDE2NiwyMzUsMTMxLDc2LDE4NiwzNywxMDQsMjE3LDI5LDIyNywxNTUsNjAsMTA5LDc1LDEwMiwxNywxMjksMTU0LDIyNSwyMiw5OSwxODIsMTcwLDU2LDI1LDIzMSwxNTEsNzksMTYxLDUwLDEwLDIyOSwzLDQwLDE5NiwyNiwxNzgsMTM0LDE0NSwxNywxNTUsMTE2LDE0MSwyMCwxNzIsMTQxLDE2OSw1LDQwLDIwOSw2MiwzNSwzNiwxNCw3NiwyMzYsMTk0LDI0MiwxMTYsMTgwLDIzNiw0Miw4NCw5MSwxMTgsMTM5LDIyNSwxNzksMTg4LDAsMTA1LDEzLDk5LDE4Myw1MywyMjIsMjEzLDEzMSwyMzIsMjI1LDk2LDE5Myw3MSw0LDEwNCw2LDE2NSwxNzksMjM1LDQ5LDIwNywxMTUsMzgsMTIzLDE4NSwyOSw2NSwxODEsMTc2LDE4NSw3MCwxNjksMTgxLDI0MSwyMiw0MSw5MCw2NiwxMjMsODksMTYxLDMwLDE0OCwxMTUsMTI0LDE5OCw2NCw2NiwxMDMsMTAxLDUyLDE5NywxOTAsMTMzLDEwMCwxMzksMTQyLDgzLDk3LDI1MiwxLDEzMiwyMzAsMjM0LDE4MiwyMjEsMjEsODksMTA1LDEyNCwxMDgsMjIwLDE5MywxOTYsMTU1LDE1NiwxNjEsMTUxLDI0MSwxMTcsNjQsMTIwLDIwNiwzOCwyNDEsOTMsMTA2LDIxMiwyNSwxNDAsMTU0LDI3LDE4MSwyNDEsMTAxLDIxMiwzNCwxMzksNTEsNyw5OSwzNCwxNjYsNjAsNTMsMTgyLDc4LDE5MSw3MywxNTUsMjUxLDU2LDE3MSw1MywxOTcsMzYsNDIsMTk5LDE0OCwyNTAsMTk2LDE5MiwxMzUsMTM0LDEwMiwyNTQsMjgsMTE3LDEyNiw4Niw1LDE1Nyw1MywxNjUsMjM4LDEzNSwxNzgsMTgxLDM5LDc2LDE0LDM0LDgwLDYsMjI3LDE2MiwxMjAsMTMwLDEwMywxNywxODgsMTc3LDU0LDk4LDE0MCwxOTUsMTc4LDY3LDE2MCwxNjcsMTQsMTUyLDQ5LDE2Myw2NywyNTAsMTUyLDIwOCwxMTYsMzMsMjQ3LDE4MiwxMjIsMTE2LDEyMywxNjksMTk0LDE2NCwxMTIsMTU2LDc0LDE0OCwxNDgsNjcsMTI1LDExOSwzOSwxMTksMTI0LDU1LDEzMywyMTAsNTksMTI1LDkxLDE4NywxMTQsMTQ1LDcxLDE3MiwxODEsNTEsOTEsMTYxLDU3LDU1LDE0OCw4MSw0OSwxNzQsMTA4LDE1MywyMDYsMjQyLDc4LDIzOSwxOCwxMzAsMzIsMjExLDEyOSwyMjIsNjQsOCwxMjgsMTkzLDEyOCwxNiwxMDYsODUsMTUwLDMsMjAyLDc0LDE2MywyMDIsOCwxOTcsNjMsMTMzLDIwNCwxODQsMTQ4LDE1MywxODksNjIsMTY4LDI2LDE4MywyMTksMTUwLDIwMCwyMTEsNTQsMjQ4LDc1LDExMSwyMzcsMjAyLDE2LDE5MywyMjUsMTkyLDE4Miw1OSwyMDIsMzYsMjMyLDE4MCwxOTcsMTMwLDEyMywxNTksMTU0LDEyMywyMTYsMjQwLDE2MSwyMTIsMTQ1LDExMCwxNTAsODAsMTE4LDIwOCw5MCwxMDYsODEsNzIsMjAsNjksNjAsMjgsMTc3LDkwLDE2NCwxODksMzksMCw4Myw4Miw5OCwxMzAsODAsNDUsMTc3LDc5LDE3NywyMzUsNDEsMTQ0LDI1LDMyLDIyLDEyMiwzMSwxNDUsMjE3LDE2MywxMDEsMjIwLDEsOTgsMTA4LDE5NiwxNzEsMTg2LDEzMiwyOSwyNDAsMjI1LDExMiw0LDY2LDk2LDE0OCwxODQsMTY0LDM2LDIyMywzMCwxMSw2OSwxMDUsNzcsMTk2LDE2NywxNiwxNDksMTg1LDI0NiwxNTMsMTI5LDE4MCwxMjAsMjQ0LDE1NiwxMiwxMzEsOTcsMjQyLDIyNyw3NCwxNDUsNzksN119fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6Wzc1LDk4LDQzLDU2LDE2Niw2MiwxNDgsNjAsMTU1LDIwOSwxOTUsMTY5LDQxLDI0OSwxOTYsMTk3LDcsMTQ5LDE1NCw0MSwxMiwxMDksMjE1LDQyLDE5Myw1MiwxMDQsMTU1LDcyLDQxLDI5LDU2LDc5LDE3MiwxOTQsMTkwLDE2OSwyNDAsNDksMTg0LDE2MSwyNCwzOSw0OSwzOCw0OCwxMjEsMTUxLDMzLDY0LDgzLDExOSwyMzYsMzcsMTk1LDEwMiwxMDQsMjEyLDEyMCwxODksNjMsMTUxLDQyLDcxLDIyNiwxODAsMTM3LDQxLDgsMzksMTAxLDE1OCwxNCwxOTcsNjQsOTAsNzAsNjYsMjUsMjAzLDE2NSwzNSwxNTQsNTYsNDMsODcsMTEyLDE5OSw1OCwxNTUsMjcsMTQ3LDExMiw5NSwxNzksMTEyLDc3LDE3Miw2NiwzMiwxMzYsNiwxNSwxMzUsMTQzLDc1LDEyMiwxOTQsMjA5LDQxLDIwNyw5LDcsOTYsMTE0LDIzMCwxMzgsMTQwLDI1MCw3MiwxNjQsMTU0LDEzOSwxNzYsMTA0LDQ5LDEwMywyNywyOCwxNDAsMiwxMzMsMTIyLDEwNSwxMDgsNjAsNTQsMTYyLDE3MCwxNzksMTkyLDIzMiwxODUsMTQ2LDM5LDIyOCwzMCwyMDIsMTQ4LDE0Myw0OSwyNywxMTcsMTkzLDIyOSwxMzIsMjUwLDEwOCwxNTEsNzEsMjQwLDE2MCwzNywxMjQsMTk0LDIwNywyNDEsMTEwLDE2OCwyMjcsNSwxOTEsMTAzLDg4LDI0OSw5MCwxMTIsMjQ3LDEzOCw2Niw0NSw2LDExLDE1NSwxMjIsNTUsMTcyLDIxOCwxNTIsMzUsODIsMTI5LDExMSwyNDgsMTE4LDk1LDE5OCwxMzcsMjM2LDI3LDM0LDIxMyw3NSwxMzksMjAsMjI5LDEyLDkzLDE1MCwxMjUsNzIsOTYsMTI4LDIwMCwxMDcsMjcsNDQsMjIwLDE4NSw0NCwxMTQsODcsMSwxMzYsNTMsMTM1LDUyLDE0LDk1LDE2NSwxMzYsMjI2LDE3MCwxMDYsMTcwLDE1NSwxMDQsMjExLDE5LDY1LDU2LDE0NSwxNjUsMjUzLDE0OCw5NiwxNCwxODQsMTk0LDI1NSw3MSwyMCwxMzMsNzUsMjAsNzgsMTU0LDE1MCwxNDgsMTMzLDEwNCw5MSw4OCwxMzAsMTE5LDQyLDUxLDI3LDI0MSwxMzAsMjQ0LDIzMCwxMTAsNzEsNTAsMTIwLDIzMCw1NywyOCwxNTQsMTYzLDE5LDQ5LDIzMiwxNDksNTEsMTQ5LDI1LDE3MiwyNCwxNzksNjQsNzYsNywzNiwyMjQsMTMwLDEyNSwxOTMsOTcsMTQ1LDEsMjEsMzMsMTgwLDI5LDIyNCwxNTQsMTc2LDExNywxMDIsMTYwLDg1LDI0NywxMTEsMjUwLDIzNCwyMDUsMjMwLDg2LDIwNywyNTEsMzgsOCw2MywxNjgsMTY0LDI1MiwxMzQsMTM2LDE4Miw3MCwxMjYsNjcsMTEyLDEzNCwxODksNDMsMTg3LDIyNiwxODgsOTcsODQsMTY0LDIwNCw5MCw3MCw2NywyNDYsMTQwLDEyMSwxOTQsNjgsNDYsODEsMjMwLDEzNiwxNjcsMTc3LDY3LDIzNiwxNjAsMTcwLDEzMiwxMTcsMTUyLDE0MSwxMTQsMTg1LDIwMCwxMzQsMTcsMjIsMjE1LDYzLDIzNywxMzgsMTMsMTY0LDExNyw4MCwxNTcsMTYyLDEwNCwxOSwyMTUsMTQwLDgsNTAsMTkzLDQ5LDI0OCw2OSwxOTUsMTc5LDE1NiwxNDcsMjcsMzYsMTQ3LDE5Nyw3NywyMDMsMjUxLDE1Miw2MSwyMzUsNDMsMTk3LDEwLDE5MCwyMjgsNTgsMTcwLDE2OSwyNDcsNjgsMTIzLDIyNSwxNzMsMTUyLDE3MCwxNjMsMjUyLDEzMCw2LDM5LDE5MywxODMsMjA3LDE2LDE2OCwxMDEsMCw1MCwyMTEsMjM2LDI1LDEzMSwxNTQsNDIsNTYsMjQ5LDkxLDEzNCw1MCw5LDE0MywyMDksMjUsMTA5LDEwNCwxODMsMjA5LDY5LDQ3LDEzNCw5OCw4NSwxNDAsMTM4LDE5OSwyMjEsMjE3LDEwMiwyOSwxNTUsNTUsODgsMTQ1LDEsMTI0LDIxMSwxNzksMTM2LDIxNSwxNDQsMTYwLDIzNCwxMjIsNzksMTg0LDE2MSwxMzUsMzUsMTczLDEwMCw4LDE1NCw3MywxMjQsMTMyLDE1MCwxMDEsNDYsMjE4LDIwNCwxOTQsMTc5LDU2LDYyLDEyMCwxNDYsMTc2LDIzNyw1MywxMTksOTAsNjgsMTksMjM3LDIwLDE2NiwyMCw5OSwxMTMsMTg2LDk2LDY0LDI0OCwyMzUsMTQsMjA1LDEzOCwxMDgsMzEsMTAsMTI1LDI0NCwzOCwxNTUsMTEwLDc0LDQ0LDk5LDg3LDk2LDEzNCwzNiwxMiwxNTEsNzMsMTksMTM1LDE5MiwyMDQsMjAyLDEzNywxNzYsMzcsNTcsMTcyLDEwMywyMTMsOTUsNjksMTQ0LDE4OCwzNywyNCwyNCw0MywxNDUsMTgzLDE3MCw2LDI4LDE0MCw3LDExMiwxNTYsMTIwLDEyMCwxODMsMTIsMTkxLDIyOSw4MywzMywxNjksMTE2LDM0LDEyNiwxMDIsNTYsMTU3LDEyMSw0NCwxOSwyMDAsMjEsMTAsNTMsMTgzLDI2LDIxOSwxMTYsMjA1LDE2OCwxNjcsMjU1LDcsMTc3LDE5Nyw0MCwxMywyNTUsMTg3LDU3LDExLDE4OCwxNzUsNTksMjQ4LDg2LDI1MCwxMiwxNSwxNjMsMjE3LDE1NiwxOCwxNjMsNDgsMTI3LDEzOSwxMDIsMTkwLDE3MCwxOTIsMSwxODAsMTY2LDEwNiwxOTgsMzIsMTc3LDk5LDkwLDE4MiwyNDIsNjAsMTUyLDE2LDE3NiwxNTAsMTg0LDEwMSw3Nyw3MCwxNzYsMjgsMTc3LDkwLDEwLDI1MCw2MCwyNDMsMTksMTIzLDE2OSw5MCw0OCwyNTIsMjQyLDE4MCwxNTcsMTcsNTcsMTMzLDcwLDExOCwxNjIsMTY3LDksMTczLDEzNiwxNzUsMTE3LDIyNCwyMyw0Niw0MiwxNzIsMTUyLDE2MCw5NiwxNjAsMjAwLDE1LDU2LDEzNCw1MSw3MSw4NCw5MCw5NSw3NSwyNywxOCwxNDcsNDgsMTIzLDg4LDE5NiwxODAsODcsNTcsNjcsMTgxLDgsMjI3LDgwLDEwLDIwMCwxNTYsMjEsMjE5LDI1MiwxMDksMTUwLDEwMCwyMyw0NSwxODYsMTk2LDIzNywyMjgsNjAsMjAyLDE2NywyMyw3NiwxODIsOTcsMjMsMTM2LDUwLDg1LDE2OSwxMTcsMjE1LDgzLDIxLDEzMCwxNTEsMjAxLDE2NiwxNjUsMTc2LDEwMCwyMTIsNTMsOTIsMTQ1LDExMSw2OSwxNjYsMzgsMjQ4LDIzLDI2LDI1MCwyMTYsMTgxLDI0NywxOTMsMjA2LDExNCwyMTYsMTMyLDEzMywxMDgsNTAsMTU2LDU5LDI5LDE4NSwxMiwxNjEsODEsMTMxLDIwMSwxNjQsMTUxLDE4LDE0OSw3NiwxMjMsMTMyLDI1LDk1LDE0LDExNCwxNTksMTkzLDI1MCwxMDAsMTE1LDE3MSwxNDAsMTI2LDg5LDg2LDE1NSwyMTgsMTcyLDE2MSwyMTEsNDMsNjUsMTAxLDksMTQxLDI0NiwyMDUsNTIsMjQ3LDE1MSw5Myw3MywxNDksMTMwLDIyOCwyMDUsNTIsMSwyOCw3Nyw3MiwyMDcsMjI2LDExNCwzNCwxNzcsMTg3LDk4LDgsMTg3LDE0MywxNCwxOTgsODYsNDcsMTAyLDEyMSwyMDgsMTQ4LDc2LDk3LDc0LDQ3LDEzNSwxNTEsMTYxLDE4NCwzOCwxMzYsMjI0LDEwNiwxNzYsMTcyLDExNCwxNDUsMjMzLDE1Niw5OCwxNDMsMTg4LDEyMCwxNDksNTcsNywxOTYsMTkzLDM0LDE3OCw5MSw0NSw4MSwyMzIsNDQsMTE4LDI0Niw3NSwxNzQsMTc4LDk1LDc5LDEyMiwxMTQsMjU0LDYwLDE1Nyw4OSwyNiwxOTIsMTIwLDEwLDczLDIwNSwxMTcsMTUxLDEyNiwxOTcsOTMsMTMzLDIwOCwxNzksNTIsMzYsNzEsMjEwLDI0NywxMjYsMTI5LDUyLDMxLDk0LDE3MCw4LDE2MSwyMjUsMTAyLDE3MSwyLDIyLDEzOSw5Niw3LDEwNCwxODYsNDAsMTExLDI3LDEwMywyNTIsNDIsMTc3LDkyLDcxLDEyOCwyMjgsMjUyLDE5MywxNTgsMTEsNjAsMTMzLDQwLDEwMiwxNzQsNDksMTg5LDE1NCwxNzksOTEsNTgsMTU2LDExLDI0NCwxNTMsMTAxLDczLDEsMzIsMTU0LDE4OCwxMTUsNzYsMTQ0LDEwOCwxNywyMTMsOTIsMjE2LDIxLDkxLDIzOSwyMzEsMTg2LDk5LDQ4LDE3MSwxMTMsOTEsNTUsMjAyLDEzMiwxNDEsMTQ1LDEwNCwxNDgsMzksMzksMTMsNDMsMjQ2LDE0MSwxNTUsMjM1LDEyLDQsMjE4LDE4Niw5NywyLDE4LDIyOCwxMzIsMTU0LDE3LDIyMCwxMjMsMjA4LDM4LDIwNCwzOCw4OSwxODEsNSwyMzMsNzIsMjQ4LDE1Niw4MiwyMTMsMTcxLDIsMTUyLDU5LDExMSw4MiwxNjUsNTYsMTkxLDksNTAsMjQ5LDE2Niw5NywzMiw0OCwxMjgsMjE1LDg4LDgzLDExOCwzNywxMjYsODcsMTY4LDE2OCw4MywyMzQsMTkzLDE2MiwyMSw2OSwxMDMsMTMzLDE4LDk3LDEwMiw0MSwxOTUsMTg3LDc3LDY0LDE2MiwyOCwyMSw4LDUwLDk0LDEwMSwxNjAsMTQzLDEzOCwxLDEwNywxMTcsMTE3LDE2OSwyMCw2NywzMCwyMzAsMTE1LDIzMiwxODgsNDYsODMsMTAyLDIwMiwyMzcsMTY1LDU3LDExOSw3LDE1LDE5MiwyNTEsNzIsMjE5LDQwLDUyLDE2Niw1MCw5MywzNiwxNTIsMjAxLDI0Niw4MSwxMTMsNzQsNzQsMTMwLDYsMTY0LDEyLDExOCwyMzMsMzcsMzgsMjQ2LDU4LDM3LDEyMSwxMDIsNzgsMCwyMiwzNywxOTMsNDEsMTM5LDEwMCwxODksNDYsMTk5LDE4NSwyMDcsNTYsMTMwLDEyMSw4LDAsMjA5LDcyLDYxLDExNiwxNjYsNjIsMTI5LDE3NywxNjMsMTI0LDIxNCwxMDgsODAsODYsMTQ1LDI4LDE0NCw2NCwxODUsNCw4OSw2MCwxMTYsMzMsMTksMjI1LDE1Nyw3MCwxMjMsMTMzLDUzLDE4MCw4OSw2NywxNDksNDMsNjYsMTgzLDE0Myw0NywzNCwxODAsODcsMTYsMTEsMTEwLDI1MSw2MSwyMDIsMjMzLDE1Myw4LDEwMiw5MSwxOTgsNDksNTksMTYwLDE5OCw4Niw1OCwyNDAsMTU4LDE1OSw4MSwyMDcsOTQsMjA5LDEyMCwyMjgsODQsNTUsMjM5LDIyLDE5NywxMDMsMjM0LDc3LDE5OCwyNDEsNDcsOSw4MCwxNjIsMTg2LDE1NCwxODIsMjYsMTM5LDg2LDI0MSwyMCwxMDQsMTY5LDIxOSwxMzcsMjA3LDgsMTgsMTU0LDE2LDI1LDExOSwxNDYsMTg2LDE1Myw4OSwyLDksMTA0LDQyLDM2LDE2LDM3LDIxLDE5NSw5NSwzOSwxOTYsMTU0LDE4NSw3NCwxMzIsMjQ2LDg5LDE0NSwxMjAsMjI3LDIxLDYyLDE4MiwxMDIsMjMyLDI1MiwyLDE3OSwxNjksNDIsMTQ1LDEwMywxOTEsMjA1LDIzNCwxMTYsMTkwLDEwOCwxNDIsOTksNTksNDUsMTAxLDEyMSw5LDYzLDE2NywxOTQsODQsMTAyLDQ4LDIzLDIxMCwxMTgsMjI3LDE1MiwxMzUsMTYzLDQzLDQyLDg0LDI0NCwzNywyMDUsMTM1LDE1MSwxMTUsMTUwLDg4LDE4MCwyMzMsMTQ2LDY5LDE5LDIwNyw2Niw0MiwxMjMsMTcyLDI0OCw4OCwxODMsMTY5LDMwLDM1LDUyLDc2LDg1LDE1MywxNTgsOSwxMTUsOTAsMjUxLDk5LDE1LDE2NCwxNjIsMjMsODYsMTUwLDE3Miw4NSwxMDEsMTI5LDI0MSwxMzQsMTk5LDEyNCwyNSwwLDE5MCwxNDYsMzQsNzEsMjQsOTYsMzgsMjEsNjAsMTkxLDE0MCwxNzMsMjUyLDExMyw5NSw2MCw3NSw0OSw1OSwyNDQsMjAzLDI0MSwxMjksNjksMjM1LDIyLDMyLDE1LDIzNiwxOTAsMTIyLDEwMSw2NCwxMTEsNywxNzEsMjI4LDU3LDEyMSwxMTQsMjAzLDEzLDEwMyw5LDM0LDE1LDM2LDI5LDIyMiwyMjcsMTk4LDE1NCwzMywxMTEsMTM3LDE2OCwxMTgsMTA1LDIzMSwxMDEsNjEsMzUsMTgwLDc4LDg5LDQzLDE0MCw5MCwyNiw1MCwyMSwxNDMsMjQxLDIxMiw3NywxMyw0OCwxNzEsMzMsMTYzLDIwMywyMDgsMTgxLDE5NCwxMDgsODIsMTI1LDExNyw4Miw2OSwxMywxNDgsODMsNDUsNjUsNjcsMTExLDE5Nyw4NiwxMDMsMTY2LDMwLDI1MywyNTIsNDksMzUsNTcsMTgzLDc1LDkxLDE0MSwxODYsOTEsMTcwLDE0NywyNTEsMTYzLDQyLDE4MSwxNzQsMjI4LDI0LDIzLDE3NywyMTUsNzYsMjA2LDIxOSw1MiwyNTIsODYsOTIsNjQsMTY4LDIyLDc4LDE4NywxNDQsNzgsODgsMTAxLDIxOCwxNDYsMTA1LDE2Niw2LDEzNCwxNTYsNjYsMTkxLDE4NSwxOTksMTg2LDEyLDUsOTYsMTI1LDY0LDQ0LDE0MiwxMiwxNzEsMTI5LDg0LDc2LDcxLDIxNiw5NiwzMywxNDUsNTIsMjU1LDE0Niw5MSwxMzUsNTUsMTk3LDMzLDI0NCwxNjIsNjgsOTcsNDgsNjcsODksMTMzLDIwMywxODYsMTAwLDgzLDE4NSw3MCwxMTgsNTksMTg5LDI0OCwyMTMsMTQyLDk1LDE5NiwxMTIsMTc5LDE0OCwxODcsNywxMDgsMjgsMjM1LDEzMiwxLDIwMCwyMjgsMTgzLDE2NCwxMzUsMTYsODIsMjgsMTY2LDMwLDIzMSwxMzMsODUsMjUwLDEzOCw4OSwxOTYsMTE4LDE3Miw2NSwxOTAsMjMyLDgsMTMsNTgsODMsNzIsMjM5LDEwMyw0Niw5NiwzNiw1NSw4OSwxODcsMzYsMjUsMjE2LDEwNCwyMDAsMzQsNzUsMjIwLDIzNCwxMTIsMjIzLDAsMTI2LDEwNiwyMTYsMTkyLDE0OSw0Myw4NiwyMCwxNzEsMTE1LDgzLDIwMywxMiw0OSwxODQsODIsMjM4LDIxMywxNDAsNTQsMTUxLDksOTMsMTc3LDgyLDU0LDEyMSwzMiwxMjUsMzIsMTExLDExOSwxODUsMTAxLDEzNCwyNDEsMTQ0LDIyNywyMTYsMjgsMzgsMjI4LDUsMzQsMTE0LDExMSwyOSwyMDksMjA3LDEyNSw0OCwzOSwyMzEsMTI5LDc4LDIyOSw5MSw3NCw1LDI1MiwxNjAsMTY2LDE0OCwyMCw0OCwxNDcsMjAyLDE5OSwyNDcsMTcwLDIzMSwxMjksODMsMjI0LDE2Nyw0OSwyMzQsMTM2LDE2MywzNCwyMjgsMTE5LDE1MCwxNiw1OCwxODYsMTk4LDEzMyw0LDY4LDE1OSwxNzUsODEsMTQwLDI0MywyNCw4MCw3OSwyNDQsMTA4LDgwLDEwMywxNDMsMTYxLDg4LDIwMywyMjUsMTYzLDE2NCwxOTcsNSw4MiwyNywxMzgsNjksMjQwLDE4Niw5MSwyMzMsMTMxLDE1OCwyMDIsNDAsOTAsODEsMTYwLDgyLDE0MywxMzcsMTY0LDEzMSwyMCwxNzMsMTUzLDI1LDk1LDgwLDI2LDE4MSwzOCwxNDgsNTQsMTk2LDEwNCwyMywyMzcsMTM2LDE2MywyMTgsMTcsMjcsNjYsMjI4LDEyNywyMTEsMjUwLDE0OSwxNjQsODUsMTA5LDE2OSwxODYsMjAwLDEsMjUxLDIwMSwxMDMsMTIzLDE4MywxNTUsODcsOTQsMTg3LDIzNSwxNzgsOTgsOTcsMjA2LDI1LDEwNSwxNjEsMjAyLDIzMSwxMjMsNjYsMTM4LDE0LDE3NywxMTQsMTYxLDU5LDE3Nyw0MCwxMywzOSwzMCw4NCw0OCwxODcsMjMzLDEzMSwxODYsMjA0LDE2Nyw5MSwyMjMsMjQzLDE5Myw5MiwyMTMsMTkxLDE0LDE0NywxNywxMzcsNCwzNiw5Niw1Niw0NSwyNywzNSwyMDEsMTkwLDE5MywyNCwxNzcsMTU0LDg2LDE5NywxNTYsMTY4LDE2OCwxMTUsMzEsMTI1LDIyOSwzNSw4MCw4OSw5OSwyMzcsMjUxLDE5MCw4MiwxLDEzMywxNTAsMjE0LDIwNSw4Nyw5LDE5NCwyMzQsMjM0LDg2LDE2OCwxNDQsMTkwLDIwMSw5NywxMTIsMTQxLDc0LDc2LDE0MCw5Niw1LDExNyw2Niw3LDI1NSw0MCwxNTksNDIsNDMsMTE5LDg0LDUsOTcsMSwyMTYsNzEsMTEsMTY3LDE0NSw2NSwyNTEsNTAsMTAwLDUyLDE3MCw0LDE5LDE5LDExOSwxNDAsMTAsMTAsODUsMTcsODQsMzcsMTA5LDI0MCwxOTQsMjMsMTY2LDIzNSwxMzEsNzYsMTg2LDM3LDEwNCwyMTcsMjksMjI3LDE1NSw2MCwxMDksNzUsMTAyLDE3LDEyOSwxNTQsMjI1LDIyLDk5LDE4MiwxNzAsNTYsMjUsMjMxLDE1MSw3OSwxNjEsNTAsMTAsMjI5LDMsNDAsMTk2LDI2LDE3OCwxMzQsMTQ1LDE3LDE1NSwxMTYsMTQxLDIwLDE3MiwxNDEsMTY5LDUsNDAsMjA5LDYyLDM1LDM2LDE0LDc2LDIzNiwxOTQsMjQyLDExNiwxODAsMjM2LDQyLDg0LDkxLDExOCwxMzksMjI1LDE3OSwxODgsMCwxMDUsMTMsOTksMTgzLDUzLDIyMiwyMTMsMTMxLDIzMiwyMjUsOTYsMTkzLDcxLDQsMTA0LDYsMTY1LDE3OSwyMzUsNDksMjA3LDExNSwzOCwxMjMsMTg1LDI5LDY1LDE4MSwxNzYsMTg1LDcwLDE2OSwxODEsMjQxLDIyLDQxLDkwLDY2LDEyMyw4OSwxNjEsMzAsMTQ4LDExNSwxMjQsMTk4LDY0LDY2LDEwMywxMDEsNTIsMTk3LDE5MCwxMzMsMTAwLDEzOSwxNDIsODMsOTcsMjUyLDEsMTMyLDIzMCwyMzQsMTgyLDIyMSwyMSw4OSwxMDUsMTI0LDEwOCwyMjAsMTkzLDE5NiwxNTUsMTU2LDE2MSwxNTEsMjQxLDExNyw2NCwxMjAsMjA2LDM4LDI0MSw5MywxMDYsMjEyLDI1LDE0MCwxNTQsMjcsMTgxLDI0MSwxMDEsMjEyLDM0LDEzOSw1MSw3LDk5LDM0LDE2Niw2MCw1MywxODIsNzgsMTkxLDczLDE1NSwyNTEsNTYsMTcxLDUzLDE5NywzNiw0MiwxOTksMTQ4LDI1MCwxOTYsMTkyLDEzNSwxMzQsMTAyLDI1NCwyOCwxMTcsMTI2LDg2LDUsMTU3LDUzLDE2NSwyMzgsMTM1LDE3OCwxODEsMzksNzYsMTQsMzQsODAsNiwyMjcsMTYyLDEyMCwxMzAsMTAzLDE3LDE4OCwxNzcsNTQsOTgsMTQwLDE5NSwxNzgsNjcsMTYwLDE2NywxNCwxNTIsNDksMTYzLDY3LDI1MCwxNTIsMjA4LDExNiwzMywyNDcsMTgyLDEyMiwxMTYsMTIzLDE2OSwxOTQsMTY0LDExMiwxNTYsNzQsMTQ4LDE0OCw2NywxMjUsMTE5LDM5LDExOSwxMjQsNTUsMTMzLDIxMCw1OSwxMjUsOTEsMTg3LDExNCwxNDUsNzEsMTcyLDE4MSw1MSw5MSwxNjEsNTcsNTUsMTQ4LDgxLDQ5LDE3NCwxMDgsMTUzLDIwNiwyNDIsNzgsMjM5LDE4LDEzMCwzMiwyMTEsMTI5LDIyMiw2NCw4LDEyOCwxOTMsMTI4LDE2LDEwNiw4NSwxNTAsMywyMDIsNzQsMTYzLDIwMiw4LDE5Nyw2MywxMzMsMjA0LDE4NCwxNDgsMTUzLDE4OSw2MiwxNjgsMjYsMTgzLDIxOSwxNTAsMjAwLDIxMSw1NCwyNDgsNzUsMTExLDIzNywyMDIsMTYsMTkzLDIyNSwxOTIsMTgyLDU5LDIwMiwzNiwyMzIsMTgwLDE5NywxMzAsMTIzLDE1OSwxNTQsMTIzLDIxNiwyNDAsMTYxLDIxMiwxNDUsMTEwLDE1MCw4MCwxMTgsMjA4LDkwLDEwNiw4MSw3MiwyMCw2OSw2MCwyOCwxNzcsOTAsMTY0LDE4OSwzOSwwLDgzLDgyLDk4LDEzMCw4MCw0NSwxNzcsNzksMTc3LDIzNSw0MSwxNDQsMjUsMzIsMjIsMTIyLDMxLDE0NSwyMTcsMTYzLDEwMSwyMjAsMSw5OCwxMDgsMTk2LDE3MSwxODYsMTMyLDI5LDI0MCwyMjUsMTEyLDQsNjYsMTAyLDExOSwxNDIsMjI2LDI0Myw0MCwxODQsMjUxLDEzOCw5MywyMDksMjIyLDIxNSwyMDgsMTEwLDI0MiwxNiwyOSwyNTIsNTIsMjIyLDkxLDg1LDE0Niw1Niw2OSw2NiwyMTgsNDYsOTEsMzksMjQsMjQ1LDU3LDI0OCwyMTQsNiwzOCw3OCw2NCw5MCwxMzcsNjMsNzIsMjksMjI0LDEyMCwxMzksMzgsMjksMjI0LDM1LDEwMCwxMDYsNzAsMTMzLDEzLDExLDEzNywyNDQsMTQwLDIzNSwyNCwyMjEsMTQxLDE3LDE1Niw0NiwxMCwxOTMsMjI4LDE2OCwxMzAsMTgxLDIzMywxNywxNDMsMTI5LDU1LDEwOSwyMCwzNSwyMjYsNDksMTY4LDEzNywxNDcsOTUsMTcwLDEzMCwyNDAsNjAsMTM5LDEwMywxNzQsMTE2LDk2LDE0OCwxODQsMTY0LDM2LDIyMywzMCwxMSw2OSwxMDUsNzcsMTk2LDE2NywxNiwxNDksMTg1LDI0NiwxNTMsMTI5LDE4MCwxMjAsMjQ0LDE1NiwxMiwxMzEsOTcsMjQyLDIyNyw3NCwxNDUsNzksN119fX1dAAAAAAAAAFgAAAAAAAAADUdyb3VwU3RhdGV7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAEiT3BlcmF0aW9uYWwiAAAAAAAAAFIAAAAAAAA6f1RyZWV7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAF7InRyZWUiOnsibGVhZl9ub2RlcyI6W3sibm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxMzQsMTY5LDEwNCwyMDcsMTM0LDE0NSwyMCwyNyw5OCwyMTQsNjcsNjQsMTAwLDkyLDkxLDc5LDE2OCwxNjgsMjgsMjA4LDc0LDIzMiwxMSwxNzcsODcsMjUxLDI1LDEsMjUwLDE3MSwyMDksMTYsMTYzLDE3NSwxNDAsNDEsOTIsMTUyLDIyLDgwLDgwLDEwNyw2OCwyNTEsMywxNTksMjA5LDEyNSw0OCwxNjUsMTA4LDIzNiwyMCwxMSw1NCwxMDAsMTg4LDIyOCwxNDQsMTc2LDE4NiwyMjAsMTQ3LDEwOCwxNiw5Myw5MywxNzYsNDMsMjEyLDY1LDM4LDE0NywxNjAsOCw3MiwyNywxMDQsMjI0LDI0MywxMzMsMTQyLDEwMSwyMDYsMjA0LDE5Nyw2Niw4OCwyNCwxNDMsMTA1LDEzNywxMDMsMCwxOTYsNDksMjQxLDIwNCw1Myw4NywyMiwxMjcsMTg4LDEzMiwzOCwxMTIsMTY4LDUwLDk2LDQ0LDY3LDI0NCwxMzksMTExLDE2NSw1NCw1MywxODYsMjE5LDg0LDEzMSwxMSw4MiwxOTAsOTYsMTgsMjMwLDE5Myw5NywyMDksODAsODUsNjQsNzMsNTQsOTMsMTU1LDE4OCwxNCw2LDM1LDE4MiwxMzIsMTcwLDExNiwyMzAsNDIsMzMsMjM1LDg1LDEyNiwzOSwxMDUsMTM5LDkyLDU3LDYsMTg2LDg5LDE1Nyw4Myw0MCwyMDcsMTc5LDE2MSw2MCwxNDAsMjA2LDE5OCwxNzEsMTE4LDIzMiwxMzQsODgsNjksMTQwLDg5LDEzNSwxMTcsNjIsMTU1LDI1MCw5NSwxNTIsMjI2LDMwLDMwLDExNCwxOTIsOTgsMjE3LDExNiw3NiwxNjgsMCwyMjUsMSwxNTcsMTkwLDE3MiwxMDMsMTQxLDkyLDE1NSwxOCwxMTcsNTgsMTMwLDE4MSwxOTYsMjcsNTgsNzksOTksODQsOCwxODksMTk0LDEyOCw1LDExNCwyMSwxNSw5MiwxODksOTUsMTMzLDE4MiwxNDksMTg2LDUyLDI0OSwzOSw3Miw4LDIxLDEwOSwxNCw1MywzNywxNzgsMTk2LDExNCwxNzksMTcxLDY5LDE4OSw0MSwxNTUsMTQsODMsMTU3LDE3MCwyNDQsMzksMTQ4LDI0NCwxNzAsODAsMTg2LDE1NSwxMDAsMjQzLDE4OSw1MCwxNzcsMTQ1LDIyNSw4NCwxOCwyLDcsMTQ5LDIxOCw4NCwxNzYsMTkyLDUwLDExOSw3NiwxMDAsMCw2NywyOCwyMDYsMjI4LDE0OSwxMDEsMTc3LDI0NywxOTksOTgsMTU0LDgsMjQ2LDIyMCw1MCwxLDExOCwxNjcsNjAsNzIsMTUwLDIyOSw1OCwxODksNDUsMjIwLDExOSwyMTgsNDAsMjgsMTg2LDE4LDE3NCwwLDIwOSwxNDAsMTcxLDE2MywxNCw5NCw5MiwxMzgsMjE3LDc1LDE0MCwxNzAsMjI3LDIwMCwxMjcsMTU1LDQ4LDE4MSwxMiwxMzMsMjI1LDI0OSwxNjAsNDEsMjA0LDI2LDEwMSwyMTksMCwxODQsMTU0LDIwNSwyMzMsMTk2LDE0MiwyMzIsMTIzLDMwLDIzNywyMTAsOTMsNjQsODMsODYsMTUwLDIwLDE4OSwxMDcsNTUsMjQsMTYsODQsMjMsMTE1LDE0NSw4LDExMSwyNyw0LDE4NCw1Niw0NCwyNDYsMjA4LDEwNiwxMTUsOTEsMTU5LDI0NCwxMjMsMTk2LDI3LDIxNiw5NywxNTAsMjA4LDIsMjUyLDYwLDE3OCwxOTAsMzksNiwyMiwxNDcsMTYwLDMzLDI0NSwyMSwxNjMsMjE2LDUsMTksMTM2LDE1NiwxMDYsMTU2LDEyNywyMzEsMTAyLDIwNywzNSw5NiwxMjksMTE0LDIwOCw4NiwxODAsMTE2LDExOSwxMjYsNzQsMTIsNjcsNiwxMzMsNDEsMTE4LDc2LDAsMjYsMjA2LDYsNSwxMDMsMTUxLDIwNCwxMzYsMTY0LDM4LDY2LDE0LDkyLDEyNSwxNjMsNTMsMTUxLDEzMCwyMzUsMTg0LDE1OCwxNDksMTYxLDIzOCwxOTksNzEsMjUxLDE4NywzNSwxODgsMjQsMzEsMTYzLDIzNSwxNjMsNjAsNjAsMTMwLDc5LDE1NCwyNSwyMTcsNjQsMTk1LDE3NCwxMzksODUsMTk1LDIwOCwxMzksNzMsNjAsMTk2LDEyOSw2NCwyMDMsMTY2LDEyOCwxMzksMjA0LDE4LDEyNywxMzgsMjI5LDc3LDE2OCwxNjEsMTkzLDIwNywxMDUsMCwxODAsMTA3LDE3Miw2NSwxMTcsNjMsNzQsMzYsMTY1LDE0LDUxLDEyNCwxNiwxMDcsMjMsODIsMTQ1LDEwNiwyNDcsMTQ0LDQ0LDE5MywxMjAsMywxMDQsMTY4LDQxLDE4OCwzNCwyMDYsMjUxLDE3MCwyMDUsMjAzLDExMiwxNzEsMTYxLDEzMyw3NiwxNDgsMTM4LDM0LDgwLDQxLDE2OCwxMjgsMjMsMjAzLDgxLDE0Nyw1MCw1MSwxNDUsMTk4LDE1MiwyMzQsOTYsNzIsMTg1LDUwLDIzMSwyNywxNDUsMjA3LDIxMSw0Miw0MCw4NiwzMSwyNTAsODYsODgsMjM2LDE5NywxNjksMTc2LDE2NSwxMzAsMjM0LDI0NCwxODQsMTU1LDE4NiwyLDE5OSw1NSw2OSw1NywyMDAsMTI4LDE1LDE5LDc4LDIzMSwyMTMsMTcyLDIwLDIxNCwzNCwxODksMjEyLDE4Myw0LDExLDE0MiwxODgsMTYwLDQ5LDE1NywyNywyMSwxNTQsMTY0LDE3OSwyMjAsMTY2LDE3NCwyMDYsMTMxLDExLDY0LDgwLDI4LDMxLDEyMSwxMTAsMTgxLDEyMiwxMzMsMjI1LDE0NywxNzksOTgsODksMTc5LDY2LDE2OCw0MiwyNDAsODcsMjA1LDE4NywxOTUsMTEwLDE5OSwyMjAsMTMsMTgzLDQ0LDE5LDEsMTUxLDU5LDE4MCwxNjEsMTkxLDEwMywxMjMsMTMsMjU1LDE2OCw3MCw4NCwyNiwyMDQsMTMwLDg2LDM4LDEzNiwyMywxMzQsMTU4LDEwMSwxMjgsMjUzLDIwMiwxMzksMTYyLDIxNCwzMCwxOTEsMTEyLDEyMCwyMDIsMTUwLDE3NywzLDE2NSw4MywyNDAsMTY0LDE2NiwyNDYsMTUyLDE0NywxOTksODQsMTUsMjAyLDIzNCwzMCw3NSwzOCw3Myw5OCw2NywxNjQsMTIwLDU0LDcsMTIyLDUzLDcxLDM3LDI1LDE5Nyw3NSwxODcsMTIsMTg5LDE5Nyw0MSwxOTAsMzIsMTIzLDIxNCwxMzksMjA1LDE3MiwyNDcsMTMzLDE1MCw3LDE5NSwxMjYsODAsMTIwLDIwMSw5OCwxNDIsMjE1LDg1LDIwMCwyMzQsNzUsNTAsMjE0LDQ5LDEwNiwyMTYsNTgsMTksNjgsMjEzLDczLDM3LDE0OCwxMzQsMjAxLDIzNSwxMDIsMTkxLDc1LDE4MCwyMTQsNTUsMTg3LDE5OSw4NiwyOSwwLDcsMjAwLDEzMywxMzUsNDIsMTg5LDE4MCwxNzgsMTQyLDM3LDEyMCwxMjgsMzYsNzAsMjM0LDEzMiw1OSw0NiwyMTcsMTQyLDgzLDg2LDY2LDE5MywxNjgsMTQyLDE5OCwxMDMsNjUsMTM5LDI0MywxNTEsMjksMTM5LDYzLDYzLDE4OCwxMjIsNDIsMzUsNjksMTUwLDk5LDExMSwxNDYsMTg0LDI1LDM5LDkwLDMzLDEyNiwyNDksMTg5LDEyNywxNzYsNjEsMTE1LDEwNSw5OCw5MSw1MywxMzUsMTE0LDEyMiwxNjAsODIsNzMsMTY1LDU3LDY4LDExMCwyMDgsMTI0LDEyNSwyLDE2OSwxMTgsMTE5LDg0LDM3LDEyOCw4NiwxNTAsNTEsMTA1LDg3LDI1NSwzMywyMDMsMjAwLDIzMSwxMDMsMTI5LDUyLDY0LDE4OCw4Miw1OCw2NiwxNjMsNTcsMjExLDEyMCwxMTAsMTg2LDE4LDg1LDEzMSwyMTgsMTksMTcsOCw3OCwyMDUsMTc3LDU2LDIyMywxMjAsOTIsNDMsMTk2LDcsMTI3LDE1Niw0Miw4MywxMDcsMTAsMjIzLDEzMCwxMCwyNDAsMjMzLDE4OSwxNSwxOTgsNDAsMjQwLDExOCw1LDQ1LDY1LDIxLDk1LDE4NywxNzksMTA2LDEzMiwxMTMsMTkyLDEwLDMwLDEzMywxNjQsMjEsOTMsOTIsMTU4LDE3MCwxMzksMTI2LDI0OCwyNDgsMTMxLDIyNywxODIsOTQsMTU5LDQsMzcsNTQsMTk5LDE4NywxNDUsMTE3LDEzMywxNyw1Nyw1NSwyMTIsMzUsMTEyLDE4NSwxMzEsOSwyMDksNjQsNzQsMTQ2LDIxNyw1MiwyMiwyMjQsNDksMTk1LDg3LDE3NCw2MCwyMSw4OCw3NiwyMDgsODcsMTk1LDIyNiw3MywyMDEsMjI5LDEyOCw2OCwyMzYsODQsMjI3LDI0MiwxNjQsNzksMTk2LDEzNCwxMTgsNjcsMTI4LDIsMTAsMTcsMjI2LDIwLDEyNiwxMzcsMywxODYsMTAxLDE0NCwyMDAsMTg5LDE1MywxMTQsMTYxLDE5OSw1LDkyLDE0OCwxMTIsNTQsMiwxNDQsNjAsMjE4LDAsMjMsMjMyLDYwLDI0MywyMTIsMTc1LDAsMzcsMjUsNDcsMjEyLDExMCwyMTYsNDgsNCwxNDcsMjI0LDU0LDE0LDcwLDIwMCwyMzMsMjEyLDU2LDE0LDIxNCwxMzUsNzksODEsMTUwLDExNiwxMzMsMyw3NSwyMzIsMTg4LDI1MywyMjAsMTM5LDIwMiwxNDQsNTYsODIsNTIsMywyNSwyMjgsOTcsOTgsMjUyLDIwMSw3NiwxNDAsMTksMTQ0LDk4LDEwMiwyMDIsMTM2LDE4Nyw1MCwxOTIsMTAzLDQ0LDg2LDk3LDEyNywxMjAsMTIsODgsMjM2LDE2Myw4MCwyMTQsMTg0LDIyMCwyMTUsNDAsMTM5LDExNyw3MSwyMTksMTgxLDExNyw1MSwyMTIsMTI0LDEwMiwxMTMsMTAxLDMxLDE0Niw0NiwxOTEsMjAxLDk5LDYsMjI4LDEyMiwyMjgsNzEsMjA3LDkwLDkyLDU0LDcwLDI1MCwxNjEsMjIxLDEzOSwxMTEsNDYsODUsMTgwLDE2NSw3LDU2LDEyNSwyMSwzNCw2NywxMTksMTEyLDE2NSwxMSwxOTcsMTAwLDY1LDY3LDIyMSw1OSwyMzQsMTg5LDE5NSwyMDMsMTYyLDE1OSwyMDMsMTk5LDE1OCwxODIsMTY1LDEsMTkyLDE1NSwxMTUsMjksMTc5LDIzMywzNSwyMTUsOTUsMTksMjI0LDIsMTksODMsMjE2LDEyLDgxLDE5OCwxODMsMTgwLDAsNTgsMjQ4LDM5LDM5LDI1Myw4NCw1MCw5NCwyNTQsMjI1LDIxMiwxNSwxMCw4OCwyNTMsMjEwLDksMjQ2LDM3LDIyNCwxNjUsMTg1LDksNiwzMywwXX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6WzE2NCwxODAsMTI1LDEyNiw3OSwyMjAsMjIxLDI1MywxMjMsNDIsMjAxLDEyMCwxODAsMTY0LDIwMCwyMDgsMTc3LDk5LDgyLDYwLDU1LDE1NiwxMjYsNzcsMTE3LDExNSwyMDMsMjAzLDE0MiwyNTUsMTY2LDM0XX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTcsMTA4LDEwNSw5OSwxMDFdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IkNvbW1pdCI6eyJ2ZWMiOlsxNjUsMjQwLDIyMiwxNDUsMTkxLDE5OSwyMDEsMjA4LDc2LDIwMywxNjIsMTc5LDE0MiwyMzUsMTE3LDIyNywxMzQsNTYsMTE1LDM5LDgyLDUzLDE1NCw0OSwxNzcsMjE5LDg5LDIwOSwxODQsMywxMzksMjA5XX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzEzMiwzMCwzOSw4Myw2OSwxMDcsMTg5LDM2LDEwMSwxMDQsMTcwLDIyMCwxMzQsMjUxLDQxLDQ1LDE2NCw5NiwzOSwyNDIsNTcsNTksMTY4LDgzLDg0LDE2MywxMzksMTg5LDIzMSwxMjgsMTI3LDE5NSwxOTAsMTU0LDEyMiw1NCwxMjYsMTU3LDEzMCw1OSw3MCwxNDQsMTAxLDMyLDE3MCwyNSwyMDgsMjA0LDI0NywxMzQsMTU1LDIwOSw5OSwxMTUsNTQsMTM3LDIzLDEyOSwyMTksMTQzLDE1MiwxNTYsMTAwLDEzXX19fX0seyJub2RlIjp7InBheWxvYWQiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzcwLDE4MCwxMzgsNzEsMjQyLDEwOCw2MywyNDAsMTg5LDE5OSw0MSwxMTAsODksODksMTk1LDE0NSw4OSw3NCwzMywyMTMsMTQsMTY3LDkxLDEwMywxNjMsNjYsNywyMTAsMjM2LDksNTAsMjQwLDEwMCwxNTMsMTAxLDI4LDg1LDksMTYsMTYzLDE3NywxMjAsNjQsMjQ3LDExLDksMTMzLDk1LDE1OCw4OCw2MiwxNDUsMjUyLDEwOSwxMzQsMjMwLDkyLDIzMiwyMDQsMTAxLDIxNyw2MCwxNjksMTI2LDkyLDIwMywyMzgsODYsMjEsMjMzLDg0LDQ1LDE1NSwxMjksNDIsMTM3LDE1MCw1OCwxMDgsNDEsMTYxLDExMywxNDgsMTc1LDg2LDE1NiwxNiw5OCw3NSwxMzgsMTIyLDcsMzMsMTM1LDkxLDc3LDI0MiwyMywxOTEsMjQzLDQ4LDksMjUsMTAwLDQ0LDI0OCw3MywxMjQsNzEsNzQsMTQ3LDIyMCw0OSw0MywyMjgsNTEsMTg2LDEyMCw5NiwxODksMTc1LDM4LDExNSwxMDgsMTEyLDE2MiwxMDMsNTgsNDcsOTQsMjQ2LDQ4LDI0Niw2NiwxMDksMCw2Nyw2NywyMjksMTQ3LDY0LDEzNywzLDE2MywxMTksMTc5LDYzLDEwNSwyMzEsNDYsMTgwLDk4LDEzMSw4OCw0OCwxNDYsMTA0LDIwOCwxMzQsNiwyMCw1LDcsMjMzLDE0NiwyNDgsMTM1LDExNSwxNjcsODEsNzMsMTE5LDEzNyw4MSw5MCwxNzcsNDMsMTY3LDIyLDQ5LDIxLDI1LDExNiwzMywxMzAsNjIsMTEwLDIxNywxOTUsMTU2LDEwLDE3MiwxMzAsODYsNTgsMjEzLDU4LDEyOCw1Miw2NywzMywxNiwyMTksODMsOCw0LDE4MCwxMTksMTc2LDE5NywxMDcsMyw3OSwyMTYsMjQ0LDEwOCwyNDIsMzksNjQsMTY3LDI0OSw0NiwyMzksMTM2LDE2MSwxODAsMjI4LDE2NywxOTMsNSw0MSwxNTYsMTQ5LDEzOCwyMjAsMTQ3LDE0NywxMDcsMTI4LDY1LDgzLDE4MiwxMzIsMjUxLDIzNSwxNjAsMTk0LDIyOCw3OSwxNTIsMTQ1LDE3MCwxNDYsMTIyLDE2LDIwNiwxNzgsNjEsODQsMjE5LDIxLDksMjUxLDE4OCwyMTcsNjcsMzUsMTQ3LDIzMiwyNyw4NiwxNiwxMTAsMTMzLDE1Myw2MywzMCwxOTMsMjAxLDg4LDIzNSw3MiwyNTQsMTY3LDIxLDkzLDg1LDUsNjIsMjQ3LDc2LDE0LDg3LDEwNCwxNzYsMTY0LDEzLDE1NCwyMTUsMTA0LDEzNiwxMzIsMTQyLDU2LDIzMSw5NiwxNTksMTY4LDI0LDE2NywxMDEsMTQyLDEyNyw5MiwxMywyMzYsNjUsNTUsMTAwLDE3NiwxNDAsMTY5LDY3LDY4LDY4LDcyLDExNCwxOTcsMjExLDExOSw5MiwxMzgsMTk3LDIxMCwxOTksMTMyLDE2Niw1MCw1NCwxNDYsMTE1LDQwLDM4LDE3LDY4LDIzNiw0Myw4NSwxOCw4OCwxNDksMjQyLDgyLDgyLDIwMCw5NywxODAsOTcsNTEsOCwxMTcsMTk4LDExNywyMDEsMTYwLDU1LDExNiwxOTMsMTQwLDE0OCwxNyw0LDYyLDUzLDExNywyMTgsNTQsNzcsMTY3LDIxNCwxMSwyMDEsNDEsMSwxNSwxODYsMTcxLDIyNyw0NCwzNiwxMSwxOTksMjA0LDM2LDI0LDE3OSwyMjAsNTMsOTksMTgwLDEzNCwxNiwxNzgsMjI4LDQyLDE3OCw2OSwxNTEsMjA3LDEyMCw4MSwyMDIsMTE4LDE2MywxMDUsMjA0LDU0LDU5LDE5MywxMDQsMjAwLDE2OCwxNzYsNzMsMjUwLDY3LDI0NSwxNzIsMjksNzMsMTAxLDExMCwzOSwxMDQsMjUsNTksMTMzLDkyLDc1LDEwMSw4NSwxMzksMTE4LDE3NSwzNSw3LDEwNywyMTQsMTIsMTU0LDI0Niw1NiwyMCwxMDksNTMsNDgsNzksNzIsMTEyLDE1Niw4LDkxLDI1MiwzMiw3MSwxNzcsMjQzLDEzOSwxODQsMTk2LDEzNSw3Miw2NywxMjEsNDYsMjQ0LDEzMCwxMjEsMjQ4LDE1NSwyMjUsMiwxMDgsMTY4LDUwLDEwOCwxLDEwMiw1Nyw1OCwxNTAsMTI2LDEyMCwxMDUsNDgsOCwxOTksMTAsMTYwLDE4MSwxMzIsMywxMjMsNTMsMTYyLDE3LDE5MywyMDIsMTg4LDE0OSwyMjUsMjYsODMsMTMyLDExNSwxMDcsMTg2LDExMyw5OSwyOSwyNTIsNTQsMjQ3LDE1MywxNjUsMTQ4LDE0NywzOSwzMCw0OSw2Niw5NywxNjIsMTMwLDQsMTA1LDE2MywyMDAsNzMsMjA2LDc0LDE4Myw2Miw4NiwxNjYsMTg4LDEwMywyMjAsNTgsMTgwLDE2Miw1MCwxMTksMjA5LDExNSwxNjksNjQsMTMwLDEwLDkwLDQ3LDc0LDgsMTYwLDM3LDY0LDExOCwxOTMsMTUwLDEyLDQxLDI1MSwxMSw3NSwxNjQsMTMyLDE5NywyMzYsMTQ2LDIzNiwxMzQsMTMyLDI0MCwzOSwxMDYsMjQ0LDI0NSwyMCwxMzQsMjI1LDgxLDI1LDE0MCw3MiwyNTIsMTM3LDI4LDUyLDEzMSwxNjUsMTcyLDEwOCwyMDMsMjgsMjA4LDc3LDIyMCwxODMsNzYsMjA4LDczLDM4LDIzNiwxODAsMCwxOTksMTE5LDM4LDM5LDQ5LDYwLDQzLDIxNywyOCwxNiwzNiwxODAsMjM1LDExOSwxMjksMTcwLDcxLDE4OSwxNzcsMTM5LDcxLDE1MiwxMjAsMTc2LDEyNiw1OCwxMTQsMTMyLDczLDUwLDE5Niw3LDE3NCw0NSw4NCwxMDMsNzAsOTEsMTgyLDEzNSw2OSw5NSwxODUsMjUwLDEzNSwxNjYsMTYyLDE0NywxOTQsMTk3LDExNCw5MiwyNyw5OCwyMzQsMjMyLDE0MywxMDAsMTQ4LDEzNCwyMDgsMjI3LDMwLDUzLDI0OCwxMTAsMTc1LDI0NCwxODYsMzIsMTI0LDcsMTY4LDI0MCw1MSwyMDMsMjQ5LDIyLDYsMTk0LDcwLDExMSwyMSwxMTgsMywxOTIsNDIsMTc3LDI0MCwxNiwxMTcsMTgxLDI3LDQxLDIwMiwxNSwzOSw2NiwxODEsMjAxLDY2LDg3LDE3OSwxMjksMTAwLDExNCwxNDQsNzcsMTI2LDkyLDIwMiwyMjAsNjQsMTE3LDE0MiwyOCwxMzIsMjE2LDI0OSwxNzcsNTEsMTUwLDEwMiwyMzksMTIzLDMwLDE5LDgwLDIwNCwxNjAsMjMsMTM3LDExNiwxNTYsMTI1LDEyOCwxMzEsOTksMTg4LDYsMjAsMTQ0LDE1MywyNCwyMjcsMjEzLDgwLDI0OSw0MSw2Nyw2NSwxLDQyLDI0NCwxNDYsMTI5LDE4Myw4MywxLDE5NCwxNjQsMTQsMTcxLDE4NCwxMjQsMTI4LDExNyw3MywxMTQsNDksMTc3LDE5Myw4NCwxNTUsMTUyLDAsNTgsNTksMjQ1LDEyMSwxMjcsMjEzLDEzMCwxMDYsMTc5LDcsMjE5LDE2OSwyOCw3MiwxMTcsNSwxOCw5MCwxODQsMjQwLDgyLDE3MCwyNTAsMjQ1LDYzLDQwLDE4Miw2OCw4NCwxNTUsMTc0LDUxLDE3NiwxMjgsMTAwLDExLDE1MSw4NSwyNTAsMTg2LDExNiwyNywyNSwxNTYsMTcxLDUxLDE2NCwxOTcsMjAzLDE4NywxODAsNDYsMTQ3LDIxNSw2NCw3MCwxMTYsMTYsMjE3LDIyOSw5OCw1MSwxNTAsMTQ3LDIxNiwxNzcsMTQ2LDE5MSwxNTMsMTQzLDM2LDIzLDMxLDIxOCwxOTksMTYyLDIwLDIxMiwxMCw3MCwxNjQsNTQsMTYsNjUsMjQsMTE5LDE3Niw0LDIwOCwxNTEsMTg4LDUxLDcxLDE4OSwxMDksMTY2LDE1NiwyMTEsMTU2LDE4NywxOTgsMTM4LDUzLDEzOSwxNTQsNDMsODcsMTUwLDQ5LDE3OSwyNDAsNTEsMTEwLDExOCwxMzIsMjEwLDkwLDEzMCwxNTQsNjQsMTMwLDIxMywyMjcsMTg2LDUxLDEwNywxOTEsOTEsMTU0LDQ3LDEzNCwyMDgsMjA1LDIxMywyMTIsMjA2LDUsMTI4LDE4NywxMDcsMTMzLDEwMSwxOTEsMTE1LDE4LDEzOCwxMDUsMjcsOTgsMjI1LDEzMywyMTgsODEsMzgsMTE5LDIxNyw0OCwxMzYsMjEwLDIwNCwxMjAsMTY3LDcyLDk3LDEzNSwxMDYsMjAzLDM0LDE2LDQ1LDE1NCwxOTAsOTIsNTEsNDYsMjA5LDk2LDE4MCwxNjgsMTAwLDQwLDI1MCwxOTIsMTQ3LDIxOSwxMDUsMTgzLDg3LDQzLDE1OSwxODUsMjQ3LDUzLDIzOCw0NCwxODAsNDYsMTgsMjgsMjE2LDE2NSwxMDEsMTYwLDIzMSw1Myw2MywxMTIsMTAzLDIxNywxODYsMTAyLDEyOSwxOCwxNDEsNzYsMTE5LDczLDIxMiw4MCwxNDcsMTU3LDk4LDEyNSwxMjIsMjAzLDU3LDI1LDE5NywxNSwxODcsMjE5LDMsMTI1LDgyLDEwMyw0MCwwLDQ3LDIyOSwyNSwxMTcsMjQ2LDIwLDE5MiwzLDIwMCwxLDE4MCwxNTAsMjA1LDIwMSw1NCwxMDYsMTgxLDExMyw0Myw4Myw0Myw1NCw3MiwxMDUsODAsMjUsNTksMzcsMTc1LDIxNCwxMjMsMzMsMTUzLDExLDIyMSwxOSwxMzEsMTMyLDI0MCw4MCw5NSwyNTEsNCwyNTQsMjUwLDgwLDEzMywxODcsMTgyLDExMiwyNDUsNzUsMTI0LDEwNywxMjEsNCwyNDAsMTk4LDI0MCwxNjIsNzIsMjI4LDI1MiwxMjAsNzcsMCw3MiwxODEsMTk4LDI5LDEwMiwzNywxODEsNDUsMTk3LDk3LDE1LDIzLDE4NCwxNjgsMTAyLDUxLDY0LDExNSwxMTMsMjM3LDIyNSwxMzgsODksMiwxMjgsMjM5LDE4MSwxNzUsMTAyLDIxMSwxNjAsNTQsMTgyLDM1LDIzMyw1MCw5LDEwNCwxMDAsMTMxLDI2LDg1LDQ4LDE1Nyw2Nyw2OSw3MywyMDMsMTI4LDQsMTcyLDE1OSwyNDMsNzQsMTQyLDE5NiwxNjksMTksNzksMTUyLDIsNiwzMCwxMzIsMTcxLDEwMywyMjEsNywyMTEsMTY5LDc4LDIzNSwyMDYsNjksMjgsMjUyLDEzLDY5LDEyNSw2NCwyNTQsMjQ3LDE3LDE2MCwyMCwyMDIsMTQ2LDAsMjMyLDAsMTIsMTcxLDk2LDc2LDEzMywxMzQsMjQzLDU5LDI0MCwxNTAsMTQ5LDk1LDIwOSwyMTksMTk5LDczLDE4OCwxMDUsMTAzLDEwMSwxODUsMjQ1LDEzLDk1LDIyMiwyMDQsMTYyLDQ1LDEzOSwzMiwxMDUsNV19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyMzksMjM3LDI1MSwxNTIsMjMxLDE0MCwyNTIsMzMsMjM3LDE3NCwyNDIsMjQxLDEyNCwxMDMsMTMwLDI0LDc2LDEwNiwxNDUsMjI3LDAsNTEsNjgsMTEyLDE2MCw0Niw0Miw0OSw4MiwyMzMsNzcsMTE3XX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTgsMTExLDk4XX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJLZXlQYWNrYWdlIjp7Im5vdF9iZWZvcmUiOjE3MjA2ODg5NTAsIm5vdF9hZnRlciI6MTcyNzk1MDE1MH19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzIyMiwxNzksMywzMiw5NCwxMjcsNjYsMjQ5LDE4OCwxMDcsNzcsMTg2LDEyNiwxODksMTM1LDUyLDY4LDQwLDE3MiwxMTAsMTM1LDI0NCwyMDgsOTUsMTY3LDIyMywxNzcsMTgyLDE2MCw0NiwxLDQ1LDEwOCwxOTEsNzIsMTE5LDE5NiwyMiwxNTAsMTk0LDUzLDIyLDIwMyw5MSwyMjMsMjA0LDE1MSwxNDQsMTI2LDIwMywyNDksMTIxLDYyLDQ1LDQsMTQ0LDg5LDI3LDE4MCw4NCwyMzYsNjYsNTksMV19fX19XSwicGFyZW50X25vZGVzIjpbeyJub2RlIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxMTYsMTY2LDYyLDEyOSwxNzcsMTYzLDEyNCwyMTQsMTA4LDgwLDg2LDE0NSwyOCwxNDQsNjQsMTg1LDQsODksNjAsMTE2LDMzLDE5LDIyNSwxNTcsNzAsMTIzLDEzMyw1MywxODAsODksNjcsMTQ5LDQzLDY2LDE4MywxNDMsNDcsMzQsMTgwLDg3LDE2LDExLDExMCwyNTEsNjEsMjAyLDIzMywxNTMsOCwxMDIsOTEsMTk4LDQ5LDU5LDE2MCwxOTgsODYsNTgsMjQwLDE1OCwxNTksODEsMjA3LDk0LDIwOSwxMjAsMjI4LDg0LDU1LDIzOSwyMiwxOTcsMTAzLDIzNCw3NywxOTgsMjQxLDQ3LDksODAsMTYyLDE4NiwxNTQsMTgyLDI2LDEzOSw4NiwyNDEsMjAsMTA0LDE2OSwyMTksMTM3LDIwNyw4LDE4LDE1NCwxNiwyNSwxMTksMTQ2LDE4NiwxNTMsODksMiw5LDEwNCw0MiwzNiwxNiwzNywyMSwxOTUsOTUsMzksMTk2LDE1NCwxODUsNzQsMTMyLDI0Niw4OSwxNDUsMTIwLDIyNywyMSw2MiwxODIsMTAyLDIzMiwyNTIsMiwxNzksMTY5LDQyLDE0NSwxMDMsMTkxLDIwNSwyMzQsMTE2LDE5MCwxMDgsMTQyLDk5LDU5LDQ1LDEwMSwxMjEsOSw2MywxNjcsMTk0LDg0LDEwMiw0OCwyMywyMTAsMTE4LDIyNywxNTIsMTM1LDE2Myw0Myw0Miw4NCwyNDQsMzcsMjA1LDEzNSwxNTEsMTE1LDE1MCw4OCwxODAsMjMzLDE0Niw2OSwxOSwyMDcsNjYsNDIsMTIzLDE3MiwyNDgsODgsMTgzLDE2OSwzMCwzNSw1Miw3Niw4NSwxNTMsMTU4LDksMTE1LDkwLDI1MSw5OSwxNSwxNjQsMTYyLDIzLDg2LDE1MCwxNzIsODUsMTAxLDEyOSwyNDEsMTM0LDE5OSwxMjQsMjUsMCwxOTAsMTQ2LDM0LDcxLDI0LDk2LDM4LDIxLDYwLDE5MSwxNDAsMTczLDI1MiwxMTMsOTUsNjAsNzUsNDksNTksMjQ0LDIwMywyNDEsMTI5LDY5LDIzNSwyMiwzMiwxNSwyMzYsMTkwLDEyMiwxMDEsNjQsMTExLDcsMTcxLDIyOCw1NywxMjEsMTE0LDIwMywxMywxMDMsOSwzNCwxNSwzNiwyOSwyMjIsMjI3LDE5OCwxNTQsMzMsMTExLDEzNywxNjgsMTE4LDEwNSwyMzEsMTAxLDYxLDM1LDE4MCw3OCw4OSw0MywxNDAsOTAsMjYsNTAsMjEsMTQzLDI0MSwyMTIsNzcsMTMsNDgsMTcxLDMzLDE2MywyMDMsMjA4LDE4MSwxOTQsMTA4LDgyLDEyNSwxMTcsODIsNjksMTMsMTQ4LDgzLDQ1LDY1LDY3LDExMSwxOTcsODYsMTAzLDE2NiwzMCwyNTMsMjUyLDQ5LDM1LDU3LDE4Myw3NSw5MSwxNDEsMTg2LDkxLDE3MCwxNDcsMjUxLDE2Myw0MiwxODEsMTc0LDIyOCwyNCwyMywxNzcsMjE1LDc2LDIwNiwyMTksNTIsMjUyLDg2LDkyLDY0LDE2OCwyMiw3OCwxODcsMTQ0LDc4LDg4LDEwMSwyMTgsMTQ2LDEwNSwxNjYsNiwxMzQsMTU2LDY2LDE5MSwxODUsMTk5LDE4NiwxMiw1LDk2LDEyNSw2NCw0NCwxNDIsMTIsMTcxLDEyOSw4NCw3Niw3MSwyMTYsOTYsMzMsMTQ1LDUyLDI1NSwxNDYsOTEsMTM1LDU1LDE5NywzMywyNDQsMTYyLDY4LDk3LDQ4LDY3LDg5LDEzMywyMDMsMTg2LDEwMCw4MywxODUsNzAsMTE4LDU5LDE4OSwyNDgsMjEzLDE0Miw5NSwxOTYsMTEyLDE3OSwxNDgsMTg3LDcsMTA4LDI4LDIzNSwxMzIsMSwyMDAsMjI4LDE4MywxNjQsMTM1LDE2LDgyLDI4LDE2NiwzMCwyMzEsMTMzLDg1LDI1MCwxMzgsODksMTk2LDExOCwxNzIsNjUsMTkwLDIzMiw4LDEzLDU4LDgzLDcyLDIzOSwxMDMsNDYsOTYsMzYsNTUsODksMTg3LDM2LDI1LDIxNiwxMDQsMjAwLDM0LDc1LDIyMCwyMzQsMTEyLDIyMywwLDEyNiwxMDYsMjE2LDE5MiwxNDksNDMsODYsMjAsMTcxLDExNSw4MywyMDMsMTIsNDksMTg0LDgyLDIzOCwyMTMsMTQwLDU0LDE1MSw5LDkzLDE3Nyw4Miw1NCwxMjEsMzIsMTI1LDMyLDExMSwxMTksMTg1LDEwMSwxMzQsMjQxLDE0NCwyMjcsMjE2LDI4LDM4LDIyOCw1LDM0LDExNCwxMTEsMjksMjA5LDIwNywxMjUsNDgsMzksMjMxLDEyOSw3OCwyMjksOTEsNzQsNSwyNTIsMTYwLDE2NiwxNDgsMjAsNDgsMTQ3LDIwMiwxOTksMjQ3LDE3MCwyMzEsMTI5LDgzLDIyNCwxNjcsNDksMjM0LDEzNiwxNjMsMzQsMjI4LDExOSwxNTAsMTYsNTgsMTg2LDE5OCwxMzMsNCw2OCwxNTksMTc1LDgxLDE0MCwyNDMsMjQsODAsNzksMjQ0LDEwOCw4MCwxMDMsMTQzLDE2MSw4OCwyMDMsMjI1LDE2MywxNjQsMTk3LDUsODIsMjcsMTM4LDY5LDI0MCwxODYsOTEsMjMzLDEzMSwxNTgsMjAyLDQwLDkwLDgxLDE2MCw4MiwxNDMsMTM3LDE2NCwxMzEsMjAsMTczLDE1MywyNSw5NSw4MCwyNiwxODEsMzgsMTQ4LDU0LDE5NiwxMDQsMjMsMjM3LDEzNiwxNjMsMjE4LDE3LDI3LDY2LDIyOCwxMjcsMjExLDI1MCwxNDksMTY0LDg1LDEwOSwxNjksMTg2LDIwMCwxLDI1MSwyMDEsMTAzLDEyMywxODMsMTU1LDg3LDk0LDE4NywyMzUsMTc4LDk4LDk3LDIwNiwyNSwxMDUsMTYxLDIwMiwyMzEsMTIzLDY2LDEzOCwxNCwxNzcsMTE0LDE2MSw1OSwxNzcsNDAsMTMsMzksMzAsODQsNDgsMTg3LDIzMywxMzEsMTg2LDIwNCwxNjcsOTEsMjIzLDI0MywxOTMsOTIsMjEzLDE5MSwxNCwxNDcsMTcsMTM3LDQsMzYsOTYsNTYsNDUsMjcsMzUsMjAxLDE5MCwxOTMsMjQsMTc3LDE1NCw4NiwxOTcsMTU2LDE2OCwxNjgsMTE1LDMxLDEyNSwyMjksMzUsODAsODksOTksMjM3LDI1MSwxOTAsODIsMSwxMzMsMTUwLDIxNCwyMDUsODcsOSwxOTQsMjM0LDIzNCw4NiwxNjgsMTQ0LDE5MCwyMDEsOTcsMTEyLDE0MSw3NCw3NiwxNDAsOTYsNSwxMTcsNjYsNywyNTUsNDAsMTU5LDQyLDQzLDExOSw4NCw1LDk3LDEsMjE2LDcxLDExLDE2NywxNDUsNjUsMjUxLDUwLDEwMCw1MiwxNzAsNCwxOSwxOSwxMTksMTQwLDEwLDEwLDg1LDE3LDg0LDM3LDEwOSwyNDAsMTk0LDIzLDE2NiwyMzUsMTMxLDc2LDE4NiwzNywxMDQsMjE3LDI5LDIyNywxNTUsNjAsMTA5LDc1LDEwMiwxNywxMjksMTU0LDIyNSwyMiw5OSwxODIsMTcwLDU2LDI1LDIzMSwxNTEsNzksMTYxLDUwLDEwLDIyOSwzLDQwLDE5NiwyNiwxNzgsMTM0LDE0NSwxNywxNTUsMTE2LDE0MSwyMCwxNzIsMTQxLDE2OSw1LDQwLDIwOSw2MiwzNSwzNiwxNCw3NiwyMzYsMTk0LDI0MiwxMTYsMTgwLDIzNiw0Miw4NCw5MSwxMTgsMTM5LDIyNSwxNzksMTg4LDAsMTA1LDEzLDk5LDE4Myw1MywyMjIsMjEzLDEzMSwyMzIsMjI1LDk2LDE5Myw3MSw0LDEwNCw2LDE2NSwxNzksMjM1LDQ5LDIwNywxMTUsMzgsMTIzLDE4NSwyOSw2NSwxODEsMTc2LDE4NSw3MCwxNjksMTgxLDI0MSwyMiw0MSw5MCw2NiwxMjMsODksMTYxLDMwLDE0OCwxMTUsMTI0LDE5OCw2NCw2NiwxMDMsMTAxLDUyLDE5NywxOTAsMTMzLDEwMCwxMzksMTQyLDgzLDk3LDI1MiwxLDEzMiwyMzAsMjM0LDE4MiwyMjEsMjEsODksMTA1LDEyNCwxMDgsMjIwLDE5MywxOTYsMTU1LDE1NiwxNjEsMTUxLDI0MSwxMTcsNjQsMTIwLDIwNiwzOCwyNDEsOTMsMTA2LDIxMiwyNSwxNDAsMTU0LDI3LDE4MSwyNDEsMTAxLDIxMiwzNCwxMzksNTEsNyw5OSwzNCwxNjYsNjAsNTMsMTgyLDc4LDE5MSw3MywxNTUsMjUxLDU2LDE3MSw1MywxOTcsMzYsNDIsMTk5LDE0OCwyNTAsMTk2LDE5MiwxMzUsMTM0LDEwMiwyNTQsMjgsMTE3LDEyNiw4Niw1LDE1Nyw1MywxNjUsMjM4LDEzNSwxNzgsMTgxLDM5LDc2LDE0LDM0LDgwLDYsMjI3LDE2MiwxMjAsMTMwLDEwMywxNywxODgsMTc3LDU0LDk4LDE0MCwxOTUsMTc4LDY3LDE2MCwxNjcsMTQsMTUyLDQ5LDE2Myw2NywyNTAsMTUyLDIwOCwxMTYsMzMsMjQ3LDE4MiwxMjIsMTE2LDEyMywxNjksMTk0LDE2NCwxMTIsMTU2LDc0LDE0OCwxNDgsNjcsMTI1LDExOSwzOSwxMTksMTI0LDU1LDEzMywyMTAsNTksMTI1LDkxLDE4NywxMTQsMTQ1LDcxLDE3MiwxODEsNTEsOTEsMTYxLDU3LDU1LDE0OCw4MSw0OSwxNzQsMTA4LDE1MywyMDYsMjQyLDc4LDIzOSwxOCwxMzAsMzIsMjExLDEyOSwyMjIsNjQsOCwxMjgsMTkzLDEyOCwxNiwxMDYsODUsMTUwLDMsMjAyLDc0LDE2MywyMDIsOCwxOTcsNjMsMTMzLDIwNCwxODQsMTQ4LDE1MywxODksNjIsMTY4LDI2LDE4MywyMTksMTUwLDIwMCwyMTEsNTQsMjQ4LDc1LDExMSwyMzcsMjAyLDE2LDE5MywyMjUsMTkyLDE4Miw1OSwyMDIsMzYsMjMyLDE4MCwxOTcsMTMwLDEyMywxNTksMTU0LDEyMywyMTYsMjQwLDE2MSwyMTIsMTQ1LDExMCwxNTAsODAsMTE4LDIwOCw5MCwxMDYsODEsNzIsMjAsNjksNjAsMjgsMTc3LDkwLDE2NCwxODksMzksMCw4Myw4Miw5OCwxMzAsODAsNDUsMTc3LDc5LDE3NywyMzUsNDEsMTQ0LDI1LDMyLDIyLDEyMiwzMSwxNDUsMjE3LDE2MywxMDEsMjIwLDEsOTgsMTA4LDE5NiwxNzEsMTg2LDEzMiwyOSwyNDAsMjI1LDExMiw0LDY2LDk2LDE0OCwxODQsMTY0LDM2LDIyMywzMCwxMSw2OSwxMDUsNzcsMTk2LDE2NywxNiwxNDksMTg1LDI0NiwxNTMsMTI5LDE4MCwxMjAsMjQ0LDE1NiwxMiwxMzEsOTcsMjQyLDIyNyw3NCwxNDUsNzksN119fSwicGFyZW50X2hhc2giOnsidmVjIjpbXX0sInVubWVyZ2VkX2xlYXZlcyI6eyJsaXN0IjpbXX19fV0sImRlZmF1bHRfbGVhZiI6eyJub2RlIjpudWxsfSwiZGVmYXVsdF9wYXJlbnQiOnsibm9kZSI6bnVsbH19LCJ0cmVlX2hhc2giOlsxMjUsMTE1LDI0NCwxMzcsMjM2LDE1NywyNCwxMzQsMTMwLDczLDEwMSwyMTQsNjAsODYsMTg4LDkyLDEsMjQzLDc1LDQ2LDg1LDYwLDIyMCwxOTAsMTI3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NiwyMzAsNDIsMzMsMjM1LDg1LDEyNiwzOSwxMDUsMTM5LDkyLDU3LDYsMTg2LDg5LDE1Nyw4Myw0MCwyMDcsMTc5LDE2MSw2MCwxNDAsMjA2LDE5OCwxNzEsMTE4LDIzMiwxMzQsODgsNjksMTQwLDg5LDEzNSwxMTcsNjIsMTU1LDI1MCw5NSwxNTIsMjI2LDMwLDMwLDExNCwxOTIsOTgsMjE3LDExNiw3NiwxNjgsMCwyMjUsMSwxNTcsMTkwLDE3MiwxMDMsMTQxLDkyLDE1NSwxOCwxMTcsNTgsMTMwLDE4MSwxOTYsMjcsNTgsNzksOTksODQsOCwxODksMTk0LDEyOCw1LDExNCwyMSwxNSw5MiwxODksOTUsMTMzLDE4MiwxNDksMTg2LDUyLDI0OSwzOSw3Miw4LDIxLDEwOSwxNCw1MywzNywxNzgsMTk2LDExNCwxNzksMTcxLDY5LDE4OSw0MSwxNTUsMTQsODMsMTU3LDE3MCwyNDQsMzksMTQ4LDI0NCwxNzAsODAsMTg2LDE1NSwxMDAsMjQzLDE4OSw1MCwxNzcsMTQ1LDIyNSw4NCwxOCwyLDcsMTQ5LDIxOCw4NCwxNzYsMTkyLDUwLDExOSw3NiwxMDAsMCw2NywyOCwyMDYsMjI4LDE0OSwxMDEsMTc3LDI0NywxOTksOTgsMTU0LDgsMjQ2LDIyMCw1MCwxLDExOCwxNjcsNjAsNzIsMTUwLDIyOSw1OCwxODksNDUsMjIwLDExOSwyMTgsNDAsMjgsMTg2LDE4LDE3NCwwLDIwOSwxNDAsMTcxLDE2MywxNCw5NCw5MiwxMzgsMjE3LDc1LDE0MCwxNzAsMjI3LDIwMCwxMjcsMTU1LDQ4LDE4MSwxMiwxMzMsMjI1LDI0OSwxNjAsNDEsMjA0LDI2LDEwMSwyMTksMCwxODQsMTU0LDIwNSwyMzMsMTk2LDE0MiwyMzIsMTIzLDMwLDIzNywyMTAsOTMsNjQsODMsODYsMTUwLDIwLDE4OSwxMDcsNTUsMjQsMTYsODQsMjMsMTE1LDE0NSw4LDExMSwyNyw0LDE4NCw1Niw0NCwyNDYsMjA4LDEwNiwxMTUsOTEsMTU5LDI0NCwxMjMsMTk2LDI3LDIxNiw5NywxNTAsMjA4LDIsMjUyLDYwLDE3OCwxOTAsMzksNiwyMiwxNDcsMTYwLDMzLDI0NSwyMSwxNjMsMjE2LDUsMTksMTM2LDE1NiwxMDYsMTU2LDEyNywyMzEsMTAyLDIwNywzNSw5NiwxMjksMTE0LDIwOCw4NiwxODAsMTE2LDExOSwxMjYsNzQsMTIsNjcsNiwxMzMsNDEsMTE4LDc2LDAsMjYsMjA2LDYsNSwxMDMsMTUxLDIwNCwxMzYsMTY0LDM4LDY2LDE0LDkyLDEyNSwxNjMsNTMsMTUxLDEzMCwyMzUsMTg0LDE1OCwxNDksMTYxLDIzOCwxOTksNzEsMjUxLDE4NywzNSwxODgsMjQsMzEsMTYzLDIzNSwxNjMsNjAsNjAsMTMwLDc5LDE1NCwyNSwyMTcsNjQsMTk1LDE3NCwxMzksODUsMTk1LDIwOCwxMzksNzMsNjAsMTk2LDEyOSw2NCwyMDMsMTY2LDEyOCwxMzksMjA0LDE4LDEyNywxMzgsMjI5LDc3LDE2OCwxNjEsMTkzLDIwNywxMDUsMCwxODAsMTA3LDE3Miw2NSwxMTcsNjMsNzQsMzYsMTY1LDE0LDUxLDEyNCwxNiwxMDcsMjMsODIsMTQ1LDEwNiwyNDcsMTQ0LDQ0LDE5MywxMjAsMywxMDQsMTY4LDQxLDE4OCwzNCwyMDYsMjUxLDE3MCwyMDUsMjAzLDExMiwxNzEsMTYxLDEzMyw3NiwxNDgsMTM4LDM0LDgwLDQxLDE2OCwxMjgsMjMsMjAzLDgxLDE0Nyw1MCw1MSwxNDUsMTk4LDE1MiwyMzQsOTYsNzIsMTg1LDUwLDIzMSwyNywxNDUsMjA3LDIxMSw0Miw0MCw4NiwzMSwyNTAsODYsODgsMjM2LDE5NywxNjksMTc2LDE2NSwxMzAsMjM0LDI0NCwxODQsMTU1LDE4NiwyLDE5OSw1NSw2OSw1NywyMDAsMTI4LDE1LDE5LDc4LDIzMSwyMTMsMTcyLDIwLDIxNCwzNCwxODksMjEyLDE4Myw0LDExLDE0MiwxODgsMTYwLDQ5LDE1NywyNywyMSwxNTQsMTY0LDE3OSwyMjAsMTY2LDE3NCwyMDYsMTMxLDExLDY0LDgwLDI4LDMxLDEyMSwxMTAsMTgxLDEyMiwxMzMsMjI1LDE0NywxNzksOTgsODksMTc5LDY2LDE2OCw0MiwyNDAsODcsMjA1LDE4NywxOTUsMTEwLDE5OSwyMjAsMTMsMTgzLDQ0LDE5LDEsMTUxLDU5LDE4MCwxNjEsMTkxLDEwMywxMjMsMTMsMjU1LDE2OCw3MCw4NCwyNiwyMDQsMTMwLDg2LDM4LDEzNiwyMywxMzQsMTU4LDEwMSwxMjgsMjUzLDIwMiwxMzksMTYyLDIxNCwzMCwxOTEsMTEyLDEyMCwyMDIsMTUwLDE3NywzLDE2NSw4MywyNDAsMTY0LDE2NiwyNDYsMTUyLDE0NywxOTksODQsMTUsMjAyLDIzNCwzMCw3NSwzOCw3Myw5OCw2NywxNjQsMTIwLDU0LDcsMTIyLDUzLDcxLDM3LDI1LDE5Nyw3NSwxODcsMTIsMTg5LDE5Nyw0MSwxOTAsMzIsMTIzLDIxNCwxMzksMjA1LDE3MiwyNDcsMTMzLDE1MCw3LDE5NSwxMjYsODAsMTIwLDIwMSw5OCwxNDIsMjE1LDg1LDIwMCwyMzQsNzUsNTAsMjE0LDQ5LDEwNiwyMTYsNTgsMTksNjgsMjEzLDczLDM3LDE0OCwxMzQsMjAxLDIzNSwxMDIsMTkxLDc1LDE4MCwyMTQsNTUsMTg3LDE5OSw4NiwyOSwwLDcsMjAwLDEzMywxMzUsNDIsMTg5LDE4MCwxNzgsMTQyLDM3LDEyMCwxMjgsMzYsNzAsMjM0LDEzMiw1OSw0NiwyMTcsMTQyLDgzLDg2LDY2LDE5MywxNjgsMTQyLDE5OCwxMDMsNjUsMTM5LDI0MywxNTEsMjksMTM5LDYzLDYzLDE4OCwxMjIsNDIsMzUsNjksMTUwLDk5LDExMSwxNDYsMTg0LDI1LDM5LDkwLDMzLDEyNiwyNDksMTg5LDEyNywxNzYsNjEsMTE1LDEwNSw5OCw5MSw1MywxMzUsMTE0LDEyMiwxNjAsODIsNzMsMTY1LDU3LDY4LDExMCwyMDgsMTI0LDEyNSwyLDE2OSwxMTgsMTE5LDg0LDM3LDEyOCw4NiwxNTAsNTEsMTA1LDg3LDI1NSwzMywyMDMsMjAwLDIzMSwxMDMsMTI5LDUyLDY0LDE4OCw4Miw1OCw2NiwxNjMsNTcsMjExLDEyMCwxMTAsMTg2LDE4LDg1LDEzMSwyMTgsMTksMTcsOCw3OCwyMDUsMTc3LDU2LDIyMywxMjAsOTIsNDMsMTk2LDcsMTI3LDE1Niw0Miw4MywxMDcsMTAsMjIzLDEzMCwxMCwyNDAsMjMzLDE4OSwxNSwxOTgsNDAsMjQwLDExOCw1LDQ1LDY1LDIxLDk1LDE4NywxNzksMTA2LDEzMiwxMTMsMTkyLDEwLDMwLDEzMywxNjQsMjEsOTMsOTIsMTU4LDE3MCwxMzksMTI2LDI0OCwyNDgsMTMxLDIyNywxODIsOTQsMTU5LDQsMzcsNTQsMTk5LDE4NywxNDUsMTE3LDEzMywxNyw1Nyw1NSwyMTIsMzUsMTEyLDE4NSwxMzEsOSwyMDksNjQsNzQsMTQ2LDIxNyw1MiwyMiwyMjQsNDksMTk1LDg3LDE3NCw2MCwyMSw4OCw3NiwyMDgsODcsMTk1LDIyNiw3MywyMDEsMjI5LDEyOCw2OCwyMzYsODQsMjI3LDI0MiwxNjQsNzksMTk2LDEzNCwxMTgsNjcsMTI4LDIsMTAsMTcsMjI2LDIwLDEyNiwxMzcsMywxODYsMTAxLDE0NCwyMDAsMTg5LDE1MywxMTQsMTYxLDE5OSw1LDkyLDE0OCwxMTIsNTQsMiwxNDQsNjAsMjE4LDAsMjMsMjMyLDYwLDI0MywyMTIsMTc1LDAsMzcsMjUsNDcsMjEyLDExMCwyMTYsNDgsNCwxNDcsMjI0LDU0LDE0LDcwLDIwMCwyMzMsMjEyLDU2LDE0LDIxNCwxMzUsNzksODEsMTUwLDExNiwxMzMsMyw3NSwyMzIsMTg4LDI1MywyMjAsMTM5LDIwMiwxNDQsNTYsODIsNTIsMywyNSwyMjgsOTcsOTgsMjUyLDIwMSw3NiwxNDAsMTksMTQ0LDk4LDEwMiwyMDIsMTM2LDE4Nyw1MCwxOTIsMTAzLDQ0LDg2LDk3LDEyNywxMjAsMTIsODgsMjM2LDE2Myw4MCwyMTQsMTg0LDIyMCwyMTUsNDAsMTM5LDExNyw3MSwyMTksMTgxLDExNyw1MSwyMTIsMTI0LDEwMiwxMTMsMTAxLDMxLDE0Niw0NiwxOTEsMjAxLDk5LDYsMjI4LDEyMiwyMjgsNzEsMjA3LDkwLDkyLDU0LDcwLDI1MCwxNjEsMjIxLDEzOSwxMTEsNDYsODUsMTgwLDE2NSw3LDU2LDEyNSwyMSwzNCw2NywxMTksMTEyLDE2NSwxMSwxOTcsMTAwLDY1LDY3LDIyMSw1OSwyMzQsMTg5LDE5NSwyMDMsMTYyLDE1OSwyMDMsMTk5LDE1OCwxODIsMTY1LDEsMTkyLDE1NSwxMTUsMjksMTc5LDIzMywzNSwyMTUsOTUsMTksMjI0LDIsMTksODMsMjE2LDEyLDgxLDE5OCwxODMsMTgwLDAsNTgsMjQ4LDM5LDM5LDI1Myw4NCw1MCw5NCwyNTQsMjI1LDIxMiwxNSwxMCw4OCwyNTMsMjEwLDksMjQ2LDM3LDIyNCwxNjUsMTg1LDksNiwzMywwXX19LCJwcml2YXRlX2tleSI6eyJrZXkiOnsidmVjIjpbMTM0LDE1MSwxNywyMjIsNTcsMTYsOTMsMjMzLDg3LDEyMCwxNzEsMTYzLDE1NiwxMzksMTIzLDE4MiwyMDksMTUyLDEwMSwxMzgsMTkzLDY2LDEzOCwxMTcsMjI4LDEzOCw0LDYzLDEyMiwxLDE2OCw4MSwzLDQ5LDIyNyw4OSwyMDMsMjQ1LDgwLDI0MywxOTQsMTg5LDExNCw0MywxMjIsMTMsNTgsMTc2LDQxLDE4MCw1NSw0NCwyMjUsMTg2LDEzNywxMDIsNjYsNzgsMzIsMTMzLDIwNSw5LDIyLDIzMiwxNTEsMTgxLDE5NCwxNDQsMjcsMjIwLDE2NywxNjcsMTYxLDEzMywxODIsNzUsMTk5LDEwNCwzLDY5LDE2MCwyOCw0NCwxNTgsNTIsMjMsMyw1NSwyMiw3MywyMjUsMjI1LDIwMCw3MCw4MSwyNSwyNDgsMTYyLDExNSw5OSwyMTcsMjUsMTg2LDg3LDE4Niw4NywyNTIsNjMsMTMxLDE2MywxODUsODMsMzcsMTk1LDE1MiwxMjQsMTgwLDEyNCw5OCw1MCwxNTYsMjE5LDY4LDczLDE3MCw0LDQ0LDEyOSwxNjYsMjI2LDEwNCwxODAsMjUwLDM0LDE3MCwyMjEsMjE3LDc5LDE4LDI1MiwxNjQsNzQsMjUyLDE1OSwxMTMsMzksMTgwLDQyLDE3LDE5MSwyNDYsNzIsMTk3LDgzLDE5NSwxNDcsNjMsMjE1LDU2LDIxLDUwLDEzNCwyMjgsMjE1LDEzNSwyNTUsMTM5LDQxLDE0Nyw5MCwyMDEsMTM3LDg2LDExMSwxMTAsOTIsMTUwLDE1MCwxOTIsMTgxLDI0NSwxMzAsMTA1LDE4LDQ5LDE2MiwyNTIsNzAsMTUsMjU1LDgxLDE5NCwxMTAsMjM1LDc0LDE5NSw4Myw0LDE5NiwxMzIsMTgzLDE0NiwxNiw2OCwxNDYsOTYsMTcxLDk3LDAsMjYsNzgsMjgsMTQ1LDExLDUxLDE2MywxMDQsNzIsNTMsMTM3LDQ0LDE2LDIyMSw4OCwyMywxNjksNjYsMTQzLDYzLDIwMyw4MSwyMDYsMjQxLDE4NywyNywxMzEsMTgzLDgzLDQsMTAwLDE4MSw2LDEzNSwyMDQsMjIwLDgzLDE4Nyw1Niw4Miw3Nyw3MywxMDgsMTYsMTYzLDE1Niw5MSw5OCwxMDcsMjgsMywxODMsMjE2LDU5LDE2NiwxODEsMzQsMTU5LDAsMjEyLDQxLDIwMywxMzUsMTI2LDE5NSw4MywxODcsMTIxLDgsMTE5LDE0OCwzOCwxMzgsMzksMTcwLDExNywyMjAsMTc5LDEyOSw1MCwzNSw5MywxNjksNjQsMTAwLDE1NiwyMzIsMTcxLDM2LDE0NywxMzUsODksODksMTkyLDE3LDkyLDE0MiwxNjAsMTc4LDEwNywxNDEsMTY5LDEyLDEzOCwzNSw3MSwxNDAsMjI4LDM4LDEwLDIxNSw3NCwyOSwxNTAsMjYsMTU3LDIxNCwxOTEsNDgsMjAsMTY5LDQyLDUyLDE5NSwzLDEwOCwxOTAsMTA0LDIxMiwxNzQsMjI1LDI0MywzLDc0LDIwMCwxNjYsMywxMjksMTA5LDE1MiwxOTYsODksMTExLDE2Nyw2NSwxODgsOTIsNzgsMTkzLDI3LDk3LDgsMTQ3LDE0LDE0MywyNDIsMjA3LDIzNCwxMTIsMTgxLDg2LDUzLDEyNyw5MiwxOTUsMTYzLDIzNiw4LDEwMCwyMDUsMTQ2LDEzOSwxNDMsOTYsMTkzLDIxNiw1OCwxMDAsMTYxLDUyLDEzMSwzNiwxMjksMTMxLDIzMyw2OSwzMSw5NywxMTYsMTc5LDExNSwxNTEsODMsMTAxLDE3MiwyMiwxNTUsMjI3LDY0LDkyLDExOSw5NSw3OCw3NSwxMzMsNjksOTcsMTkzLDI4LDIwMywxMjgsMjQ5LDI0NiwxMjgsMjI0LDIzMywxMzYsMTc5LDEzNCwxMzUsMTI2LDI2LDk1LDI0MywxOTgsMTEsMTEwLDE2NCwyNywwLDIxNSwyMDQsMjUyLDE1NCwyMDcsMTA4LDgzLDExMiwxMjAsMTk1LDM5LDE0Myw3NCwxMzQsMTM3LDQzLDg1LDE0OCwxNTEsNzUsOTQsMjUyLDY4LDc4LDE4NCw4NSwyMjEsMTcsMTI5LDE5MSwxNjQsNzUsMjE0LDMsNTAsNzcsODQsMTY0LDIzMywyMTEsMTQ4LDIxNywyMjgsMTQwLDE4NCwyMzUsNjUsMTAxLDQsMTUsMTI5LDgzLDE3MSwyNDAsMTIwLDE1Miw5Miw5MSw1Miw1OSw5Nyw5OSwyMywyMTQsMTg1LDc1LDIyOCwxMiw2NCw2NSw2OCwyNiw5OSwxODQsMTcxLDExNCwxMCw2MCwyMzAsMTg1LDIzOSwxNzYsMjA0LDEwMywyNTAsMTIzLDc1LDE5NSw2OSwyMzQsMjI1LDAsMTk5LDI1MSwxMTMsNjYsNTgsMTIzLDI1NCwyMTcsMTU5LDE2NCwxODAsMTYsODksMjMsMzAsMTExLDE3OCwyMDUsMTIwLDIyOSwxMDcsMTE4LDIyNiw4MCwyMiw4NiwzMSwxMDIsMTYzLDE3OCw3MSwxNzYsNSwxMDUsODksMTgxLDIyOSw0NCwxODMsNSwxNjAsMTIxLDEwOSw1NCwxNzcsMjAwLDI0NiwxNjEsMTcyLDE0NCwyMDMsMjI2LDE5OSwzOCwxMTEsMjYsMjA0LDEzMSwyNDIsMTksMTM1LDI0MCwxODUsNSwxNTMsMTk4LDIzNCwxMTIsMTg1LDIsMTQ2LDMwLDIxMiwyNDksODIsMjM5LDI0MSwxMjYsMTE2LDIwOCwxMDQsMTYzLDIzMCwzLDEzNCwxMDQsMTYsMjE3LDcwLDE2NiwxMDMsNSwxODMsODgsMTM2LDEwMSwxOTEsNzMsNzEsMjUxLDE2Nyw0NywyMTcsODksNDMsMTEyLDIxMSwxMTUsMTQ4LDI1MiwyOCw3MiwxOTksMTM5LDIyMCwxNzIsMTc3LDEwMCw1NSwxMTgsOCwxNDAsODQsMTQzLDIyLDMzLDQ3LDgxLDk5LDM1LDIwMSwyNiwxOTUsMjQwLDE1MCw1NCwyMzQsMjIsNzEsNTQsMjAwLDIwMywxNjEsMTc0LDI0NiwyNDksNDAsMTY4LDIyNiwxNjIsMTgxLDE1NSwxNzQsMjI2LDEyOSw4NSwyMjAsODYsMTY4LDEzNSwxNjEsNjgsNjcsNjYsMzgsMTcsMTksNiw3NiwxMTgsODAsMjQ3LDkxLDk3LDQyLDIxNCwzMSwyMDUsMTE0LDk0LDE3NCwyNDMsMTEsMjU0LDEzNywzNiw1OSwzNCwxMzcsMTgwLDYsMTM0LDUyLDExMiwxNzUsMTY5LDIzNCw4NCwyNiwyNiwxOTQsMjIxLDE5NywzMywyNTMsMTk2LDI2LDI4LDEzMSw0NywxMjQsMjI3LDc3LDI0MSw1Nyw2MCwxNTAsMTg2LDE0OCwxODUsOTcsMTEzLDc5LDIzNiwxMTUsMjM3LDQsMTA0LDExMSwyNCw0OSwxODgsNjksOSw5Nyw4Myw5MSwyNDQsMTI4LDE4NCwyMzIsMjAzLDI1LDIxOSwxNDgsMSwxMzIsMjEwLDE1MCw4MSw1MywyMiwxNDMsMTc5LDIwNSwyMTksMjEwLDE3MiwxMDIsMTk0LDEwMywxMDYsMTg4LDE5NCwxMzUsMTE2LDE0NSw2LDUwLDksODAsMjEwLDMyLDgwLDU3LDUyLDEzNiwxLDE1MiwxMzUsMTg4LDU4LDcyLDE4NiwxNjAsNjQsOTcsMTg2LDE5NywyMDgsNTksMjUsOTYsMTU5LDcsMTc5LDQyLDYxLDIxNyw4NCwxOTksMTQ3LDIsMzksMjMwLDYzLDEzNSwxODcsMTUxLDIxNCw1MCwxNCwxNDcsMTkyLDIwNCwxMjgsMTA3LDE4OSwzMiwyMjgsMTI0LDE1OCwxMzYsMjgsMTI1LDE2OSwxNDcsNTQsMTAxLDExNywxMTQsMTE4LDE1Nyw1MiwyMDksODIsMjIwLDk3LDcxLDEyLDIxMCwxMTQsMTIyLDIwMywxOTMsMTIzLDE4MCwxMTQsODIsMTUzLDE4MCwyMjIsMjYsMTYxLDEsMjAsMTgzLDYwLDIxOCwxNTcsMjgsNDgsMTg3LDE5MywyNDEsMSwyNTQsMTIxLDM0LDE3NSwxNjYsMTU5LDE0OSwxMTQsMzMsNzQsMCw0MywyMzYsODcsNDQsMjAzLDE1NCw5MCwyMDYsMTMyLDYxLDExMCw0MSwzMSwyNDYsNSw4LDIyMSwxODIsMTQ4LDIxOSwxOTcsOTIsMTQxLDIwOCwxMTYsMTAxLDEwOCw3NywyMjMsMTc2LDE1LDE2MSwyMjgsNjIsNTAsMTE0LDExNCw3Miw3Miw1OSwxODAsMTY0LDEzOCwxMzgsMTgzLDgsOTAsMjQsMTcyLDIyNywxNzEsMjksMjQ2LDM5LDEzNSw3MSwxMzMsMTEzLDEwMSwyMjQsNTYsMTM0LDI4LDIwMCwyMjYsMjQ0LDEyMSwxODMsMTQ5LDkzLDYwLDIxMCwyMDYsMjMyLDEyLDEyMywzOCw1NywxNzUsMjMzLDEyMSw4NCw1NywxODcsNDgsMjI2LDAsMjA3LDI5LDIxOSw0NywxMzAsOTIsNjAsMjU0LDEzMiwxMDksOTAsMTA4LDE1MCwxLDYwLDEzMiw3Niw1Nyw3OCw5MSwxNzcsMjAyLDE4MCwxOTYsNzgsMzcsMTgwLDQyLDE1MSwzNywxNTQsMTgxLDkyLDcyLDI0NSw4LDI0LDE3NywxLDEyMywxNDIsMTIwLDEzMywxNzcsMjI4LDc1LDc1LDIyOCwxMzgsMjE2LDIzMywxNDEsNjUsMjAyLDE4MSwxMTcsNTcsMTQxLDI1MCwyNDQsMTAsMTQ5LDU0LDE3MywxMDQsMzYsMTU2LDM1LDI1MSwxNiwyMTEsMTQ0LDMwLDE0MSw5MSwxNzYsMzIsNzYsMTYyLDE1MiwyMDgsMTA4LDg1LDIxLDE1OSw4OSw3LDE1MywyMDgsMTEyLDE5NSwyMTcsMTA3LDE0OSw3MywxODAsODQsMTIsNDAsMTMyLDE1Niw4NCwxOTAsMTk0LDE1MiwxNDUsNDAsMTA0LDgsMSwxMTMsNzIsNjksMjQ3LDE1MSwyMTcsMjQ5LDgyLDU4LDExOSwxOTcsMTMwLDE2MywxMTAsOTYsODUsMjcsMTMyLDg3LDU5LDEwNiw4LDEwNywxMTIsNTUsOTcsMTAwLDExOSwxMTIsMTM2LDIxMCw0NCwxOTksMzgsMjA3LDIyMCwxMzksOTYsNyw4NiwxMyw0LDE0NCwxNTIsMTg2LDYsOTEsMTM0LDE2OSwxMDQsMjA3LDEzNCwxNDUsMjAsMjcsOTgsMjE0LDY3LDY0LDEwMCw5Miw5MSw3OSwxNjgsMTY4LDI4LDIwOCw3NCwyMzIsMTEsMTc3LDg3LDI1MSwyNSwxLDI1MCwxNzEsMjA5LDE2LDE2MywxNzUsMTQwLDQxLDkyLDE1MiwyMiw4MCw4MCwxMDcsNjgsMjUxLDMsMTU5LDIwOSwxMjUsNDgsMTY1LDEwOCwyMzYsMjAsMTEsNTQsMTAwLDE4OCwyMjgsMTQ0LDE3NiwxODYsMjIwLDE0NywxMDgsMTYsOTMsOTMsMTc2LDQzLDIxMiw2NSwzOCwxNDcsMTYwLDgsNzIsMjcsMTA0LDIyNCwyNDMsMTMzLDE0MiwxMDEsMjA2LDIwNCwxOTcsNjYsODgsMjQsMTQzLDEwNSwxMzcsMTAzLDAsMTk2LDQ5LDI0MSwyMDQsNTMsODcsMjIsMTI3LDE4OCwxMzIsMzgsMTEyLDE2OCw1MCw5Niw0NCw2NywyNDQsMTM5LDExMSwxNjUsNTQsNTMsMTg2LDIxOSw4NCwxMzEsMTEsODIsMTkwLDk2LDE4LDIzMCwxOTMsOTcsMjA5LDgwLDg1LDY0LDczLDU0LDkzLDE1NSwxODgsMTQsNiwzNSwxODIsMTMyLDE3MCwxMTYsMjMwLDQyLDMzLDIzNSw4NSwxMjYsMzksMTA1LDEzOSw5Miw1Nyw2LDE4Niw4OSwxNTcsODMsNDAsMjA3LDE3OSwxNjEsNjAsMTQwLDIwNiwxOTgsMTcxLDExOCwyMzIsMTM0LDg4LDY5LDE0MCw4OSwxMzUsMTE3LDYyLDE1NSwyNTAsOTUsMTUyLDIyNiwzMCwzMCwxMTQsMTkyLDk4LDIxNywxMTYsNzYsMTY4LDAsMjI1LDEsMTU3LDE5MCwxNzIsMTAzLDE0MSw5MiwxNTUsMTgsMTE3LDU4LDEzMCwxODEsMTk2LDI3LDU4LDc5LDk5LDg0LDgsMTg5LDE5NCwxMjgsNSwxMTQsMjEsMTUsOTIsMTg5LDk1LDEzMywxODIsMTQ5LDE4Niw1MiwyNDksMzksNzIsOCwyMSwxMDksMTQsNTMsMzcsMTc4LDE5NiwxMTQsMTc5LDE3MSw2OSwxODksNDEsMTU1LDE0LDgzLDE1NywxNzAsMjQ0LDM5LDE0OCwyNDQsMTcwLDgwLDE4NiwxNTUsMTAwLDI0MywxODksNTAsMTc3LDE0NSwyMjUsODQsMTgsMiw3LDE0OSwyMTgsODQsMTc2LDE5Miw1MCwxMTksNzYsMTAwLDAsNjcsMjgsMjA2LDIyOCwxNDksMTAxLDE3NywyNDcsMTk5LDk4LDE1NCw4LDI0NiwyMjAsNTAsMSwxMTgsMTY3LDYwLDcyLDE1MCwyMjksNTgsMTg5LDQ1LDIyMCwxMTksMjE4LDQwLDI4LDE4NiwxOCwxNzQsMCwyMDksMTQwLDE3MSwxNjMsMTQsOTQsOTIsMTM4LDIxNyw3NSwxNDAsMTcwLDIyNywyMDAsMTI3LDE1NSw0OCwxODEsMTIsMTMzLDIyNSwyNDksMTYwLDQxLDIwNCwyNiwxMDEsMjE5LDAsMTg0LDE1NCwyMDUsMjMzLDE5NiwxNDIsMjMyLDEyMywzMCwyMzcsMjEwLDkzLDY0LDgzLDg2LDE1MCwyMCwxODksMTA3LDU1LDI0LDE2LDg0LDIzLDExNSwxNDUsOCwxMTEsMjcsNCwxODQsNTYsNDQsMjQ2LDIwOCwxMDYsMTE1LDkxLDE1OSwyNDQsMTIzLDE5NiwyNywyMTYsOTcsMTUwLDIwOCwyLDI1Miw2MCwxNzgsMTkwLDM5LDYsMjIsMTQ3LDE2MCwzMywyNDUsMjEsMTYzLDIxNiw1LDE5LDEzNiwxNTYsMTA2LDE1NiwxMjcsMjMxLDEwMiwyMDcsMzUsOTYsMTI5LDExNCwyMDgsODYsMTgwLDExNiwxMTksMTI2LDc0LDEyLDY3LDYsMTMzLDQxLDExOCw3NiwwLDI2LDIwNiw2LDUsMTAzLDE1MSwyMDQsMTM2LDE2NCwzOCw2NiwxNCw5MiwxMjUsMTYzLDUzLDE1MSwxMzAsMjM1LDE4NCwxNTgsMTQ5LDE2MSwyMzgsMTk5LDcxLDI1MSwxODcsMzUsMTg4LDI0LDMxLDE2MywyMzUsMTYzLDYwLDYwLDEzMCw3OSwxNTQsMjUsMjE3LDY0LDE5NSwxNzQsMTM5LDg1LDE5NSwyMDgsMTM5LDczLDYwLDE5NiwxMjksNjQsMjAzLDE2NiwxMjgsMTM5LDIwNCwxOCwxMjcsMTM4LDIyOSw3NywxNjgsMTYxLDE5MywyMDcsMTA1LDAsMTgwLDEwNywxNzIsNjUsMTE3LDYzLDc0LDM2LDE2NSwxNCw1MSwxMjQsMTYsMTA3LDIzLDgyLDE0NSwxMDYsMjQ3LDE0NCw0NCwxOTMsMTIwLDMsMTA0LDE2OCw0MSwxODgsMzQsMjA2LDI1MSwxNzAsMjA1LDIwMywxMTIsMTcxLDE2MSwxMzMsNzYsMTQ4LDEzOCwzNCw4MCw0MSwxNjgsMTI4LDIzLDIwMyw4MSwxNDcsNTAsNTEsMTQ1LDE5OCwxNTIsMjM0LDk2LDcyLDE4NSw1MCwyMzEsMjcsMTQ1LDIwNywyMTEsNDIsNDAsODYsMzEsMjUwLDg2LDg4LDIzNiwxOTcsMTY5LDE3NiwxNjUsMTMwLDIzNCwyNDQsMTg0LDE1NSwxODYsMiwxOTksNTUsNjksNTcsMjAwLDEyOCwxNSwxOSw3OCwyMzEsMjEzLDE3MiwyMCwyMTQsMzQsMTg5LDIxMiwxODMsNCwxMSwxNDIsMTg4LDE2MCw0OSwxNTcsMjcsMjEsMTU0LDE2NCwxNzksMjIwLDE2NiwxNzQsMjA2LDEzMSwxMSw2NCw4MCwyOCwzMSwxMjEsMTEwLDE4MSwxMjIsMTMzLDIyNSwxNDcsMTc5LDk4LDg5LDE3OSw2NiwxNjgsNDIsMjQwLDg3LDIwNSwxODcsMTk1LDExMCwxOTksMjIwLDEzLDE4Myw0NCwxOSwxLDE1MSw1OSwxODAsMTYxLDE5MSwxMDMsMTIzLDEzLDI1NSwxNjgsNzAsODQsMjYsMjA0LDEzMCw4NiwzOCwxMzYsMjMsMTM0LDE1OCwxMDEsMTI4LDI1MywyMDIsMTM5LDE2MiwyMTQsMzAsMTkxLDExMiwxMjAsMjAyLDE1MCwxNzcsMywxNjUsODMsMjQwLDE2NCwxNjYsMjQ2LDE1MiwxNDcsMTk5LDg0LDE1LDIwMiwyMzQsMzAsNzUsMzgsNzMsOTgsNjcsMTY0LDEyMCw1NCw3LDEyMiw1Myw3MSwzNywyNSwxOTcsNzUsMTg3LDEyLDE4OSwxOTcsNDEsMTkwLDMyLDEyMywyMTQsMTM5LDIwNSwxNzIsMjQ3LDEzMywxNTAsNywxOTUsMTI2LDgwLDEyMCwyMDEsOTgsMTQyLDIxNSw4NSwyMDAsMjM0LDc1LDUwLDIxNCw0OSwxMDYsMjE2LDU4LDE5LDY4LDIxMyw3MywzNywxNDgsMTM0LDIwMSwyMzUsMTAyLDE5MSw3NSwxODAsMjE0LDU1LDE4NywxOTksODYsMjksMCw3LDIwMCwxMzMsMTM1LDQyLDE4OSwxODAsMTc4LDE0MiwzNywxMjAsMTI4LDM2LDcwLDIzNCwxMzIsNTksNDYsMjE3LDE0Miw4Myw4Niw2NiwxOTMsMTY4LDE0MiwxOTgsMTAzLDY1LDEzOSwyNDMsMTUxLDI5LDEzOSw2Myw2MywxODgsMTIyLDQyLDM1LDY5LDE1MCw5OSwxMTEsMTQ2LDE4NCwyNSwzOSw5MCwzMywxMjYsMjQ5LDE4OSwxMjcsMTc2LDYxLDExNSwxMDUsOTgsOTEsNTMsMTM1LDExNCwxMjIsMTYwLDgyLDczLDE2NSw1Nyw2OCwxMTAsMjA4LDEyNCwxMjUsMiwxNjksMTE4LDExOSw4NCwzNywxMjgsODYsMTUwLDUxLDEwNSw4NywyNTUsMzMsMjAzLDIwMCwyMzEsMTAzLDEyOSw1Miw2NCwxODgsODIsNTgsNjYsMTYzLDU3LDIxMSwxMjAsMTEwLDE4NiwxOCw4NSwxMzEsMjE4LDE5LDE3LDgsNzgsMjA1LDE3Nyw1NiwyMjMsMTIwLDkyLDQzLDE5Niw3LDEyNywxNTYsNDIsODMsMTA3LDEwLDIyMywxMzAsMTAsMjQwLDIzMywxODksMTUsMTk4LDQwLDI0MCwxMTgsNSw0NSw2NSwyMSw5NSwxODcsMTc5LDEwNiwxMzIsMTEzLDE5MiwxMCwzMCwxMzMsMTY0LDIxLDkzLDkyLDE1OCwxNzAsMTM5LDEyNiwyNDgsMjQ4LDEzMSwyMjcsMTgyLDk0LDE1OSw0LDM3LDU0LDE5OSwxODcsMTQ1LDExNywxMzMsMTcsNTcsNTUsMjEyLDM1LDExMiwxODUsMTMxLDksMjA5LDY0LDc0LDE0NiwyMTcsNTIsMjIsMjI0LDQ5LDE5NSw4NywxNzQsNjAsMjEsODgsNzYsMjA4LDg3LDE5NSwyMjYsNzMsMjAxLDIyOSwxMjgsNjgsMjM2LDg0LDIyNywyNDIsMTY0LDc5LDE5NiwxMzQsMTE4LDY3LDEyOCwyLDEwLDE3LDIyNiwyMCwxMjYsMTM3LDMsMTg2LDEwMSwxNDQsMjAwLDE4OSwxNTMsMTE0LDE2MSwxOTksNSw5MiwxNDgsMTEyLDU0LDIsMTQ0LDYwLDIxOCwwLDIzLDIzMiw2MCwyNDMsMjEyLDE3NSwwLDM3LDI1LDQ3LDIxMiwxMTAsMjE2LDQ4LDQsMTQ3LDIyNCw1NCwxNCw3MCwyMDAsMjMzLDIxMiw1NiwxNCwyMTQsMTM1LDc5LDgxLDE1MCwxMTYsMTMzLDMsNzUsMjMyLDE4OCwyNTMsMjIwLDEzOSwyMDIsMTQ0LDU2LDgyLDUyLDMsMjUsMjI4LDk3LDk4LDI1MiwyMDEsNzYsMTQwLDE5LDE0NCw5OCwxMDIsMjAyLDEzNiwxODcsNTAsMTkyLDEwMyw0NCw4Niw5NywxMjcsMTIwLDEyLDg4LDIzNiwxNjMsODAsMjE0LDE4NCwyMjAsMjE1LDQwLDEzOSwxMTcsNzEsMjE5LDE4MSwxMTcsNTEsMjEyLDEyNCwxMDIsMTEzLDEwMSwzMSwxNDYsNDYsMTkxLDIwMSw5OSw2LDIyOCwxMjIsMjI4LDcxLDIwNyw5MCw5Miw1NCw3MCwyNTAsMTYxLDIyMSwxMzksMTExLDQ2LDg1LDE4MCwxNjUsNyw1NiwxMjUsMjEsMzQsNjcsMTE5LDExMiwxNjUsMTEsMTk3LDEwMCw2NSw2NywyMjEsNTksMjM0LDE4OSwxOTUsMjAzLDE2MiwxNTksMjAzLDE5OSwxNTgsMTgyLDE2NSwxLDE5MiwxNTUsMTE1LDI5LDE3OSwyMzMsMzUsMjE1LDk1LDE5LDIyNCwyLDE5LDgzLDIxNiwxNDMsMTQyLDEzNCwxNTIsNjIsMjUxLDE1NCwzNSwyMCwxMDcsMTIsMTQ3LDE1MSw3OCwxNTMsOTMsODcsMTQ1LDM4LDI2LDE4NSwxNDMsOTQsNjYsMjExLDUsMjIsMTU2LDM4LDEyNSwxNjgsNTIsNTQsMjA3LDE3MSwxMTEsNTksOTUsMjA4LDIxOSwyMzUsOSwzMCw1NywxNDIsMTgsMjU0LDYzLDE4OSwxNjAsNzgsMTE2LDUwLDIwNCwyMzYsMjAsMTU3LDEzOSwxMDUsMTQsMjUwLDIyNCwxOTksNDksODIsNjYsMTYwLDE4MSwzMiwxNDEsMTI2LDIyMCwyMTMsNzcsMTgzLDI0NiwyNTMsMTk1LDIxNCwzNywxOTQsMTg1LDk4LDE0NSwxMjQsNjIsMTgsNTIsNDYsMjI1LDEsMTAsNDQsMTIwLDE0MywyNDAsMTIsODEsMTk4LDE4MywxODAsMCw1OCwyNDgsMzksMzksMjUzLDg0LDUwLDk0LDI1NCwyMjUsMjEyLDE1LDEwLDg4LDI1MywyMTAsOSwyNDYsMzcsMjI0LDE2NSwxODUsOSw2LDMzLDBdfX19LHsicHVibGljX2tleSI6eyJrZXkiOnsidmVjIjpbMTE2LDE2Niw2MiwxMjksMTc3LDE2MywxMjQsMjE0LDEwOCw4MCw4NiwxNDUsMjgsMTQ0LDY0LDE4NSw0LDg5LDYwLDExNiwzMywxOSwyMjUsMTU3LDcwLDEyMywxMzMsNTMsMTgwLDg5LDY3LDE0OSw0Myw2NiwxODMsMTQzLDQ3LDM0LDE4MCw4NywxNiwxMSwxMTAsMjUxLDYxLDIwMiwyMzMsMTUzLDgsMTAyLDkxLDE5OCw0OSw1OSwxNjAsMTk4LDg2LDU4LDI0MCwxNTgsMTU5LDgxLDIwNyw5NCwyMDksMTIwLDIyOCw4NCw1NSwyMzksMjIsMTk3LDEwMywyMzQsNzcsMTk4LDI0MSw0Nyw5LDgwLDE2MiwxODYsMTU0LDE4MiwyNiwxMzksODYsMjQxLDIwLDEwNCwxNjksMjE5LDEzNywyMDcsOCwxOCwxNTQsMTYsMjUsMTE5LDE0NiwxODYsMTUzLDg5LDIsOSwxMDQsNDIsMzYsMTYsMzcsMjEsMTk1LDk1LDM5LDE5NiwxNTQsMTg1LDc0LDEzMiwyNDYsODksMTQ1LDEyMCwyMjcsMjEsNjIsMTgyLDEwMiwyMzIsMjUyLDIsMTc5LDE2OSw0MiwxNDUsMTAzLDE5MSwyMDUsMjM0LDExNiwxOTAsMTA4LDE0Miw5OSw1OSw0NSwxMDEsMTIxLDksNjMsMTY3LDE5NCw4NCwxMDIsNDgsMjMsMjEwLDExOCwyMjcsMTUyLDEzNSwxNjMsNDMsNDIsODQsMjQ0LDM3LDIwNSwxMzUsMTUxLDExNSwxNTAsODgsMTgwLDIzMywxNDYsNjksMTksMjA3LDY2LDQyLDEyMywxNzIsMjQ4LDg4LDE4MywxNjksMzAsMzUsNTIsNzYsODUsMTUzLDE1OCw5LDExNSw5MCwyNTEsOTksMTUsMTY0LDE2MiwyMyw4NiwxNTAsMTcyLDg1LDEwMSwxMjksMjQxLDEzNCwxOTksMTI0LDI1LDAsMTkwLDE0NiwzNCw3MSwyNCw5NiwzOCwyMSw2MCwxOTEsMTQwLDE3MywyNTIsMTEzLDk1LDYwLDc1LDQ5LDU5LDI0NCwyMDMsMjQxLDEyOSw2OSwyMzUsMjIsMzIsMTUsMjM2LDE5MCwxMjIsMTAxLDY0LDExMSw3LDE3MSwyMjgsNTcsMTIxLDExNCwyMDMsMTMsMTAzLDksMzQsMTUsMzYsMjksMjIyLDIyNywxOTgsMTU0LDMzLDExMSwxMzcsMTY4LDExOCwxMDUsMjMxLDEwMSw2MSwzNSwxODAsNzgsODksNDMsMTQwLDkwLDI2LDUwLDIxLDE0MywyNDEsMjEyLDc3LDEzLDQ4LDE3MSwzMywxNjMsMjAzLDIwOCwxODEsMTk0LDEwOCw4MiwxMjUsMTE3LDgyLDY5LDEzLDE0OCw4Myw0NSw2NSw2NywxMTEsMTk3LDg2LDEwMywxNjYsMzAsMjUzLDI1Miw0OSwzNSw1NywxODMsNzUsOTEsMTQxLDE4Niw5MSwxNzAsMTQ3LDI1MSwxNjMsNDIsMTgxLDE3NCwyMjgsMjQsMjMsMTc3LDIxNSw3NiwyMDYsMjE5LDUyLDI1Miw4Niw5Miw2NCwxNjgsMjIsNzgsMTg3LDE0NCw3OCw4OCwxMDEsMjE4LDE0NiwxMDUsMTY2LDYsMTM0LDE1Niw2NiwxOTEsMTg1LDE5OSwxODYsMTIsNSw5NiwxMjUsNjQsNDQsMTQyLDEyLDE3MSwxMjksODQsNzYsNzEsMjE2LDk2LDMzLDE0NSw1MiwyNTUsMTQ2LDkxLDEzNSw1NSwxOTcsMzMsMjQ0LDE2Miw2OCw5Nyw0OCw2Nyw4OSwxMzMsMjAzLDE4NiwxMDAsODMsMTg1LDcwLDExOCw1OSwxODksMjQ4LDIxMywxNDIsOTUsMTk2LDExMiwxNzksMTQ4LDE4Nyw3LDEwOCwyOCwyMzUsMTMyLDEsMjAwLDIyOCwxODMsMTY0LDEzNSwxNiw4MiwyOCwxNjYsMzAsMjMxLDEzMyw4NSwyNTAsMTM4LDg5LDE5NiwxMTgsMTcyLDY1LDE5MCwyMzIsOCwxMyw1OCw4Myw3MiwyMzksMTAzLDQ2LDk2LDM2LDU1LDg5LDE4NywzNiwyNSwyMTYsMTA0LDIwMCwzNCw3NSwyMjAsMjM0LDExMiwyMjMsMCwxMjYsMTA2LDIxNiwxOTIsMTQ5LDQzLDg2LDIwLDE3MSwxMTUsODMsMjAzLDEyLDQ5LDE4NCw4MiwyMzgsMjEzLDE0MCw1NCwxNTEsOSw5MywxNzcsODIsNTQsMTIxLDMyLDEyNSwzMiwxMTEsMTE5LDE4NSwxMDEsMTM0LDI0MSwxNDQsMjI3LDIxNiwyOCwzOCwyMjgsNSwzNCwxMTQsMTExLDI5LDIwOSwyMDcsMTI1LDQ4LDM5LDIzMSwxMjksNzgsMjI5LDkxLDc0LDUsMjUyLDE2MCwxNjYsMTQ4LDIwLDQ4LDE0NywyMDIsMTk5LDI0NywxNzAsMjMxLDEyOSw4MywyMjQsMTY3LDQ5LDIzNCwxMzYsMTYzLDM0LDIyOCwxMTksMTUwLDE2LDU4LDE4NiwxOTgsMTMzLDQsNjgsMTU5LDE3NSw4MSwxNDAsMjQzLDI0LDgwLDc5LDI0NCwxMDgsODAsMTAzLDE0MywxNjEsODgsMjAzLDIyNSwxNjMsMTY0LDE5Nyw1LDgyLDI3LDEzOCw2OSwyNDAsMTg2LDkxLDIzMywxMzEsMTU4LDIwMiw0MCw5MCw4MSwxNjAsODIsMTQzLDEzNywxNjQsMTMxLDIwLDE3MywxNTMsMjUsOTUsODAsMjYsMTgxLDM4LDE0OCw1NCwxOTYsMTA0LDIzLDIzNywxMzYsMTYzLDIxOCwxNywyNyw2NiwyMjgsMTI3LDIxMSwyNTAsMTQ5LDE2NCw4NSwxMDksMTY5LDE4NiwyMDAsMSwyNTEsMjAxLDEwMywxMjMsMTgzLDE1NSw4Nyw5NCwxODcsMjM1LDE3OCw5OCw5NywyMDYsMjUsMTA1LDE2MSwyMDIsMjMxLDEyMyw2NiwxMzgsMTQsMTc3LDExNCwxNjEsNTksMTc3LDQwLDEzLDM5LDMwLDg0LDQ4LDE4NywyMzMsMTMxLDE4NiwyMDQsMTY3LDkxLDIyMywyNDMsMTkzLDkyLDIxMywxOTEsMTQsMTQ3LDE3LDEzNyw0LDM2LDk2LDU2LDQ1LDI3LDM1LDIwMSwxOTAsMTkzLDI0LDE3NywxNTQsODYsMTk3LDE1NiwxNjgsMTY4LDExNSwzMSwxMjUsMjI5LDM1LDgwLDg5LDk5LDIzNywyNTEsMTkwLDgyLDEsMTMzLDE1MCwyMTQsMjA1LDg3LDksMTk0LDIzNCwyMzQsODYsMTY4LDE0NCwxOTAsMjAxLDk3LDExMiwxNDEsNzQsNzYsMTQwLDk2LDUsMTE3LDY2LDcsMjU1LDQwLDE1OSw0Miw0MywxMTksODQsNSw5NywxLDIxNiw3MSwxMSwxNjcsMTQ1LDY1LDI1MSw1MCwxMDAsNTIsMTcwLDQsMTksMTksMTE5LDE0MCwxMCwxMCw4NSwxNyw4NCwzNywxMDksMjQwLDE5NCwyMywxNjYsMjM1LDEzMSw3NiwxODYsMzcsMTA0LDIxNywyOSwyMjcsMTU1LDYwLDEwOSw3NSwxMDIsMTcsMTI5LDE1NCwyMjUsMjIsOTksMTgyLDE3MCw1NiwyNSwyMzEsMTUxLDc5LDE2MSw1MCwxMCwyMjksMyw0MCwxOTYsMjYsMTc4LDEzNCwxNDUsMTcsMTU1LDExNiwxNDEsMjAsMTcyLDE0MSwxNjksNSw0MCwyMDksNjIsMzUsMzYsMTQsNzYsMjM2LDE5NCwyNDIsMTE2LDE4MCwyMzYsNDIsODQsOTEsMTE4LDEzOSwyMjUsMTc5LDE4OCwwLDEwNSwxMyw5OSwxODMsNTMsMjIyLDIxMywxMzEsMjMyLDIyNSw5NiwxOTMsNzEsNCwxMDQsNiwxNjUsMTc5LDIzNSw0OSwyMDcsMTE1LDM4LDEyMywxODUsMjksNjUsMTgxLDE3NiwxODUsNzAsMTY5LDE4MSwyNDEsMjIsNDEsOTAsNjYsMTIzLDg5LDE2MSwzMCwxNDgsMTE1LDEyNCwxOTgsNjQsNjYsMTAzLDEwMSw1MiwxOTcsMTkwLDEzMywxMDAsMTM5LDE0Miw4Myw5NywyNTIsMSwxMzIsMjMwLDIzNCwxODIsMjIxLDIxLDg5LDEwNSwxMjQsMTA4LDIyMCwxOTMsMTk2LDE1NSwxNTYsMTYxLDE1MSwyNDEsMTE3LDY0LDEyMCwyMDYsMzgsMjQxLDkzLDEwNiwyMTIsMjUsMTQwLDE1NCwyNywxODEsMjQxLDEwMSwyMTIsMzQsMTM5LDUxLDcsOTksMzQsMTY2LDYwLDUzLDE4Miw3OCwxOTEsNzMsMTU1LDI1MSw1NiwxNzEsNTMsMTk3LDM2LDQyLDE5OSwxNDgsMjUwLDE5NiwxOTIsMTM1LDEzNCwxMDIsMjU0LDI4LDExNywxMjYsODYsNSwxNTcsNTMsMTY1LDIzOCwxMzUsMTc4LDE4MSwzOSw3NiwxNCwzNCw4MCw2LDIyNywxNjIsMTIwLDEzMCwxMDMsMTcsMTg4LDE3Nyw1NCw5OCwxNDAsMTk1LDE3OCw2NywxNjAsMTY3LDE0LDE1Miw0OSwxNjMsNjcsMjUwLDE1MiwyMDgsMTE2LDMzLDI0NywxODIsMTIyLDExNiwxMjMsMTY5LDE5NCwxNjQsMTEyLDE1Niw3NCwxNDgsMTQ4LDY3LDEyNSwxMTksMzksMTE5LDEyNCw1NSwxMzMsMjEwLDU5LDEyNSw5MSwxODcsMTE0LDE0NSw3MSwxNzIsMTgxLDUxLDkxLDE2MSw1Nyw1NSwxNDgsODEsNDksMTc0LDEwOCwxNTMsMjA2LDI0Miw3OCwyMzksMTgsMTMwLDMyLDIxMSwxMjksMjIyLDY0LDgsMTI4LDE5MywxMjgsMTYsMTA2LDg1LDE1MCwzLDIwMiw3NCwxNjMsMjAyLDgsMTk3LDYzLDEzMywyMDQsMTg0LDE0OCwxNTMsMTg5LDYyLDE2OCwyNiwxODMsMjE5LDE1MCwyMDAsMjExLDU0LDI0OCw3NSwxMTEsMjM3LDIwMiwxNiwxOTMsMjI1LDE5MiwxODIsNTksMjAyLDM2LDIzMiwxODAsMTk3LDEzMCwxMjMsMTU5LDE1NCwxMjMsMjE2LDI0MCwxNjEsMjEyLDE0NSwxMTAsMTUwLDgwLDExOCwyMDgsOTAsMTA2LDgxLDcyLDIwLDY5LDYwLDI4LDE3Nyw5MCwxNjQsMTg5LDM5LDAsODMsODIsOTgsMTMwLDgwLDQ1LDE3Nyw3OSwxNzcsMjM1LDQxLDE0NCwyNSwzMiwyMiwxMjIsMzEsMTQ1LDIxNywxNjMsMTAxLDIyMCwxLDk4LDEwOCwxOTYsMTcxLDE4NiwxMzIsMjksMjQwLDIyNSwxMTIsNCw2Niw5NiwxNDgsMTg0LDE2NCwzNiwyMjMsMzAsMTEsNjksMTA1LDc3LDE5NiwxNjcsMTYsMTQ5LDE4NSwyNDYsMTUzLDEyOSwxODAsMTIwLDI0NCwxNTYsMTIsMTMxLDk3LDI0MiwyMjcsNzQsMTQ1LDc5LDddfX0sInByaXZhdGVfa2V5Ijp7ImtleSI6eyJ2ZWMiOls3NSw5OCw0Myw1NiwxNjYsNjIsMTQ4LDYwLDE1NSwyMDksMTk1LDE2OSw0MSwyNDksMTk2LDE5Nyw3LDE0OSwxNTQsNDEsMTIsMTA5LDIxNSw0MiwxOTMsNTIsMTA0LDE1NSw3Miw0MSwyOSw1Niw3OSwxNzIsMTk0LDE5MCwxNjksMjQwLDQ5LDE4NCwxNjEsMjQsMzksNDksMzgsNDgsMTIxLDE1MSwzMyw2NCw4MywxMTksMjM2LDM3LDE5NSwxMDIsMTA0LDIxMiwxMjAsMTg5LDYzLDE1MSw0Miw3MSwyMjYsMTgwLDEzNyw0MSw4LDM5LDEwMSwxNTgsMTQsMTk3LDY0LDkwLDcwLDY2LDI1LDIwMywxNjUsMzUsMTU0LDU2LDQzLDg3LDExMiwxOTksNTgsMTU1LDI3LDE0NywxMTIsOTUsMTc5LDExMiw3NywxNzIsNjYsMzIsMTM2LDYsMTUsMTM1LDE0Myw3NSwxMjIsMTk0LDIwOSw0MSwyMDcsOSw3LDk2LDExNCwyMzAsMTM4LDE0MCwyNTAsNzIsMTY0LDE1NCwxMzksMTc2LDEwNCw0OSwxMDMsMjcsMjgsMTQwLDIsMTMzLDEyMiwxMDUsMTA4LDYwLDU0LDE2MiwxNzAsMTc5LDE5MiwyMzIsMTg1LDE0NiwzOSwyMjgsMzAsMjAyLDE0OCwxNDMsNDksMjcsMTE3LDE5MywyMjksMTMyLDI1MCwxMDgsMTUxLDcxLDI0MCwxNjAsMzcsMTI0LDE5NCwyMDcsMjQxLDExMCwxNjgsMjI3LDUsMTkxLDEwMyw4OCwyNDksOTAsMTEyLDI0NywxMzgsNjYsNDUsNiwxMSwxNTUsMTIyLDU1LDE3MiwyMTgsMTUyLDM1LDgyLDEyOSwxMTEsMjQ4LDExOCw5NSwxOTgsMTM3LDIzNiwyNywzNCwyMTMsNzUsMTM5LDIwLDIyOSwxMiw5MywxNTAsMTI1LDcyLDk2LDEyOCwyMDAsMTA3LDI3LDQ0LDIyMCwxODUsNDQsMTE0LDg3LDEsMTM2LDUzLDEzNSw1MiwxNCw5NSwxNjUsMTM2LDIyNiwxNzAsMTA2LDE3MCwxNTUsMTA0LDIxMSwxOSw2NSw1NiwxNDUsMTY1LDI1MywxNDgsOTYsMTQsMTg0LDE5NCwyNTUsNzEsMjAsMTMzLDc1LDIwLDc4LDE1NCwxNTAsMTQ4LDEzMywxMDQsOTEsODgsMTMwLDExOSw0Miw1MSwyNywyNDEsMTMwLDI0NCwyMzAsMTEwLDcxLDUwLDEyMCwyMzAsNTcsMjgsMTU0LDE2MywxOSw0OSwyMzIsMTQ5LDUxLDE0OSwyNSwxNzIsMjQsMTc5LDY0LDc2LDcsMzYsMjI0LDEzMCwxMjUsMTkzLDk3LDE0NSwxLDIxLDMzLDE4MCwyOSwyMjQsMTU0LDE3NiwxMTcsMTAyLDE2MCw4NSwyNDcsMTExLDI1MCwyMzQsMjA1LDIzMCw4NiwyMDcsMjUxLDM4LDgsNjMsMTY4LDE2NCwyNTIsMTM0LDEzNiwxODIsNzAsMTI2LDY3LDExMiwxMzQsMTg5LDQzLDE4NywyMjYsMTg4LDk3LDg0LDE2NCwyMDQsOTAsNzAsNjcsMjQ2LDE0MCwxMjEsMTk0LDY4LDQ2LDgxLDIzMCwxMzYsMTY3LDE3Nyw2NywyMzYsMTYwLDE3MCwxMzIsMTE3LDE1MiwxNDEsMTE0LDE4NSwyMDAsMTM0LDE3LDIyLDIxNSw2MywyMzcsMTM4LDEzLDE2NCwxMTcsODAsMTU3LDE2MiwxMDQsMTksMjE1LDE0MCw4LDUwLDE5Myw0OSwyNDgsNjksMTk1LDE3OSwxNTYsMTQ3LDI3LDM2LDE0NywxOTcsNzcsMjAzLDI1MSwxNTIsNjEsMjM1LDQzLDE5NywxMCwxOTAsMjI4LDU4LDE3MCwxNjksMjQ3LDY4LDEyMywyMjUsMTczLDE1MiwxNzAsMTYzLDI1MiwxMzAsNiwzOSwxOTMsMTgzLDIwNywxNiwxNjgsMTAxLDAsNTAsMjExLDIzNiwyNSwxMzEsMTU0LDQyLDU2LDI0OSw5MSwxMzQsNTAsOSwxNDMsMjA5LDI1LDEwOSwxMDQsMTgzLDIwOSw2OSw0NywxMzQsOTgsODUsMTQwLDEzOCwxOTksMjIxLDIxNywxMDIsMjksMTU1LDU1LDg4LDE0NSwxLDEyNCwyMTEsMTc5LDEzNiwyMTUsMTQ0LDE2MCwyMzQsMTIyLDc5LDE4NCwxNjEsMTM1LDM1LDE3MywxMDAsOCwxNTQsNzMsMTI0LDEzMiwxNTAsMTAxLDQ2LDIxOCwyMDQsMTk0LDE3OSw1Niw2MiwxMjAsMTQ2LDE3NiwyMzcsNTMsMTE5LDkwLDY4LDE5LDIzNywyMCwxNjYsMjAsOTksMTEzLDE4Niw5Niw2NCwyNDgsMjM1LDE0LDIwNSwxMzgsMTA4LDMxLDEwLDEyNSwyNDQsMzgsMTU1LDExMCw3NCw0NCw5OSw4Nyw5NiwxMzQsMzYsMTIsMTUxLDczLDE5LDEzNSwxOTIsMjA0LDIwMiwxMzcsMTc2LDM3LDU3LDE3MiwxMDMsMjEzLDk1LDY5LDE0NCwxODgsMzcsMjQsMjQsNDMsMTQ1LDE4MywxNzAsNiwyOCwxNDAsNywxMTIsMTU2LDEyMCwxMjAsMTgzLDEyLDE5MSwyMjksODMsMzMsMTY5LDExNiwzNCwxMjYsMTAyLDU2LDE1NywxMjEsNDQsMTksMjAwLDIxLDEwLDUzLDE4MywyNiwyMTksMTE2LDIwNSwxNjgsMTY3LDI1NSw3LDE3NywxOTcsNDAsMTMsMjU1LDE4Nyw1NywxMSwxODgsMTc1LDU5LDI0OCw4NiwyNTAsMTIsMTUsMTYzLDIxNywxNTYsMTgsMTYzLDQ4LDEyNywxMzksMTAyLDE5MCwxNzAsMTkyLDEsMTgwLDE2NiwxMDYsMTk4LDMyLDE3Nyw5OSw5MCwxODIsMjQyLDYwLDE1MiwxNiwxNzYsMTUwLDE4NCwxMDEsNzcsNzAsMTc2LDI4LDE3Nyw5MCwxMCwyNTAsNjAsMjQzLDE5LDEyMywxNjksOTAsNDgsMjUyLDI0MiwxODAsMTU3LDE3LDU3LDEzMyw3MCwxMTgsMTYyLDE2Nyw5LDE3MywxMzYsMTc1LDExNywyMjQsMjMsNDYsNDIsMTcyLDE1MiwxNjAsOTYsMTYwLDIwMCwxNSw1NiwxMzQsNTEsNzEsODQsOTAsOTUsNzUsMjcsMTgsMTQ3LDQ4LDEyMyw4OCwxOTYsMTgwLDg3LDU3LDY3LDE4MSw4LDIyNyw4MCwxMCwyMDAsMTU2LDIxLDIxOSwyNTIsMTA5LDE1MCwxMDAsMjMsNDUsMTg2LDE5NiwyMzcsMjI4LDYwLDIwMiwxNjcsMjMsNzYsMTgyLDk3LDIzLDEzNiw1MCw4NSwxNjksMTE3LDIxNSw4MywyMSwxMzAsMTUxLDIwMSwxNjYsMTY1LDE3NiwxMDAsMjEyLDUzLDkyLDE0NSwxMTEsNjksMTY2LDM4LDI0OCwyMywyNiwyNTAsMjE2LDE4MSwyNDcsMTkzLDIwNiwxMTQsMjE2LDEzMiwxMzMsMTA4LDUwLDE1Niw1OSwyOSwxODUsMTIsMTYxLDgxLDEzMSwyMDEsMTY0LDE1MSwxOCwxNDksNzYsMTIzLDEzMiwyNSw5NSwxNCwxMTQsMTU5LDE5MywyNTAsMTAwLDExNSwxNzEsMTQwLDEyNiw4OSw4NiwxNTUsMjE4LDE3MiwxNjEsMjExLDQzLDY1LDEwMSw5LDE0MSwyNDYsMjA1LDUyLDI0NywxNTEsOTMsNzMsMTQ5LDEzMCwyMjgsMjA1LDUyLDEsMjgsNzcsNzIsMjA3LDIyNiwxMTQsMzQsMTc3LDE4Nyw5OCw4LDE4NywxNDMsMTQsMTk4LDg2LDQ3LDEwMiwxMjEsMjA4LDE0OCw3Niw5Nyw3NCw0NywxMzUsMTUxLDE2MSwxODQsMzgsMTM2LDIyNCwxMDYsMTc2LDE3MiwxMTQsMTQ1LDIzMywxNTYsOTgsMTQzLDE4OCwxMjAsMTQ5LDU3LDcsMTk2LDE5MywzNCwxNzgsOTEsNDUsODEsMjMyLDQ0LDExOCwyNDYsNzUsMTc0LDE3OCw5NSw3OSwxMjIsMTE0LDI1NCw2MCwxNTcsODksMjYsMTkyLDEyMCwxMCw3MywyMDUsMTE3LDE1MSwxMjYsMTk3LDkzLDEzMywyMDgsMTc5LDUyLDM2LDcxLDIxMCwyNDcsMTI2LDEyOSw1MiwzMSw5NCwxNzAsOCwxNjEsMjI1LDEwMiwxNzEsMiwyMiwxMzksOTYsNywxMDQsMTg2LDQwLDExMSwyNywxMDMsMjUyLDQyLDE3Nyw5Miw3MSwxMjgsMjI4LDI1MiwxOTMsMTU4LDExLDYwLDEzMyw0MCwxMDIsMTc0LDQ5LDE4OSwxNTQsMTc5LDkxLDU4LDE1NiwxMSwyNDQsMTUzLDEwMSw3MywxLDMyLDE1NCwxODgsMTE1LDc2LDE0NCwxMDgsMTcsMjEzLDkyLDIxNiwyMSw5MSwyMzksMjMxLDE4Niw5OSw0OCwxNzEsMTEzLDkxLDU1LDIwMiwxMzIsMTQxLDE0NSwxMDQsMTQ4LDM5LDM5LDEzLDQzLDI0NiwxNDEsMTU1LDIzNSwxMiw0LDIxOCwxODYsOTcsMiwxOCwyMjgsMTMyLDE1NCwxNywyMjAsMTIzLDIwOCwzOCwyMDQsMzgsODksMTgxLDUsMjMzLDcyLDI0OCwxNTYsODIsMjEzLDE3MSwyLDE1Miw1OSwxMTEsODIsMTY1LDU2LDE5MSw5LDUwLDI0OSwxNjYsOTcsMzIsNDgsMTI4LDIxNSw4OCw4MywxMTgsMzcsMTI2LDg3LDE2OCwxNjgsODMsMjM0LDE5MywxNjIsMjEsNjksMTAzLDEzMywxOCw5NywxMDIsNDEsMTk1LDE4Nyw3Nyw2NCwxNjIsMjgsMjEsOCw1MCw5NCwxMDEsMTYwLDE0MywxMzgsMSwxMDcsMTE3LDExNywxNjksMjAsNjcsMzAsMjMwLDExNSwyMzIsMTg4LDQ2LDgzLDEwMiwyMDIsMjM3LDE2NSw1NywxMTksNywxNSwxOTIsMjUxLDcyLDIxOSw0MCw1MiwxNjYsNTAsOTMsMzYsMTUyLDIwMSwyNDYsODEsMTEzLDc0LDc0LDEzMCw2LDE2NCwxMiwxMTgsMjMzLDM3LDM4LDI0Niw1OCwzNywxMjEsMTAyLDc4LDAsMjIsMzcsMTkzLDQxLDEzOSwxMDAsMTg5LDQ2LDE5OSwxODUsMjA3LDU2LDEzMCwxMjEsOCwwLDIwOSw3Miw2MSwxMTYsMTY2LDYyLDEyOSwxNzcsMTYzLDEyNCwyMTQsMTA4LDgwLDg2LDE0NSwyOCwxNDQsNjQsMTg1LDQsODksNjAsMTE2LDMzLDE5LDIyNSwxNTcsNzAsMTIzLDEzMyw1MywxODAsODksNjcsMTQ5LDQzLDY2LDE4MywxNDMsNDcsMzQsMTgwLDg3LDE2LDExLDExMCwyNTEsNjEsMjAyLDIzMywxNTMsOCwxMDIsOTEsMTk4LDQ5LDU5LDE2MCwxOTgsODYsNTgsMjQwLDE1OCwxNTksODEsMjA3LDk0LDIwOSwxMjAsMjI4LDg0LDU1LDIzOSwyMiwxOTcsMTAzLDIzNCw3NywxOTgsMjQxLDQ3LDksODAsMTYyLDE4NiwxNTQsMTgyLDI2LDEzOSw4NiwyNDEsMjAsMTA0LDE2OSwyMTksMTM3LDIwNyw4LDE4LDE1NCwxNiwyNSwxMTksMTQ2LDE4NiwxNTMsODksMiw5LDEwNCw0MiwzNiwxNiwzNywyMSwxOTUsOTUsMzksMTk2LDE1NCwxODUsNzQsMTMyLDI0Niw4OSwxNDUsMTIwLDIyNywyMSw2MiwxODIsMTAyLDIzMiwyNTIsMiwxNzksMTY5LDQyLDE0NSwxMDMsMTkxLDIwNSwyMzQsMTE2LDE5MCwxMDgsMTQyLDk5LDU5LDQ1LDEwMSwxMjEsOSw2MywxNjcsMTk0LDg0LDEwMiw0OCwyMywyMTAsMTE4LDIyNywxNTIsMTM1LDE2Myw0Myw0Miw4NCwyNDQsMzcsMjA1LDEzNSwxNTEsMTE1LDE1MCw4OCwxODAsMjMzLDE0Niw2OSwxOSwyMDcsNjYsNDIsMTIzLDE3MiwyNDgsODgsMTgzLDE2OSwzMCwzNSw1Miw3Niw4NSwxNTMsMTU4LDksMTE1LDkwLDI1MSw5OSwxNSwxNjQsMTYyLDIzLDg2LDE1MCwxNzIsODUsMTAxLDEyOSwyNDEsMTM0LDE5OSwxMjQsMjUsMCwxOTAsMTQ2LDM0LDcxLDI0LDk2LDM4LDIxLDYwLDE5MSwxNDAsMTczLDI1MiwxMTMsOTUsNjAsNzUsNDksNTksMjQ0LDIwMywyNDEsMTI5LDY5LDIzNSwyMiwzMiwxNSwyMzYsMTkwLDEyMiwxMDEsNjQsMTExLDcsMTcxLDIyOCw1NywxMjEsMTE0LDIwMywxMywxMDMsOSwzNCwxNSwzNiwyOSwyMjIsMjI3LDE5OCwxNTQsMzMsMTExLDEzNywxNjgsMTE4LDEwNSwyMzEsMTAxLDYxLDM1LDE4MCw3OCw4OSw0MywxNDAsOTAsMjYsNTAsMjEsMTQzLDI0MSwyMTIsNzcsMTMsNDgsMTcxLDMzLDE2MywyMDMsMjA4LDE4MSwxOTQsMTA4LDgyLDEyNSwxMTcsODIsNjksMTMsMTQ4LDgzLDQ1LDY1LDY3LDExMSwxOTcsODYsMTAzLDE2NiwzMCwyNTMsMjUyLDQ5LDM1LDU3LDE4Myw3NSw5MSwxNDEsMTg2LDkxLDE3MCwxNDcsMjUxLDE2Myw0MiwxODEsMTc0LDIyOCwyNCwyMywxNzcsMjE1LDc2LDIwNiwyMTksNTIsMjUyLDg2LDkyLDY0LDE2OCwyMiw3OCwxODcsMTQ0LDc4LDg4LDEwMSwyMTgsMTQ2LDEwNSwxNjYsNiwxMzQsMTU2LDY2LDE5MSwxODUsMTk5LDE4NiwxMiw1LDk2LDEyNSw2NCw0NCwxNDIsMTIsMTcxLDEyOSw4NCw3Niw3MSwyMTYsOTYsMzMsMTQ1LDUyLDI1NSwxNDYsOTEsMTM1LDU1LDE5NywzMywyNDQsMTYyLDY4LDk3LDQ4LDY3LDg5LDEzMywyMDMsMTg2LDEwMCw4MywxODUsNzAsMTE4LDU5LDE4OSwyNDgsMjEzLDE0Miw5NSwxOTYsMTEyLDE3OSwxNDgsMTg3LDcsMTA4LDI4LDIzNSwxMzIsMSwyMDAsMjI4LDE4MywxNjQsMTM1LDE2LDgyLDI4LDE2NiwzMCwyMzEsMTMzLDg1LDI1MCwxMzgsODksMTk2LDExOCwxNzIsNjUsMTkwLDIzMiw4LDEzLDU4LDgzLDcyLDIzOSwxMDMsNDYsOTYsMzYsNTUsODksMTg3LDM2LDI1LDIxNiwxMDQsMjAwLDM0LDc1LDIyMCwyMzQsMTEyLDIyMywwLDEyNiwxMDYsMjE2LDE5MiwxNDksNDMsODYsMjAsMTcxLDExNSw4MywyMDMsMTIsNDksMTg0LDgyLDIzOCwyMTMsMTQwLDU0LDE1MSw5LDkzLDE3Nyw4Miw1NCwxMjEsMzIsMTI1LDMyLDExMSwxMTksMTg1LDEwMSwxMzQsMjQxLDE0NCwyMjcsMjE2LDI4LDM4LDIyOCw1LDM0LDExNCwxMTEsMjksMjA5LDIwNywxMjUsNDgsMzksMjMxLDEyOSw3OCwyMjksOTEsNzQsNSwyNTIsMTYwLDE2NiwxNDgsMjAsNDgsMTQ3LDIwMiwxOTksMjQ3LDE3MCwyMzEsMTI5LDgzLDIyNCwxNjcsNDksMjM0LDEzNiwxNjMsMzQsMjI4LDExOSwxNTAsMTYsNTgsMTg2LDE5OCwxMzMsNCw2OCwxNTksMTc1LDgxLDE0MCwyNDMsMjQsODAsNzksMjQ0LDEwOCw4MCwxMDMsMTQzLDE2MSw4OCwyMDMsMjI1LDE2MywxNjQsMTk3LDUsODIsMjcsMTM4LDY5LDI0MCwxODYsOTEsMjMzLDEzMSwxNTgsMjAyLDQwLDkwLDgxLDE2MCw4MiwxNDMsMTM3LDE2NCwxMzEsMjAsMTczLDE1MywyNSw5NSw4MCwyNiwxODEsMzgsMTQ4LDU0LDE5NiwxMDQsMjMsMjM3LDEzNiwxNjMsMjE4LDE3LDI3LDY2LDIyOCwxMjcsMjExLDI1MCwxNDksMTY0LDg1LDEwOSwxNjksMTg2LDIwMCwxLDI1MSwyMDEsMTAzLDEyMywxODMsMTU1LDg3LDk0LDE4NywyMzUsMTc4LDk4LDk3LDIwNiwyNSwxMDUsMTYxLDIwMiwyMzEsMTIzLDY2LDEzOCwxNCwxNzcsMTE0LDE2MSw1OSwxNzcsNDAsMTMsMzksMzAsODQsNDgsMTg3LDIzMywxMzEsMTg2LDIwNCwxNjcsOTEsMjIzLDI0MywxOTMsOTIsMjEzLDE5MSwxNCwxNDcsMTcsMTM3LDQsMzYsOTYsNTYsNDUsMjcsMzUsMjAxLDE5MCwxOTMsMjQsMTc3LDE1NCw4NiwxOTcsMTU2LDE2OCwxNjgsMTE1LDMxLDEyNSwyMjksMzUsODAsODksOTksMjM3LDI1MSwxOTAsODIsMSwxMzMsMTUwLDIxNCwyMDUsODcsOSwxOTQsMjM0LDIzNCw4NiwxNjgsMTQ0LDE5MCwyMDEsOTcsMTEyLDE0MSw3NCw3NiwxNDAsOTYsNSwxMTcsNjYsNywyNTUsNDAsMTU5LDQyLDQzLDExOSw4NCw1LDk3LDEsMjE2LDcxLDExLDE2NywxNDUsNjUsMjUxLDUwLDEwMCw1MiwxNzAsNCwxOSwxOSwxMTksMTQwLDEwLDEwLDg1LDE3LDg0LDM3LDEwOSwyNDAsMTk0LDIzLDE2NiwyMzUsMTMxLDc2LDE4NiwzNywxMDQsMjE3LDI5LDIyNywxNTUsNjAsMTA5LDc1LDEwMiwxNywxMjksMTU0LDIyNSwyMiw5OSwxODIsMTcwLDU2LDI1LDIzMSwxNTEsNzksMTYxLDUwLDEwLDIyOSwzLDQwLDE5NiwyNiwxNzgsMTM0LDE0NSwxNywxNTUsMTE2LDE0MSwyMCwxNzIsMTQxLDE2OSw1LDQwLDIwOSw2MiwzNSwzNiwxNCw3NiwyMzYsMTk0LDI0MiwxMTYsMTgwLDIzNiw0Miw4NCw5MSwxMTgsMTM5LDIyNSwxNzksMTg4LDAsMTA1LDEzLDk5LDE4Myw1MywyMjIsMjEzLDEzMSwyMzIsMjI1LDk2LDE5Myw3MSw0LDEwNCw2LDE2NSwxNzksMjM1LDQ5LDIwNywxMTUsMzgsMTIzLDE4NSwyOSw2NSwxODEsMTc2LDE4NSw3MCwxNjksMTgxLDI0MSwyMiw0MSw5MCw2NiwxMjMsODksMTYxLDMwLDE0OCwxMTUsMTI0LDE5OCw2NCw2NiwxMDMsMTAxLDUyLDE5NywxOTAsMTMzLDEwMCwxMzksMTQyLDgzLDk3LDI1MiwxLDEzMiwyMzAsMjM0LDE4MiwyMjEsMjEsODksMTA1LDEyNCwxMDgsMjIwLDE5MywxOTYsMTU1LDE1NiwxNjEsMTUxLDI0MSwxMTcsNjQsMTIwLDIwNiwzOCwyNDEsOTMsMTA2LDIxMiwyNSwxNDAsMTU0LDI3LDE4MSwyNDEsMTAxLDIxMiwzNCwxMzksNTEsNyw5OSwzNCwxNjYsNjAsNTMsMTgyLDc4LDE5MSw3MywxNTUsMjUxLDU2LDE3MSw1MywxOTcsMzYsNDIsMTk5LDE0OCwyNTAsMTk2LDE5MiwxMzUsMTM0LDEwMiwyNTQsMjgsMTE3LDEyNiw4Niw1LDE1Nyw1MywxNjUsMjM4LDEzNSwxNzgsMTgxLDM5LDc2LDE0LDM0LDgwLDYsMjI3LDE2MiwxMjAsMTMwLDEwMywxNywxODgsMTc3LDU0LDk4LDE0MCwxOTUsMTc4LDY3LDE2MCwxNjcsMTQsMTUyLDQ5LDE2Myw2NywyNTAsMTUyLDIwOCwxMTYsMzMsMjQ3LDE4MiwxMjIsMTE2LDEyMywxNjksMTk0LDE2NCwxMTIsMTU2LDc0LDE0OCwxNDgsNjcsMTI1LDExOSwzOSwxMTksMTI0LDU1LDEzMywyMTAsNTksMTI1LDkxLDE4NywxMTQsMTQ1LDcxLDE3MiwxODEsNTEsOTEsMTYxLDU3LDU1LDE0OCw4MSw0OSwxNzQsMTA4LDE1MywyMDYsMjQyLDc4LDIzOSwxOCwxMzAsMzIsMjExLDEyOSwyMjIsNjQsOCwxMjgsMTkzLDEyOCwxNiwxMDYsODUsMTUwLDMsMjAyLDc0LDE2MywyMDIsOCwxOTcsNjMsMTMzLDIwNCwxODQsMTQ4LDE1MywxODksNjIsMTY4LDI2LDE4MywyMTksMTUwLDIwMCwyMTEsNTQsMjQ4LDc1LDExMSwyMzcsMjAyLDE2LDE5MywyMjUsMTkyLDE4Miw1OSwyMDIsMzYsMjMyLDE4MCwxOTcsMTMwLDEyMywxNTksMTU0LDEyMywyMTYsMjQwLDE2MSwyMTIsMTQ1LDExMCwxNTAsODAsMTE4LDIwOCw5MCwxMDYsODEsNzIsMjAsNjksNjAsMjgsMTc3LDkwLDE2NCwxODksMzksMCw4Myw4Miw5OCwxMzAsODAsNDUsMTc3LDc5LDE3NywyMzUsNDEsMTQ0LDI1LDMyLDIyLDEyMiwzMSwxNDUsMjE3LDE2MywxMDEsMjIwLDEsOTgsMTA4LDE5NiwxNzEsMTg2LDEzMiwyOSwyNDAsMjI1LDExMiw0LDY2LDEwMiwxMTksMTQyLDIyNiwyNDMsNDAsMTg0LDI1MSwxMzgsOTMsMjA5LDIyMiwyMTUsMjA4LDExMCwyNDIsMTYsMjksMjUyLDUyLDIyMiw5MSw4NSwxNDYsNTYsNjksNjYsMjE4LDQ2LDkxLDM5LDI0LDI0NSw1NywyNDgsMjE0LDYsMzgsNzgsNjQsOTAsMTM3LDYzLDcyLDI5LDIyNCwxMjAsMTM5LDM4LDI5LDIyNCwzNSwxMDAsMTA2LDcwLDEzMywxMywxMSwxMzcsMjQ0LDE0MCwyMzUsMjQsMjIxLDE0MSwxNywxNTYsNDYsMTAsMTkzLDIyOCwxNjgsMTMwLDE4MSwyMzMsMTcsMTQzLDEyOSw1NSwxMDksMjAsMzUsMjI2LDQ5LDE2OCwxMzcsMTQ3LDk1LDE3MCwxMzAsMjQwLDYwLDEzOSwxMDMsMTc0LDExNiw5NiwxNDgsMTg0LDE2NCwzNiwyMjMsMzAsMTEsNjksMTA1LDc3LDE5NiwxNjcsMTYsMTQ5LDE4NSwyNDYsMTUzLDEyOSwxODAsMTIwLDI0NCwxNTYsMTIsMTMxLDk3LDI0MiwyMjcsNzQsMTQ1LDc5LDddfX19XQAAAAAAAABYAAAAAAAAr2BHcm91cFN0YXRleyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJQZW5kaW5nQ29tbWl0Ijp7Ik1lbWJlciI6eyJzdGFnZWRfcHJvcG9zYWxfcXVldWUiOnsicHJvcG9zYWxfcmVmZXJlbmNlcyI6W3sidmFsdWUiOnsidmVjIjpbMTQ4LDEwNiwyNSwxMDQsMjA3LDE3Myw1NCw4OCwxNzMsNjAsMTg4LDE4MSwxMiwyNTEsOTAsMTM2LDIxNCwyMDIsMiwxNSwxNzgsNSwxMzIsOCw1LDU3LDIsNDUsNjcsMTk0LDcwLDgxXX19XSwicXVldWVkX3Byb3Bvc2FscyI6W1t7InZhbHVlIjp7InZlYyI6WzE0OCwxMDYsMjUsMTA0LDIwNywxNzMsNTQsODgsMTczLDYwLDE4OCwxODEsMTIsMjUxLDkwLDEzNiwyMTQsMjAyLDIsMTUsMTc4LDUsMTMyLDgsNSw1NywyLDQ1LDY3LDE5NCw3MCw4MV19fSx7InByb3Bvc2FsIjp7Ikdyb3VwQ29udGV4dEV4dGVuc2lvbnMiOnsiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOlt7IlJlcXVpcmVkQ2FwYWJpbGl0aWVzIjp7ImV4dGVuc2lvbl90eXBlcyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxfdHlwZXMiOltdLCJjcmVkZW50aWFsX3R5cGVzIjpbXX19XX19fSwicHJvcG9zYWxfcmVmZXJlbmNlIjp7InZhbHVlIjp7InZlYyI6WzE0OCwxMDYsMjUsMTA0LDIwNywxNzMsNTQsODgsMTczLDYwLDE4OCwxODEsMTIsMjUxLDkwLDEzNiwyMTQsMjAyLDIsMTUsMTc4LDUsMTMyLDgsNSw1NywyLDQ1LDY3LDE5NCw3MCw4MV19fSwic2VuZGVyIjp7Ik1lbWJlciI6MH0sInByb3Bvc2FsX29yX3JlZl90eXBlIjoiUHJvcG9zYWwifV1dfSwic3RhdGUiOnsiR3JvdXBNZW1iZXIiOnsiZ3JvdXBfZXBvY2hfc2VjcmV0cyI6eyJpbml0X3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTg0LDUxLDcxLDk2LDE3NSwyMTEsMTk4LDQsMTg3LDUzLDE0MiwxNzksMTUxLDksMzAsNjksMTQ3LDIwOSwxOTMsMTc5LDE4OCwxMzgsMTYyLDE4NCwxOTEsNjcsMTY1LDE2MiwxOTQsNjEsMjQ2LDE2M119fX0sImV4cG9ydGVyX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTkxLDIxOCw0Myw2NiwxNDQsOTIsMCwyMzAsMjI2LDMzLDE4OSwxNjUsNjksMSwyNTAsMjQ0LDI4LDIwMiwxNzMsMjI4LDkxLDg1LDEwMywyNDksMTI3LDQ1LDEwLDk5LDIyOCw4MywwLDEwNF19fX0sImVwb2NoX2F1dGhlbnRpY2F0b3IiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6Wzk2LDEyNiwyMjgsODQsMjA4LDEwNywxMDEsOTQsMTU5LDg0LDIzNywxNjMsNTksNDQsMTMxLDIxNywyNDcsNTYsMjE4LDEyMSwxMTQsMjU1LDMxLDY3LDcyLDM0LDEsNjcsMTYsMTY2LDE2Miw2NV19fX0sImV4dGVybmFsX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTgsMjE1LDQyLDIxNSwyNDUsNjMsMTM2LDEyMywxMiw0NiwxMjksMjA0LDUwLDE0OCwyMzQsMjIyLDQ0LDM2LDE2OCwxNjIsMjA3LDEwOCwyNSwxMzgsMTA5LDIzNSwxNTQsMiwyNDUsMzAsMTMxLDldfX19LCJyZXN1bXB0aW9uX3BzayI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbOTIsMzAsMTgsMzYsMTc2LDIyMCw0Niw0MywxOTAsNyw0NSw3OCwyNDEsMTAyLDE0MywyNDYsMjcsMTYsMTYwLDIyNCwyNCwxMTQsMjUsNTQsMTI4LDIyNywyMiw1Miw2MywyMDYsMTAyLDExXX19fX0sIm1lc3NhZ2Vfc2VjcmV0cyI6eyJzZW5kZXJfZGF0YV9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzIwMiwxMTcsMjQ3LDEwMCw2OSwyMjEsMjAzLDIxLDIwOCwxNTgsMTExLDI0OSwxNjUsMzgsMjM4LDQ0LDE3MywxNTAsMjExLDE0MiwyMTMsMjksOTYsMjAwLDExMCwyNTEsNDMsMTksMTgyLDI0NiwyNDYsOF19fX0sIm1lbWJlcnNoaXBfa2V5Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxOTAsMjQ1LDExMiwxNjAsMzIsMTMsOTgsMTQwLDUzLDEwNiwyMCwyMTYsMjI5LDE3MCw4NywxOTMsNDMsMTM4LDk4LDE0MSwxMzEsMjIxLDE2MSwxMDMsNjEsMjUwLDkwLDYxLDU2LDExMywxMjIsMjM1XX19fSwiY29uZmlybWF0aW9uX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbNDQsMjQzLDUwLDExNCw2MywxNzYsMTg3LDkyLDExMyw0NywxNTIsMjUsMzYsMTc2LDIyOSwxMTQsMTg2LDI1Miw3MiwyMjIsNzIsNzIsOTQsMTQzLDYzLDgzLDAsMTg4LDQxLDI0OSwyMDEsMTQ4XX19fSwic2VyaWFsaXplZF9jb250ZXh0IjpbMCwxLDAsNzcsMTYsMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjIsMCwwLDAsMCwwLDAsMCwyLDMyLDIxNywxMTcsMTIxLDE4NiwxMTMsMTA4LDE2MCw5MSwyNSwxNjgsMjUzLDU4LDE4NywyMTQsMjQ4LDExMCwxNjcsMjUzLDQ5LDkwLDU4LDEwNCwxMzgsMSwyMCwxOTksMjUxLDIyNywxODksNDksMjAyLDE4MCwzMiwxNywyMzgsMjQ4LDI0LDIzOSwxNzksMTQsMjQxLDE4OSwwLDE1LDE0NCwxMDQsMTcsODYsMTEzLDE4Nyw1Nyw5MSwyMDEsNzQsMjQ4LDk5LDI1NCw3NiwyMzAsMTMsNTAsMjIxLDE0Myw3Nyw1MCw4LDAsMyw1LDIsMjQwLDY2LDAsMF0sInNlY3JldF90cmVlIjp7Im93bl9pbmRleCI6MCwibGVhZl9ub2RlcyI6W251bGwsbnVsbF0sInBhcmVudF9ub2RlcyI6W3sic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzYxLDE3MCwxNDksMjM4LDIzMCwyMjcsNDMsMTE2LDE5NiwxOTYsMjQ4LDEzOCwzNCwyMTksODMsMTk1LDE3NCwxMjYsOSwzMiwxMiwyMjYsMTMyLDEwNywxNjksMTk1LDI0MywyMiwzOSwxNTQsMTQsMTM4XX19fSxudWxsXSwiaGFuZHNoYWtlX3NlbmRlcl9yYXRjaGV0cyI6W251bGwsbnVsbF0sImFwcGxpY2F0aW9uX3NlbmRlcl9yYXRjaGV0cyI6W251bGwsbnVsbF0sInNpemUiOjN9fSwic3RhZ2VkX2RpZmYiOnsic3RhZ2VkX2RpZmYiOnsiZGlmZiI6eyJsZWFmX2RpZmYiOnsiMCI6eyJub2RlIjp7InBheWxvYWQiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzM0LDIxMywxMjYsMTAyLDE4MCwxOTcsNywxMTksNSwxNDgsMjMxLDU3LDE1Niw4OCwxNTQsMjcsMTAxLDEsMTE2LDEzMiw1NCw1OCw4MywxMzAsMjQ3LDI0Nyw3MywxNzgsNCwxNDQsMTI2LDIxNiwxMDUsMjMyLDE0MCwxMywyMzIsMjI2LDE4LDIzMSwxNjMsMjA3LDE1OCwyMzAsMTA2LDgxLDUsNDMsMTE4LDgyLDIsNzAsNDAsNCwyMDYsMTg3LDE1OCwxOTksMTE4LDgwLDU2LDIyNCwzOSwyMTksMTE4LDE1MywzNywyNDUsMjUsNDYsMjI5LDE5MywxMzMsNTIsMjA0LDE1NiwzNSwyMDQsMjM5LDEyNCwxNzMsMjIwLDY1LDE2NCwxOTgsMTY2LDE1LDIyLDEwNCwxOTIsNjksMjM2LDE0OCwxMDYsMTc5LDE3NSwzOSw5NiwxOCwyNyw1NSwxODEsMzcsMTYsNjAsMTksMTc4LDExMiw3MywyMTcsMTgzLDE3OSwxMDgsMTQ5LDIzMCwxNzIsMjA1LDk4LDEyMCwxNDIsMjUzLDE3LDE3MCw2NywxMTcsMTk2LDE4MiwxNzIsMTAxLDIzNiwxNzAsMTIxLDE4Niw1Nyw3NywzMyw2NiwzMiw3MywxMTcsMTcyLDEyMiwxNTAsMTM0LDgwLDIyMCw5MiwyMzksMjI5LDksNzMsMjE5LDE2OCwzMywyNTEsMzMsOTcsMTcxLDIwNCw2NiwxNDAsNjMsMzUsMTUzLDE4OSwyMjksMTA2LDEzOSwxMDEsMTU1LDE4NSwxNjAsMjEwLDM4LDUwLDQxLDE4Myw2OSw1OSwxNjAsNDksMTEyLDE2OCwyMzQsMTM0LDksMjAzLDM2LDE5OSwxNjIsMTA4LDUxLDE3NCwyNDEsMTI3LDczLDE3MiwxODcsNTEsMjYsMTUyLDE3MywxNDksODAsODUsNTgsMTY1LDE4Miw4NywyMDAsMjA3LDEyOSwxMjYsMTM1LDExOSwxNjUsMzAsMjMxLDEzNSwyMjQsMTkzLDE2OCwwLDE2MSwxMzgsNjAsMjQ4LDEwLDE4Niw0OCwzMSw5MywxNzgsNywxOTcsMTk5LDU0LDI0NCwxNTAsMTU3LDAsMTIxLDY4LDI0MCwyNDcsMTEwLDE0OSw2OSwxMTIsMTc3LDEwLDE5OCwyNDksMTIzLDE1MywxMjgsMTkyLDIzLDI2LDU2LDc0LDIyNywyMTcsOTcsMTMyLDE4MywxNSwyMiwxMjAsMTc1LDkzLDQ4LDE4LDExOCwxNzgsMTMsMjMyLDE5MiwxMzEsMTU4LDE3NiwxMTcsMTIwLDE2NSw1MiwyMzksMjI2LDE4NSwzNiwxMTUsMTIxLDE1OSwxNjAsOTIsMTIxLDE0NiwxMDYsMTcxLDE5OSw5MywyMzIsMjMsMzUsMjYsMyw0MCw1Miw1LDIwNiwxODIsMjMzLDc0LDE4NCw5MCw2LDI0NiwxODcsNSwxOTUsMTgwLDE3LDk1LDI0MiwxMDksMTY0LDM3LDE0Niw4MywxOTcsMSwzMiwxNzEsMTI2LDgzLDg5LDEwMyw5LDc2LDksMTc0LDY5LDE2NSw5MywxODMsOSw3MywxNjAsMTExLDEyOCwxMiwxNDksMTk4LDI0OCwxMTcsMCwyOCwyLDE2NywyMzUsMjMsNzMsOTcsMTE2LDExMywxNTAsMTQ1LDE2OSw3LDIwNSwxMTMsMTQ3LDcsMTM4LDE4MCw4LDk3LDEwMCwxLDk1LDE2NCw1MCw1Niw2OCwxNzIsMjQ0LDYsMTMwLDgsMTksMTc4LDExMCwyNDEsMTUyLDEzNiwxMzQsMTk2LDU2LDIwMSwxOTYsMjA4LDUzLDg5LDEzMiwyMjYsNTQsMjI0LDI2LDI3LDIyLDE3OCw5Miw0Niw0Miw2OSwxMDAsNTYsMTE4LDgzLDM4LDE5OCwwLDM3LDg2LDExOCwyMjUsNCw0NywzMywyMywyMDgsMTkyLDEwNCwxMCw3Myw3NywyMTcsMTE3LDE0LDE2NSwyMTMsMTUzLDM4LDgzLDE1MCwxMzcsMjQzLDIwMCwyMzcsMTcsMzQsMTI5LDE3OCw4Nyw1MywxNDksMTUwLDExNywxMzQsMTg2LDc0LDIyNiwxNDIsMTIwLDIxMSwxMDMsNzcsMTQ5LDc1LDMxLDIzMCwxNTUsMTYxLDIyOCw3LDU4LDE2NywxNDYsMTc0LDEzMyw2LDE5OCwyMSw1MCwxNDQsMjUyLDE0MywyNDgsOTgsNCwxNiwxMzksMjA0LDEzLDQ5LDExMiw4MiwxODIsNiw5MiwxNjksNzEsODAsNjQsNDUsMTQxLDM5LDE4MSwyMDQsMTMzLDE2Niw4NSw0MSwxNCwyMDMsMjI5LDUxLDI1NCwyMiwxNTIsNjAsMTk5LDgyLDQyLDE4NiwzNywzMywyNiwxLDIzNiw3MiwxNTUsOTksMTIxLDE1OSwyMjAsMjEsMTY2LDExMiw2Nyw0NCw0MywxNiwzNiwxNTcsMTQwLDQ0LDU3LDE0Niw1MiwxMCwxNjYsMTQzLDE0NSwzMiw4MCwxNTQsOTIsMCw2NCw0OCwxNDAsMjI4LDE5MiwxNzEsMTczLDE3MCwxOTYsNDcsMTA0LDc1LDEwNCw4MCw1MCwxNTcsMTM2LDI5LDEyNywxMzgsNDUsNSwyMTQsMjIsNzEsMTE2LDYxLDIxNywyOCwyNyw5NCwxMjksNiwxMiw3NiwxNDYsOTAsNTksMTI0LDQ2LDE2Niw4NiwyMDgsODMsMTk1LDI0OCwxMTUsNTgsMTU4LDIxNiwxMzgsMjI3LDExNCw3LDI0NCwzOSwyNiwyNywyMzIsMzUsOTYsMjMsOCwyMCwxNTAsODgsMTAyLDExOCwxNzMsMTAzLDE1MSwxMjgsMzIsMTMyLDQ2LDEzOSw2NCwxNjgsMjQwLDE0NCw0Niw0LDIxLDY3LDMsMjI5LDE1NCw2OCwxMTksNzAsMTA4LDI0OCwxNzgsMjA1LDE4NSwxLDM0LDY3LDQyLDE0OSw4MSwxNTMsMTM1LDEzOSw5OSwyMzUsMTgxLDEsMTY5LDI2LDIyLDIwNiw1MCwxNiw1NSwxNiw5LDEsMCwxOTUsMjM0LDE4NSwyMDMsMjQwLDE5NywxMDEsMjQzLDI0NCw5NywxNzgsMjAyLDE4Nyw0MCwzOSwxNDQsMTIyLDcsNjEsMTY4LDEsMTY1LDE3Niw3NCwxMjQsMTY5LDEzOSwxNjEsMTQ3LDIxOCwxODMsMTEzLDIwLDI2LDEyMCwxMCwxMDksMTIyLDgxLDEwMSwxMjMsMTE0LDE0Miw5NiwxNTQsMTc0LDIyOCw3MSw3MSwyNDYsMjMwLDExOCw3NSwxMzQsMjA2LDg5LDIwMSwxMTAsMjM3LDE3OSw0MCwxNjMsMjA5LDE4Nyw5OSwwLDU0LDEwMywxNjEsNzIsMjIwLDEyLDIwNiwxMzUsMTE0LDExNCwxNjMsMzYsMTU4LDEyMSwxMDEsNTQsMTUyLDMyLDE2NywxMTgsMTEsMTk0LDg3LDg3LDIwMiw1MiwyMDgsMjAwLDI1NCwyNDUsMTMsMjAwLDIyLDE0OSwyMDUsMTA1LDEyMSw4MCwxNjcsMzUsMTA4LDEzMiwxNTEsMjA5LDE3MCw2MiwxNzMsMTQ5LDE4Miw3OSwyMywxNiwxLDY5LDEwOSwxNiwyNTIsMTY0LDY5LDI0MiwxOTEsMjgsNSwxMjQsMzAsMTYyLDE2MSw3MCwzMiwxOTksMTA2LDY5LDIwMyw5NywyNTAsODMsMjI0LDIwNCwxOTEsMTkxLDIzNSw5OSwxMjgsNTcsMTUwLDEzNyw1NywxNDYsMTAzLDE1MywxNDMsNzEsNTUsMTAxLDIwNCwxNTUsNzcsNSwyMjYsMjQsNDgsMTM0LDY1LDEzLDIwOSwxODEsNDAsODMsMTA2LDIzNCwxMTksNjksNTAsMTYzLDM4LDcyLDIwMiw4OSwxNjgsOCwyMDMsMjIyLDI0NywxMTcsMTMyLDEyMywxMTUsMTE2LDI0NSwxODksMzUsMTY5LDE0MiwxMjMsNCwxMjgsNDEsMjI3LDExNiwxNDAsMTAyLDExLDI0MiwyMjYsMTgyLDQzLDUyLDIwMSwxMzYsMTc4LDE4NCwxNTcsNCwxMzEsOTUsNTMsNzIsMjEyLDE4MSw5NCwyMzgsMjE2LDY4LDIwMywzNiwxMTUsMzgsMjA4LDE5OCwyMTksMTQ4LDE2Myw3MSwxMzAsMTExLDM3LDEzMiwxOTQsOTYsOTAsMTA4LDE3MywwLDE2NCwxNjAsMjQwLDE2OCw2LDE5NiwzMywxMjIsMTk1LDcsMTI1LDIxMSw5NywxNjgsMjMwLDE3Nyw5OSwxNzIsMTM5LDk5LDEyOSw4MSwyNTQsMTU0LDE0Niw0LDE2MywxMTcsNDAsNywxMjEsMTUwLDEwNywyNCwxNzMsMjA5LDY3LDY0LDE3MiwxODUsNjAsMjYsMTk0LDEyMiwxODUsMTczLDQ4LDIzNiwxMTAsMjUzLDE3OCwxNSwyNTMsMjMyLDUwLDE4OSwxNTEsMTQwLDI0MiwxNzgsMTIwLDIzNyw3NiwxNzksMjE5LDEzOSw2NSwxOTgsNTksNiwxODcsMjMzLDE2Miw0NiwxOTcsOTMsNiwxODAsOSwyMTYsMjUyLDE5NSwyNDAsMjQsMTY5LDE1NCwxOTYsMTYzLDEyMywyMzMsNDksMzUsMTIzLDEwLDIxMSw0LDE5Myw1MywxOTUsNDUsNTcsMTU1LDcyLDkxLDQxLDE0Myw4NCwyNSwyLDEyOCwxMzUsMTg1LDE1Niw1MCwxOTUsMjMzLDg2LDE2MCwxMTYsODUsMTgsNzIsMTYyLDM5LDE5NywyNDAsMTc1LDY1LDE1NSwxMjksNDIsMjEyLDksNjEsMyw1MSw3NSwxNzYsNTUsMTM4LDEzNSwyMDcsMjMsMTI4LDEzMiwxNjYsMjEyLDE1Nyw5MCwxMTYsOTcsMTA0LDI0MywxMCwxNTAsMTQwLDE2MiwxNjYsODUsMTM0LDE1NywzMiwxMjMsMjUxLDEwMywxODMsMjE0LDE3MCwxNCwyNDgsNzIsMTg5LDUyLDE2NCwxODUsNjgsMTQ0LDEwMiw3LDM3LDEwNiw1MiwyMjAsMTU1LDIxMCw4MiwyMDcsNzcsMjQ1LDE5NywyNSw1MiwyNywyMDksMjUxLDIxLDE5LDE5NSw2Miw4OSwxMzgsMzAsODMsNCwxNDQsNzgsMjQzLDg0LDEyOSwyMzIsMSwyMTcsMTQ4LDEwMSwxNjgsMTAyLDg3LDk5LDY2LDE3Miw4LDIsMTU1LDIxNSwxMDgsNTMsMTI5LDgzLDM0LDE5NywxMjgsMzAsMjIwLDk2LDEyMyw4MywzNywzNywxNDgsNjYsMTQ5LDE5MSw1Myw1NiwxNjAsMTEyLDE3NywzOCwyMTksMjI4LDE1LDE0NSwxNDQsMTg3LDYxLDQ0LDEyMSwyNywyMjcsNDIsMzEsNSwxOTgsMTY2LDE2MywyMTYsMTg1LDE1NSwxOTUsMTY4LDEwOCwxNjQsMjMwLDI0LDM2LDU3LDY0LDExNSwxMzIsMTA1LDI0MCwyMSw4MiwyMywzLDgzLDIxMywyMDcsMjMyLDYwXX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6WzE2NCwxODAsMTI1LDEyNiw3OSwyMjAsMjIxLDI1MywxMjMsNDIsMjAxLDEyMCwxODAsMTY0LDIwMCwyMDgsMTc3LDk5LDgyLDYwLDU1LDE1NiwxMjYsNzcsMTE3LDExNSwyMDMsMjAzLDE0MiwyNTUsMTY2LDM0XX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTcsMTA4LDEwNSw5OSwxMDFdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IkNvbW1pdCI6eyJ2ZWMiOls2NywyNDEsMTY2LDIyMiwxMCwxNTMsMjM5LDE1NCwxNDEsNDcsMzEsMTQyLDIyMywxNzgsMjQzLDU3LDE1NywxMjIsMTU2LDEwMiwxOSwxMTYsMjAxLDIxNywyNDcsMjI5LDExOCwxNjYsMTQzLDM2LDEyOCwyMzRdfX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbMjE4LDEwNSwxNDEsMTgyLDIwMCwyMjQsMTcyLDExMCwxMjYsMTksMTAxLDI2LDI0Nyw0NSwxOTUsMTczLDIxMywxNjIsODQsMjI5LDEwOSw4LDE3MywyNTEsMTQ1LDIxOCwyNDIsMzIsMCwyMTQsMiwxMCwyNDQsMjA2LDMzLDAsNTAsMjQ3LDgxLDIwOSw0MiwwLDEyMywyMDYsMjEyLDM0LDgyLDc0LDU5LDczLDE4NywxMzksMjEsNjUsMTc3LDEyOCwxMTcsMTc1LDExNyw4NCwxNDMsMjMsMTU4LDddfX19fX0sInBhcmVudF9kaWZmIjp7IjAiOnsibm9kZSI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbMjM3LDE0NywxNDUsMjUxLDk4LDE1LDksMTIsMTg3LDEwLDE5MiwxNTcsMTE0LDIzLDYwLDEsMjQwLDk1LDIwNSwxODgsNTQsMjQwLDMzLDE2MCwxMjUsMjI0LDE5NiwxMzksMTYwLDg0LDIxNywxNjYsMTA1LDExOSwxMTYsOTYsMjA4LDE2NywxODYsMTY4LDQzLDE5MiwyMTMsMjMwLDE0LDI5LDEwLDUxLDYwLDE0NSwxODgsNDYsMTIxLDE5OCwzMCw1OCwxNjMsNCwyNDcsMTEwLDcyLDE4Miw4Niw4Niw1OCwxNTksMTk3LDUxLDE1NywxMDUsMzQsMTM0LDE4MCwyOCwxNzMsMTk0LDEzMiwxMDYsMjQ3LDEzMSwxOTcsNjgsODMsMTAwLDI0NCwyNDQsNTAsMzgsMjEwLDI5LDY4LDI1MiwzNiw3MCwyNDksNjUsNTEsMjEyLDgyLDE4NSw5MCwxNTIsMTM0LDM5LDEzMSw0OSwxODgsNiwxMDUsOTgsMTgzLDcyLDEwNSw5MiwyMzYsNjQsMTM4LDQwLDE5LDI5LDE1LDYwLDk4LDgxLDExNyw2NSw4NywxNTYsMTAsMTk4LDE4NiwxMzYsMTc5LDI0NCwxNzYsNDUsMjYsNTUsMjMyLDE5NCwxODcsOTUsODIsMTQ1LDUsMTAwLDcxLDIwNiwxMzAsMTk4LDEwNCwyMzQsMTg5LDIsMjI1LDIxLDEyNywzNiwxNCwxMiwxNjcsNSw2NSw1MCwxNTIsNDgsMTQwLDU4LDM2LDIxOCwxMjQsMTk4LDYsMjA2LDE2OSwxMDIsMTA2LDE3Niw1NiwxOTIsMTc3LDE0NSwxNzMsNjMsMzgsMTE1LDE3LDI0OSwxNCwxOTcsMjExLDE4Niw5MiwxMCwxNjgsNTUsNjUsMTA5LDIxNiwyMDEsNTQsMiwxMjIsMTEsMzMsNCwxNzcsNTEsOTAsOTgsNzUsMTEyLDEyNCw1Miw0Miw0MSwxMjcsMzYsMTUyLDczLDgsMTIwLDc5LDE4Myw2OSwxNzgsMjIwLDE1MiwyMTEsNzYsMTY1LDQzLDkxLDYyLDEwNCwxMzIsNzEsNDAsMzgsMTQ5LDI0MywxMjAsMjA3LDIyMiwxMzUsMTc4LDE5NSwxMzIsMTQ0LDQ1LDE2NCwyMywxNDAsODksNDcsMTYwLDEwLDEwOSwxNDAsMjA5LDEwNiwxMzgsMTQ0LDE2OSwxNDMsMTIsMywxOTEsNzQsMTU5LDE5NiwyMjUsMTAxLDIxNywyMTAsMTU5LDE1MywyNDAsMjYsMjUxLDI1MSw1LDEyLDExOSwxMjMsMTA2LDE3MCwwLDE3NSw3MCw5NiwxNDksMjA4LDgsMjIsNjYsMTkxLDIwNiwxMzYsMTAwLDEsODYsNDUsMTU0LDM3LDE4OSwxMTIsNjcsMTU0LDMxLDI1LDk1LDQwLDE2OSwxNjEsMTExLDE2NCwzNSwyMjgsMTM3LDU3LDEyNCwyMzQsODgsOTIsNzQsNTAsMTQ4LDYwLDE2Nyw1MCwyMDgsNTcsODMsMjMxLDEwNiwyMDAsMTEyLDMxLDc5LDExOSw4OCwxNDYsMTIyLDI2LDEwMywyMSw0MCwxNTAsMTM4LDE5MiwxNTcsMzUsMTAyLDEyMiwxMjksMTQ2LDEyNCwyMjcsODAsNjQsMTY1LDU5LDEyOSwxNTUsMywxODksOTAsMjgsMTk5LDE1Miw5MywzLDExMiwxMzksMTksODksMTYwLDEwLDE2MCwxMzYsOCwyMjcsMTg3LDE3NCw1NywxNTIsMjEsODQsOTcsNzUsMTgxLDExLDcxLDIwOSw4MiwxMjQsMzIsNDYsMjgsMjQ2LDQ0LDEyMSw4MCw2MSwxMTcsMTA1LDkwLDIzMSwxMzIsMzUsMTkzLDcxLDE0NiwxNTgsMjcsMTc5LDIzOCw4MywxMDgsNjksODksMTg4LDIyOSwyMjQsMTEwLDIzNywxMTUsOTQsMTU5LDIwMCw1MywxMjgsMTkyLDEyNSwxMzMsMjUyLDE5OCwyNDgsMyw0LDAsMTk5LDEyMCwxNjUsMTgzLDE3NywxMzgsOCwxNjgsOTcsMjI1LDksMTk5LDQwLDEyMSw2MCwyMDQsMTQsMjQ4LDIxMCwyNSwyMzUsODEsMTQsMjE3LDEyOCwwLDE0MSwxOTQsMTI0LDE5OCwyNDksMTgwLDYsNjUsMTE4LDEzMywxNTAsNjYsNzgsOTAsMTU1LDMwLDcxLDE2MiwxNjUsODcsNjgsMTQyLDk4LDE5OCwxNTgsODQsNDEsMTUwLDM1LDEzOSwxMCw5LDE0NCw4LDEzMywxMDIsNzAsNzEsNSwyMDAsNjksMTIzLDE5MSwxNjEsMzgsOTEsMjEyLDMyLDI1MiwyNDcsMTYyLDIxNywxMDUsMTgwLDkwLDE0MCwxNDYsMSwyMTMsMTYwLDQ3LDEzNSwxNTgsMTAyLDExOCwyMywyNTIsMTcwLDc0LDcxLDc1LDUsMjM0LDUsNjUsMjI4LDEwNywzNiw4NywxMCwxMTIsOTcsMzksMTE1LDIxNiwzMiw1OSwxODIsMTM5LDU5LDE3NCwyLDIzLDMwLDEwNyw3NCw1NCwxNjgsMTUwLDkyLDIxMiwxOTEsMTI1LDEwMywxNTUsMTQzLDE0NiwzOCwxODQsOTcsMzIsMTE0LDE5NSw3MCw0OSw5NiwxODEsMTAyLDIyOSwxOCwxNjcsMTc5LDEzNSwxNjMsMjUsOTMsMjcsMTMzLDkwLDE5Myw1MywxNDMsMTEyLDM5LDEyOCwxOTksMjgsMTczLDIwOCw0OCw1NCwxMjgsMTYyLDQ4LDQ5LDM5LDEyNCwyMzQsMjQ2LDE4NSwxMzIsNjQsNjgsOTgsMTgwLDExNSw5NiwxLDE4OCwzNCw4Myw5OSwxNDgsMTQ3LDE0OSwxODAsMTcsMTMwLDE3NSw5LDQ1LDIxLDY4LDE0MSwxMDYsMTk1LDY2LDIwMiwxNjEsNTMsNzksMjA5LDI3LDExMCw2OSw1Myw4NywxNzcsMTc1LDI5LDI0NiwyMDUsMTEyLDIzNSwxMTMsMjM1LDEwMSw0MiwyMTMsMTE5LDQsOSwyMzYsNDIsNjAsMTQ2LDEyOCwxNTcsMTg4LDU2LDIxMywzNiwzMCwyMzEsMzksMTk1LDIyNCw0OCwxNzMsMjExLDQ0LDExNSwyMjUsMTg2LDkzLDM0LDc0LDE5MCwxMzMsOTIsMTYxLDExOCwyNiwxOTcsMTQwLDM3LDU2LDQ5LDM3LDI2LDEwOCwyNDMsMTE0LDI1MSwyMjcsMTIsMyw1Nyw1MSwyMjAsMTQ1LDIyLDIzMiw0MCwyOCwzOSwxMzUsMTY5LDE2NiwxNzYsMjQsMTU1LDE4LDEyNiwyMSwxOTgsMTgzLDI1LDc2LDc0LDE0MywzOCw2NSwyMjUsMTYwLDExLDE3MSwxNTQsOTYsMzgsMTIyLDI5LDcsMTY4LDE3Nyw2MCw1MSwxMTksMjI5LDEwNiw4OSwyMiwxNiwxMjEsMTYxLDEzMCwxMDMsMTAyLDI4LDI4LDIyNSwxMDAsODYsMTUsNTAsNzUsMTk0LDQwLDE0MSwxMzksMTE1LDg2LDQ3LDMsNTcsMTcyLDEzNSwwLDIsMjM1LDIwMSwxNDcsMTcyLDE2NSwxNTIsMTY2LDE0MiwxNCwyNTIsNDcsMjAxLDQyLDE0NywxMzEsMjA0LDUwLDQxLDE5LDE3OSw2LDU2LDEyMCwxMiwyMzAsMTYzLDk5LDEyOCwxNiwxMDEsMTg4LDEzNSwyNTQsMjMyLDEzNywxMTMsNDMsMTkyLDIyNSwxMTIsMjAwLDE2MCwyMCwyLDI1NCwxODMsMjEsMjgsNTUsMTM2LDYwLDIzNSwxNTcsNzQsMzYsMTM5LDIyNiw4NiwxMzAsMjU1LDIyNSwxNjcsMTg4LDQ5LDkxLDE3NCwxNDAsMTI5LDMsODQsMTAwLDExNSw0Myw3NSw0LDEyNCwxMzUsNDUsMTYzLDM4LDQ0LDE1NiwxNDAsMTE3LDE4MCwxNzEsMTgwLDI4LDE5Miw1MCwxMjgsMTI3LDc3LDE5LDE3OCwxMzAsMTM0LDEwNywxODksMTcwLDc0LDIzMywxMDUsMTIzLDI0NCwxMjAsMjA3LDEzMiwxMjMsMTc1LDE3OCwxOCwxODQsMjI0LDM5LDIxLDE4MSwxMDIsMTk1LDIxOSwxNjIsMTEsMzYsMzUsMTE2LDY2LDIxLDE2NSwxNDEsMTAsNDYsMTIzLDE3LDE5Miw3MiwzOCwxODMsMTg5LDE4MSwxNzEsMjUxLDE4Myw5Niw3MSwxMzQsNDYsMzAsMjQ4LDQ0LDYzLDEwOCwxMTUsODAsMjIwLDE0MCwxMjUsMzUsMTMyLDIyNSwyMiw1LDEwOCwyOCwxNzgsNjMsMTk4LDExMSwyMzYsODUsMTc5LDE0OSwxLDE4MywxNDMsMTYyLDEzOSwyMiw4MCw0NiwyMzYsMTM5LDYxLDEwOCwxMzMsMTMsMTc1LDI4LDE3OSwxNjMsMTgxLDczLDE5LDEwMSw0Nyw1NSwyNDUsNCwxMTIsMTAwLDQsMTY3LDIyNCwxMjUsMTUwLDE0OSwyMDEsNSwxMjksMTc5LDIzNCwyMDMsMTM3LDU0LDkxLDEwMSwxMTksMTcxLDk4LDc1LDk5LDY1LDg1LDEyOSwxOTQsOSw5LDEzMCw0LDU1LDEzNSwxNjMsMTUzLDUxLDEzNywyMSwzMiwyMTIsMzksODAsMTE3LDU0LDk1LDc3LDIwMywxMTksMTIxLDE1NCw3LDIxNCwxNDQsMTIyLDczLDEzMSwxNjYsMTI4LDE3NywxODgsMTgzLDEsMTc0LDE1MSwxODUsNjUsNjAsODYsODAsOTksNTksMTQsMjQsNjYsNDAsMjIxLDY4LDQ3LDY1LDY1LDE3NywxMzEsMTkyLDE0NCw0Nyw3LDM3LDMzLDc2LDE2NywyNTQsMTY3LDEyMSwyMjIsMTY2LDE1NCw2Myw5NywxNTksMjQwLDE2OSwxMzYsMjMzLDEyMiwxMTgsNTcsMTEyLDE5OSwxMzEsMTc3LDI4LDUxLDE0MCwxODMsMTExLDI1MiwxNTksOTQsNzYsNTMsMTMwLDQxLDE3MiwxMTQsMTE5LDEzMCwxOTUsMTI0LDU2LDEyMiwyMzAsMTAsMTA4LDExMywxMzUsMTY3LDE1NSw0Nyw3NywxMDcsNjksODQsNzAsMTA5LDI1LDE2LDExNywxNjcsNzIsMTM5LDEzLDEwMywxNTQsMjcsMjEwLDYyLDQzLDAsMTI2LDE4NCwyMDgsMTAwLDQxLDI0MCwxODUsMTYyLDIxMSw1NCw1NiwyMDcsMTE2LDQzLDExNywxOCwyMTAsNDIsMjUwLDIxMSwyNTAsMTEyLDEzNywxMTcsMjQ3LDE1MCwxMTMsNDMsMTczLDIyNCwxODEsNTQsMjUxLDUyLDEzMywxMjIsNzcsMzEsMTM1LDIwNywyMDUsMjM1LDIyNCwxMzQsNTQsMTMwLDIzMywxMDgsMjA3LDE1NSwxNTMsOTcsNjcsNzksOTIsNDAsMjA2LDIxNiwyNDMsODcsMjAsMzEsMjIxLDY1LDgxLDIwNiwxNzksMjUxLDQ3LDM2LDEwLDEzMSwxNzUsNTBdfX0sInBhcmVudF9oYXNoIjp7InZlYyI6W119LCJ1bm1lcmdlZF9sZWF2ZXMiOnsibGlzdCI6W119fX19LCJzaXplIjozfSwibmV3X3RyZWVfaGFzaCI6WzIxNywxMTcsMTIxLDE4NiwxMTMsMTA4LDE2MCw5MSwyNSwxNjgsMjUzLDU4LDE4NywyMTQsMjQ4LDExMCwxNjcsMjUzLDQ5LDkwLDU4LDEwNCwxMzgsMSwyMCwxOTksMjUxLDIyNywxODksNDksMjAyLDE4MF19LCJncm91cF9jb250ZXh0Ijp7InByb3RvY29sX3ZlcnNpb24iOiJNbHMxMCIsImNpcGhlcnN1aXRlIjoiTUxTXzI1Nl9YV0lOR19DSEFDSEEyMFBPTFkxMzA1X1NIQTI1Nl9FZDI1NTE5IiwiZ3JvdXBfaWQiOnsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0sImVwb2NoIjoyLCJ0cmVlX2hhc2giOnsidmVjIjpbMjE3LDExNywxMjEsMTg2LDExMywxMDgsMTYwLDkxLDI1LDE2OCwyNTMsNTgsMTg3LDIxNCwyNDgsMTEwLDE2NywyNTMsNDksOTAsNTgsMTA0LDEzOCwxLDIwLDE5OSwyNTEsMjI3LDE4OSw0OSwyMDIsMTgwXX0sImNvbmZpcm1lZF90cmFuc2NyaXB0X2hhc2giOnsidmVjIjpbMTcsMjM4LDI0OCwyNCwyMzksMTc5LDE0LDI0MSwxODksMCwxNSwxNDQsMTA0LDE3LDg2LDExMywxODcsNTcsOTEsMjAxLDc0LDI0OCw5OSwyNTQsNzYsMjMwLDEzLDUwLDIyMSwxNDMsNzcsNTBdfSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOlt7IlJlcXVpcmVkQ2FwYWJpbGl0aWVzIjp7ImV4dGVuc2lvbl90eXBlcyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxfdHlwZXMiOltdLCJjcmVkZW50aWFsX3R5cGVzIjpbXX19XX19LCJpbnRlcmltX3RyYW5zY3JpcHRfaGFzaCI6WzE1MSwxOTMsMTI1LDM4LDc5LDEzOSw0MiwxODQsODQsMjIsMTgzLDMxLDg4LDU4LDExNSwyMTAsMjQ2LDEzNiw5LDExNiwyMTAsMTkxLDEwNiwyLDE0Nyw4MywzNCwyMDgsMTI1LDQ0LDE2NywxODJdLCJjb25maXJtYXRpb25fdGFnIjp7Im1hY192YWx1ZSI6eyJ2ZWMiOlsxMCwyNTIsMTk4LDE0NiwxMTYsMzMsOTUsNSw4OCwxNTEsMzMsMTU1LDI0NiwyMzAsOTUsMTIxLDU4LDEwMCwxMjAsMTAxLDIyNyw0NSwyMDQsMjQ4LDIxNywyMjQsMTMwLDE2OCwxMyw5NywxMzEsMjA2XX19fSwibmV3X2tleXBhaXJzIjpbeyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOlszNCwyMTMsMTI2LDEwMiwxODAsMTk3LDcsMTE5LDUsMTQ4LDIzMSw1NywxNTYsODgsMTU0LDI3LDEwMSwxLDExNiwxMzIsNTQsNTgsODMsMTMwLDI0NywyNDcsNzMsMTc4LDQsMTQ0LDEyNiwyMTYsMTA1LDIzMiwxNDAsMTMsMjMyLDIyNiwxOCwyMzEsMTYzLDIwNywxNTgsMjMwLDEwNiw4MSw1LDQzLDExOCw4MiwyLDcwLDQwLDQsMjA2LDE4NywxNTgsMTk5LDExOCw4MCw1NiwyMjQsMzksMjE5LDExOCwxNTMsMzcsMjQ1LDI1LDQ2LDIyOSwxOTMsMTMzLDUyLDIwNCwxNTYsMzUsMjA0LDIzOSwxMjQsMTczLDIyMCw2NSwxNjQsMTk4LDE2NiwxNSwyMiwxMDQsMTkyLDY5LDIzNiwxNDgsMTA2LDE3OSwxNzUsMzksOTYsMTgsMjcsNTUsMTgxLDM3LDE2LDYwLDE5LDE3OCwxMTIsNzMsMjE3LDE4MywxNzksMTA4LDE0OSwyMzAsMTcyLDIwNSw5OCwxMjAsMTQyLDI1MywxNywxNzAsNjcsMTE3LDE5NiwxODIsMTcyLDEwMSwyMzYsMTcwLDEyMSwxODYsNTcsNzcsMzMsNjYsMzIsNzMsMTE3LDE3MiwxMjIsMTUwLDEzNCw4MCwyMjAsOTIsMjM5LDIyOSw5LDczLDIxOSwxNjgsMzMsMjUxLDMzLDk3LDE3MSwyMDQsNjYsMTQwLDYzLDM1LDE1MywxODksMjI5LDEwNiwxMzksMTAxLDE1NSwxODUsMTYwLDIxMCwzOCw1MCw0MSwxODMsNjksNTksMTYwLDQ5LDExMiwxNjgsMjM0LDEzNCw5LDIwMywzNiwxOTksMTYyLDEwOCw1MSwxNzQsMjQxLDEyNyw3MywxNzIsMTg3LDUxLDI2LDE1MiwxNzMsMTQ5LDgwLDg1LDU4LDE2NSwxODIsODcsMjAwLDIwNywxMjksMTI2LDEzNSwxMTksMTY1LDMwLDIzMSwxMzUsMjI0LDE5MywxNjgsMCwxNjEsMTM4LDYwLDI0OCwxMCwxODYsNDgsMzEsOTMsMTc4LDcsMTk3LDE5OSw1NCwyNDQsMTUwLDE1NywwLDEyMSw2OCwyNDAsMjQ3LDExMCwxNDksNjksMTEyLDE3NywxMCwxOTgsMjQ5LDEyMywxNTMsMTI4LDE5MiwyMywyNiw1Niw3NCwyMjcsMjE3LDk3LDEzMiwxODMsMTUsMjIsMTIwLDE3NSw5Myw0OCwxOCwxMTgsMTc4LDEzLDIzMiwxOTIsMTMxLDE1OCwxNzYsMTE3LDEyMCwxNjUsNTIsMjM5LDIyNiwxODUsMzYsMTE1LDEyMSwxNTksMTYwLDkyLDEyMSwxNDYsMTA2LDE3MSwxOTksOTMsMjMyLDIzLDM1LDI2LDMsNDAsNTIsNSwyMDYsMTgyLDIzMyw3NCwxODQsOTAsNiwyNDYsMTg3LDUsMTk1LDE4MCwxNyw5NSwyNDIsMTA5LDE2NCwzNywxNDYsODMsMTk3LDEsMzIsMTcxLDEyNiw4Myw4OSwxMDMsOSw3Niw5LDE3NCw2OSwxNjUsOTMsMTgzLDksNzMsMTYwLDExMSwxMjgsMTIsMTQ5LDE5OCwyNDgsMTE3LDAsMjgsMiwxNjcsMjM1LDIzLDczLDk3LDExNiwxMTMsMTUwLDE0NSwxNjksNywyMDUsMTEzLDE0Nyw3LDEzOCwxODAsOCw5NywxMDAsMSw5NSwxNjQsNTAsNTYsNjgsMTcyLDI0NCw2LDEzMCw4LDE5LDE3OCwxMTAsMjQxLDE1MiwxMzYsMTM0LDE5Niw1NiwyMDEsMTk2LDIwOCw1Myw4OSwxMzIsMjI2LDU0LDIyNCwyNiwyNywyMiwxNzgsOTIsNDYsNDIsNjksMTAwLDU2LDExOCw4MywzOCwxOTgsMCwzNyw4NiwxMTgsMjI1LDQsNDcsMzMsMjMsMjA4LDE5MiwxMDQsMTAsNzMsNzcsMjE3LDExNywxNCwxNjUsMjEzLDE1MywzOCw4MywxNTAsMTM3LDI0MywyMDAsMjM3LDE3LDM0LDEyOSwxNzgsODcsNTMsMTQ5LDE1MCwxMTcsMTM0LDE4Niw3NCwyMjYsMTQyLDEyMCwyMTEsMTAzLDc3LDE0OSw3NSwzMSwyMzAsMTU1LDE2MSwyMjgsNyw1OCwxNjcsMTQ2LDE3NCwxMzMsNiwxOTgsMjEsNTAsMTQ0LDI1MiwxNDMsMjQ4LDk4LDQsMTYsMTM5LDIwNCwxMyw0OSwxMTIsODIsMTgyLDYsOTIsMTY5LDcxLDgwLDY0LDQ1LDE0MSwzOSwxODEsMjA0LDEzMywxNjYsODUsNDEsMTQsMjAzLDIyOSw1MSwyNTQsMjIsMTUyLDYwLDE5OSw4Miw0MiwxODYsMzcsMzMsMjYsMSwyMzYsNzIsMTU1LDk5LDEyMSwxNTksMjIwLDIxLDE2NiwxMTIsNjcsNDQsNDMsMTYsMzYsMTU3LDE0MCw0NCw1NywxNDYsNTIsMTAsMTY2LDE0MywxNDUsMzIsODAsMTU0LDkyLDAsNjQsNDgsMTQwLDIyOCwxOTIsMTcxLDE3MywxNzAsMTk2LDQ3LDEwNCw3NSwxMDQsODAsNTAsMTU3LDEzNiwyOSwxMjcsMTM4LDQ1LDUsMjE0LDIyLDcxLDExNiw2MSwyMTcsMjgsMjcsOTQsMTI5LDYsMTIsNzYsMTQ2LDkwLDU5LDEyNCw0NiwxNjYsODYsMjA4LDgzLDE5NSwyNDgsMTE1LDU4LDE1OCwyMTYsMTM4LDIyNywxMTQsNywyNDQsMzksMjYsMjcsMjMyLDM1LDk2LDIzLDgsMjAsMTUwLDg4LDEwMiwxMTgsMTczLDEwMywxNTEsMTI4LDMyLDEzMiw0NiwxMzksNjQsMTY4LDI0MCwxNDQsNDYsNCwyMSw2NywzLDIyOSwxNTQsNjgsMTE5LDcwLDEwOCwyNDgsMTc4LDIwNSwxODUsMSwzNCw2Nyw0MiwxNDksODEsMTUzLDEzNSwxMzksOTksMjM1LDE4MSwxLDE2OSwyNiwyMiwyMDYsNTAsMTYsNTUsMTYsOSwxLDAsMTk1LDIzNCwxODUsMjAzLDI0MCwxOTcsMTAxLDI0MywyNDQsOTcsMTc4LDIwMiwxODcsNDAsMzksMTQ0LDEyMiw3LDYxLDE2OCwxLDE2NSwxNzYsNzQsMTI0LDE2OSwxMzksMTYxLDE0NywyMTgsMTgzLDExMywyMCwyNiwxMjAsMTAsMTA5LDEyMiw4MSwxMDEsMTIzLDExNCwxNDIsOTYsMTU0LDE3NCwyMjgsNzEsNzEsMjQ2LDIzMCwxMTgsNzUsMTM0LDIwNiw4OSwyMDEsMTEwLDIzNywxNzksNDAsMTYzLDIwOSwxODcsOTksMCw1NCwxMDMsMTYxLDcyLDIyMCwxMiwyMDYsMTM1LDExNCwxMTQsMTYzLDM2LDE1OCwxMjEsMTAxLDU0LDE1MiwzMiwxNjcsMTE4LDExLDE5NCw4Nyw4NywyMDIsNTIsMjA4LDIwMCwyNTQsMjQ1LDEzLDIwMCwyMiwxNDksMjA1LDEwNSwxMjEsODAsMTY3LDM1LDEwOCwxMzIsMTUxLDIwOSwxNzAsNjIsMTczLDE0OSwxODIsNzksMjMsMTYsMSw2OSwxMDksMTYsMjUyLDE2NCw2OSwyNDIsMTkxLDI4LDUsMTI0LDMwLDE2MiwxNjEsNzAsMzIsMTk5LDEwNiw2OSwyMDMsOTcsMjUwLDgzLDIyNCwyMDQsMTkxLDE5MSwyMzUsOTksMTI4LDU3LDE1MCwxMzcsNTcsMTQ2LDEwMywxNTMsMTQzLDcxLDU1LDEwMSwyMDQsMTU1LDc3LDUsMjI2LDI0LDQ4LDEzNCw2NSwxMywyMDksMTgxLDQwLDgzLDEwNiwyMzQsMTE5LDY5LDUwLDE2MywzOCw3MiwyMDIsODksMTY4LDgsMjAzLDIyMiwyNDcsMTE3LDEzMiwxMjMsMTE1LDExNiwyNDUsMTg5LDM1LDE2OSwxNDIsMTIzLDQsMTI4LDQxLDIyNywxMTYsMTQwLDEwMiwxMSwyNDIsMjI2LDE4Miw0Myw1MiwyMDEsMTM2LDE3OCwxODQsMTU3LDQsMTMxLDk1LDUzLDcyLDIxMiwxODEsOTQsMjM4LDIxNiw2OCwyMDMsMzYsMTE1LDM4LDIwOCwxOTgsMjE5LDE0OCwxNjMsNzEsMTMwLDExMSwzNywxMzIsMTk0LDk2LDkwLDEwOCwxNzMsMCwxNjQsMTYwLDI0MCwxNjgsNiwxOTYsMzMsMTIyLDE5NSw3LDEyNSwyMTEsOTcsMTY4LDIzMCwxNzcsOTksMTcyLDEzOSw5OSwxMjksODEsMjU0LDE1NCwxNDYsNCwxNjMsMTE3LDQwLDcsMTIxLDE1MCwxMDcsMjQsMTczLDIwOSw2Nyw2NCwxNzIsMTg1LDYwLDI2LDE5NCwxMjIsMTg1LDE3Myw0OCwyMzYsMTEwLDI1MywxNzgsMTUsMjUzLDIzMiw1MCwxODksMTUxLDE0MCwyNDIsMTc4LDEyMCwyMzcsNzYsMTc5LDIxOSwxMzksNjUsMTk4LDU5LDYsMTg3LDIzMywxNjIsNDYsMTk3LDkzLDYsMTgwLDksMjE2LDI1MiwxOTUsMjQwLDI0LDE2OSwxNTQsMTk2LDE2MywxMjMsMjMzLDQ5LDM1LDEyMywxMCwyMTEsNCwxOTMsNTMsMTk1LDQ1LDU3LDE1NSw3Miw5MSw0MSwxNDMsODQsMjUsMiwxMjgsMTM1LDE4NSwxNTYsNTAsMTk1LDIzMyw4NiwxNjAsMTE2LDg1LDE4LDcyLDE2MiwzOSwxOTcsMjQwLDE3NSw2NSwxNTUsMTI5LDQyLDIxMiw5LDYxLDMsNTEsNzUsMTc2LDU1LDEzOCwxMzUsMjA3LDIzLDEyOCwxMzIsMTY2LDIxMiwxNTcsOTAsMTE2LDk3LDEwNCwyNDMsMTAsMTUwLDE0MCwxNjIsMTY2LDg1LDEzNCwxNTcsMzIsMTIzLDI1MSwxMDMsMTgzLDIxNCwxNzAsMTQsMjQ4LDcyLDE4OSw1MiwxNjQsMTg1LDY4LDE0NCwxMDIsNywzNywxMDYsNTIsMjIwLDE1NSwyMTAsODIsMjA3LDc3LDI0NSwxOTcsMjUsNTIsMjcsMjA5LDI1MSwyMSwxOSwxOTUsNjIsODksMTM4LDMwLDgzLDQsMTQ0LDc4LDI0Myw4NCwxMjksMjMyLDEsMjE3LDE0OCwxMDEsMTY4LDEwMiw4Nyw5OSw2NiwxNzIsOCwyLDE1NSwyMTUsMTA4LDUzLDEyOSw4MywzNCwxOTcsMTI4LDMwLDIyMCw5NiwxMjMsODMsMzcsMzcsMTQ4LDY2LDE0OSwxOTEsNTMsNTYsMTYwLDExMiwxNzcsMzgsMjE5LDIyOCwxNSwxNDUsMTQ0LDE4Nyw2MSw0NCwxMjEsMjcsMjI3LDQyLDMxLDUsMTk4LDE2NiwxNjMsMjE2LDE4NSwxNTUsMTk1LDE2OCwxMDgsMTY0LDIzMCwyNCwzNiw1Nyw2NCwxMTUsMTMyLDEwNSwyNDAsMjEsODIsMjMsMyw4MywyMTMsMjA3LDIzMiw2MF19fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6WzExNSwxLDIsOTUsMjQ1LDU4LDYxLDE5NywyMDIsNjgsMjQ0LDE4OSwxMjgsMTgyLDEyOSwyMSwxODIsMTIsOTIsMjI4LDYyLDIzNCwxNzYsMTg4LDYxLDIxMCwxNDAsMjIxLDE0Niw2NiwxOTUsNzIsMjUsMjE3LDE4NiwxMTYsNTQsMTA4LDEzNCwxNTYsMTIwLDE3NiwyNCwxMTMsOTksMTAwLDk5LDIwNCwyNDUsMTE3LDE2OSw2Myw0NCwxNzQsMTUxLDIzMCw1OCwxNzQsMTA4LDIwMCwxNjcsMTgwLDYzLDIwLDk4LDEwNiwyMzQsMTcyLDEwMywxODYsMjQ2LDE2MCwyMDMsMjQ1LDEzMiwxMjksMTgyLDExNSwxNDMsMTksMTE1LDI0MCw5OSwxOTYsMjMzLDI1MCwxOTQsMjE3LDE2Nyw5NCwyMjgsNDMsOCwyMDUsMjQxLDE1NSwxNTAsNTgsMjAsMTQ2LDE5LDUyLDcxLDExOCw1LDE3MywxMiwxMjYsNjMsMzksMTgyLDI5LDU5LDE2OSwxNTUsMjE1LDIwLDQyLDI0NywxMzAsMTA2LDUyLDE3MSw5MCwyNDAsMTEzLDE2OSwxMzIsMTA2LDI0Myw0MSwxMzIsOTksMTY4LDM0LDEwMSw0OSw0Miw3MiwyMDMsOTAsMjQ0LDM5LDE1MywyMzUsMTEsMjMsMjEyLDQyLDE5NywyMTIsMTE0LDE3MSwxOTEsODIsODEsMjAwLDI0NiwxODQsMTksMjAsMTE5LDIyNiw2NiwxNzAsMjE2LDU3LDE2NSwzMSwxMjksNTAsMjAsODAsMTU2LDEwOSwxMjQsMTk3LDE1NiwxNjAsMTQwLDE2NSwxNjgsMTI0LDAsNzYsNTUsNjQsMjEsNTcsMjA4LDEwMSwxMzIsMjI0LDM2LDEwLDIyNCw0NCwxNjQsMjA2LDIyNywxMTgsMTI2LDEsMzgsMTM3LDE2NSwxMDYsMTQ1LDYsOTIsNTUsMTU0LDE4Nyw3NiwyMjksNiwyMDUsMTg3LDEwNCwyMTksMTEsMTI4LDIwNyw1MywxMDksNzEsMTM1LDk3LDI1MSw0MCw0OCwxNywxMjMsMTQ3LDExMCwxNjksMTI0LDIzNSwzMiwxNTUsMTk2LDEwNSw0NSwxOTcsMTA2LDE1NiwxMiwxMzAsMTMyLDI0NCw4NywxNyw1OSw2OCwxNywyMDQsMTM5LDU2LDY3LDgsMjA1LDcxLDY3LDEsMTA2LDIwMSwxMSwxMTcsODAsNzQsMTU5LDE1NSwxMzMsMTExLDExNywzNCwyNCw4NCw5MCw3NCwxNjUsMTM0LDQsODMsMTUxLDE1MCwxNzksMTAyLDEyMyw5NywxMTUsOTYsMjAyLDE2MCwyMTQsMjcsMjgsMTY3LDEwLDMwLDIzNCwxNTEsMTA5LDExMCw4MiwxODgsMjM3LDE3OCwxMjcsODgsMTMwLDEyOSwxODMsMjMwLDUxLDI1Myw4LDk2LDE4MSwyNTEsOTQsMTkwLDIwLDQ3LDQsMTAzLDExMSwxNjcsMTYsMTE4LDU3LDE2NiwxLDM5LDIyNSw4MSwxMDksOTcsMTg3LDE5MCwxODIsMTY2LDE1NCw3MiwxNDEsMTUsMjMwLDIwNSwyNDMsMTk2LDIwNiw0MiwzMywxOTAsMTM4LDExNCwxMjcsMTgwLDE5LDk0LDg5LDgsMTQ1LDE2NCwyNDMsMjAxLDY3LDIwNCwxNDcsODEsNzEsMjA3LDIyNywxNzEsMTU1LDU4LDExLDIxLDEyMywxOTQsMzgsMTc3LDE3MCwxODMsMjQ3LDEzNiw4LDEyMywxMzksMTQ5LDYsMTYyLDg3LDE5MywxNTAsMTk5LDE4OSwxNzYsMTQyLDI1NCwyNDUsNjEsODEsMTM3LDQyLDE1LDIsMjUsMTE1LDIwMiwxMTYsNjQsMTAyLDMzLDE4MSwxNjgsNTIsMTg4LDE3MSwxMzksNjYsMjA4LDE0NCwxNTIsMTAxLDkyLDEwMiw1NSwxMDQsMjIxLDEwNywxODEsNDAsMTg1LDgwLDE0MCwyNDYsMTY0LDIwNiw5Miw2MSwxNjQsMzUsOTMsMTQxLDE3NywxMDcsMjI0LDEzOSw3LDIxMSwxMzgsMTk3LDI4LDg3LDE0Nyw1MCwxMTYsMTQ1LDIxMCw4MCwxOCwxMDEsMTE0LDE1MywxNDMsMTc4LDEwOCwxNTYsMTUwLDE3MSwxMzAsMTM3LDE5MiwzNCw4NSw1OCwyNDMsNTEsMTk2LDI0NSwxMDMsMjAzLDE2NywyMTcsMTkyLDM3LDM0LDE0NCwxOSwxMSw1NCwyNDQsNTEsMTUzLDIxMiwyNCwxMTYsMTQyLDEwNCw5OSwyMDcsNDIsMTYwLDQ5LDEyMiw1NSwyNTAsNjYsMTA2LDk2LDIxNSw5NSwzMSwxNTEsMzUsODAsMTk0LDEzMCwxOCwxODQsMzgsMTkxLDgsMTgxLDIxMSwxODEsNzIsMTU3LDE2LDE3NCw1LDU4LDEyLDIyNywxOTIsMTg3LDExNCwxMSwxNCw4NSwxMjEsMTg4LDEwLDEwMywxNjAsMTA0LDcxLDEwNywyMTEsNjgsMTEyLDQ4LDExMiwxMzQsMTAwLDg0LDEzMyw5OCw5LDk4LDI1MSw1MSw3OSwyMDEsNTQsMTIxLDI0Myw3NiwwLDI1MiwyNDIsMTc3LDEzLDk2LDEsODgsMTM0LDQwLDI0NywxNiwxMTcsMjIxLDUzLDExMywyNDMsMjQxLDI3LDE4MCwxMzQsMzIsMjM3LDIyLDE2NCwyNTEsMTUwLDQ2LDE1NCwxMjEsMTMxLDg0LDY0LDExMCwxODYsMTU0LDQ2LDIxNiwzNSwxMDgsMTEwLDE5NywxODAsMTQ1LDE0NSwxMSw5NiwyNywxNDAsMTMyLDIxMCw3NywxMzAsMjE3LDE0MywxNCwyMDQsOTQsNjcsMTI0LDEwNyw1OCwxLDMzLDk0LDUzLDE0MSwxNiwyMzMsOTksMTkzLDEzNiw2NCw2MCwxMTksMTYxLDQ2LDExNywxODUsNTMsMTgsMTQ1LDI0MiwxMSw4MywxOTgsMjAzLDEzMyw4OCwyMjgsMTM3LDQ3LDIzMSwxNTcsMTUsMTY4LDE5OCwyLDY0LDE4NCw0NSwyNDUsMTcwLDI5LDIwMiwxMjEsNjMsMjAxLDE3MSwyMTgsNjgsMzksMTA3LDE5OSwyMDQsODEsMjUxLDQ1LDc2LDgwLDIwMiwxODcsNTIsMjEsNzMsMTE1LDE2Nyw0NSw1NSwxMzYsMTM0LDU1LDY0LDYzLDExLDk4LDE1LDE2OSwxODQsMjE0LDY0LDIwNSw2MywyNTIsMTAsMTMsMjI4LDIwNCwyMDksNjYsMTM4LDkxLDE5NCwxMDAsMjU0LDM4LDE0MSw0MywyMzAsODgsMzMsMTIsMTc4LDk2LDE5NSwyMCw4NSwxMDUsMjA0LDgxLDE0NSw1Niw0NSwyMzYsMTgwLDE2OCwxNTUsMTU3LDk0LDIxMiw2OSw5NywxMjksOTcsMjA1LDk2LDgxLDIyMSwxNTEsMjAzLDIxNCw5LDIwMiwxMzMsMTkyLDkxLDQ3LDExNiw2MSw5NSw2NCwyMDEsMjM2LDIyOCwxMzQsMjMwLDIyNiwxOTcsMTE5LDcyLDE0NSwyMjUsNDQsNjAsMzQsMTQ5LDEyNiwxNDQsMTc4LDYxLDEwMSw5MCw1NCw2MiwxMjksOTcsMjI0LDUxLDE5Myw3MSw4OCwxNywwLDQwLDE1NiwyNTMsNDAsNTgsNjcsNTMsMTcsMjAwLDIyOSw0MCwyMzcsMjI4LDE2Miw0NiwyNTEsMTgxLDIxMyw2MCwxNywxOTYsMjQzLDE2MiwyMTIsMTg1LDI0LDIzOSwxNjAsMjAxLDQxLDM1LDk3LDEzOCwyMiwxNTYsOTEsNjAsMywzMywxMTcsMjcsMjE4LDEzOCwxMzgsMjU1LDI1LDEyNSwxNzUsMTkzLDQ1LDEyNyw5LDEyOCwyNTQsMjQ4LDg1LDY2LDE4OCw0MCwxMjcsMjA4LDM3LDE0NywxODgsNDcsNjgsMjE3LDgsNCwyMDQsMTQsMTMzLDEzNCw5Myw4OSwyNTAsOTgsMTA0LDQ4LDQyLDE3NiwxNTAsMTgsMjUyLDE4Myw1NywxNDYsMTY3LDE0NSwxNjAsMTgxLDE5MCwyMSwzOCwyMSwxNDQsMzMsODUsODQsMjQ1LDg2LDgsMjE1LDEyMywzNiw5LDExOSwyMjYsNDgsOTIsMTE3LDMsMTYyLDQ4LDEzNiwxNjEsMTAxLDE5NiwyMiwzOCw1OSw3MCwzMSwyNDYsMTY4LDEwNiw5OSwxNTcsMTU2LDI0OSwxOTIsMTcxLDI1MiwxNjUsMjA0LDE0MCwxNjUsMTk5LDExOSw0OCwxMzIsMTI0LDEzNCwyMzMsMjE5LDE0NCw1MywxNTQsOTMsMTUzLDQsMTgyLDE0NCw3NCw0NywyMjksMjEzLDE5NCwxMDEsNDQsODAsMTkzLDE4OCwxNDcsMTQ0LDExNiwxMDEsMjIxLDE5NCwxNDgsMjQwLDI1MSwxOTksNCwxMTQsNjEsNzksMTIyLDkxLDE3MSwxOTgsMTg3LDEyMCwyMzIsMiwxMDIsMjIwLDEyLDE2Niw1NCwxMSwxOTEsNDksNjMsMjE4LDE3MSwxNTcsMTgsNTEsMTE4LDk0LDU3LDE0MCw4MCwzNywxMzQsNjAsOTksMTEsMTc3LDUxLDEyMSwxMTUsMTg1LDE5Miw4OCw1MywxMTUsMjMzLDE5NSw3Myw3NSwyMTgsMTQyLDIsNDIsNTMsMTM4LDM0LDg4LDE3NiwxMDAsNTIsMTMxLDY5LDE4NSw5MSwxNTYsMTYyLDI0NiwyNywxOTMsMTQsMjMzLDMwLDIwNiwxNjEsNDQsNjgsMTksNzEsMTc1LDE1MiwxNDAsNTcsMTgyLDE3LDYwLDEyMSw4NiwxMDAsMjQ1LDMzLDE3NCwxMTIsMTI0LDE4MSwyNywxNDYsMTM3LDIyOCwxMDcsMTE1LDg3LDE0NywxODUsMTE0LDY3LDk3LDEzNCwxMjIsMTE2LDUyLDUxLDIxNCwxNjUsMjAyLDYyLDAsMTYyLDMxLDIwMywyMSwxNSwxMiw4MSwxNzQsMjI5LDE4OCwxOTcsMTk3LDExMCw1NywyNDEsMTI2LDI0Miw5OCw3MSwxODMsNzIsODQsNDMsMTcsMTA1LDg0LDg1LDQ2LDExMSwyNDQsNCwzNywxNTEsNSwyMDYsMTk3LDE4LDExMyw3MSw2MCwxMjIsMjAwLDE1NiwyMjcsMTMwLDE5OCwyMzYsMTc4LDExNiwzMiw1MSw0MywxMjAsOCwxMSwxMjcsNTksMTA0LDczLDE5NSwxNzgsMzQsMjEzLDEyNiwxMDIsMTgwLDE5Nyw3LDExOSw1LDE0OCwyMzEsNTcsMTU2LDg4LDE1NCwyNywxMDEsMSwxMTYsMTMyLDU0LDU4LDgzLDEzMCwyNDcsMjQ3LDczLDE3OCw0LDE0NCwxMjYsMjE2LDEwNSwyMzIsMTQwLDEzLDIzMiwyMjYsMTgsMjMxLDE2MywyMDcsMTU4LDIzMCwxMDYsODEsNSw0MywxMTgsODIsMiw3MCw0MCw0LDIwNiwxODcsMTU4LDE5OSwxMTgsODAsNTYsMjI0LDM5LDIxOSwxMTgsMTUzLDM3LDI0NSwyNSw0NiwyMjksMTkzLDEzMyw1MiwyMDQsMTU2LDM1LDIwNCwyMzksMTI0LDE3MywyMjAsNjUsMTY0LDE5OCwxNjYsMTUsMjIsMTA0LDE5Miw2OSwyMzYsMTQ4LDEwNiwxNzksMTc1LDM5LDk2LDE4LDI3LDU1LDE4MSwzNywxNiw2MCwxOSwxNzgsMTEyLDczLDIxNywxODMsMTc5LDEwOCwxNDksMjMwLDE3MiwyMDUsOTgsMTIwLDE0MiwyNTMsMTcsMTcwLDY3LDExNywxOTYsMTgyLDE3MiwxMDEsMjM2LDE3MCwxMjEsMTg2LDU3LDc3LDMzLDY2LDMyLDczLDExNywxNzIsMTIyLDE1MCwxMzQsODAsMjIwLDkyLDIzOSwyMjksOSw3MywyMTksMTY4LDMzLDI1MSwzMyw5NywxNzEsMjA0LDY2LDE0MCw2MywzNSwxNTMsMTg5LDIyOSwxMDYsMTM5LDEwMSwxNTUsMTg1LDE2MCwyMTAsMzgsNTAsNDEsMTgzLDY5LDU5LDE2MCw0OSwxMTIsMTY4LDIzNCwxMzQsOSwyMDMsMzYsMTk5LDE2MiwxMDgsNTEsMTc0LDI0MSwxMjcsNzMsMTcyLDE4Nyw1MSwyNiwxNTIsMTczLDE0OSw4MCw4NSw1OCwxNjUsMTgyLDg3LDIwMCwyMDcsMTI5LDEyNiwxMzUsMTE5LDE2NSwzMCwyMzEsMTM1LDIyNCwxOTMsMTY4LDAsMTYxLDEzOCw2MCwyNDgsMTAsMTg2LDQ4LDMxLDkzLDE3OCw3LDE5NywxOTksNTQsMjQ0LDE1MCwxNTcsMCwxMjEsNjgsMjQwLDI0NywxMTAsMTQ5LDY5LDExMiwxNzcsMTAsMTk4LDI0OSwxMjMsMTUzLDEyOCwxOTIsMjMsMjYsNTYsNzQsMjI3LDIxNyw5NywxMzIsMTgzLDE1LDIyLDEyMCwxNzUsOTMsNDgsMTgsMTE4LDE3OCwxMywyMzIsMTkyLDEzMSwxNTgsMTc2LDExNywxMjAsMTY1LDUyLDIzOSwyMjYsMTg1LDM2LDExNSwxMjEsMTU5LDE2MCw5MiwxMjEsMTQ2LDEwNiwxNzEsMTk5LDkzLDIzMiwyMywzNSwyNiwzLDQwLDUyLDUsMjA2LDE4MiwyMzMsNzQsMTg0LDkwLDYsMjQ2LDE4Nyw1LDE5NSwxODAsMTcsOTUsMjQyLDEwOSwxNjQsMzcsMTQ2LDgzLDE5NywxLDMyLDE3MSwxMjYsODMsODksMTAzLDksNzYsOSwxNzQsNjksMTY1LDkzLDE4Myw5LDczLDE2MCwxMTEsMTI4LDEyLDE0OSwxOTgsMjQ4LDExNywwLDI4LDIsMTY3LDIzNSwyMyw3Myw5NywxMTYsMTEzLDE1MCwxNDUsMTY5LDcsMjA1LDExMywxNDcsNywxMzgsMTgwLDgsOTcsMTAwLDEsOTUsMTY0LDUwLDU2LDY4LDE3MiwyNDQsNiwxMzAsOCwxOSwxNzgsMTEwLDI0MSwxNTIsMTM2LDEzNCwxOTYsNTYsMjAxLDE5NiwyMDgsNTMsODksMTMyLDIyNiw1NCwyMjQsMjYsMjcsMjIsMTc4LDkyLDQ2LDQyLDY5LDEwMCw1NiwxMTgsODMsMzgsMTk4LDAsMzcsODYsMTE4LDIyNSw0LDQ3LDMzLDIzLDIwOCwxOTIsMTA0LDEwLDczLDc3LDIxNywxMTcsMTQsMTY1LDIxMywxNTMsMzgsODMsMTUwLDEzNywyNDMsMjAwLDIzNywxNywzNCwxMjksMTc4LDg3LDUzLDE0OSwxNTAsMTE3LDEzNCwxODYsNzQsMjI2LDE0MiwxMjAsMjExLDEwMyw3NywxNDksNzUsMzEsMjMwLDE1NSwxNjEsMjI4LDcsNTgsMTY3LDE0NiwxNzQsMTMzLDYsMTk4LDIxLDUwLDE0NCwyNTIsMTQzLDI0OCw5OCw0LDE2LDEzOSwyMDQsMTMsNDksMTEyLDgyLDE4Miw2LDkyLDE2OSw3MSw4MCw2NCw0NSwxNDEsMzksMTgxLDIwNCwxMzMsMTY2LDg1LDQxLDE0LDIwMywyMjksNTEsMjU0LDIyLDE1Miw2MCwxOTksODIsNDIsMTg2LDM3LDMzLDI2LDEsMjM2LDcyLDE1NSw5OSwxMjEsMTU5LDIyMCwyMSwxNjYsMTEyLDY3LDQ0LDQzLDE2LDM2LDE1NywxNDAsNDQsNTcsMTQ2LDUyLDEwLDE2NiwxNDMsMTQ1LDMyLDgwLDE1NCw5MiwwLDY0LDQ4LDE0MCwyMjgsMTkyLDE3MSwxNzMsMTcwLDE5Niw0NywxMDQsNzUsMTA0LDgwLDUwLDE1NywxMzYsMjksMTI3LDEzOCw0NSw1LDIxNCwyMiw3MSwxMTYsNjEsMjE3LDI4LDI3LDk0LDEyOSw2LDEyLDc2LDE0Niw5MCw1OSwxMjQsNDYsMTY2LDg2LDIwOCw4MywxOTUsMjQ4LDExNSw1OCwxNTgsMjE2LDEzOCwyMjcsMTE0LDcsMjQ0LDM5LDI2LDI3LDIzMiwzNSw5NiwyMyw4LDIwLDE1MCw4OCwxMDIsMTE4LDE3MywxMDMsMTUxLDEyOCwzMiwxMzIsNDYsMTM5LDY0LDE2OCwyNDAsMTQ0LDQ2LDQsMjEsNjcsMywyMjksMTU0LDY4LDExOSw3MCwxMDgsMjQ4LDE3OCwyMDUsMTg1LDEsMzQsNjcsNDIsMTQ5LDgxLDE1MywxMzUsMTM5LDk5LDIzNSwxODEsMSwxNjksMjYsMjIsMjA2LDUwLDE2LDU1LDE2LDksMSwwLDE5NSwyMzQsMTg1LDIwMywyNDAsMTk3LDEwMSwyNDMsMjQ0LDk3LDE3OCwyMDIsMTg3LDQwLDM5LDE0NCwxMjIsNyw2MSwxNjgsMSwxNjUsMTc2LDc0LDEyNCwxNjksMTM5LDE2MSwxNDcsMjE4LDE4MywxMTMsMjAsMjYsMTIwLDEwLDEwOSwxMjIsODEsMTAxLDEyMywxMTQsMTQyLDk2LDE1NCwxNzQsMjI4LDcxLDcxLDI0NiwyMzAsMTE4LDc1LDEzNCwyMDYsODksMjAxLDExMCwyMzcsMTc5LDQwLDE2MywyMDksMTg3LDk5LDAsNTQsMTAzLDE2MSw3MiwyMjAsMTIsMjA2LDEzNSwxMTQsMTE0LDE2MywzNiwxNTgsMTIxLDEwMSw1NCwxNTIsMzIsMTY3LDExOCwxMSwxOTQsODcsODcsMjAyLDUyLDIwOCwyMDAsMjU0LDI0NSwxMywyMDAsMjIsMTQ5LDIwNSwxMDUsMTIxLDgwLDE2NywzNSwxMDgsMTMyLDE1MSwyMDksMTcwLDYyLDE3MywxNDksMTgyLDc5LDIzLDE2LDEsNjksMTA5LDE2LDI1MiwxNjQsNjksMjQyLDE5MSwyOCw1LDEyNCwzMCwxNjIsMTYxLDcwLDMyLDE5OSwxMDYsNjksMjAzLDk3LDI1MCw4MywyMjQsMjA0LDE5MSwxOTEsMjM1LDk5LDEyOCw1NywxNTAsMTM3LDU3LDE0NiwxMDMsMTUzLDE0Myw3MSw1NSwxMDEsMjA0LDE1NSw3Nyw1LDIyNiwyNCw0OCwxMzQsNjUsMTMsMjA5LDE4MSw0MCw4MywxMDYsMjM0LDExOSw2OSw1MCwxNjMsMzgsNzIsMjAyLDg5LDE2OCw4LDIwMywyMjIsMjQ3LDExNywxMzIsMTIzLDExNSwxMTYsMjQ1LDE4OSwzNSwxNjksMTQyLDEyMyw0LDEyOCw0MSwyMjcsMTE2LDE0MCwxMDIsMTEsMjQyLDIyNiwxODIsNDMsNTIsMjAxLDEzNiwxNzgsMTg0LDE1Nyw0LDEzMSw5NSw1Myw3MiwyMTIsMTgxLDk0LDIzOCwyMTYsNjgsMjAzLDM2LDExNSwzOCwyMDgsMTk4LDIxOSwxNDgsMTYzLDcxLDEzMCwxMTEsMzcsMTMyLDE5NCw5Niw5MCwxMDgsMTczLDAsMTY0LDE2MCwyNDAsMTY4LDYsMTk2LDMzLDEyMiwxOTUsNywxMjUsMjExLDk3LDE2OCwyMzAsMTc3LDk5LDE3MiwxMzksOTksMTI5LDgxLDI1NCwxNTQsMTQ2LDQsMTYzLDExNyw0MCw3LDEyMSwxNTAsMTA3LDI0LDE3MywyMDksNjcsNjQsMTcyLDE4NSw2MCwyNiwxOTQsMTIyLDE4NSwxNzMsNDgsMjM2LDExMCwyNTMsMTc4LDE1LDI1MywyMzIsNTAsMTg5LDE1MSwxNDAsMjQyLDE3OCwxMjAsMjM3LDc2LDE3OSwyMTksMTM5LDY1LDE5OCw1OSw2LDE4NywyMzMsMTYyLDQ2LDE5Nyw5Myw2LDE4MCw5LDIxNiwyNTIsMTk1LDI0MCwyNCwxNjksMTU0LDE5NiwxNjMsMTIzLDIzMyw0OSwzNSwxMjMsMTAsMjExLDQsMTkzLDUzLDE5NSw0NSw1NywxNTUsNzIsOTEsNDEsMTQzLDg0LDI1LDIsMTI4LDEzNSwxODUsMTU2LDUwLDE5NSwyMzMsODYsMTYwLDExNiw4NSwxOCw3MiwxNjIsMzksMTk3LDI0MCwxNzUsNjUsMTU1LDEyOSw0MiwyMTIsOSw2MSwzLDUxLDc1LDE3Niw1NSwxMzgsMTM1LDIwNywyMywxMjgsMTMyLDE2NiwyMTIsMTU3LDkwLDExNiw5NywxMDQsMjQzLDEwLDE1MCwxNDAsMTYyLDE2Niw4NSwxMzQsMTU3LDMyLDEyMywyNTEsMTAzLDE4MywyMTQsMTcwLDE0LDI0OCw3MiwxODksNTIsMTY0LDE4NSw2OCwxNDQsMTAyLDcsMzcsMTA2LDUyLDIyMCwxNTUsMjEwLDgyLDIwNyw3NywyNDUsMTk3LDI1LDUyLDI3LDIwOSwyNTEsMjEsMTksMTk1LDYyLDg5LDEzOCwzMCw4Myw0LDE0NCw3OCwyNDMsODQsMTI5LDIzMiwxLDIxNywxNDgsMTAxLDE2OCwxMDIsODcsOTksNjYsMTcyLDgsMiwxNTUsMjE1LDEwOCw1MywxMjksODMsMzQsMTk3LDEyOCwzMCwyMjAsOTYsMTIzLDgzLDM3LDM3LDE0OCw2NiwxNDksMTkxLDUzLDU2LDE2MCwxMTIsMTc3LDM4LDIxOSwyMjgsMTUsMTQ1LDE0NCwxODcsNjEsNDQsMTIxLDI3LDEyMCwyMTIsOTcsNzksMTYxLDE3OCw3Miw4MiwxOTEsNTksMTMwLDExMCwyMzYsMjM0LDE1NCw0OSwxMjAsNTAsMjMsMzIsMTQ4LDExMywxNjksNDYsMjEsMTEwLDExLDEsMTkwLDExLDI1NSwyNCwyMzIsMjUsMTkyLDE2Niw2NywxLDU5LDIyLDEwOCw1MiwyMjEsMjE3LDE5NCwzOSwxMjMsMTYzLDQxLDEwNywyMDgsNjAsMjUwLDY0LDU1LDE5MSwyMzgsMjI4LDEwNyw2Nyw1MCw2NiwxMzcsMTEyLDczLDExNSw4MiwyMTQsOTgsMjUwLDIwNCwxNTAsMjQyLDc5LDIyMSwxODEsMjQ1LDM2LDE1MSwyNSwyMTgsOTQsMjQ1LDE4MiwyNTMsMTcwLDgsMTE2LDEyNiwxODcsNjIsMjU0LDE1NSwzNywxMjcsNjAsMjI3LDQyLDMxLDUsMTk4LDE2NiwxNjMsMjE2LDE4NSwxNTUsMTk1LDE2OCwxMDgsMTY0LDIzMCwyNCwzNiw1Nyw2NCwxMTUsMTMyLDEwNSwyNDAsMjEsODIsMjMsMyw4MywyMTMsMjA3LDIzMiw2MF19fX0seyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOlsyMzcsMTQ3LDE0NSwyNTEsOTgsMTUsOSwxMiwxODcsMTAsMTkyLDE1NywxMTQsMjMsNjAsMSwyNDAsOTUsMjA1LDE4OCw1NCwyNDAsMzMsMTYwLDEyNSwyMjQsMTk2LDEzOSwxNjAsODQsMjE3LDE2NiwxMDUsMTE5LDExNiw5NiwyMDgsMTY3LDE4NiwxNjgsNDMsMTkyLDIxMywyMzAsMTQsMjksMTAsNTEsNjAsMTQ1LDE4OCw0NiwxMjEsMTk4LDMwLDU4LDE2Myw0LDI0NywxMTAsNzIsMTgyLDg2LDg2LDU4LDE1OSwxOTcsNTEsMTU3LDEwNSwzNCwxMzQsMTgwLDI4LDE3MywxOTQsMTMyLDEwNiwyNDcsMTMxLDE5Nyw2OCw4MywxMDAsMjQ0LDI0NCw1MCwzOCwyMTAsMjksNjgsMjUyLDM2LDcwLDI0OSw2NSw1MSwyMTIsODIsMTg1LDkwLDE1MiwxMzQsMzksMTMxLDQ5LDE4OCw2LDEwNSw5OCwxODMsNzIsMTA1LDkyLDIzNiw2NCwxMzgsNDAsMTksMjksMTUsNjAsOTgsODEsMTE3LDY1LDg3LDE1NiwxMCwxOTgsMTg2LDEzNiwxNzksMjQ0LDE3Niw0NSwyNiw1NSwyMzIsMTk0LDE4Nyw5NSw4MiwxNDUsNSwxMDAsNzEsMjA2LDEzMCwxOTgsMTA0LDIzNCwxODksMiwyMjUsMjEsMTI3LDM2LDE0LDEyLDE2Nyw1LDY1LDUwLDE1Miw0OCwxNDAsNTgsMzYsMjE4LDEyNCwxOTgsNiwyMDYsMTY5LDEwMiwxMDYsMTc2LDU2LDE5MiwxNzcsMTQ1LDE3Myw2MywzOCwxMTUsMTcsMjQ5LDE0LDE5NywyMTEsMTg2LDkyLDEwLDE2OCw1NSw2NSwxMDksMjE2LDIwMSw1NCwyLDEyMiwxMSwzMyw0LDE3Nyw1MSw5MCw5OCw3NSwxMTIsMTI0LDUyLDQyLDQxLDEyNywzNiwxNTIsNzMsOCwxMjAsNzksMTgzLDY5LDE3OCwyMjAsMTUyLDIxMSw3NiwxNjUsNDMsOTEsNjIsMTA0LDEzMiw3MSw0MCwzOCwxNDksMjQzLDEyMCwyMDcsMjIyLDEzNSwxNzgsMTk1LDEzMiwxNDQsNDUsMTY0LDIzLDE0MCw4OSw0NywxNjAsMTAsMTA5LDE0MCwyMDksMTA2LDEzOCwxNDQsMTY5LDE0MywxMiwzLDE5MSw3NCwxNTksMTk2LDIyNSwxMDEsMjE3LDIxMCwxNTksMTUzLDI0MCwyNiwyNTEsMjUxLDUsMTIsMTE5LDEyMywxMDYsMTcwLDAsMTc1LDcwLDk2LDE0OSwyMDgsOCwyMiw2NiwxOTEsMjA2LDEzNiwxMDAsMSw4Niw0NSwxNTQsMzcsMTg5LDExMiw2NywxNTQsMzEsMjUsOTUsNDAsMTY5LDE2MSwxMTEsMTY0LDM1LDIyOCwxMzcsNTcsMTI0LDIzNCw4OCw5Miw3NCw1MCwxNDgsNjAsMTY3LDUwLDIwOCw1Nyw4MywyMzEsMTA2LDIwMCwxMTIsMzEsNzksMTE5LDg4LDE0NiwxMjIsMjYsMTAzLDIxLDQwLDE1MCwxMzgsMTkyLDE1NywzNSwxMDIsMTIyLDEyOSwxNDYsMTI0LDIyNyw4MCw2NCwxNjUsNTksMTI5LDE1NSwzLDE4OSw5MCwyOCwxOTksMTUyLDkzLDMsMTEyLDEzOSwxOSw4OSwxNjAsMTAsMTYwLDEzNiw4LDIyNywxODcsMTc0LDU3LDE1MiwyMSw4NCw5Nyw3NSwxODEsMTEsNzEsMjA5LDgyLDEyNCwzMiw0NiwyOCwyNDYsNDQsMTIxLDgwLDYxLDExNywxMDUsOTAsMjMxLDEzMiwzNSwxOTMsNzEsMTQ2LDE1OCwyNywxNzksMjM4LDgzLDEwOCw2OSw4OSwxODgsMjI5LDIyNCwxMTAsMjM3LDExNSw5NCwxNTksMjAwLDUzLDEyOCwxOTIsMTI1LDEzMywyNTIsMTk4LDI0OCwzLDQsMCwxOTksMTIwLDE2NSwxODMsMTc3LDEzOCw4LDE2OCw5NywyMjUsOSwxOTksNDAsMTIxLDYwLDIwNCwxNCwyNDgsMjEwLDI1LDIzNSw4MSwxNCwyMTcsMTI4LDAsMTQxLDE5NCwxMjQsMTk4LDI0OSwxODAsNiw2NSwxMTgsMTMzLDE1MCw2Niw3OCw5MCwxNTUsMzAsNzEsMTYyLDE2NSw4Nyw2OCwxNDIsOTgsMTk4LDE1OCw4NCw0MSwxNTAsMzUsMTM5LDEwLDksMTQ0LDgsMTMzLDEwMiw3MCw3MSw1LDIwMCw2OSwxMjMsMTkxLDE2MSwzOCw5MSwyMTIsMzIsMjUyLDI0NywxNjIsMjE3LDEwNSwxODAsOTAsMTQwLDE0NiwxLDIxMywxNjAsNDcsMTM1LDE1OCwxMDIsMTE4LDIzLDI1MiwxNzAsNzQsNzEsNzUsNSwyMzQsNSw2NSwyMjgsMTA3LDM2LDg3LDEwLDExMiw5NywzOSwxMTUsMjE2LDMyLDU5LDE4MiwxMzksNTksMTc0LDIsMjMsMzAsMTA3LDc0LDU0LDE2OCwxNTAsOTIsMjEyLDE5MSwxMjUsMTAzLDE1NSwxNDMsMTQ2LDM4LDE4NCw5NywzMiwxMTQsMTk1LDcwLDQ5LDk2LDE4MSwxMDIsMjI5LDE4LDE2NywxNzksMTM1LDE2MywyNSw5MywyNywxMzMsOTAsMTkzLDUzLDE0MywxMTIsMzksMTI4LDE5OSwyOCwxNzMsMjA4LDQ4LDU0LDEyOCwxNjIsNDgsNDksMzksMTI0LDIzNCwyNDYsMTg1LDEzMiw2NCw2OCw5OCwxODAsMTE1LDk2LDEsMTg4LDM0LDgzLDk5LDE0OCwxNDcsMTQ5LDE4MCwxNywxMzAsMTc1LDksNDUsMjEsNjgsMTQxLDEwNiwxOTUsNjYsMjAyLDE2MSw1Myw3OSwyMDksMjcsMTEwLDY5LDUzLDg3LDE3NywxNzUsMjksMjQ2LDIwNSwxMTIsMjM1LDExMywyMzUsMTAxLDQyLDIxMywxMTksNCw5LDIzNiw0Miw2MCwxNDYsMTI4LDE1NywxODgsNTYsMjEzLDM2LDMwLDIzMSwzOSwxOTUsMjI0LDQ4LDE3MywyMTEsNDQsMTE1LDIyNSwxODYsOTMsMzQsNzQsMTkwLDEzMyw5MiwxNjEsMTE4LDI2LDE5NywxNDAsMzcsNTYsNDksMzcsMjYsMTA4LDI0MywxMTQsMjUxLDIyNywxMiwzLDU3LDUxLDIyMCwxNDUsMjIsMjMyLDQwLDI4LDM5LDEzNSwxNjksMTY2LDE3NiwyNCwxNTUsMTgsMTI2LDIxLDE5OCwxODMsMjUsNzYsNzQsMTQzLDM4LDY1LDIyNSwxNjAsMTEsMTcxLDE1NCw5NiwzOCwxMjIsMjksNywxNjgsMTc3LDYwLDUxLDExOSwyMjksMTA2LDg5LDIyLDE2LDEyMSwxNjEsMTMwLDEwMywxMDIsMjgsMjgsMjI1LDEwMCw4NiwxNSw1MCw3NSwxOTQsNDAsMTQxLDEzOSwxMTUsODYsNDcsMyw1NywxNzIsMTM1LDAsMiwyMzUsMjAxLDE0NywxNzIsMTY1LDE1MiwxNjYsMTQyLDE0LDI1Miw0NywyMDEsNDIsMTQ3LDEzMSwyMDQsNTAsNDEsMTksMTc5LDYsNTYsMTIwLDEyLDIzMCwxNjMsOTksMTI4LDE2LDEwMSwxODgsMTM1LDI1NCwyMzIsMTM3LDExMyw0MywxOTIsMjI1LDExMiwyMDAsMTYwLDIwLDIsMjU0LDE4MywyMSwyOCw1NSwxMzYsNjAsMjM1LDE1Nyw3NCwzNiwxMzksMjI2LDg2LDEzMCwyNTUsMjI1LDE2NywxODgsNDksOTEsMTc0LDE0MCwxMjksMyw4NCwxMDAsMTE1LDQzLDc1LDQsMTI0LDEzNSw0NSwxNjMsMzgsNDQsMTU2LDE0MCwxMTcsMTgwLDE3MSwxODAsMjgsMTkyLDUwLDEyOCwxMjcsNzcsMTksMTc4LDEzMCwxMzQsMTA3LDE4OSwxNzAsNzQsMjMzLDEwNSwxMjMsMjQ0LDEyMCwyMDcsMTMyLDEyMywxNzUsMTc4LDE4LDE4NCwyMjQsMzksMjEsMTgxLDEwMiwxOTUsMjE5LDE2MiwxMSwzNiwzNSwxMTYsNjYsMjEsMTY1LDE0MSwxMCw0NiwxMjMsMTcsMTkyLDcyLDM4LDE4MywxODksMTgxLDE3MSwyNTEsMTgzLDk2LDcxLDEzNCw0NiwzMCwyNDgsNDQsNjMsMTA4LDExNSw4MCwyMjAsMTQwLDEyNSwzNSwxMzIsMjI1LDIyLDUsMTA4LDI4LDE3OCw2MywxOTgsMTExLDIzNiw4NSwxNzksMTQ5LDEsMTgzLDE0MywxNjIsMTM5LDIyLDgwLDQ2LDIzNiwxMzksNjEsMTA4LDEzMywxMywxNzUsMjgsMTc5LDE2MywxODEsNzMsMTksMTAxLDQ3LDU1LDI0NSw0LDExMiwxMDAsNCwxNjcsMjI0LDEyNSwxNTAsMTQ5LDIwMSw1LDEyOSwxNzksMjM0LDIwMywxMzcsNTQsOTEsMTAxLDExOSwxNzEsOTgsNzUsOTksNjUsODUsMTI5LDE5NCw5LDksMTMwLDQsNTUsMTM1LDE2MywxNTMsNTEsMTM3LDIxLDMyLDIxMiwzOSw4MCwxMTcsNTQsOTUsNzcsMjAzLDExOSwxMjEsMTU0LDcsMjE0LDE0NCwxMjIsNzMsMTMxLDE2NiwxMjgsMTc3LDE4OCwxODMsMSwxNzQsMTUxLDE4NSw2NSw2MCw4Niw4MCw5OSw1OSwxNCwyNCw2Niw0MCwyMjEsNjgsNDcsNjUsNjUsMTc3LDEzMSwxOTIsMTQ0LDQ3LDcsMzcsMzMsNzYsMTY3LDI1NCwxNjcsMTIxLDIyMiwxNjYsMTU0LDYzLDk3LDE1OSwyNDAsMTY5LDEzNiwyMzMsMTIyLDExOCw1NywxMTIsMTk5LDEzMSwxNzcsMjgsNTEsMTQwLDE4MywxMTEsMjUyLDE1OSw5NCw3Niw1MywxMzAsNDEsMTcyLDExNCwxMTksMTMwLDE5NSwxMjQsNTYsMTIyLDIzMCwxMCwxMDgsMTEzLDEzNSwxNjcsMTU1LDQ3LDc3LDEwNyw2OSw4NCw3MCwxMDksMjUsMTYsMTE3LDE2Nyw3MiwxMzksMTMsMTAzLDE1NCwyNywyMTAsNjIsNDMsMCwxMjYsMTg0LDIwOCwxMDAsNDEsMjQwLDE4NSwxNjIsMjExLDU0LDU2LDIwNywxMTYsNDMsMTE3LDE4LDIxMCw0MiwyNTAsMjExLDI1MCwxMTIsMTM3LDExNywyNDcsMTUwLDExMyw0MywxNzMsMjI0LDE4MSw1NCwyNTEsNTIsMTMzLDEyMiw3NywzMSwxMzUsMjA3LDIwNSwyMzUsMjI0LDEzNCw1NCwxMzAsMjMzLDEwOCwyMDcsMTU1LDE1Myw5Nyw2Nyw3OSw5Miw0MCwyMDYsMjE2LDI0Myw4NywyMCwzMSwyMjEsNjUsODEsMjA2LDE3OSwyNTEsNDcsMzYsMTAsMTMxLDE3NSw1MF19fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6WzMsMTg3LDE2MSw2OCwyMDgsMTI5LDIwNSwyMzIsNTEsMjI1LDE4LDQsMTMwLDE2OSwyMDMsMTg4LDExNSwxODgsMjM2LDY3LDE2NywxMjIsMTg0LDE5OCwxMTUsOTYsMTU0LDI1MiwyNDIsMTEwLDE5MywxNTQsMTg1LDI5LDI0NywxMjIsMTQxLDQ0LDE1Myw5MywxNjQsMTkyLDEyMSw1NiwxMTQsMTU5LDEzNSwxNjYsMTIxLDEwNywxLDE5NiwyNyw1NSwyNDMsMjE5LDExMiwyNTQsMTIxLDUwLDQ1LDE5Miw3NSw0MCwzMiwyMDIsMjQ0LDksMTI5LDIyLDU3LDE3Miw0MSwyMzIsODQsOTAsNTIsNzksMTYzLDExNCwzNCwyMjMsOTYsMjksMjQ3LDE0Niw3NSwzNywyMTcsMTA5LDEyOSwxNzksMTksMjQ4LDE5MiwxMjcsMjE4LDQ0LDE3MCw3OCwyMjUsMTUzLDkxLDUwLDU5LDE1MywxODQsNDQsNjcsMTM4LDIwNiwxNzgsMjE1LDYsMTMxLDE1MSwyNCwzOCwxMjIsMTY2LDIzMCw2OSwxMiwxNTIsMTY1LDE3MywxNzIsMTE2LDE0MSw2OCwyMDIsMTg3LDExLDIyNyw3OSw5MywyMTIsNzEsNjYsNDgsNDMsMCwxOTcsOTMsMTYyLDIyLDEwOSwyMTQsOSw1NCwxMTEsNTEsMjYsOTQsODMsMywyMDMsMTk1LDMsMTYxLDExNywxOTAsMjI0LDk5LDIwMywxNzcsMTI0LDExOCw4MCwyLDE0MiwxNTIsMTk5LDE0MSwxMTEsODAsNTQsNDIsMTM3LDE0OCwzNiwxMzYsMTAwLDIyNiwxODQsNjgsNzEsMTIxLDU0LDQ2LDg4LDE0NiwxNywxMzYsMTE3LDI0NSw1OCw3NCwyMzYsMTQwLDM3LDIzMiwxNzksMTg1LDEwMywyMTgsMTk2LDEwMiwxNTEsMjMsMjMsMjE3LDMxLDY1LDEyLDYxLDEyMyw5Miw3NiwxMTYsMjA5LDkzLDIzMyw5OCwzLDUyLDI0Nyw5NiwxNSwyNDcsNDUsMTg2LDE3MSwxMzIsOCwyMTcsMTYsMjE4LDI3LDEyOSwyMjksMTI0LDIwNCw4MCwxNTEsNjMsMTQsMjAzLDM2LDg0LDk4LDE1NCw5MiwxMTIsMzgsMTgyLDI1MiwxNzIsMjA2LDE2NywxOTAsMjM4LDE0NiwxNTQsMTEyLDEwLDQxLDY5LDE3NywyOSwxMjEsMTc5LDE2NCwyMzgsMjI3LDMxLDk4LDIyNSwxNTAsMTE1LDIxMywxNjgsMTg0LDc1LDU0LDIzMSwxNDYsOTksMTM5LDIwOCw1MCwxNjMsODEsNTYsMTk5LDE3Nyw1LDIwMywyMjUsNDYsNTEsMTk4LDE2MiwxODksODQsMTQ1LDMsMjQ0LDE5Miw1MiwxMDUsMzYsMTM2LDIxNCw5OSwyMzksNzEsOTUsOTcsMTMzLDE1NywxNzIsMTk0LDE3OSw1NywxMzUsMTM2LDIzOCw2Niw5MiwxNTgsMTY5LDEzMiwxMTEsMTA1LDE1OCwyNTAsMjIsMTgwLDQ0LDI0LDczLDEwNyw1MSw0MiwyNTAsMTA0LDM0LDE4NCwyMjQsMTQ2LDM1LDEyMSw0NywxNDAsMzYsODIsMjQ0LDIxLDI0LDIzOSwyNTAsMTY2LDI0OSw2OSwxMjAsMTA5LDEwNywxMTgsMjA2LDUyLDEwNSwxNjMsNzMsMjUsMzcsMjAwLDE1MCwxLDE1NSw0OSw1LDIyNSw0Niw4OSwyMzUsMTExLDc5LDE1MSwxNzIsMTk0LDEzMiwzNiwxMCwxLDEyLDM0LDIyNyw2NiwxNjAsMjQ2LDc4LDE4LDEzOCwxNTMsNTEsMjM1LDE3LDk0LDEzNSwxOTMsMTEsMjE0LDUyLDMzLDE5NiwxMTEsMjEwLDI0Miw0MCwyMjcsMjYsODcsMTI1LDE1NCwxMjAsMTE2LDEzMyw4Miw5LDIxOSwxOTYsMTcwLDI3LDEwLDE4OSwyMiwzOSwxMDUsMTcwLDk4LDE1LDEzMSwyMDUsNDEsODksMTQzLDM2LDI0MSwxOTYsMjI1LDE3OSw3NSwxODgsMTQ0LDMxLDU1LDM5LDExNiw1LDIsMTEsMTQ1LDczLDExMiwxODIsMTE5LDIwMiwyMjMsNDQsMTUzLDgzLDI2LDE5OCwxMzgsMjEsNTYsMTU2LDE3OCwxODIsNjgsMjQ0LDE4LDE4NywyMzIsMTQ1LDc1LDIzNiwxMTIsMjQ5LDE1MCw0MCwyMywxOTYsMTg1LDI1NCwxNTEsMTUsMTY0LDI1MSw0OSwyNDMsMTg2LDcwLDIwNiwxMDUsNzEsMjQ5LDE0OSw0LDI0NCwyMzQsMTksNzQsNTQsMTgxLDE3Miw1NywzMSwxODQsMjE5LDEzMywyMTcsMTIwLDU0LDE4Miw3NCwxMjEsMSwxOSw5OCwxOTksMTAsMTIyLDI1NCwzNywzMCwyMCw3LDIsMTE4LDE2OCwxNSwxOTcsODQsMzcsMjE5LDIxNiwxNTQsNDAsMTU2LDUsOTIsMTEyLDE1Miw2MSwxLDE5OCwxNjMsMTkyLDE2NCwxMiw2NCwxNSw1OSwxODQsMTU1LDEwMywwLDkwLDE1MiwyMDAsOTgsOSwyLDYzLDE4MiwyMzEsODUsMTMwLDE2NywxMzQsMTE4LDYwLDE1NywyMjgsMjA5LDE5MywyMDcsMTE2LDE0NywxNCwzNiwxMzksNDEsMjIwLDE1MiwxODQsOSwzNSw4MywxMTYsMTA5LDIzNSwxNzksOTksNjEsNzUsMzQsOTgsMTAxLDMsMzQsNzQsMzIsMTY0LDE5OCw1OCwyNDIsMTk5LDE3MSw3MywyMiw0Myw2NSwyMjUsMTU2LDM1LDMyLDMxLDEyLDIzNiwyNiw2MCwxMTksMTY3LDE1OSwxMDcsNyw5OSwxODUsMTg0LDExMywxMDQsNDYsMjM2LDMsMTM3LDc4LDIxOSw5MCw4NCwyNDEsMTksMjAzLDUzLDEzOCw3NywxNyw2MCwxODIsMzQsNjcsMjEwLDczLDE3NiwyNCw2NSwxNTcsOTQsNDQsMTMzLDE3OCwyNDIsMTQ0LDE0MSwxMzgsMTIwLDE3MiwxODIsMTE2LDYxLDQyLDE1MSwxOTUsNjcsMTk0LDczLDEzMSw2MCwzLDI0Myw4MCw5OSwxNjMsMjA3LDIwMCwxOTMsNzUsMzIsMjI5LDEyMiw4Nyw0MCw3NiwyMjYsMTg4LDUxLDExNyw3MywxNTgsMjA3LDE3MCwxMzEsMTkzLDg4LDIzLDM1LDEyOCwxMTIsMTMwLDIyNywxNzAsNTcsNTAsMTg0LDQ3LDIzMSwxMjksMTYyLDcyLDYzLDIyMiwyMjcsMTA4LDgwLDMsMTY3LDU0LDEwMSwxNDQsMTk0LDIyMCw4MSwyMDgsMzksMTQsMTI3LDExNywxMDUsMTgxLDE0Nyw2LDE4NCwxMzAsMTcxLDIyOSwxMzAsNTAsMTIwLDE2MiwxNjYsMjQzLDg2LDEwMyw3NywzOSwxNjYsMTk2LDYsMTU1LDQ5LDE5OCw0NiwyNTIsMTMyLDI5LDkzLDIxMywxMDUsNjQsNTcsMTk5LDIyOSwzMiw5OSwyNywyMDksNzcsNTIsMTkzLDEzOCwxMzgsMTQ3LDY5LDkyLDE1MywxMTEsMjM5LDE1NSwxNjUsMjM4LDEwLDE2LDk2LDIxMywxMjUsMTQ4LDIzNSwxMTUsNCwxMTcsMTYwLDE2NSwxMzgsMTk4LDk2LDU3LDkzLDIzMywxMzksOTIsNTcsNDMsMTYwLDE2NiwxOSwxNzMsMiw5OSw1LDEwLDEwMSwxMDksOTMsMTcxLDI1LDIyLDY4LDEwNSwyMjMsMjMzLDc3LDE0Niw5NywzMCwxNTMsMTEzLDE3MywyNCwxOTMsMTEwLDI0OCwyNDcsMTk4LDIyMyw0MSwyMDQsMjQyLDI1MiwyMiwxOTUsMjA5LDU3LDE1LDM2LDc5LDM1LDc2LDE1Nyw4OCwxMzEsMTk0LDI1MywxNjksMTQsNywxMCwxMTYsMjM2LDExOCw2NCwxOTIsMjI0LDc4LDEyLDExNiw1MCwxNTAsNjUsMiwxNjgsMjMxLDE0MSw1Miw5Niw4NywyMDcsMTM4LDE5MSw3MCwxOSwxMCwyMTQsMTUzLDE5OCw5NCwyNSwxNzUsMTQsMTM1LDE0NCwxMyw1MiwxMTIsMjM0LDEzMSwxNzMsMTUwLDIxMywxMjEsMTY5LDMzLDQyLDE1MCw2Niw4Nyw4MywxMzksMTY2LDE2NiwzNSwxMzksOTAsMjI4LDExOCwxODQsMTc2LDQ2LDYyLDI0MSwyMDEsNTYsMTUwLDE5NSw1Myw1NiwxMjYsOTYsMTA1LDE4LDI1MCwyNTEsOTEsMTQ2LDIzMSwxODAsNDMsMTg1LDEzNCwyNCw1NSwxMzMsMTE2LDE1MCw2LDIxNywxMDQsOTMsMTk4LDEzNSw2MCwxNywxMjMsMjYsMTgzLDU1LDQyLDIyOSwxOTQsMzksNDUsMTM0LDkyLDI1NSw1MCwxOTMsMjE5LDIwMCwyMiwyMzEsODgsNDYsMjksMTgwLDc0LDkzLDIyNSwxNzgsMjE3LDEzOSw0MCwyMzYsMjM0LDEzLDE2NSwxNTEsMTU2LDY2LDExNCwyNSw2MCwzOSw0NywxMDQsMTY3LDg5LDEsMjI0LDE1MCwxNCwyNywxNjYsNDYsMTgwLDE0OCwyMDcsMTYsNzcsMTIzLDIzMiwyOSwyNTAsMjE2LDMwLDQyLDczLDE2OSwzNiw5Niw3NSw3NSw4NSwxNTQsOTQsMjQsMTQsNiwxNzEsMTQ0LDE4OSwyMzIsMTQ0LDIyMywxNTQsOTIsOTYsMjQ4LDIyLDE1LDE2NiwxMDMsMTk2LDk4LDQ5LDIzOSw2NCwxNzEsMTc4LDIxMCw3OSwyMzUsMjA0LDEwMCwxNyw4OSwxNDgsMTcsMTY2LDEwMCw4NSwxLDE0NiwxNjIsMjQsMTIwLDE2LDIzMCwyMDMsMzcsMTY0LDI2LDY5LDExNCw1MSwxOTgsMTI5LDY5LDE0Nyw4NywxMjMsMTk3LDE1NCw3MSwyMjgsMjE5LDMwLDY0LDMsMTAwLDIxNSwxOTgsMTU3LDE1OSwxLDI1LDY4LDQyLDQ2LDUyLDU4LDQ5LDE3NywyMTAsMjA1LDE0OCw4Nyw2Niw3MywxMDcsODUsMTIxLDE3MCwxOTcsNDIsMzcsMzUsMTU3LDE0NCw5OSwyMDQsODksOTEsMTgzLDE4MywxMTUsMTQ0LDEwOCwxNywyMCwyMTUsNzcsMjM3LDE0NywxNDUsMjUxLDk4LDE1LDksMTIsMTg3LDEwLDE5MiwxNTcsMTE0LDIzLDYwLDEsMjQwLDk1LDIwNSwxODgsNTQsMjQwLDMzLDE2MCwxMjUsMjI0LDE5NiwxMzksMTYwLDg0LDIxNywxNjYsMTA1LDExOSwxMTYsOTYsMjA4LDE2NywxODYsMTY4LDQzLDE5MiwyMTMsMjMwLDE0LDI5LDEwLDUxLDYwLDE0NSwxODgsNDYsMTIxLDE5OCwzMCw1OCwxNjMsNCwyNDcsMTEwLDcyLDE4Miw4Niw4Niw1OCwxNTksMTk3LDUxLDE1NywxMDUsMzQsMTM0LDE4MCwyOCwxNzMsMTk0LDEzMiwxMDYsMjQ3LDEzMSwxOTcsNjgsODMsMTAwLDI0NCwyNDQsNTAsMzgsMjEwLDI5LDY4LDI1MiwzNiw3MCwyNDksNjUsNTEsMjEyLDgyLDE4NSw5MCwxNTIsMTM0LDM5LDEzMSw0OSwxODgsNiwxMDUsOTgsMTgzLDcyLDEwNSw5MiwyMzYsNjQsMTM4LDQwLDE5LDI5LDE1LDYwLDk4LDgxLDExNyw2NSw4NywxNTYsMTAsMTk4LDE4NiwxMzYsMTc5LDI0NCwxNzYsNDUsMjYsNTUsMjMyLDE5NCwxODcsOTUsODIsMTQ1LDUsMTAwLDcxLDIwNiwxMzAsMTk4LDEwNCwyMzQsMTg5LDIsMjI1LDIxLDEyNywzNiwxNCwxMiwxNjcsNSw2NSw1MCwxNTIsNDgsMTQwLDU4LDM2LDIxOCwxMjQsMTk4LDYsMjA2LDE2OSwxMDIsMTA2LDE3Niw1NiwxOTIsMTc3LDE0NSwxNzMsNjMsMzgsMTE1LDE3LDI0OSwxNCwxOTcsMjExLDE4Niw5MiwxMCwxNjgsNTUsNjUsMTA5LDIxNiwyMDEsNTQsMiwxMjIsMTEsMzMsNCwxNzcsNTEsOTAsOTgsNzUsMTEyLDEyNCw1Miw0Miw0MSwxMjcsMzYsMTUyLDczLDgsMTIwLDc5LDE4Myw2OSwxNzgsMjIwLDE1MiwyMTEsNzYsMTY1LDQzLDkxLDYyLDEwNCwxMzIsNzEsNDAsMzgsMTQ5LDI0MywxMjAsMjA3LDIyMiwxMzUsMTc4LDE5NSwxMzIsMTQ0LDQ1LDE2NCwyMywxNDAsODksNDcsMTYwLDEwLDEwOSwxNDAsMjA5LDEwNiwxMzgsMTQ0LDE2OSwxNDMsMTIsMywxOTEsNzQsMTU5LDE5NiwyMjUsMTAxLDIxNywyMTAsMTU5LDE1MywyNDAsMjYsMjUxLDI1MSw1LDEyLDExOSwxMjMsMTA2LDE3MCwwLDE3NSw3MCw5NiwxNDksMjA4LDgsMjIsNjYsMTkxLDIwNiwxMzYsMTAwLDEsODYsNDUsMTU0LDM3LDE4OSwxMTIsNjcsMTU0LDMxLDI1LDk1LDQwLDE2OSwxNjEsMTExLDE2NCwzNSwyMjgsMTM3LDU3LDEyNCwyMzQsODgsOTIsNzQsNTAsMTQ4LDYwLDE2Nyw1MCwyMDgsNTcsODMsMjMxLDEwNiwyMDAsMTEyLDMxLDc5LDExOSw4OCwxNDYsMTIyLDI2LDEwMywyMSw0MCwxNTAsMTM4LDE5MiwxNTcsMzUsMTAyLDEyMiwxMjksMTQ2LDEyNCwyMjcsODAsNjQsMTY1LDU5LDEyOSwxNTUsMywxODksOTAsMjgsMTk5LDE1Miw5MywzLDExMiwxMzksMTksODksMTYwLDEwLDE2MCwxMzYsOCwyMjcsMTg3LDE3NCw1NywxNTIsMjEsODQsOTcsNzUsMTgxLDExLDcxLDIwOSw4MiwxMjQsMzIsNDYsMjgsMjQ2LDQ0LDEyMSw4MCw2MSwxMTcsMTA1LDkwLDIzMSwxMzIsMzUsMTkzLDcxLDE0NiwxNTgsMjcsMTc5LDIzOCw4MywxMDgsNjksODksMTg4LDIyOSwyMjQsMTEwLDIzNywxMTUsOTQsMTU5LDIwMCw1MywxMjgsMTkyLDEyNSwxMzMsMjUyLDE5OCwyNDgsMyw0LDAsMTk5LDEyMCwxNjUsMTgzLDE3NywxMzgsOCwxNjgsOTcsMjI1LDksMTk5LDQwLDEyMSw2MCwyMDQsMTQsMjQ4LDIxMCwyNSwyMzUsODEsMTQsMjE3LDEyOCwwLDE0MSwxOTQsMTI0LDE5OCwyNDksMTgwLDYsNjUsMTE4LDEzMywxNTAsNjYsNzgsOTAsMTU1LDMwLDcxLDE2MiwxNjUsODcsNjgsMTQyLDk4LDE5OCwxNTgsODQsNDEsMTUwLDM1LDEzOSwxMCw5LDE0NCw4LDEzMywxMDIsNzAsNzEsNSwyMDAsNjksMTIzLDE5MSwxNjEsMzgsOTEsMjEyLDMyLDI1MiwyNDcsMTYyLDIxNywxMDUsMTgwLDkwLDE0MCwxNDYsMSwyMTMsMTYwLDQ3LDEzNSwxNTgsMTAyLDExOCwyMywyNTIsMTcwLDc0LDcxLDc1LDUsMjM0LDUsNjUsMjI4LDEwNywzNiw4NywxMCwxMTIsOTcsMzksMTE1LDIxNiwzMiw1OSwxODIsMTM5LDU5LDE3NCwyLDIzLDMwLDEwNyw3NCw1NCwxNjgsMTUwLDkyLDIxMiwxOTEsMTI1LDEwMywxNTUsMTQzLDE0NiwzOCwxODQsOTcsMzIsMTE0LDE5NSw3MCw0OSw5NiwxODEsMTAyLDIyOSwxOCwxNjcsMTc5LDEzNSwxNjMsMjUsOTMsMjcsMTMzLDkwLDE5Myw1MywxNDMsMTEyLDM5LDEyOCwxOTksMjgsMTczLDIwOCw0OCw1NCwxMjgsMTYyLDQ4LDQ5LDM5LDEyNCwyMzQsMjQ2LDE4NSwxMzIsNjQsNjgsOTgsMTgwLDExNSw5NiwxLDE4OCwzNCw4Myw5OSwxNDgsMTQ3LDE0OSwxODAsMTcsMTMwLDE3NSw5LDQ1LDIxLDY4LDE0MSwxMDYsMTk1LDY2LDIwMiwxNjEsNTMsNzksMjA5LDI3LDExMCw2OSw1Myw4NywxNzcsMTc1LDI5LDI0NiwyMDUsMTEyLDIzNSwxMTMsMjM1LDEwMSw0MiwyMTMsMTE5LDQsOSwyMzYsNDIsNjAsMTQ2LDEyOCwxNTcsMTg4LDU2LDIxMywzNiwzMCwyMzEsMzksMTk1LDIyNCw0OCwxNzMsMjExLDQ0LDExNSwyMjUsMTg2LDkzLDM0LDc0LDE5MCwxMzMsOTIsMTYxLDExOCwyNiwxOTcsMTQwLDM3LDU2LDQ5LDM3LDI2LDEwOCwyNDMsMTE0LDI1MSwyMjcsMTIsMyw1Nyw1MSwyMjAsMTQ1LDIyLDIzMiw0MCwyOCwzOSwxMzUsMTY5LDE2NiwxNzYsMjQsMTU1LDE4LDEyNiwyMSwxOTgsMTgzLDI1LDc2LDc0LDE0MywzOCw2NSwyMjUsMTYwLDExLDE3MSwxNTQsOTYsMzgsMTIyLDI5LDcsMTY4LDE3Nyw2MCw1MSwxMTksMjI5LDEwNiw4OSwyMiwxNiwxMjEsMTYxLDEzMCwxMDMsMTAyLDI4LDI4LDIyNSwxMDAsODYsMTUsNTAsNzUsMTk0LDQwLDE0MSwxMzksMTE1LDg2LDQ3LDMsNTcsMTcyLDEzNSwwLDIsMjM1LDIwMSwxNDcsMTcyLDE2NSwxNTIsMTY2LDE0MiwxNCwyNTIsNDcsMjAxLDQyLDE0NywxMzEsMjA0LDUwLDQxLDE5LDE3OSw2LDU2LDEyMCwxMiwyMzAsMTYzLDk5LDEyOCwxNiwxMDEsMTg4LDEzNSwyNTQsMjMyLDEzNywxMTMsNDMsMTkyLDIyNSwxMTIsMjAwLDE2MCwyMCwyLDI1NCwxODMsMjEsMjgsNTUsMTM2LDYwLDIzNSwxNTcsNzQsMzYsMTM5LDIyNiw4NiwxMzAsMjU1LDIyNSwxNjcsMTg4LDQ5LDkxLDE3NCwxNDAsMTI5LDMsODQsMTAwLDExNSw0Myw3NSw0LDEyNCwxMzUsNDUsMTYzLDM4LDQ0LDE1NiwxNDAsMTE3LDE4MCwxNzEsMTgwLDI4LDE5Miw1MCwxMjgsMTI3LDc3LDE5LDE3OCwxMzAsMTM0LDEwNywxODksMTcwLDc0LDIzMywxMDUsMTIzLDI0NCwxMjAsMjA3LDEzMiwxMjMsMTc1LDE3OCwxOCwxODQsMjI0LDM5LDIxLDE4MSwxMDIsMTk1LDIxOSwxNjIsMTEsMzYsMzUsMTE2LDY2LDIxLDE2NSwxNDEsMTAsNDYsMTIzLDE3LDE5Miw3MiwzOCwxODMsMTg5LDE4MSwxNzEsMjUxLDE4Myw5Niw3MSwxMzQsNDYsMzAsMjQ4LDQ0LDYzLDEwOCwxMTUsODAsMjIwLDE0MCwxMjUsMzUsMTMyLDIyNSwyMiw1LDEwOCwyOCwxNzgsNjMsMTk4LDExMSwyMzYsODUsMTc5LDE0OSwxLDE4MywxNDMsMTYyLDEzOSwyMiw4MCw0NiwyMzYsMTM5LDYxLDEwOCwxMzMsMTMsMTc1LDI4LDE3OSwxNjMsMTgxLDczLDE5LDEwMSw0Nyw1NSwyNDUsNCwxMTIsMTAwLDQsMTY3LDIyNCwxMjUsMTUwLDE0OSwyMDEsNSwxMjksMTc5LDIzNCwyMDMsMTM3LDU0LDkxLDEwMSwxMTksMTcxLDk4LDc1LDk5LDY1LDg1LDEyOSwxOTQsOSw5LDEzMCw0LDU1LDEzNSwxNjMsMTUzLDUxLDEzNywyMSwzMiwyMTIsMzksODAsMTE3LDU0LDk1LDc3LDIwMywxMTksMTIxLDE1NCw3LDIxNCwxNDQsMTIyLDczLDEzMSwxNjYsMTI4LDE3NywxODgsMTgzLDEsMTc0LDE1MSwxODUsNjUsNjAsODYsODAsOTksNTksMTQsMjQsNjYsNDAsMjIxLDY4LDQ3LDY1LDY1LDE3NywxMzEsMTkyLDE0NCw0Nyw3LDM3LDMzLDc2LDE2NywyNTQsMTY3LDEyMSwyMjIsMTY2LDE1NCw2Myw5NywxNTksMjQwLDE2OSwxMzYsMjMzLDEyMiwxMTgsNTcsMTEyLDE5OSwxMzEsMTc3LDI4LDUxLDE0MCwxODMsMTExLDI1MiwxNTksOTQsNzYsNTMsMTMwLDQxLDE3MiwxMTQsMTE5LDEzMCwxOTUsMTI0LDU2LDEyMiwyMzAsMTAsMTA4LDExMywxMzUsMTY3LDE1NSw0Nyw3NywxMDcsNjksODQsNzAsMTA5LDI1LDE2LDExNywxNjcsNzIsMTM5LDEzLDEwMywxNTQsMjcsMjEwLDYyLDQzLDAsMTI2LDE4NCwyMDgsMTAwLDQxLDI0MCwxODUsMTYyLDIxMSw1NCw1NiwyMDcsMTE2LDQzLDExNywxOCwyMTAsNDIsMjUwLDIxMSwyNTAsMTEyLDEzNywxMTcsMjQ3LDE1MCwxMTMsNDMsMTczLDIyNCwxODEsNTQsMjUxLDUyLDEzMywxMjIsNzcsMzEsMTM1LDIwNywyMDUsMjM1LDE2NSw1NiwyMjYsMjI2LDY4LDI0OCwxNCw1MSw4OCw3LDIxMyw5NCwxNTEsMiwxNjcsMjAsMTYyLDU4LDczLDM4LDE4LDUzLDE0NCwyMDAsMjYsMTA2LDEyMiwyMDQsMjMwLDEzNSwxMDQsMjAyLDEzLDIwMywxMDIsMTg1LDIwLDI1MywyMTksMTI2LDEzNCwxODIsNjMsMTk2LDUsOCw1OCwyMSwyNDAsNTIsNDgsMjA0LDc0LDExNSwxOTIsMTcwLDI0Myw2MiwyNDQsMTg3LDUyLDMwLDIxMywxNTQsODAsMTg4LDI0MCw1NywyMjIsNiw3OCw5LDQsMTkyLDgwLDE0MCwxODIsMTU1LDIxMCwxMiwxMDEsMTczLDE1MCwxODMsMjQ2LDIwNCwxNjQsMCwxNiwxNCwxNDcsNTQsNCwxMjYsMTQ4LDE2MSwyMjQsMTM0LDU0LDEzMCwyMzMsMTA4LDIwNywxNTUsMTUzLDk3LDY3LDc5LDkyLDQwLDIwNiwyMTYsMjQzLDg3LDIwLDMxLDIyMSw2NSw4MSwyMDYsMTc5LDI1MSw0NywzNiwxMCwxMzEsMTc1LDUwXX19fV0sIm5ld19sZWFmX2tleXBhaXJfb3B0aW9uIjpudWxsLCJ1cGRhdGVfcGF0aF9sZWFmX25vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbMzQsMjEzLDEyNiwxMDIsMTgwLDE5Nyw3LDExOSw1LDE0OCwyMzEsNTcsMTU2LDg4LDE1NCwyNywxMDEsMSwxMTYsMTMyLDU0LDU4LDgzLDEzMCwyNDcsMjQ3LDczLDE3OCw0LDE0NCwxMjYsMjE2LDEwNSwyMzIsMTQwLDEzLDIzMiwyMjYsMTgsMjMxLDE2MywyMDcsMTU4LDIzMCwxMDYsODEsNSw0MywxMTgsODIsMiw3MCw0MCw0LDIwNiwxODcsMTU4LDE5OSwxMTgsODAsNTYsMjI0LDM5LDIxOSwxMTgsMTUzLDM3LDI0NSwyNSw0NiwyMjksMTkzLDEzMyw1MiwyMDQsMTU2LDM1LDIwNCwyMzksMTI0LDE3MywyMjAsNjUsMTY0LDE5OCwxNjYsMTUsMjIsMTA0LDE5Miw2OSwyMzYsMTQ4LDEwNiwxNzksMTc1LDM5LDk2LDE4LDI3LDU1LDE4MSwzNywxNiw2MCwxOSwxNzgsMTEyLDczLDIxNywxODMsMTc5LDEwOCwxNDksMjMwLDE3MiwyMDUsOTgsMTIwLDE0MiwyNTMsMTcsMTcwLDY3LDExNywxOTYsMTgyLDE3MiwxMDEsMjM2LDE3MCwxMjEsMTg2LDU3LDc3LDMzLDY2LDMyLDczLDExNywxNzIsMTIyLDE1MCwxMzQsODAsMjIwLDkyLDIzOSwyMjksOSw3MywyMTksMTY4LDMzLDI1MSwzMyw5NywxNzEsMjA0LDY2LDE0MCw2MywzNSwxNTMsMTg5LDIyOSwxMDYsMTM5LDEwMSwxNTUsMTg1LDE2MCwyMTAsMzgsNTAsNDEsMTgzLDY5LDU5LDE2MCw0OSwxMTIsMTY4LDIzNCwxMzQsOSwyMDMsMzYsMTk5LDE2MiwxMDgsNTEsMTc0LDI0MSwxMjcsNzMsMTcyLDE4Nyw1MSwyNiwxNTIsMTczLDE0OSw4MCw4NSw1OCwxNjUsMTgyLDg3LDIwMCwyMDcsMTI5LDEyNiwxMzUsMTE5LDE2NSwzMCwyMzEsMTM1LDIyNCwxOTMsMTY4LDAsMTYxLDEzOCw2MCwyNDgsMTAsMTg2LDQ4LDMxLDkzLDE3OCw3LDE5NywxOTksNTQsMjQ0LDE1MCwxNTcsMCwxMjEsNjgsMjQwLDI0NywxMTAsMTQ5LDY5LDExMiwxNzcsMTAsMTk4LDI0OSwxMjMsMTUzLDEyOCwxOTIsMjMsMjYsNTYsNzQsMjI3LDIxNyw5NywxMzIsMTgzLDE1LDIyLDEyMCwxNzUsOTMsNDgsMTgsMTE4LDE3OCwxMywyMzIsMTkyLDEzMSwxNTgsMTc2LDExNywxMjAsMTY1LDUyLDIzOSwyMjYsMTg1LDM2LDExNSwxMjEsMTU5LDE2MCw5MiwxMjEsMTQ2LDEwNiwxNzEsMTk5LDkzLDIzMiwyMywzNSwyNiwzLDQwLDUyLDUsMjA2LDE4MiwyMzMsNzQsMTg0LDkwLDYsMjQ2LDE4Nyw1LDE5NSwxODAsMTcsOTUsMjQyLDEwOSwxNjQsMzcsMTQ2LDgzLDE5NywxLDMyLDE3MSwxMjYsODMsODksMTAzLDksNzYsOSwxNzQsNjksMTY1LDkzLDE4Myw5LDczLDE2MCwxMTEsMTI4LDEyLDE0OSwxOTgsMjQ4LDExNywwLDI4LDIsMTY3LDIzNSwyMyw3Myw5NywxMTYsMTEzLDE1MCwxNDUsMTY5LDcsMjA1LDExMywxNDcsNywxMzgsMTgwLDgsOTcsMTAwLDEsOTUsMTY0LDUwLDU2LDY4LDE3MiwyNDQsNiwxMzAsOCwxOSwxNzgsMTEwLDI0MSwxNTIsMTM2LDEzNCwxOTYsNTYsMjAxLDE5NiwyMDgsNTMsODksMTMyLDIyNiw1NCwyMjQsMjYsMjcsMjIsMTc4LDkyLDQ2LDQyLDY5LDEwMCw1NiwxMTgsODMsMzgsMTk4LDAsMzcsODYsMTE4LDIyNSw0LDQ3LDMzLDIzLDIwOCwxOTIsMTA0LDEwLDczLDc3LDIxNywxMTcsMTQsMTY1LDIxMywxNTMsMzgsODMsMTUwLDEzNywyNDMsMjAwLDIzNywxNywzNCwxMjksMTc4LDg3LDUzLDE0OSwxNTAsMTE3LDEzNCwxODYsNzQsMjI2LDE0MiwxMjAsMjExLDEwMyw3NywxNDksNzUsMzEsMjMwLDE1NSwxNjEsMjI4LDcsNTgsMTY3LDE0NiwxNzQsMTMzLDYsMTk4LDIxLDUwLDE0NCwyNTIsMTQzLDI0OCw5OCw0LDE2LDEzOSwyMDQsMTMsNDksMTEyLDgyLDE4Miw2LDkyLDE2OSw3MSw4MCw2NCw0NSwxNDEsMzksMTgxLDIwNCwxMzMsMTY2LDg1LDQxLDE0LDIwMywyMjksNTEsMjU0LDIyLDE1Miw2MCwxOTksODIsNDIsMTg2LDM3LDMzLDI2LDEsMjM2LDcyLDE1NSw5OSwxMjEsMTU5LDIyMCwyMSwxNjYsMTEyLDY3LDQ0LDQzLDE2LDM2LDE1NywxNDAsNDQsNTcsMTQ2LDUyLDEwLDE2NiwxNDMsMTQ1LDMyLDgwLDE1NCw5MiwwLDY0LDQ4LDE0MCwyMjgsMTkyLDE3MSwxNzMsMTcwLDE5Niw0NywxMDQsNzUsMTA0LDgwLDUwLDE1NywxMzYsMjksMTI3LDEzOCw0NSw1LDIxNCwyMiw3MSwxMTYsNjEsMjE3LDI4LDI3LDk0LDEyOSw2LDEyLDc2LDE0Niw5MCw1OSwxMjQsNDYsMTY2LDg2LDIwOCw4MywxOTUsMjQ4LDExNSw1OCwxNTgsMjE2LDEzOCwyMjcsMTE0LDcsMjQ0LDM5LDI2LDI3LDIzMiwzNSw5NiwyMyw4LDIwLDE1MCw4OCwxMDIsMTE4LDE3MywxMDMsMTUxLDEyOCwzMiwxMzIsNDYsMTM5LDY0LDE2OCwyNDAsMTQ0LDQ2LDQsMjEsNjcsMywyMjksMTU0LDY4LDExOSw3MCwxMDgsMjQ4LDE3OCwyMDUsMTg1LDEsMzQsNjcsNDIsMTQ5LDgxLDE1MywxMzUsMTM5LDk5LDIzNSwxODEsMSwxNjksMjYsMjIsMjA2LDUwLDE2LDU1LDE2LDksMSwwLDE5NSwyMzQsMTg1LDIwMywyNDAsMTk3LDEwMSwyNDMsMjQ0LDk3LDE3OCwyMDIsMTg3LDQwLDM5LDE0NCwxMjIsNyw2MSwxNjgsMSwxNjUsMTc2LDc0LDEyNCwxNjksMTM5LDE2MSwxNDcsMjE4LDE4MywxMTMsMjAsMjYsMTIwLDEwLDEwOSwxMjIsODEsMTAxLDEyMywxMTQsMTQyLDk2LDE1NCwxNzQsMjI4LDcxLDcxLDI0NiwyMzAsMTE4LDc1LDEzNCwyMDYsODksMjAxLDExMCwyMzcsMTc5LDQwLDE2MywyMDksMTg3LDk5LDAsNTQsMTAzLDE2MSw3MiwyMjAsMTIsMjA2LDEzNSwxMTQsMTE0LDE2MywzNiwxNTgsMTIxLDEwMSw1NCwxNTIsMzIsMTY3LDExOCwxMSwxOTQsODcsODcsMjAyLDUyLDIwOCwyMDAsMjU0LDI0NSwxMywyMDAsMjIsMTQ5LDIwNSwxMDUsMTIxLDgwLDE2NywzNSwxMDgsMTMyLDE1MSwyMDksMTcwLDYyLDE3MywxNDksMTgyLDc5LDIzLDE2LDEsNjksMTA5LDE2LDI1MiwxNjQsNjksMjQyLDE5MSwyOCw1LDEyNCwzMCwxNjIsMTYxLDcwLDMyLDE5OSwxMDYsNjksMjAzLDk3LDI1MCw4MywyMjQsMjA0LDE5MSwxOTEsMjM1LDk5LDEyOCw1NywxNTAsMTM3LDU3LDE0NiwxMDMsMTUzLDE0Myw3MSw1NSwxMDEsMjA0LDE1NSw3Nyw1LDIyNiwyNCw0OCwxMzQsNjUsMTMsMjA5LDE4MSw0MCw4MywxMDYsMjM0LDExOSw2OSw1MCwxNjMsMzgsNzIsMjAyLDg5LDE2OCw4LDIwMywyMjIsMjQ3LDExNywxMzIsMTIzLDExNSwxMTYsMjQ1LDE4OSwzNSwxNjksMTQyLDEyMyw0LDEyOCw0MSwyMjcsMTE2LDE0MCwxMDIsMTEsMjQyLDIyNiwxODIsNDMsNTIsMjAxLDEzNiwxNzgsMTg0LDE1Nyw0LDEzMSw5NSw1Myw3MiwyMTIsMTgxLDk0LDIzOCwyMTYsNjgsMjAzLDM2LDExNSwzOCwyMDgsMTk4LDIxOSwxNDgsMTYzLDcxLDEzMCwxMTEsMzcsMTMyLDE5NCw5Niw5MCwxMDgsMTczLDAsMTY0LDE2MCwyNDAsMTY4LDYsMTk2LDMzLDEyMiwxOTUsNywxMjUsMjExLDk3LDE2OCwyMzAsMTc3LDk5LDE3MiwxMzksOTksMTI5LDgxLDI1NCwxNTQsMTQ2LDQsMTYzLDExNyw0MCw3LDEyMSwxNTAsMTA3LDI0LDE3MywyMDksNjcsNjQsMTcyLDE4NSw2MCwyNiwxOTQsMTIyLDE4NSwxNzMsNDgsMjM2LDExMCwyNTMsMTc4LDE1LDI1MywyMzIsNTAsMTg5LDE1MSwxNDAsMjQyLDE3OCwxMjAsMjM3LDc2LDE3OSwyMTksMTM5LDY1LDE5OCw1OSw2LDE4NywyMzMsMTYyLDQ2LDE5Nyw5Myw2LDE4MCw5LDIxNiwyNTIsMTk1LDI0MCwyNCwxNjksMTU0LDE5NiwxNjMsMTIzLDIzMyw0OSwzNSwxMjMsMTAsMjExLDQsMTkzLDUzLDE5NSw0NSw1NywxNTUsNzIsOTEsNDEsMTQzLDg0LDI1LDIsMTI4LDEzNSwxODUsMTU2LDUwLDE5NSwyMzMsODYsMTYwLDExNiw4NSwxOCw3MiwxNjIsMzksMTk3LDI0MCwxNzUsNjUsMTU1LDEyOSw0MiwyMTIsOSw2MSwzLDUxLDc1LDE3Niw1NSwxMzgsMTM1LDIwNywyMywxMjgsMTMyLDE2NiwyMTIsMTU3LDkwLDExNiw5NywxMDQsMjQzLDEwLDE1MCwxNDAsMTYyLDE2Niw4NSwxMzQsMTU3LDMyLDEyMywyNTEsMTAzLDE4MywyMTQsMTcwLDE0LDI0OCw3MiwxODksNTIsMTY0LDE4NSw2OCwxNDQsMTAyLDcsMzcsMTA2LDUyLDIyMCwxNTUsMjEwLDgyLDIwNyw3NywyNDUsMTk3LDI1LDUyLDI3LDIwOSwyNTEsMjEsMTksMTk1LDYyLDg5LDEzOCwzMCw4Myw0LDE0NCw3OCwyNDMsODQsMTI5LDIzMiwxLDIxNywxNDgsMTAxLDE2OCwxMDIsODcsOTksNjYsMTcyLDgsMiwxNTUsMjE1LDEwOCw1MywxMjksODMsMzQsMTk3LDEyOCwzMCwyMjAsOTYsMTIzLDgzLDM3LDM3LDE0OCw2NiwxNDksMTkxLDUzLDU2LDE2MCwxMTIsMTc3LDM4LDIxOSwyMjgsMTUsMTQ1LDE0NCwxODcsNjEsNDQsMTIxLDI3LDIyNyw0MiwzMSw1LDE5OCwxNjYsMTYzLDIxNiwxODUsMTU1LDE5NSwxNjgsMTA4LDE2NCwyMzAsMjQsMzYsNTcsNjQsMTE1LDEzMiwxMDUsMjQwLDIxLDgyLDIzLDMsODMsMjEzLDIwNywyMzIsNjBdfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbMTY0LDE4MCwxMjUsMTI2LDc5LDIyMCwyMjEsMjUzLDEyMyw0MiwyMDEsMTIwLDE4MCwxNjQsMjAwLDIwOCwxNzcsOTksODIsNjAsNTUsMTU2LDEyNiw3NywxMTcsMTE1LDIwMywyMDMsMTQyLDI1NSwxNjYsMzRdfX0sImNyZWRlbnRpYWwiOnsiY3JlZGVudGlhbF90eXBlIjoiQmFzaWMiLCJzZXJpYWxpemVkX2NyZWRlbnRpYWxfY29udGVudCI6eyJ2ZWMiOls5NywxMDgsMTA1LDk5LDEwMV19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiQ29tbWl0Ijp7InZlYyI6WzY3LDI0MSwxNjYsMjIyLDEwLDE1MywyMzksMTU0LDE0MSw0NywzMSwxNDIsMjIzLDE3OCwyNDMsNTcsMTU3LDEyMiwxNTYsMTAyLDE5LDExNiwyMDEsMjE3LDI0NywyMjksMTE4LDE2NiwxNDMsMzYsMTI4LDIzNF19fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyMTgsMTA1LDE0MSwxODIsMjAwLDIyNCwxNzIsMTEwLDEyNiwxOSwxMDEsMjYsMjQ3LDQ1LDE5NSwxNzMsMjEzLDE2Miw4NCwyMjksMTA5LDgsMTczLDI1MSwxNDUsMjE4LDI0MiwzMiwwLDIxNCwyLDEwLDI0NCwyMDYsMzMsMCw1MCwyNDcsODEsMjA5LDQyLDAsMTIzLDIwNiwyMTIsMzQsODIsNzQsNTksNzMsMTg3LDEzOSwyMSw2NSwxNzcsMTI4LDExNywxNzUsMTE3LDg0LDE0MywyMywxNTgsN119fX19fX19fQAAAAAAAABSAAAAAAAAOn9UcmVleyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJ0cmVlIjp7ImxlYWZfbm9kZXMiOlt7Im5vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbMTM0LDE2OSwxMDQsMjA3LDEzNCwxNDUsMjAsMjcsOTgsMjE0LDY3LDY0LDEwMCw5Miw5MSw3OSwxNjgsMTY4LDI4LDIwOCw3NCwyMzIsMTEsMTc3LDg3LDI1MSwyNSwxLDI1MCwxNzEsMjA5LDE2LDE2MywxNzUsMTQwLDQxLDkyLDE1MiwyMiw4MCw4MCwxMDcsNjgsMjUxLDMsMTU5LDIwOSwxMjUsNDgsMTY1LDEwOCwyMzYsMjAsMTEsNTQsMTAwLDE4OCwyMjgsMTQ0LDE3NiwxODYsMjIwLDE0NywxMDgsMTYsOTMsOTMsMTc2LDQzLDIxMiw2NSwzOCwxNDcsMTYwLDgsNzIsMjcsMTA0LDIyNCwyNDMsMTMzLDE0MiwxMDEsMjA2LDIwNCwxOTcsNjYsODgsMjQsMTQzLDEwNSwxMzcsMTAzLDAsMTk2LDQ5LDI0MSwyMDQsNTMsODcsMjIsMTI3LDE4OCwxMzIsMzgsMTEyLDE2OCw1MCw5Niw0NCw2NywyNDQsMTM5LDExMSwxNjUsNTQsNTMsMTg2LDIxOSw4NCwxMzEsMTEsODIsMTkwLDk2LDE4LDIzMCwxOTMsOTcsMjA5LDgwLDg1LDY0LDczLDU0LDkzLDE1NSwxODgsMTQsNiwzNSwxODIsMTMyLDE3MCwxMTYsMjMwLDQyLDMzLDIzNSw4NSwxMjYsMzksMTA1LDEzOSw5Miw1Nyw2LDE4Niw4OSwxNTcsODMsNDAsMjA3LDE3OSwxNjEsNjAsMTQwLDIwNiwxOTgsMTcxLDExOCwyMzIsMTM0LDg4LDY5LDE0MCw4OSwxMzUsMTE3LDYyLDE1NSwyNTAsOTUsMTUyLDIyNiwzMCwzMCwxMTQsMTkyLDk4LDIxNywxMTYsNzYsMTY4LDAsMjI1LDEsMTU3LDE5MCwxNzIsMTAzLDE0MSw5MiwxNTUsMTgsMTE3LDU4LDEzMCwxODEsMTk2LDI3LDU4LDc5LDk5LDg0LDgsMTg5LDE5NCwxMjgsNSwxMTQsMjEsMTUsOTIsMTg5LDk1LDEzMywxODIsMTQ5LDE4Niw1MiwyNDksMzksNzIsOCwyMSwxMDksMTQsNTMsMzcsMTc4LDE5NiwxMTQsMTc5LDE3MSw2OSwxODksNDEsMTU1LDE0LDgzLDE1NywxNzAsMjQ0LDM5LDE0OCwyNDQsMTcwLDgwLDE4NiwxNTUsMTAwLDI0MywxODksNTAsMTc3LDE0NSwyMjUsODQsMTgsMiw3LDE0OSwyMTgsODQsMTc2LDE5Miw1MCwxMTksNzYsMTAwLDAsNjcsMjgsMjA2LDIyOCwxNDksMTAxLDE3NywyNDcsMTk5LDk4LDE1NCw4LDI0NiwyMjAsNTAsMSwxMTgsMTY3LDYwLDcyLDE1MCwyMjksNTgsMTg5LDQ1LDIyMCwxMTksMjE4LDQwLDI4LDE4NiwxOCwxNzQsMCwyMDksMTQwLDE3MSwxNjMsMTQsOTQsOTIsMTM4LDIxNyw3NSwxNDAsMTcwLDIyNywyMDAsMTI3LDE1NSw0OCwxODEsMTIsMTMzLDIyNSwyNDksMTYwLDQxLDIwNCwyNiwxMDEsMjE5LDAsMTg0LDE1NCwyMDUsMjMzLDE5NiwxNDIsMjMyLDEyMywzMCwyMzcsMjEwLDkzLDY0LDgzLDg2LDE1MCwyMCwxODksMTA3LDU1LDI0LDE2LDg0LDIzLDExNSwxNDUsOCwxMTEsMjcsNCwxODQsNTYsNDQsMjQ2LDIwOCwxMDYsMTE1LDkxLDE1OSwyNDQsMTIzLDE5NiwyNywyMTYsOTcsMTUwLDIwOCwyLDI1Miw2MCwxNzgsMTkwLDM5LDYsMjIsMTQ3LDE2MCwzMywyNDUsMjEsMTYzLDIxNiw1LDE5LDEzNiwxNTYsMTA2LDE1NiwxMjcsMjMxLDEwMiwyMDcsMzUsOTYsMTI5LDExNCwyMDgsODYsMTgwLDExNiwxMTksMTI2LDc0LDEyLDY3LDYsMTMzLDQxLDExOCw3NiwwLDI2LDIwNiw2LDUsMTAzLDE1MSwyMDQsMTM2LDE2NCwzOCw2NiwxNCw5MiwxMjUsMTYzLDUzLDE1MSwxMzAsMjM1LDE4NCwxNTgsMTQ5LDE2MSwyMzgsMTk5LDcxLDI1MSwxODcsMzUsMTg4LDI0LDMxLDE2MywyMzUsMTYzLDYwLDYwLDEzMCw3OSwxNTQsMjUsMjE3LDY0LDE5NSwxNzQsMTM5LDg1LDE5NSwyMDgsMTM5LDczLDYwLDE5NiwxMjksNjQsMjAzLDE2NiwxMjgsMTM5LDIwNCwxOCwxMjcsMTM4LDIyOSw3NywxNjgsMTYxLDE5MywyMDcsMTA1LDAsMTgwLDEwNywxNzIsNjUsMTE3LDYzLDc0LDM2LDE2NSwxNCw1MSwxMjQsMTYsMTA3LDIzLDgyLDE0NSwxMDYsMjQ3LDE0NCw0NCwxOTMsMTIwLDMsMTA0LDE2OCw0MSwxODgsMzQsMjA2LDI1MSwxNzAsMjA1LDIwMywxMTIsMTcxLDE2MSwxMzMsNzYsMTQ4LDEzOCwzNCw4MCw0MSwxNjgsMTI4LDIzLDIwMyw4MSwxNDcsNTAsNTEsMTQ1LDE5OCwxNTIsMjM0LDk2LDcyLDE4NSw1MCwyMzEsMjcsMTQ1LDIwNywyMTEsNDIsNDAsODYsMzEsMjUwLDg2LDg4LDIzNiwxOTcsMTY5LDE3NiwxNjUsMTMwLDIzNCwyNDQsMTg0LDE1NSwxODYsMiwxOTksNTUsNjksNTcsMjAwLDEyOCwxNSwxOSw3OCwyMzEsMjEzLDE3MiwyMCwyMTQsMzQsMTg5LDIxMiwxODMsNCwxMSwxNDIsMTg4LDE2MCw0OSwxNTcsMjcsMjEsMTU0LDE2NCwxNzksMjIwLDE2NiwxNzQsMjA2LDEzMSwxMSw2NCw4MCwyOCwzMSwxMjEsMTEwLDE4MSwxMjIsMTMzLDIyNSwxNDcsMTc5LDk4LDg5LDE3OSw2NiwxNjgsNDIsMjQwLDg3LDIwNSwxODcsMTk1LDExMCwxOTksMjIwLDEzLDE4Myw0NCwxOSwxLDE1MSw1OSwxODAsMTYxLDE5MSwxMDMsMTIzLDEzLDI1NSwxNjgsNzAsODQsMjYsMjA0LDEzMCw4NiwzOCwxMzYsMjMsMTM0LDE1OCwxMDEsMTI4LDI1MywyMDIsMTM5LDE2MiwyMTQsMzAsMTkxLDExMiwxMjAsMjAyLDE1MCwxNzcsMywxNjUsODMsMjQwLDE2NCwxNjYsMjQ2LDE1MiwxNDcsMTk5LDg0LDE1LDIwMiwyMzQsMzAsNzUsMzgsNzMsOTgsNjcsMTY0LDEyMCw1NCw3LDEyMiw1Myw3MSwzNywyNSwxOTcsNzUsMTg3LDEyLDE4OSwxOTcsNDEsMTkwLDMyLDEyMywyMTQsMTM5LDIwNSwxNzIsMjQ3LDEzMywxNTAsNywxOTUsMTI2LDgwLDEyMCwyMDEsOTgsMTQyLDIxNSw4NSwyMDAsMjM0LDc1LDUwLDIxNCw0OSwxMDYsMjE2LDU4LDE5LDY4LDIxMyw3MywzNywxNDgsMTM0LDIwMSwyMzUsMTAyLDE5MSw3NSwxODAsMjE0LDU1LDE4NywxOTksODYsMjksMCw3LDIwMCwxMzMsMTM1LDQyLDE4OSwxODAsMTc4LDE0MiwzNywxMjAsMTI4LDM2LDcwLDIzNCwxMzIsNTksNDYsMjE3LDE0Miw4Myw4Niw2NiwxOTMsMTY4LDE0MiwxOTgsMTAzLDY1LDEzOSwyNDMsMTUxLDI5LDEzOSw2Myw2MywxODgsMTIyLDQyLDM1LDY5LDE1MCw5OSwxMTEsMTQ2LDE4NCwyNSwzOSw5MCwzMywxMjYsMjQ5LDE4OSwxMjcsMTc2LDYxLDExNSwxMDUsOTgsOTEsNTMsMTM1LDExNCwxMjIsMTYwLDgyLDczLDE2NSw1Nyw2OCwxMTAsMjA4LDEyNCwxMjUsMiwxNjksMTE4LDExOSw4NCwzNywxMjgsODYsMTUwLDUxLDEwNSw4NywyNTUsMzMsMjAzLDIwMCwyMzEsMTAzLDEyOSw1Miw2NCwxODgsODIsNTgsNjYsMTYzLDU3LDIxMSwxMjAsMTEwLDE4NiwxOCw4NSwxMzEsMjE4LDE5LDE3LDgsNzgsMjA1LDE3Nyw1NiwyMjMsMTIwLDkyLDQzLDE5Niw3LDEyNywxNTYsNDIsODMsMTA3LDEwLDIyMywxMzAsMTAsMjQwLDIzMywxODksMTUsMTk4LDQwLDI0MCwxMTgsNSw0NSw2NSwyMSw5NSwxODcsMTc5LDEwNiwxMzIsMTEzLDE5MiwxMCwzMCwxMzMsMTY0LDIxLDkzLDkyLDE1OCwxNzAsMTM5LDEyNiwyNDgsMjQ4LDEzMSwyMjcsMTgyLDk0LDE1OSw0LDM3LDU0LDE5OSwxODcsMTQ1LDExNywxMzMsMTcsNTcsNTUsMjEyLDM1LDExMiwxODUsMTMxLDksMjA5LDY0LDc0LDE0NiwyMTcsNTIsMjIsMjI0LDQ5LDE5NSw4NywxNzQsNjAsMjEsODgsNzYsMjA4LDg3LDE5NSwyMjYsNzMsMjAxLDIyOSwxMjgsNjgsMjM2LDg0LDIyNywyNDIsMTY0LDc5LDE5NiwxMzQsMTE4LDY3LDEyOCwyLDEwLDE3LDIyNiwyMCwxMjYsMTM3LDMsMTg2LDEwMSwxNDQsMjAwLDE4OSwxNTMsMTE0LDE2MSwxOTksNSw5MiwxNDgsMTEyLDU0LDIsMTQ0LDYwLDIxOCwwLDIzLDIzMiw2MCwyNDMsMjEyLDE3NSwwLDM3LDI1LDQ3LDIxMiwxMTAsMjE2LDQ4LDQsMTQ3LDIyNCw1NCwxNCw3MCwyMDAsMjMzLDIxMiw1NiwxNCwyMTQsMTM1LDc5LDgxLDE1MCwxMTYsMTMzLDMsNzUsMjMyLDE4OCwyNTMsMjIwLDEzOSwyMDIsMTQ0LDU2LDgyLDUyLDMsMjUsMjI4LDk3LDk4LDI1MiwyMDEsNzYsMTQwLDE5LDE0NCw5OCwxMDIsMjAyLDEzNiwxODcsNTAsMTkyLDEwMyw0NCw4Niw5NywxMjcsMTIwLDEyLDg4LDIzNiwxNjMsODAsMjE0LDE4NCwyMjAsMjE1LDQwLDEzOSwxMTcsNzEsMjE5LDE4MSwxMTcsNTEsMjEyLDEyNCwxMDIsMTEzLDEwMSwzMSwxNDYsNDYsMTkxLDIwMSw5OSw2LDIyOCwxMjIsMjI4LDcxLDIwNyw5MCw5Miw1NCw3MCwyNTAsMTYxLDIyMSwxMzksMTExLDQ2LDg1LDE4MCwxNjUsNyw1NiwxMjUsMjEsMzQsNjcsMTE5LDExMiwxNjUsMTEsMTk3LDEwMCw2NSw2NywyMjEsNTksMjM0LDE4OSwxOTUsMjAzLDE2MiwxNTksMjAzLDE5OSwxNTgsMTgyLDE2NSwxLDE5MiwxNTUsMTE1LDI5LDE3OSwyMzMsMzUsMjE1LDk1LDE5LDIyNCwyLDE5LDgzLDIxNiwxMiw4MSwxOTgsMTgzLDE4MCwwLDU4LDI0OCwzOSwzOSwyNTMsODQsNTAsOTQsMjU0LDIyNSwyMTIsMTUsMTAsODgsMjUzLDIxMCw5LDI0NiwzNywyMjQsMTY1LDE4NSw5LDYsMzMsMF19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNjQsMTgwLDEyNSwxMjYsNzksMjIwLDIyMSwyNTMsMTIzLDQyLDIwMSwxMjAsMTgwLDE2NCwyMDAsMjA4LDE3Nyw5OSw4Miw2MCw1NSwxNTYsMTI2LDc3LDExNywxMTUsMjAzLDIwMywxNDIsMjU1LDE2NiwzNF19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJDb21taXQiOnsidmVjIjpbMTY1LDI0MCwyMjIsMTQ1LDE5MSwxOTksMjAxLDIwOCw3NiwyMDMsMTYyLDE3OSwxNDIsMjM1LDExNywyMjcsMTM0LDU2LDExNSwzOSw4Miw1MywxNTQsNDksMTc3LDIxOSw4OSwyMDksMTg0LDMsMTM5LDIwOV19fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMzIsMzAsMzksODMsNjksMTA3LDE4OSwzNiwxMDEsMTA0LDE3MCwyMjAsMTM0LDI1MSw0MSw0NSwxNjQsOTYsMzksMjQyLDU3LDU5LDE2OCw4Myw4NCwxNjMsMTM5LDE4OSwyMzEsMTI4LDEyNywxOTUsMTkwLDE1NCwxMjIsNTQsMTI2LDE1NywxMzAsNTksNzAsMTQ0LDEwMSwzMiwxNzAsMjUsMjA4LDIwNCwyNDcsMTM0LDE1NSwyMDksOTksMTE1LDU0LDEzNywyMywxMjksMjE5LDE0MywxNTIsMTU2LDEwMCwxM119fX19LHsibm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOls3MCwxODAsMTM4LDcxLDI0MiwxMDgsNjMsMjQwLDE4OSwxOTksNDEsMTEwLDg5LDg5LDE5NSwxNDUsODksNzQsMzMsMjEzLDE0LDE2Nyw5MSwxMDMsMTYzLDY2LDcsMjEwLDIzNiw5LDUwLDI0MCwxMDAsMTUzLDEwMSwyOCw4NSw5LDE2LDE2MywxNzcsMTIwLDY0LDI0NywxMSw5LDEzMyw5NSwxNTgsODgsNjIsMTQ1LDI1MiwxMDksMTM0LDIzMCw5MiwyMzIsMjA0LDEwMSwyMTcsNjAsMTY5LDEyNiw5MiwyMDMsMjM4LDg2LDIxLDIzMyw4NCw0NSwxNTUsMTI5LDQyLDEzNywxNTAsNTgsMTA4LDQxLDE2MSwxMTMsMTQ4LDE3NSw4NiwxNTYsMTYsOTgsNzUsMTM4LDEyMiw3LDMzLDEzNSw5MSw3NywyNDIsMjMsMTkxLDI0Myw0OCw5LDI1LDEwMCw0NCwyNDgsNzMsMTI0LDcxLDc0LDE0NywyMjAsNDksNDMsMjI4LDUxLDE4NiwxMjAsOTYsMTg5LDE3NSwzOCwxMTUsMTA4LDExMiwxNjIsMTAzLDU4LDQ3LDk0LDI0Niw0OCwyNDYsNjYsMTA5LDAsNjcsNjcsMjI5LDE0Nyw2NCwxMzcsMywxNjMsMTE5LDE3OSw2MywxMDUsMjMxLDQ2LDE4MCw5OCwxMzEsODgsNDgsMTQ2LDEwNCwyMDgsMTM0LDYsMjAsNSw3LDIzMywxNDYsMjQ4LDEzNSwxMTUsMTY3LDgxLDczLDExOSwxMzcsODEsOTAsMTc3LDQzLDE2NywyMiw0OSwyMSwyNSwxMTYsMzMsMTMwLDYyLDExMCwyMTcsMTk1LDE1NiwxMCwxNzIsMTMwLDg2LDU4LDIxMyw1OCwxMjgsNTIsNjcsMzMsMTYsMjE5LDgzLDgsNCwxODAsMTE5LDE3NiwxOTcsMTA3LDMsNzksMjE2LDI0NCwxMDgsMjQyLDM5LDY0LDE2NywyNDksNDYsMjM5LDEzNiwxNjEsMTgwLDIyOCwxNjcsMTkzLDUsNDEsMTU2LDE0OSwxMzgsMjIwLDE0NywxNDcsMTA3LDEyOCw2NSw4MywxODIsMTMyLDI1MSwyMzUsMTYwLDE5NCwyMjgsNzksMTUyLDE0NSwxNzAsMTQ2LDEyMiwxNiwyMDYsMTc4LDYxLDg0LDIxOSwyMSw5LDI1MSwxODgsMjE3LDY3LDM1LDE0NywyMzIsMjcsODYsMTYsMTEwLDEzMywxNTMsNjMsMzAsMTkzLDIwMSw4OCwyMzUsNzIsMjU0LDE2NywyMSw5Myw4NSw1LDYyLDI0Nyw3NiwxNCw4NywxMDQsMTc2LDE2NCwxMywxNTQsMjE1LDEwNCwxMzYsMTMyLDE0Miw1NiwyMzEsOTYsMTU5LDE2OCwyNCwxNjcsMTAxLDE0MiwxMjcsOTIsMTMsMjM2LDY1LDU1LDEwMCwxNzYsMTQwLDE2OSw2Nyw2OCw2OCw3MiwxMTQsMTk3LDIxMSwxMTksOTIsMTM4LDE5NywyMTAsMTk5LDEzMiwxNjYsNTAsNTQsMTQ2LDExNSw0MCwzOCwxNyw2OCwyMzYsNDMsODUsMTgsODgsMTQ5LDI0Miw4Miw4MiwyMDAsOTcsMTgwLDk3LDUxLDgsMTE3LDE5OCwxMTcsMjAxLDE2MCw1NSwxMTYsMTkzLDE0MCwxNDgsMTcsNCw2Miw1MywxMTcsMjE4LDU0LDc3LDE2NywyMTQsMTEsMjAxLDQxLDEsMTUsMTg2LDE3MSwyMjcsNDQsMzYsMTEsMTk5LDIwNCwzNiwyNCwxNzksMjIwLDUzLDk5LDE4MCwxMzQsMTYsMTc4LDIyOCw0MiwxNzgsNjksMTUxLDIwNywxMjAsODEsMjAyLDExOCwxNjMsMTA1LDIwNCw1NCw1OSwxOTMsMTA0LDIwMCwxNjgsMTc2LDczLDI1MCw2NywyNDUsMTcyLDI5LDczLDEwMSwxMTAsMzksMTA0LDI1LDU5LDEzMyw5Miw3NSwxMDEsODUsMTM5LDExOCwxNzUsMzUsNywxMDcsMjE0LDEyLDE1NCwyNDYsNTYsMjAsMTA5LDUzLDQ4LDc5LDcyLDExMiwxNTYsOCw5MSwyNTIsMzIsNzEsMTc3LDI0MywxMzksMTg0LDE5NiwxMzUsNzIsNjcsMTIxLDQ2LDI0NCwxMzAsMTIxLDI0OCwxNTUsMjI1LDIsMTA4LDE2OCw1MCwxMDgsMSwxMDIsNTcsNTgsMTUwLDEyNiwxMjAsMTA1LDQ4LDgsMTk5LDEwLDE2MCwxODEsMTMyLDMsMTIzLDUzLDE2MiwxNywxOTMsMjAyLDE4OCwxNDksMjI1LDI2LDgzLDEzMiwxMTUsMTA3LDE4NiwxMTMsOTksMjksMjUyLDU0LDI0NywxNTMsMTY1LDE0OCwxNDcsMzksMzAsNDksNjYsOTcsMTYyLDEzMCw0LDEwNSwxNjMsMjAwLDczLDIwNiw3NCwxODMsNjIsODYsMTY2LDE4OCwxMDMsMjIwLDU4LDE4MCwxNjIsNTAsMTE5LDIwOSwxMTUsMTY5LDY0LDEzMCwxMCw5MCw0Nyw3NCw4LDE2MCwzNyw2NCwxMTgsMTkzLDE1MCwxMiw0MSwyNTEsMTEsNzUsMTY0LDEzMiwxOTcsMjM2LDE0NiwyMzYsMTM0LDEzMiwyNDAsMzksMTA2LDI0NCwyNDUsMjAsMTM0LDIyNSw4MSwyNSwxNDAsNzIsMjUyLDEzNywyOCw1MiwxMzEsMTY1LDE3MiwxMDgsMjAzLDI4LDIwOCw3NywyMjAsMTgzLDc2LDIwOCw3MywzOCwyMzYsMTgwLDAsMTk5LDExOSwzOCwzOSw0OSw2MCw0MywyMTcsMjgsMTYsMzYsMTgwLDIzNSwxMTksMTI5LDE3MCw3MSwxODksMTc3LDEzOSw3MSwxNTIsMTIwLDE3NiwxMjYsNTgsMTE0LDEzMiw3Myw1MCwxOTYsNywxNzQsNDUsODQsMTAzLDcwLDkxLDE4MiwxMzUsNjksOTUsMTg1LDI1MCwxMzUsMTY2LDE2MiwxNDcsMTk0LDE5NywxMTQsOTIsMjcsOTgsMjM0LDIzMiwxNDMsMTAwLDE0OCwxMzQsMjA4LDIyNywzMCw1MywyNDgsMTEwLDE3NSwyNDQsMTg2LDMyLDEyNCw3LDE2OCwyNDAsNTEsMjAzLDI0OSwyMiw2LDE5NCw3MCwxMTEsMjEsMTE4LDMsMTkyLDQyLDE3NywyNDAsMTYsMTE3LDE4MSwyNyw0MSwyMDIsMTUsMzksNjYsMTgxLDIwMSw2Niw4NywxNzksMTI5LDEwMCwxMTQsMTQ0LDc3LDEyNiw5MiwyMDIsMjIwLDY0LDExNywxNDIsMjgsMTMyLDIxNiwyNDksMTc3LDUxLDE1MCwxMDIsMjM5LDEyMywzMCwxOSw4MCwyMDQsMTYwLDIzLDEzNywxMTYsMTU2LDEyNSwxMjgsMTMxLDk5LDE4OCw2LDIwLDE0NCwxNTMsMjQsMjI3LDIxMyw4MCwyNDksNDEsNjcsNjUsMSw0MiwyNDQsMTQ2LDEyOSwxODMsODMsMSwxOTQsMTY0LDE0LDE3MSwxODQsMTI0LDEyOCwxMTcsNzMsMTE0LDQ5LDE3NywxOTMsODQsMTU1LDE1MiwwLDU4LDU5LDI0NSwxMjEsMTI3LDIxMywxMzAsMTA2LDE3OSw3LDIxOSwxNjksMjgsNzIsMTE3LDUsMTgsOTAsMTg0LDI0MCw4MiwxNzAsMjUwLDI0NSw2Myw0MCwxODIsNjgsODQsMTU1LDE3NCw1MSwxNzYsMTI4LDEwMCwxMSwxNTEsODUsMjUwLDE4NiwxMTYsMjcsMjUsMTU2LDE3MSw1MSwxNjQsMTk3LDIwMywxODcsMTgwLDQ2LDE0NywyMTUsNjQsNzAsMTE2LDE2LDIxNywyMjksOTgsNTEsMTUwLDE0NywyMTYsMTc3LDE0NiwxOTEsMTUzLDE0MywzNiwyMywzMSwyMTgsMTk5LDE2MiwyMCwyMTIsMTAsNzAsMTY0LDU0LDE2LDY1LDI0LDExOSwxNzYsNCwyMDgsMTUxLDE4OCw1MSw3MSwxODksMTA5LDE2NiwxNTYsMjExLDE1NiwxODcsMTk4LDEzOCw1MywxMzksMTU0LDQzLDg3LDE1MCw0OSwxNzksMjQwLDUxLDExMCwxMTgsMTMyLDIxMCw5MCwxMzAsMTU0LDY0LDEzMCwyMTMsMjI3LDE4Niw1MSwxMDcsMTkxLDkxLDE1NCw0NywxMzQsMjA4LDIwNSwyMTMsMjEyLDIwNiw1LDEyOCwxODcsMTA3LDEzMywxMDEsMTkxLDExNSwxOCwxMzgsMTA1LDI3LDk4LDIyNSwxMzMsMjE4LDgxLDM4LDExOSwyMTcsNDgsMTM2LDIxMCwyMDQsMTIwLDE2Nyw3Miw5NywxMzUsMTA2LDIwMywzNCwxNiw0NSwxNTQsMTkwLDkyLDUxLDQ2LDIwOSw5NiwxODAsMTY4LDEwMCw0MCwyNTAsMTkyLDE0NywyMTksMTA1LDE4Myw4Nyw0MywxNTksMTg1LDI0Nyw1MywyMzgsNDQsMTgwLDQ2LDE4LDI4LDIxNiwxNjUsMTAxLDE2MCwyMzEsNTMsNjMsMTEyLDEwMywyMTcsMTg2LDEwMiwxMjksMTgsMTQxLDc2LDExOSw3MywyMTIsODAsMTQ3LDE1Nyw5OCwxMjUsMTIyLDIwMyw1NywyNSwxOTcsMTUsMTg3LDIxOSwzLDEyNSw4MiwxMDMsNDAsMCw0NywyMjksMjUsMTE3LDI0NiwyMCwxOTIsMywyMDAsMSwxODAsMTUwLDIwNSwyMDEsNTQsMTA2LDE4MSwxMTMsNDMsODMsNDMsNTQsNzIsMTA1LDgwLDI1LDU5LDM3LDE3NSwyMTQsMTIzLDMzLDE1MywxMSwyMjEsMTksMTMxLDEzMiwyNDAsODAsOTUsMjUxLDQsMjU0LDI1MCw4MCwxMzMsMTg3LDE4MiwxMTIsMjQ1LDc1LDEyNCwxMDcsMTIxLDQsMjQwLDE5OCwyNDAsMTYyLDcyLDIyOCwyNTIsMTIwLDc3LDAsNzIsMTgxLDE5OCwyOSwxMDIsMzcsMTgxLDQ1LDE5Nyw5NywxNSwyMywxODQsMTY4LDEwMiw1MSw2NCwxMTUsMTEzLDIzNywyMjUsMTM4LDg5LDIsMTI4LDIzOSwxODEsMTc1LDEwMiwyMTEsMTYwLDU0LDE4MiwzNSwyMzMsNTAsOSwxMDQsMTAwLDEzMSwyNiw4NSw0OCwxNTcsNjcsNjksNzMsMjAzLDEyOCw0LDE3MiwxNTksMjQzLDc0LDE0MiwxOTYsMTY5LDE5LDc5LDE1MiwyLDYsMzAsMTMyLDE3MSwxMDMsMjIxLDcsMjExLDE2OSw3OCwyMzUsMjA2LDY5LDI4LDI1MiwxMyw2OSwxMjUsNjQsMjU0LDI0NywxNywxNjAsMjAsMjAyLDE0NiwwLDIzMiwwLDEyLDE3MSw5Niw3NiwxMzMsMTM0LDI0Myw1OSwyNDAsMTUwLDE0OSw5NSwyMDksMjE5LDE5OSw3MywxODgsMTA1LDEwMywxMDEsMTg1LDI0NSwxMyw5NSwyMjIsMjA0LDE2Miw0NSwxMzksMzIsMTA1LDVdfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbMjM5LDIzNywyNTEsMTUyLDIzMSwxNDAsMjUyLDMzLDIzNywxNzQsMjQyLDI0MSwxMjQsMTAzLDEzMCwyNCw3NiwxMDYsMTQ1LDIyNywwLDUxLDY4LDExMiwxNjAsNDYsNDIsNDksODIsMjMzLDc3LDExN119fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk4LDExMSw5OF19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiS2V5UGFja2FnZSI6eyJub3RfYmVmb3JlIjoxNzIwNjg4OTUwLCJub3RfYWZ0ZXIiOjE3Mjc5NTAxNTB9fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyMjIsMTc5LDMsMzIsOTQsMTI3LDY2LDI0OSwxODgsMTA3LDc3LDE4NiwxMjYsMTg5LDEzNSw1Miw2OCw0MCwxNzIsMTEwLDEzNSwyNDQsMjA4LDk1LDE2NywyMjMsMTc3LDE4MiwxNjAsNDYsMSw0NSwxMDgsMTkxLDcyLDExOSwxOTYsMjIsMTUwLDE5NCw1MywyMiwyMDMsOTEsMjIzLDIwNCwxNTEsMTQ0LDEyNiwyMDMsMjQ5LDEyMSw2Miw0NSw0LDE0NCw4OSwyNywxODAsODQsMjM2LDY2LDU5LDFdfX19fV0sInBhcmVudF9ub2RlcyI6W3sibm9kZSI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbMTE2LDE2Niw2MiwxMjksMTc3LDE2MywxMjQsMjE0LDEwOCw4MCw4NiwxNDUsMjgsMTQ0LDY0LDE4NSw0LDg5LDYwLDExNiwzMywxOSwyMjUsMTU3LDcwLDEyMywxMzMsNTMsMTgwLDg5LDY3LDE0OSw0Myw2NiwxODMsMTQzLDQ3LDM0LDE4MCw4NywxNiwxMSwxMTAsMjUxLDYxLDIwMiwyMzMsMTUzLDgsMTAyLDkxLDE5OCw0OSw1OSwxNjAsMTk4LDg2LDU4LDI0MCwxNTgsMTU5LDgxLDIwNyw5NCwyMDksMTIwLDIyOCw4NCw1NSwyMzksMjIsMTk3LDEwMywyMzQsNzcsMTk4LDI0MSw0Nyw5LDgwLDE2MiwxODYsMTU0LDE4MiwyNiwxMzksODYsMjQxLDIwLDEwNCwxNjksMjE5LDEzNywyMDcsOCwxOCwxNTQsMTYsMjUsMTE5LDE0NiwxODYsMTUzLDg5LDIsOSwxMDQsNDIsMzYsMTYsMzcsMjEsMTk1LDk1LDM5LDE5NiwxNTQsMTg1LDc0LDEzMiwyNDYsODksMTQ1LDEyMCwyMjcsMjEsNjIsMTgyLDEwMiwyMzIsMjUyLDIsMTc5LDE2OSw0MiwxNDUsMTAzLDE5MSwyMDUsMjM0LDExNiwxOTAsMTA4LDE0Miw5OSw1OSw0NSwxMDEsMTIxLDksNjMsMTY3LDE5NCw4NCwxMDIsNDgsMjMsMjEwLDExOCwyMjcsMTUyLDEzNSwxNjMsNDMsNDIsODQsMjQ0LDM3LDIwNSwxMzUsMTUxLDExNSwxNTAsODgsMTgwLDIzMywxNDYsNjksMTksMjA3LDY2LDQyLDEyMywxNzIsMjQ4LDg4LDE4MywxNjksMzAsMzUsNTIsNzYsODUsMTUzLDE1OCw5LDExNSw5MCwyNTEsOTksMTUsMTY0LDE2MiwyMyw4NiwxNTAsMTcyLDg1LDEwMSwxMjksMjQxLDEzNCwxOTksMTI0LDI1LDAsMTkwLDE0NiwzNCw3MSwyNCw5NiwzOCwyMSw2MCwxOTEsMTQwLDE3MywyNTIsMTEzLDk1LDYwLDc1LDQ5LDU5LDI0NCwyMDMsMjQxLDEyOSw2OSwyMzUsMjIsMzIsMTUsMjM2LDE5MCwxMjIsMTAxLDY0LDExMSw3LDE3MSwyMjgsNTcsMTIxLDExNCwyMDMsMTMsMTAzLDksMzQsMTUsMzYsMjksMjIyLDIyNywxOTgsMTU0LDMzLDExMSwxMzcsMTY4LDExOCwxMDUsMjMxLDEwMSw2MSwzNSwxODAsNzgsODksNDMsMTQwLDkwLDI2LDUwLDIxLDE0MywyNDEsMjEyLDc3LDEzLDQ4LDE3MSwzMywxNjMsMjAzLDIwOCwxODEsMTk0LDEwOCw4MiwxMjUsMTE3LDgyLDY5LDEzLDE0OCw4Myw0NSw2NSw2NywxMTEsMTk3LDg2LDEwMywxNjYsMzAsMjUzLDI1Miw0OSwzNSw1NywxODMsNzUsOTEsMTQxLDE4Niw5MSwxNzAsMTQ3LDI1MSwxNjMsNDIsMTgxLDE3NCwyMjgsMjQsMjMsMTc3LDIxNSw3NiwyMDYsMjE5LDUyLDI1Miw4Niw5Miw2NCwxNjgsMjIsNzgsMTg3LDE0NCw3OCw4OCwxMDEsMjE4LDE0NiwxMDUsMTY2LDYsMTM0LDE1Niw2NiwxOTEsMTg1LDE5OSwxODYsMTIsNSw5NiwxMjUsNjQsNDQsMTQyLDEyLDE3MSwxMjksODQsNzYsNzEsMjE2LDk2LDMzLDE0NSw1MiwyNTUsMTQ2LDkxLDEzNSw1NSwxOTcsMzMsMjQ0LDE2Miw2OCw5Nyw0OCw2Nyw4OSwxMzMsMjAzLDE4NiwxMDAsODMsMTg1LDcwLDExOCw1OSwxODksMjQ4LDIxMywxNDIsOTUsMTk2LDExMiwxNzksMTQ4LDE4Nyw3LDEwOCwyOCwyMzUsMTMyLDEsMjAwLDIyOCwxODMsMTY0LDEzNSwxNiw4MiwyOCwxNjYsMzAsMjMxLDEzMyw4NSwyNTAsMTM4LDg5LDE5NiwxMTgsMTcyLDY1LDE5MCwyMzIsOCwxMyw1OCw4Myw3MiwyMzksMTAzLDQ2LDk2LDM2LDU1LDg5LDE4NywzNiwyNSwyMTYsMTA0LDIwMCwzNCw3NSwyMjAsMjM0LDExMiwyMjMsMCwxMjYsMTA2LDIxNiwxOTIsMTQ5LDQzLDg2LDIwLDE3MSwxMTUsODMsMjAzLDEyLDQ5LDE4NCw4MiwyMzgsMjEzLDE0MCw1NCwxNTEsOSw5MywxNzcsODIsNTQsMTIxLDMyLDEyNSwzMiwxMTEsMTE5LDE4NSwxMDEsMTM0LDI0MSwxNDQsMjI3LDIxNiwyOCwzOCwyMjgsNSwzNCwxMTQsMTExLDI5LDIwOSwyMDcsMTI1LDQ4LDM5LDIzMSwxMjksNzgsMjI5LDkxLDc0LDUsMjUyLDE2MCwxNjYsMTQ4LDIwLDQ4LDE0NywyMDIsMTk5LDI0NywxNzAsMjMxLDEyOSw4MywyMjQsMTY3LDQ5LDIzNCwxMzYsMTYzLDM0LDIyOCwxMTksMTUwLDE2LDU4LDE4NiwxOTgsMTMzLDQsNjgsMTU5LDE3NSw4MSwxNDAsMjQzLDI0LDgwLDc5LDI0NCwxMDgsODAsMTAzLDE0MywxNjEsODgsMjAzLDIyNSwxNjMsMTY0LDE5Nyw1LDgyLDI3LDEzOCw2OSwyNDAsMTg2LDkxLDIzMywxMzEsMTU4LDIwMiw0MCw5MCw4MSwxNjAsODIsMTQzLDEzNywxNjQsMTMxLDIwLDE3MywxNTMsMjUsOTUsODAsMjYsMTgxLDM4LDE0OCw1NCwxOTYsMTA0LDIzLDIzNywxMzYsMTYzLDIxOCwxNywyNyw2NiwyMjgsMTI3LDIxMSwyNTAsMTQ5LDE2NCw4NSwxMDksMTY5LDE4NiwyMDAsMSwyNTEsMjAxLDEwMywxMjMsMTgzLDE1NSw4Nyw5NCwxODcsMjM1LDE3OCw5OCw5NywyMDYsMjUsMTA1LDE2MSwyMDIsMjMxLDEyMyw2NiwxMzgsMTQsMTc3LDExNCwxNjEsNTksMTc3LDQwLDEzLDM5LDMwLDg0LDQ4LDE4NywyMzMsMTMxLDE4NiwyMDQsMTY3LDkxLDIyMywyNDMsMTkzLDkyLDIxMywxOTEsMTQsMTQ3LDE3LDEzNyw0LDM2LDk2LDU2LDQ1LDI3LDM1LDIwMSwxOTAsMTkzLDI0LDE3NywxNTQsODYsMTk3LDE1NiwxNjgsMTY4LDExNSwzMSwxMjUsMjI5LDM1LDgwLDg5LDk5LDIzNywyNTEsMTkwLDgyLDEsMTMzLDE1MCwyMTQsMjA1LDg3LDksMTk0LDIzNCwyMzQsODYsMTY4LDE0NCwxOTAsMjAxLDk3LDExMiwxNDEsNzQsNzYsMTQwLDk2LDUsMTE3LDY2LDcsMjU1LDQwLDE1OSw0Miw0MywxMTksODQsNSw5NywxLDIxNiw3MSwxMSwxNjcsMTQ1LDY1LDI1MSw1MCwxMDAsNTIsMTcwLDQsMTksMTksMTE5LDE0MCwxMCwxMCw4NSwxNyw4NCwzNywxMDksMjQwLDE5NCwyMywxNjYsMjM1LDEzMSw3NiwxODYsMzcsMTA0LDIxNywyOSwyMjcsMTU1LDYwLDEwOSw3NSwxMDIsMTcsMTI5LDE1NCwyMjUsMjIsOTksMTgyLDE3MCw1NiwyNSwyMzEsMTUxLDc5LDE2MSw1MCwxMCwyMjksMyw0MCwxOTYsMjYsMTc4LDEzNCwxNDUsMTcsMTU1LDExNiwxNDEsMjAsMTcyLDE0MSwxNjksNSw0MCwyMDksNjIsMzUsMzYsMTQsNzYsMjM2LDE5NCwyNDIsMTE2LDE4MCwyMzYsNDIsODQsOTEsMTE4LDEzOSwyMjUsMTc5LDE4OCwwLDEwNSwxMyw5OSwxODMsNTMsMjIyLDIxMywxMzEsMjMyLDIyNSw5NiwxOTMsNzEsNCwxMDQsNiwxNjUsMTc5LDIzNSw0OSwyMDcsMTE1LDM4LDEyMywxODUsMjksNjUsMTgxLDE3NiwxODUsNzAsMTY5LDE4MSwyNDEsMjIsNDEsOTAsNjYsMTIzLDg5LDE2MSwzMCwxNDgsMTE1LDEyNCwxOTgsNjQsNjYsMTAzLDEwMSw1MiwxOTcsMTkwLDEzMywxMDAsMTM5LDE0Miw4Myw5NywyNTIsMSwxMzIsMjMwLDIzNCwxODIsMjIxLDIxLDg5LDEwNSwxMjQsMTA4LDIyMCwxOTMsMTk2LDE1NSwxNTYsMTYxLDE1MSwyNDEsMTE3LDY0LDEyMCwyMDYsMzgsMjQxLDkzLDEwNiwyMTIsMjUsMTQwLDE1NCwyNywxODEsMjQxLDEwMSwyMTIsMzQsMTM5LDUxLDcsOTksMzQsMTY2LDYwLDUzLDE4Miw3OCwxOTEsNzMsMTU1LDI1MSw1NiwxNzEsNTMsMTk3LDM2LDQyLDE5OSwxNDgsMjUwLDE5NiwxOTIsMTM1LDEzNCwxMDIsMjU0LDI4LDExNywxMjYsODYsNSwxNTcsNTMsMTY1LDIzOCwxMzUsMTc4LDE4MSwzOSw3NiwxNCwzNCw4MCw2LDIyNywxNjIsMTIwLDEzMCwxMDMsMTcsMTg4LDE3Nyw1NCw5OCwxNDAsMTk1LDE3OCw2NywxNjAsMTY3LDE0LDE1Miw0OSwxNjMsNjcsMjUwLDE1MiwyMDgsMTE2LDMzLDI0NywxODIsMTIyLDExNiwxMjMsMTY5LDE5NCwxNjQsMTEyLDE1Niw3NCwxNDgsMTQ4LDY3LDEyNSwxMTksMzksMTE5LDEyNCw1NSwxMzMsMjEwLDU5LDEyNSw5MSwxODcsMTE0LDE0NSw3MSwxNzIsMTgxLDUxLDkxLDE2MSw1Nyw1NSwxNDgsODEsNDksMTc0LDEwOCwxNTMsMjA2LDI0Miw3OCwyMzksMTgsMTMwLDMyLDIxMSwxMjksMjIyLDY0LDgsMTI4LDE5MywxMjgsMTYsMTA2LDg1LDE1MCwzLDIwMiw3NCwxNjMsMjAyLDgsMTk3LDYzLDEzMywyMDQsMTg0LDE0OCwxNTMsMTg5LDYyLDE2OCwyNiwxODMsMjE5LDE1MCwyMDAsMjExLDU0LDI0OCw3NSwxMTEsMjM3LDIwMiwxNiwxOTMsMjI1LDE5MiwxODIsNTksMjAyLDM2LDIzMiwxODAsMTk3LDEzMCwxMjMsMTU5LDE1NCwxMjMsMjE2LDI0MCwxNjEsMjEyLDE0NSwxMTAsMTUwLDgwLDExOCwyMDgsOTAsMTA2LDgxLDcyLDIwLDY5LDYwLDI4LDE3Nyw5MCwxNjQsMTg5LDM5LDAsODMsODIsOTgsMTMwLDgwLDQ1LDE3Nyw3OSwxNzcsMjM1LDQxLDE0NCwyNSwzMiwyMiwxMjIsMzEsMTQ1LDIxNywxNjMsMTAxLDIyMCwxLDk4LDEwOCwxOTYsMTcxLDE4NiwxMzIsMjksMjQwLDIyNSwxMTIsNCw2Niw5NiwxNDgsMTg0LDE2NCwzNiwyMjMsMzAsMTEsNjksMTA1LDc3LDE5NiwxNjcsMTYsMTQ5LDE4NSwyNDYsMTUzLDEyOSwxODAsMTIwLDI0NCwxNTYsMTIsMTMxLDk3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NjcsMTE3LDE5NiwxODIsMTcyLDEwMSwyMzYsMTcwLDEyMSwxODYsNTcsNzcsMzMsNjYsMzIsNzMsMTE3LDE3MiwxMjIsMTUwLDEzNCw4MCwyMjAsOTIsMjM5LDIyOSw5LDczLDIxOSwxNjgsMzMsMjUxLDMzLDk3LDE3MSwyMDQsNjYsMTQwLDYzLDM1LDE1MywxODksMjI5LDEwNiwxMzksMTAxLDE1NSwxODUsMTYwLDIxMCwzOCw1MCw0MSwxODMsNjksNTksMTYwLDQ5LDExMiwxNjgsMjM0LDEzNCw5LDIwMywzNiwxOTksMTYyLDEwOCw1MSwxNzQsMjQxLDEyNyw3MywxNzIsMTg3LDUxLDI2LDE1MiwxNzMsMTQ5LDgwLDg1LDU4LDE2NSwxODIsODcsMjAwLDIwNywxMjksMTI2LDEzNSwxMTksMTY1LDMwLDIzMSwxMzUsMjI0LDE5MywxNjgsMCwxNjEsMTM4LDYwLDI0OCwxMCwxODYsNDgsMzEsOTMsMTc4LDcsMTk3LDE5OSw1NCwyNDQsMTUwLDE1NywwLDEyMSw2OCwyNDAsMjQ3LDExMCwxNDksNjksMTEyLDE3NywxMCwxOTgsMjQ5LDEyMywxNTMsMTI4LDE5MiwyMywyNiw1Niw3NCwyMjcsMjE3LDk3LDEzMiwxODMsMTUsMjIsMTIwLDE3NSw5Myw0OCwxOCwxMTgsMTc4LDEzLDIzMiwxOTIsMTMxLDE1OCwxNzYsMTE3LDEyMCwxNjUsNTIsMjM5LDIyNiwxODUsMzYsMTE1LDEyMSwxNTksMTYwLDkyLDEyMSwxNDYsMTA2LDE3MSwxOTksOTMsMjMyLDIzLDM1LDI2LDMsNDAsNTIsNSwyMDYsMTgyLDIzMyw3NCwxODQsOTAsNiwyNDYsMTg3LDUsMTk1LDE4MCwxNyw5NSwyNDIsMTA5LDE2NCwzNywxNDYsODMsMTk3LDEsMzIsMTcxLDEyNiw4Myw4OSwxMDMsOSw3Niw5LDE3NCw2OSwxNjUsOTMsMTgzLDksNzMsMTYwLDExMSwxMjgsMTIsMTQ5LDE5OCwyNDgsMTE3LDAsMjgsMiwxNjcsMjM1LDIzLDczLDk3LDExNiwxMTMsMTUwLDE0NSwxNjksNywyMDUsMTEzLDE0Nyw3LDEzOCwxODAsOCw5NywxMDAsMSw5NSwxNjQsNTAsNTYsNjgsMTcyLDI0NCw2LDEzMCw4LDE5LDE3OCwxMTAsMjQxLDE1MiwxMzYsMTM0LDE5Niw1NiwyMDEsMTk2LDIwOCw1Myw4OSwxMzIsMjI2LDU0LDIyNCwyNiwyNywyMiwxNzgsOTIsNDYsNDIsNjksMTAwLDU2LDExOCw4MywzOCwxOTgsMCwzNyw4NiwxMTgsMjI1LDQsNDcsMzMsMjMsMjA4LDE5MiwxMDQsMTAsNzMsNzcsMjE3LDExNywxNCwxNjUsMjEzLDE1MywzOCw4MywxNTAsMTM3LDI0MywyMDAsMjM3LDE3LDM0LDEyOSwxNzgsODcsNTMsMTQ5LDE1MCwxMTcsMTM0LDE4Niw3NCwyMjYsMTQyLDEyMCwyMTEsMTAzLDc3LDE0OSw3NSwzMSwyMzAsMTU1LDE2MSwyMjgsNyw1OCwxNjcsMTQ2LDE3NCwxMzMsNiwxOTgsMjEsNTAsMTQ0LDI1MiwxNDMsMjQ4LDk4LDQsMTYsMTM5LDIwNCwxMyw0OSwxMTIsODIsMTgyLDYsOTIsMTY5LDcxLDgwLDY0LDQ1LDE0MSwzOSwxODEsMjA0LDEzMywxNjYsODUsNDEsMTQsMjAzLDIyOSw1MSwyNTQsMjIsMTUyLDYwLDE5OSw4Miw0MiwxODYsMzcsMzMsMjYsMSwyMzYsNzIsMTU1LDk5LDEyMSwxNTksMjIwLDIxLDE2NiwxMTIsNjcsNDQsNDMsMTYsMzYsMTU3LDE0MCw0NCw1NywxNDYsNTIsMTAsMTY2LDE0MywxNDUsMzIsODAsMTU0LDkyLDAsNjQsNDgsMTQwLDIyOCwxOTIsMTcxLDE3MywxNzAsMTk2LDQ3LDEwNCw3NSwxMDQsODAsNTAsMTU3LDEzNiwyOSwxMjcsMTM4LDQ1LDUsMjE0LDIyLDcxLDExNiw2MSwyMTcsMjgsMjcsOTQsMTI5LDYsMTIsNzYsMTQ2LDkwLDU5LDEyNCw0NiwxNjYsODYsMjA4LDgzLDE5NSwyNDgsMTE1LDU4LDE1OCwyMTYsMTM4LDIyNywxMTQsNywyNDQsMzksMjYsMjcsMjMyLDM1LDk2LDIzLDgsMjAsMTUwLDg4LDEwMiwxMTgsMTczLDEwMywxNTEsMTI4LDMyLDEzMiw0NiwxMzksNjQsMTY4LDI0MCwxNDQsNDYsNCwyMSw2NywzLDIyOSwxNTQsNjgsMTE5LDcwLDEwOCwyNDgsMTc4LDIwNSwxODUsMSwzNCw2Nyw0MiwxNDksODEsMTUzLDEzNSwxMzksOTksMjM1LDE4MSwxLDE2OSwyNiwyMiwyMDYsNTAsMTYsNTUsMTYsOSwxLDAsMTk1LDIzNCwxODUsMjAzLDI0MCwxOTcsMTAxLDI0MywyNDQsOTcsMTc4LDIwMiwxODcsNDAsMzksMTQ0LDEyMiw3LDYxLDE2OCwxLDE2NSwxNzYsNzQsMTI0LDE2OSwxMzksMTYxLDE0NywyMTgsMTgzLDExMywyMCwyNiwxMjAsMTAsMTA5LDEyMiw4MSwxMDEsMTIzLDExNCwxNDIsOTYsMTU0LDE3NCwyMjgsNzEsNzEsMjQ2LDIzMCwxMTgsNzUsMTM0LDIwNiw4OSwyMDEsMTEwLDIzNywxNzksNDAsMTYzLDIwOSwxODcsOTksMCw1NCwxMDMsMTYxLDcyLDIyMCwxMiwyMDYsMTM1LDExNCwxMTQsMTYzLDM2LDE1OCwxMjEsMTAxLDU0LDE1MiwzMiwxNjcsMTE4LDExLDE5NCw4Nyw4NywyMDIsNTIsMjA4LDIwMCwyNTQsMjQ1LDEzLDIwMCwyMiwxNDksMjA1LDEwNSwxMjEsODAsMTY3LDM1LDEwOCwxMzIsMTUxLDIwOSwxNzAsNjIsMTczLDE0OSwxODIsNzksMjMsMTYsMSw2OSwxMDksMTYsMjUyLDE2NCw2OSwyNDIsMTkxLDI4LDUsMTI0LDMwLDE2MiwxNjEsNzAsMzIsMTk5LDEwNiw2OSwyMDMsOTcsMjUwLDgzLDIyNCwyMDQsMTkxLDE5MSwyMzUsOTksMTI4LDU3LDE1MCwxMzcsNTcsMTQ2LDEwMywxNTMsMTQzLDcxLDU1LDEwMSwyMDQsMTU1LDc3LDUsMjI2LDI0LDQ4LDEzNCw2NSwxMywyMDksMTgxLDQwLDgzLDEwNiwyMzQsMTE5LDY5LDUwLDE2MywzOCw3MiwyMDIsODksMTY4LDgsMjAzLDIyMiwyNDcsMTE3LDEzMiwxMjMsMTE1LDExNiwyNDUsMTg5LDM1LDE2OSwxNDIsMTIzLDQsMTI4LDQxLDIyNywxMTYsMTQwLDEwMiwxMSwyNDIsMjI2LDE4Miw0Myw1MiwyMDEsMTM2LDE3OCwxODQsMTU3LDQsMTMxLDk1LDUzLDcyLDIxMiwxODEsOTQsMjM4LDIxNiw2OCwyMDMsMzYsMTE1LDM4LDIwOCwxOTgsMjE5LDE0OCwxNjMsNzEsMTMwLDExMSwzNywxMzIsMTk0LDk2LDkwLDEwOCwxNzMsMCwxNjQsMTYwLDI0MCwxNjgsNiwxOTYsMzMsMTIyLDE5NSw3LDEyNSwyMTEsOTcsMTY4LDIzMCwxNzcsOTksMTcyLDEzOSw5OSwxMjksODEsMjU0LDE1NCwxNDYsNCwxNjMsMTE3LDQwLDcsMTIxLDE1MCwxMDcsMjQsMTczLDIwOSw2Nyw2NCwxNzIsMTg1LDYwLDI2LDE5NCwxMjIsMTg1LDE3Myw0OCwyMzYsMTEwLDI1MywxNzgsMTUsMjUzLDIzMiw1MCwxODksMTUxLDE0MCwyNDIsMTc4LDEyMCwyMzcsNzYsMTc5LDIxOSwxMzksNjUsMTk4LDU5LDYsMTg3LDIzMywxNjIsNDYsMTk3LDkzLDYsMTgwLDksMjE2LDI1MiwxOTUsMjQwLDI0LDE2OSwxNTQsMTk2LDE2MywxMjMsMjMzLDQ5LDM1LDEyMywxMCwyMTEsNCwxOTMsNTMsMTk1LDQ1LDU3LDE1NSw3Miw5MSw0MSwxNDMsODQsMjUsMiwxMjgsMTM1LDE4NSwxNTYsNTAsMTk1LDIzMyw4NiwxNjAsMTE2LDg1LDE4LDcyLDE2MiwzOSwxOTcsMjQwLDE3NSw2NSwxNTUsMTI5LDQyLDIxMiw5LDYxLDMsNTEsNzUsMTc2LDU1LDEzOCwxMzUsMjA3LDIzLDEyOCwxMzIsMTY2LDIxMiwxNTcsOTAsMTE2LDk3LDEwNCwyNDMsMTAsMTUwLDE0MCwxNjIsMTY2LDg1LDEzNCwxNTcsMzIsMTIzLDI1MSwxMDMsMTgzLDIxNCwxNzAsMTQsMjQ4LDcyLDE4OSw1MiwxNjQsMTg1LDY4LDE0NCwxMDIsNywzNywxMDYsNTIsMjIwLDE1NSwyMTAsODIsMjA3LDc3LDI0NSwxOTcsMjUsNTIsMjcsMjA5LDI1MSwyMSwxOSwxOTUsNjIsODksMTM4LDMwLDgzLDQsMTQ0LDc4LDI0Myw4NCwxMjksMjMyLDEsMjE3LDE0OCwxMDEsMTY4LDEwMiw4Nyw5OSw2NiwxNzIsOCwyLDE1NSwyMTUsMTA4LDUzLDEyOSw4MywzNCwxOTcsMTI4LDMwLDIyMCw5NiwxMjMsODMsMzcsMzcsMTQ4LDY2LDE0OSwxOTEsNTMsNTYsMTYwLDExMiwxNzcsMzgsMjE5LDIyOCwxNSwxNDUsMTQ0LDE4Nyw2MSw0NCwxMjEsMjcsMjI3LDQyLDMxLDUsMTk4LDE2NiwxNjMsMjE2LDE4NSwxNTUsMTk1LDE2OCwxMDgsMTY0LDIzMCwyNCwzNiw1Nyw2NCwxMTUsMTMyLDEwNSwyNDAsMjEsODIsMjMsMyw4MywyMTMsMjA3LDIzMiw2MF19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNjQsMTgwLDEyNSwxMjYsNzksMjIwLDIyMSwyNTMsMTIzLDQyLDIwMSwxMjAsMTgwLDE2NCwyMDAsMjA4LDE3Nyw5OSw4Miw2MCw1NSwxNTYsMTI2LDc3LDExNywxMTUsMjAzLDIwMywxNDIsMjU1LDE2NiwzNF19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJDb21taXQiOnsidmVjIjpbNjcsMjQxLDE2NiwyMjIsMTAsMTUzLDIzOSwxNTQsMTQxLDQ3LDMxLDE0MiwyMjMsMTc4LDI0Myw1NywxNTcsMTIyLDE1NiwxMDIsMTksMTE2LDIwMSwyMTcsMjQ3LDIyOSwxMTgsMTY2LDE0MywzNiwxMjgsMjM0XX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzIxOCwxMDUsMTQxLDE4MiwyMDAsMjI0LDE3MiwxMTAsMTI2LDE5LDEwMSwyNiwyNDcsNDUsMTk1LDE3MywyMTMsMTYyLDg0LDIyOSwxMDksOCwxNzMsMjUxLDE0NSwyMTgsMjQyLDMyLDAsMjE0LDIsMTAsMjQ0LDIwNiwzMywwLDUwLDI0Nyw4MSwyMDksNDIsMCwxMjMsMjA2LDIxMiwzNCw4Miw3NCw1OSw3MywxODcsMTM5LDIxLDY1LDE3NywxMjgsMTE3LDE3NSwxMTcsODQsMTQzLDIzLDE1OCw3XX19fX0seyJub2RlIjp7InBheWxvYWQiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzcwLDE4MCwxMzgsNzEsMjQyLDEwOCw2MywyNDAsMTg5LDE5OSw0MSwxMTAsODksODksMTk1LDE0NSw4OSw3NCwzMywyMTMsMTQsMTY3LDkxLDEwMywxNjMsNjYsNywyMTAsMjM2LDksNTAsMjQwLDEwMCwxNTMsMTAxLDI4LDg1LDksMTYsMTYzLDE3NywxMjAsNjQsMjQ3LDExLDksMTMzLDk1LDE1OCw4OCw2MiwxNDUsMjUyLDEwOSwxMzQsMjMwLDkyLDIzMiwyMDQsMTAxLDIxNyw2MCwxNjksMTI2LDkyLDIwMywyMzgsODYsMjEsMjMzLDg0LDQ1LDE1NSwxMjksNDIsMTM3LDE1MCw1OCwxMDgsNDEsMTYxLDExMywxNDgsMTc1LDg2LDE1NiwxNiw5OCw3NSwxMzgsMTIyLDcsMzMsMTM1LDkxLDc3LDI0MiwyMywxOTEsMjQzLDQ4LDksMjUsMTAwLDQ0LDI0OCw3MywxMjQsNzEsNzQsMTQ3LDIyMCw0OSw0MywyMjgsNTEsMTg2LDEyMCw5NiwxODksMTc1LDM4LDExNSwxMDgsMTEyLDE2MiwxMDMsNTgsNDcsOTQsMjQ2LDQ4LDI0Niw2NiwxMDksMCw2Nyw2NywyMjksMTQ3LDY0LDEzNywzLDE2MywxMTksMTc5LDYzLDEwNSwyMzEsNDYsMTgwLDk4LDEzMSw4OCw0OCwxNDYsMTA0LDIwOCwxMzQsNiwyMCw1LDcsMjMzLDE0NiwyNDgsMTM1LDExNSwxNjcsODEsNzMsMTE5LDEzNyw4MSw5MCwxNzcsNDMsMTY3LDIyLDQ5LDIxLDI1LDExNiwzMywxMzAsNjIsMTEwLDIxNywxOTUsMTU2LDEwLDE3MiwxMzAsODYsNTgsMjEzLDU4LDEyOCw1Miw2NywzMywxNiwyMTksODMsOCw0LDE4MCwxMTksMTc2LDE5NywxMDcsMyw3OSwyMTYsMjQ0LDEwOCwyNDIsMzksNjQsMTY3LDI0OSw0NiwyMzksMTM2LDE2MSwxODAsMjI4LDE2NywxOTMsNSw0MSwxNTYsMTQ5LDEzOCwyMjAsMTQ3LDE0NywxMDcsMTI4LDY1LDgzLDE4MiwxMzIsMjUxLDIzNSwxNjAsMTk0LDIyOCw3OSwxNTIsMTQ1LDE3MCwxNDYsMTIyLDE2LDIwNiwxNzgsNjEsODQsMjE5LDIxLDksMjUxLDE4OCwyMTcsNjcsMzUsMTQ3LDIzMiwyNyw4NiwxNiwxMTAsMTMzLDE1Myw2MywzMCwxOTMsMjAxLDg4LDIzNSw3MiwyNTQsMTY3LDIxLDkzLDg1LDUsNjIsMjQ3LDc2LDE0LDg3LDEwNCwxNzYsMTY0LDEzLDE1NCwyMTUsMTA0LDEzNiwxMzIsMTQyLDU2LDIzMSw5NiwxNTksMTY4LDI0LDE2NywxMDEsMTQyLDEyNyw5MiwxMywyMzYsNjUsNTUsMTAwLDE3NiwxNDAsMTY5LDY3LDY4LDY4LDcyLDExNCwxOTcsMjExLDExOSw5MiwxMzgsMTk3LDIxMCwxOTksMTMyLDE2Niw1MCw1NCwxNDYsMTE1LDQwLDM4LDE3LDY4LDIzNiw0Myw4NSwxOCw4OCwxNDksMjQyLDgyLDgyLDIwMCw5NywxODAsOTcsNTEsOCwxMTcsMTk4LDExNywyMDEsMTYwLDU1LDExNiwxOTMsMTQwLDE0OCwxNyw0LDYyLDUzLDExNywyMTgsNTQsNzcsMTY3LDIxNCwxMSwyMDEsNDEsMSwxNSwxODYsMTcxLDIyNyw0NCwzNiwxMSwxOTksMjA0LDM2LDI0LDE3OSwyMjAsNTMsOTksMTgwLDEzNCwxNiwxNzgsMjI4LDQyLDE3OCw2OSwxNTEsMjA3LDEyMCw4MSwyMDIsMTE4LDE2MywxMDUsMjA0LDU0LDU5LDE5MywxMDQsMjAwLDE2OCwxNzYsNzMsMjUwLDY3LDI0NSwxNzIsMjksNzMsMTAxLDExMCwzOSwxMDQsMjUsNTksMTMzLDkyLDc1LDEwMSw4NSwxMzksMTE4LDE3NSwzNSw3LDEwNywyMTQsMTIsMTU0LDI0Niw1NiwyMCwxMDksNTMsNDgsNzksNzIsMTEyLDE1Niw4LDkxLDI1MiwzMiw3MSwxNzcsMjQzLDEzOSwxODQsMTk2LDEzNSw3Miw2NywxMjEsNDYsMjQ0LDEzMCwxMjEsMjQ4LDE1NSwyMjUsMiwxMDgsMTY4LDUwLDEwOCwxLDEwMiw1Nyw1OCwxNTAsMTI2LDEyMCwxMDUsNDgsOCwxOTksMTAsMTYwLDE4MSwxMzIsMywxMjMsNTMsMTYyLDE3LDE5MywyMDIsMTg4LDE0OSwyMjUsMjYsODMsMTMyLDExNSwxMDcsMTg2LDExMyw5OSwyOSwyNTIsNTQsMjQ3LDE1MywxNjUsMTQ4LDE0NywzOSwzMCw0OSw2Niw5NywxNjIsMTMwLDQsMTA1LDE2MywyMDAsNzMsMjA2LDc0LDE4Myw2Miw4NiwxNjYsMTg4LDEwMywyMjAsNTgsMTgwLDE2Miw1MCwxMTksMjA5LDExNSwxNjksNjQsMTMwLDEwLDkwLDQ3LDc0LDgsMTYwLDM3LDY0LDExOCwxOTMsMTUwLDEyLDQxLDI1MSwxMSw3NSwxNjQsMTMyLDE5NywyMzYsMTQ2LDIzNiwxMzQsMTMyLDI0MCwzOSwxMDYsMjQ0LDI0NSwyMCwxMzQsMjI1LDgxLDI1LDE0MCw3MiwyNTIsMTM3LDI4LDUyLDEzMSwxNjUsMTcyLDEwOCwyMDMsMjgsMjA4LDc3LDIyMCwxODMsNzYsMjA4LDczLDM4LDIzNiwxODAsMCwxOTksMTE5LDM4LDM5LDQ5LDYwLDQzLDIxNywyOCwxNiwzNiwxODAsMjM1LDExOSwxMjksMTcwLDcxLDE4OSwxNzcsMTM5LDcxLDE1MiwxMjAsMTc2LDEyNiw1OCwxMTQsMTMyLDczLDUwLDE5Niw3LDE3NCw0NSw4NCwxMDMsNzAsOTEsMTgyLDEzNSw2OSw5NSwxODUsMjUwLDEzNSwxNjYsMTYyLDE0NywxOTQsMTk3LDExNCw5MiwyNyw5OCwyMzQsMjMyLDE0MywxMDAsMTQ4LDEzNCwyMDgsMjI3LDMwLDUzLDI0OCwxMTAsMTc1LDI0NCwxODYsMzIsMTI0LDcsMTY4LDI0MCw1MSwyMDMsMjQ5LDIyLDYsMTk0LDcwLDExMSwyMSwxMTgsMywxOTIsNDIsMTc3LDI0MCwxNiwxMTcsMTgxLDI3LDQxLDIwMiwxNSwzOSw2NiwxODEsMjAxLDY2LDg3LDE3OSwxMjksMTAwLDExNCwxNDQsNzcsMTI2LDkyLDIwMiwyMjAsNjQsMTE3LDE0MiwyOCwxMzIsMjE2LDI0OSwxNzcsNTEsMTUwLDEwMiwyMzksMTIzLDMwLDE5LDgwLDIwNCwxNjAsMjMsMTM3LDExNiwxNTYsMTI1LDEyOCwxMzEsOTksMTg4LDYsMjAsMTQ0LDE1MywyNCwyMjcsMjEzLDgwLDI0OSw0MSw2Nyw2NSwxLDQyLDI0NCwxNDYsMTI5LDE4Myw4MywxLDE5NCwxNjQsMTQsMTcxLDE4NCwxMjQsMTI4LDExNyw3MywxMTQsNDksMTc3LDE5Myw4NCwxNTUsMTUyLDAsNTgsNTksMjQ1LDEyMSwxMjcsMjEzLDEzMCwxMDYsMTc5LDcsMjE5LDE2OSwyOCw3MiwxMTcsNSwxOCw5MCwxODQsMjQwLDgyLDE3MCwyNTAsMjQ1LDYzLDQwLDE4Miw2OCw4NCwxNTUsMTc0LDUxLDE3NiwxMjgsMTAwLDExLDE1MSw4NSwyNTAsMTg2LDExNiwyNywyNSwxNTYsMTcxLDUxLDE2NCwxOTcsMjAzLDE4NywxODAsNDYsMTQ3LDIxNSw2NCw3MCwxMTYsMTYsMjE3LDIyOSw5OCw1MSwxNTAsMTQ3LDIxNiwxNzcsMTQ2LDE5MSwxNTMsMTQzLDM2LDIzLDMxLDIxOCwxOTksMTYyLDIwLDIxMiwxMCw3MCwxNjQsNTQsMTYsNjUsMjQsMTE5LDE3Niw0LDIwOCwxNTEsMTg4LDUxLDcxLDE4OSwxMDksMTY2LDE1NiwyMTEsMTU2LDE4NywxOTgsMTM4LDUzLDEzOSwxNTQsNDMsODcsMTUwLDQ5LDE3OSwyNDAsNTEsMTEwLDExOCwxMzIsMjEwLDkwLDEzMCwxNTQsNjQsMTMwLDIxMywyMjcsMTg2LDUxLDEwNywxOTEsOTEsMTU0LDQ3LDEzNCwyMDgsMjA1LDIxMywyMTIsMjA2LDUsMTI4LDE4NywxMDcsMTMzLDEwMSwxOTEsMTE1LDE4LDEzOCwxMDUsMjcsOTgsMjI1LDEzMywyMTgsODEsMzgsMTE5LDIxNyw0OCwxMzYsMjEwLDIwNCwxMjAsMTY3LDcyLDk3LDEzNSwxMDYsMjAzLDM0LDE2LDQ1LDE1NCwxOTAsOTIsNTEsNDYsMjA5LDk2LDE4MCwxNjgsMTAwLDQwLDI1MCwxOTIsMTQ3LDIxOSwxMDUsMTgzLDg3LDQzLDE1OSwxODUsMjQ3LDUzLDIzOCw0NCwxODAsNDYsMTgsMjgsMjE2LDE2NSwxMDEsMTYwLDIzMSw1Myw2MywxMTIsMTAzLDIxNywxODYsMTAyLDEyOSwxOCwxNDEsNzYsMTE5LDczLDIxMiw4MCwxNDcsMTU3LDk4LDEyNSwxMjIsMjAzLDU3LDI1LDE5NywxNSwxODcsMjE5LDMsMTI1LDgyLDEwMyw0MCwwLDQ3LDIyOSwyNSwxMTcsMjQ2LDIwLDE5MiwzLDIwMCwxLDE4MCwxNTAsMjA1LDIwMSw1NCwxMDYsMTgxLDExMyw0Myw4Myw0Myw1NCw3MiwxMDUsODAsMjUsNTksMzcsMTc1LDIxNCwxMjMsMzMsMTUzLDExLDIyMSwxOSwxMzEsMTMyLDI0MCw4MCw5NSwyNTEsNCwyNTQsMjUwLDgwLDEzMywxODcsMTgyLDExMiwyNDUsNzUsMTI0LDEwNywxMjEsNCwyNDAsMTk4LDI0MCwxNjIsNzIsMjI4LDI1MiwxMjAsNzcsMCw3MiwxODEsMTk4LDI5LDEwMiwzNywxODEsNDUsMTk3LDk3LDE1LDIzLDE4NCwxNjgsMTAyLDUxLDY0LDExNSwxMTMsMjM3LDIyNSwxMzgsODksMiwxMjgsMjM5LDE4MSwxNzUsMTAyLDIxMSwxNjAsNTQsMTgyLDM1LDIzMyw1MCw5LDEwNCwxMDAsMTMxLDI2LDg1LDQ4LDE1Nyw2Nyw2OSw3MywyMDMsMTI4LDQsMTcyLDE1OSwyNDMsNzQsMTQyLDE5NiwxNjksMTksNzksMTUyLDIsNiwzMCwxMzIsMTcxLDEwMywyMjEsNywyMTEsMTY5LDc4LDIzNSwyMDYsNjksMjgsMjUyLDEzLDY5LDEyNSw2NCwyNTQsMjQ3LDE3LDE2MCwyMCwyMDIsMTQ2LDAsMjMyLDAsMTIsMTcxLDk2LDc2LDEzMywxMzQsMjQzLDU5LDI0MCwxNTAsMTQ5LDk1LDIwOSwyMTksMTk5LDczLDE4OCwxMDUsMTAzLDEwMSwxODUsMjQ1LDEzLDk1LDIyMiwyMDQsMTYyLDQ1LDEzOSwzMiwxMDUsNV19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyMzksMjM3LDI1MSwxNTIsMjMxLDE0MCwyNTIsMzMsMjM3LDE3NCwyNDIsMjQxLDEyNCwxMDMsMTMwLDI0LDc2LDEwNiwxNDUsMjI3LDAsNTEsNjgsMTEyLDE2MCw0Niw0Miw0OSw4MiwyMzMsNzcsMTE3XX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTgsMTExLDk4XX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJLZXlQYWNrYWdlIjp7Im5vdF9iZWZvcmUiOjE3MjA2ODg5NTAsIm5vdF9hZnRlciI6MTcyNzk1MDE1MH19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzIyMiwxNzksMywzMiw5NCwxMjcsNjYsMjQ5LDE4OCwxMDcsNzcsMTg2LDEyNiwxODksMTM1LDUyLDY4LDQwLDE3MiwxMTAsMTM1LDI0NCwyMDgsOTUsMTY3LDIyMywxNzcsMTgyLDE2MCw0NiwxLDQ1LDEwOCwxOTEsNzIsMTE5LDE5NiwyMiwxNTAsMTk0LDUzLDIyLDIwMyw5MSwyMjMsMjA0LDE1MSwxNDQsMTI2LDIwMywyNDksMTIxLDYyLDQ1LDQsMTQ0LDg5LDI3LDE4MCw4NCwyMzYsNjYsNTksMV19fX19XSwicGFyZW50X25vZGVzIjpbeyJub2RlIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOlsyMzcsMTQ3LDE0NSwyNTEsOTgsMTUsOSwxMiwxODcsMTAsMTkyLDE1NywxMTQsMjMsNjAsMSwyNDAsOTUsMjA1LDE4OCw1NCwyNDAsMzMsMTYwLDEyNSwyMjQsMTk2LDEzOSwxNjAsODQsMjE3LDE2NiwxMDUsMTE5LDExNiw5NiwyMDgsMTY3LDE4NiwxNjgsNDMsMTkyLDIxMywyMzAsMTQsMjksMTAsNTEsNjAsMTQ1LDE4OCw0NiwxMjEsMTk4LDMwLDU4LDE2Myw0LDI0NywxMTAsNzIsMTgyLDg2LDg2LDU4LDE1OSwxOTcsNTEsMTU3LDEwNSwzNCwxMzQsMTgwLDI4LDE3MywxOTQsMTMyLDEwNiwyNDcsMTMxLDE5Nyw2OCw4MywxMDAsMjQ0LDI0NCw1MCwzOCwyMTAsMjksNjgsMjUyLDM2LDcwLDI0OSw2NSw1MSwyMTIsODIsMTg1LDkwLDE1MiwxMzQsMzksMTMxLDQ5LDE4OCw2LDEwNSw5OCwxODMsNzIsMTA1LDkyLDIzNiw2NCwxMzgsNDAsMTksMjksMTUsNjAsOTgsODEsMTE3LDY1LDg3LDE1NiwxMCwxOTgsMTg2LDEzNiwxNzksMjQ0LDE3Niw0NSwyNiw1NSwyMzIsMTk0LDE4Nyw5NSw4MiwxNDUsNSwxMDAsNzEsMjA2LDEzMCwxOTgsMTA0LDIzNCwxODksMiwyMjUsMjEsMTI3LDM2LDE0LDEyLDE2Nyw1LDY1LDUwLDE1Miw0OCwxNDAsNTgsMzYsMjE4LDEyNCwxOTgsNiwyMDYsMTY5LDEwMiwxMDYsMTc2LDU2LDE5MiwxNzcsMTQ1LDE3Myw2MywzOCwxMTUsMTcsMjQ5LDE0LDE5NywyMTEsMTg2LDkyLDEwLDE2OCw1NSw2NSwxMDksMjE2LDIwMSw1NCwyLDEyMiwxMSwzMyw0LDE3Nyw1MSw5MCw5OCw3NSwxMTIsMTI0LDUyLDQyLDQxLDEyNywzNiwxNTIsNzMsOCwxMjAsNzksMTgzLDY5LDE3OCwyMjAsMTUyLDIxMSw3NiwxNjUsNDMsOTEsNjIsMTA0LDEzMiw3MSw0MCwzOCwxNDksMjQzLDEyMCwyMDcsMjIyLDEzNSwxNzgsMTk1LDEzMiwxNDQsNDUsMTY0LDIzLDE0MCw4OSw0NywxNjAsMTAsMTA5LDE0MCwyMDksMTA2LDEzOCwxNDQsMTY5LDE0MywxMiwzLDE5MSw3NCwxNTksMTk2LDIyNSwxMDEsMjE3LDIxMCwxNTksMTUzLDI0MCwyNiwyNTEsMjUxLDUsMTIsMTE5LDEyMywxMDYsMTcwLDAsMTc1LDcwLDk2LDE0OSwyMDgsOCwyMiw2NiwxOTEsMjA2LDEzNiwxMDAsMSw4Niw0NSwxNTQsMzcsMTg5LDExMiw2NywxNTQsMzEsMjUsOTUsNDAsMTY5LDE2MSwxMTEsMTY0LDM1LDIyOCwxMzcsNTcsMTI0LDIzNCw4OCw5Miw3NCw1MCwxNDgsNjAsMTY3LDUwLDIwOCw1Nyw4MywyMzEsMTA2LDIwMCwxMTIsMzEsNzksMTE5LDg4LDE0NiwxMjIsMjYsMTAzLDIxLDQwLDE1MCwxMzgsMTkyLDE1NywzNSwxMDIsMTIyLDEyOSwxNDYsMTI0LDIyNyw4MCw2NCwxNjUsNTksMTI5LDE1NSwzLDE4OSw5MCwyOCwxOTksMTUyLDkzLDMsMTEyLDEzOSwxOSw4OSwxNjAsMTAsMTYwLDEzNiw4LDIyNywxODcsMTc0LDU3LDE1MiwyMSw4NCw5Nyw3NSwxODEsMTEsNzEsMjA5LDgyLDEyNCwzMiw0NiwyOCwyNDYsNDQsMTIxLDgwLDYxLDExNywxMDUsOTAsMjMxLDEzMiwzNSwxOTMsNzEsMTQ2LDE1OCwyNywxNzksMjM4LDgzLDEwOCw2OSw4OSwxODgsMjI5LDIyNCwxMTAsMjM3LDExNSw5NCwxNTksMjAwLDUzLDEyOCwxOTIsMTI1LDEzMywyNTIsMTk4LDI0OCwzLDQsMCwxOTksMTIwLDE2NSwxODMsMTc3LDEzOCw4LDE2OCw5NywyMjUsOSwxOTksNDAsMTIxLDYwLDIwNCwxNCwyNDgsMjEwLDI1LDIzNSw4MSwxNCwyMTcsMTI4LDAsMTQxLDE5NCwxMjQsMTk4LDI0OSwxODAsNiw2NSwxMTgsMTMzLDE1MCw2Niw3OCw5MCwxNTUsMzAsNzEsMTYyLDE2NSw4Nyw2OCwxNDIsOTgsMTk4LDE1OCw4NCw0MSwxNTAsMzUsMTM5LDEwLDksMTQ0LDgsMTMzLDEwMiw3MCw3MSw1LDIwMCw2OSwxMjMsMTkxLDE2MSwzOCw5MSwyMTIsMzIsMjUyLDI0NywxNjIsMjE3LDEwNSwxODAsOTAsMTQwLDE0NiwxLDIxMywxNjAsNDcsMTM1LDE1OCwxMDIsMTE4LDIzLDI1MiwxNzAsNzQsNzEsNzUsNSwyMzQsNSw2NSwyMjgsMTA3LDM2LDg3LDEwLDExMiw5NywzOSwxMTUsMjE2LDMyLDU5LDE4MiwxMzksNTksMTc0LDIsMjMsMzAsMTA3LDc0LDU0LDE2OCwxNTAsOTIsMjEyLDE5MSwxMjUsMTAzLDE1NSwxNDMsMTQ2LDM4LDE4NCw5NywzMiwxMTQsMTk1LDcwLDQ5LDk2LDE4MSwxMDIsMjI5LDE4LDE2NywxNzksMTM1LDE2MywyNSw5MywyNywxMzMsOTAsMTkzLDUzLDE0MywxMTIsMzksMTI4LDE5OSwyOCwxNzMsMjA4LDQ4LDU0LDEyOCwxNjIsNDgsNDksMzksMTI0LDIzNCwyNDYsMTg1LDEzMiw2NCw2OCw5OCwxODAsMTE1LDk2LDEsMTg4LDM0LDgzLDk5LDE0OCwxNDcsMTQ5LDE4MCwxNywxMzAsMTc1LDksNDUsMjEsNjgsMTQxLDEwNiwxOTUsNjYsMjAyLDE2MSw1Myw3OSwyMDksMjcsMTEwLDY5LDUzLDg3LDE3NywxNzUsMjksMjQ2LDIwNSwxMTIsMjM1LDExMywyMzUsMTAxLDQyLDIxMywxMTksNCw5LDIzNiw0Miw2MCwxNDYsMTI4LDE1NywxODgsNTYsMjEzLDM2LDMwLDIzMSwzOSwxOTUsMjI0LDQ4LDE3MywyMTEsNDQsMTE1LDIyNSwxODYsOTMsMzQsNzQsMTkwLDEzMyw5MiwxNjEsMTE4LDI2LDE5NywxNDAsMzcsNTYsNDksMzcsMjYsMTA4LDI0MywxMTQsMjUxLDIyNywxMiwzLDU3LDUxLDIyMCwxNDUsMjIsMjMyLDQwLDI4LDM5LDEzNSwxNjksMTY2LDE3NiwyNCwxNTUsMTgsMTI2LDIxLDE5OCwxODMsMjUsNzYsNzQsMTQzLDM4LDY1LDIyNSwxNjAsMTEsMTcxLDE1NCw5NiwzOCwxMjIsMjksNywxNjgsMTc3LDYwLDUxLDExOSwyMjksMTA2LDg5LDIyLDE2LDEyMSwxNjEsMTMwLDEwMywxMDIsMjgsMjgsMjI1LDEwMCw4NiwxNSw1MCw3NSwxOTQsNDAsMTQxLDEzOSwxMTUsODYsNDcsMyw1NywxNzIsMTM1LDAsMiwyMzUsMjAxLDE0NywxNzIsMTY1LDE1MiwxNjYsMTQyLDE0LDI1Miw0NywyMDEsNDIsMTQ3LDEzMSwyMDQsNTAsNDEsMTksMTc5LDYsNTYsMTIwLDEyLDIzMCwxNjMsOTksMTI4LDE2LDEwMSwxODgsMTM1LDI1NCwyMzIsMTM3LDExMyw0MywxOTIsMjI1LDExMiwyMDAsMTYwLDIwLDIsMjU0LDE4MywyMSwyOCw1NSwxMzYsNjAsMjM1LDE1Nyw3NCwzNiwxMzksMjI2LDg2LDEzMCwyNTUsMjI1LDE2NywxODgsNDksOTEsMTc0LDE0MCwxMjksMyw4NCwxMDAsMTE1LDQzLDc1LDQsMTI0LDEzNSw0NSwxNjMsMzgsNDQsMTU2LDE0MCwxMTcsMTgwLDE3MSwxODAsMjgsMTkyLDUwLDEyOCwxMjcsNzcsMTksMTc4LDEzMCwxMzQsMTA3LDE4OSwxNzAsNzQsMjMzLDEwNSwxMjMsMjQ0LDEyMCwyMDcsMTMyLDEyMywxNzUsMTc4LDE4LDE4NCwyMjQsMzksMjEsMTgxLDEwMiwxOTUsMjE5LDE2MiwxMSwzNiwzNSwxMTYsNjYsMjEsMTY1LDE0MSwxMCw0NiwxMjMsMTcsMTkyLDcyLDM4LDE4MywxODksMTgxLDE3MSwyNTEsMTgzLDk2LDcxLDEzNCw0NiwzMCwyNDgsNDQsNjMsMTA4LDExNSw4MCwyMjAsMTQwLDEyNSwzNSwxMzIsMjI1LDIyLDUsMTA4LDI4LDE3OCw2MywxOTgsMTExLDIzNiw4NSwxNzksMTQ5LDEsMTgzLDE0MywxNjIsMTM5LDIyLDgwLDQ2LDIzNiwxMzksNjEsMTA4LDEzMywxMywxNzUsMjgsMTc5LDE2MywxODEsNzMsMTksMTAxLDQ3LDU1LDI0NSw0LDExMiwxMDAsNCwxNjcsMjI0LDEyNSwxNTAsMTQ5LDIwMSw1LDEyOSwxNzksMjM0LDIwMywxMzcsNTQsOTEsMTAxLDExOSwxNzEsOTgsNzUsOTksNjUsODUsMTI5LDE5NCw5LDksMTMwLDQsNTUsMTM1LDE2MywxNTMsNTEsMTM3LDIxLDMyLDIxMiwzOSw4MCwxMTcsNTQsOTUsNzcsMjAzLDExOSwxMjEsMTU0LDcsMjE0LDE0NCwxMjIsNzMsMTMxLDE2NiwxMjgsMTc3LDE4OCwxODMsMSwxNzQsMTUxLDE4NSw2NSw2MCw4Niw4MCw5OSw1OSwxNCwyNCw2Niw0MCwyMjEsNjgsNDcsNjUsNjUsMTc3LDEzMSwxOTIsMTQ0LDQ3LDcsMzcsMzMsNzYsMTY3LDI1NCwxNjcsMTIxLDIyMiwxNjYsMTU0LDYzLDk3LDE1OSwyNDAsMTY5LDEzNiwyMzMsMTIyLDExOCw1NywxMTIsMTk5LDEzMSwxNzcsMjgsNTEsMTQwLDE4MywxMTEsMjUyLDE1OSw5NCw3Niw1MywxMzAsNDEsMTcyLDExNCwxMTksMTMwLDE5NSwxMjQsNTYsMTIyLDIzMCwxMCwxMDgsMTEzLDEzNSwxNjcsMTU1LDQ3LDc3LDEwNyw2OSw4NCw3MCwxMDksMjUsMTYsMTE3LDE2Nyw3MiwxMzksMTMsMTAzLDE1NCwyNywyMTAsNjIsNDMsMCwxMjYsMTg0LDIwOCwxMDAsNDEsMjQwLDE4NSwxNjIsMjExLDU0LDU2LDIwNywxMTYsNDMsMTE3LDE4LDIxMCw0MiwyNTAsMjExLDI1MCwxMTIsMTM3LDExNywyNDcsMTUwLDExMyw0MywxNzMsMjI0LDE4MSw1NCwyNTEsNTIsMTMzLDEyMiw3NywzMSwxMzUsMjA3LDIwNSwyMzUsMjI0LDEzNCw1NCwxMzAsMjMzLDEwOCwyMDcsMTU1LDE1Myw5Nyw2Nyw3OSw5Miw0MCwyMDYsMjE2LDI0Myw4NywyMCwzMSwyMjEsNjUsODEsMjA2LDE3OSwyNTEsNDcsMzYsMTAsMTMxLDE3NSw1MF19fSwicGFyZW50X2hhc2giOnsidmVjIjpbXX0sInVubWVyZ2VkX2xlYXZlcyI6eyJsaXN0IjpbXX19fV0sImRlZmF1bHRfbGVhZiI6eyJub2RlIjpudWxsfSwiZGVmYXVsdF9wYXJlbnQiOnsibm9kZSI6bnVsbH19LCJ0cmVlX2hhc2giOlsyMTcsMTE3LDEyMSwxODYsMTEzLDEwOCwxNjAsOTEsMjUsMTY4LDI1Myw1OCwxODcsMjE0LDI0OCwxMTAsMTY3LDI1Myw0OSw5MCw1OCwxMDQsMTM4LDEsMjAsMTk5LDI1MSwyMjcsMTg5LDQ5LDIwMiwxODBdfQAAAAAAAABdAAAAAAAAZhJFcG9jaEtleVBhaXJzeyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fTIwAAFbeyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOlszNCwyMTMsMTI2LDEwMiwxODAsMTk3LDcsMTE5LDUsMTQ4LDIzMSw1NywxNTYsODgsMTU0LDI3LDEwMSwxLDExNiwxMzIsNTQsNTgsODMsMTMwLDI0NywyNDcsNzMsMTc4LDQsMTQ0LDEyNiwyMTYsMTA1LDIzMiwxNDAsMTMsMjMyLDIyNiwxOCwyMzEsMTYzLDIwNywxNTgsMjMwLDEwNiw4MSw1LDQzLDExOCw4MiwyLDcwLDQwLDQsMjA2LDE4NywxNTgsMTk5LDExOCw4MCw1NiwyMjQsMzksMjE5LDExOCwxNTMsMzcsMjQ1LDI1LDQ2LDIyOSwxOTMsMTMzLDUyLDIwNCwxNTYsMzUsMjA0LDIzOSwxMjQsMTczLDIyMCw2NSwxNjQsMTk4LDE2NiwxNSwyMiwxMDQsMTkyLDY5LDIzNiwxNDgsMTA2LDE3OSwxNzUsMzksOTYsMTgsMjcsNTUsMTgxLDM3LDE2LDYwLDE5LDE3OCwxMTIsNzMsMjE3LDE4MywxNzksMTA4LDE0OSwyMzAsMTcyLDIwNSw5OCwxMjAsMTQyLDI1MywxNywxNzAsNjcsMTE3LDE5NiwxODIsMTcyLDEwMSwyMzYsMTcwLDEyMSwxODYsNTcsNzcsMzMsNjYsMzIsNzMsMTE3LDE3MiwxMjIsMTUwLDEzNCw4MCwyMjAsOTIsMjM5LDIyOSw5LDczLDIxOSwxNjgsMzMsMjUxLDMzLDk3LDE3MSwyMDQsNjYsMTQwLDYzLDM1LDE1MywxODksMjI5LDEwNiwxMzksMTAxLDE1NSwxODUsMTYwLDIxMCwzOCw1MCw0MSwxODMsNjksNTksMTYwLDQ5LDExMiwxNjgsMjM0LDEzNCw5LDIwMywzNiwxOTksMTYyLDEwOCw1MSwxNzQsMjQxLDEyNyw3MywxNzIsMTg3LDUxLDI2LDE1MiwxNzMsMTQ5LDgwLDg1LDU4LDE2NSwxODIsODcsMjAwLDIwNywxMjksMTI2LDEzNSwxMTksMTY1LDMwLDIzMSwxMzUsMjI0LDE5MywxNjgsMCwxNjEsMTM4LDYwLDI0OCwxMCwxODYsNDgsMzEsOTMsMTc4LDcsMTk3LDE5OSw1NCwyNDQsMTUwLDE1NywwLDEyMSw2OCwyNDAsMjQ3LDExMCwxNDksNjksMTEyLDE3NywxMCwxOTgsMjQ5LDEyMywxNTMsMTI4LDE5MiwyMywyNiw1Niw3NCwyMjcsMjE3LDk3LDEzMiwxODMsMTUsMjIsMTIwLDE3NSw5Myw0OCwxOCwxMTgsMTc4LDEzLDIzMiwxOTIsMTMxLDE1OCwxNzYsMTE3LDEyMCwxNjUsNTIsMjM5LDIyNiwxODUsMzYsMTE1LDEyMSwxNTksMTYwLDkyLDEyMSwxNDYsMTA2LDE3MSwxOTksOTMsMjMyLDIzLDM1LDI2LDMsNDAsNTIsNSwyMDYsMTgyLDIzMyw3NCwxODQsOTAsNiwyNDYsMTg3LDUsMTk1LDE4MCwxNyw5NSwyNDIsMTA5LDE2NCwzNywxNDYsODMsMTk3LDEsMzIsMTcxLDEyNiw4Myw4OSwxMDMsOSw3Niw5LDE3NCw2OSwxNjUsOTMsMTgzLDksNzMsMTYwLDExMSwxMjgsMTIsMTQ5LDE5OCwyNDgsMTE3LDAsMjgsMiwxNjcsMjM1LDIzLDczLDk3LDExNiwxMTMsMTUwLDE0NSwxNjksNywyMDUsMTEzLDE0Nyw3LDEzOCwxODAsOCw5NywxMDAsMSw5NSwxNjQsNTAsNTYsNjgsMTcyLDI0NCw2LDEzMCw4LDE5LDE3OCwxMTAsMjQxLDE1MiwxMzYsMTM0LDE5Niw1NiwyMDEsMTk2LDIwOCw1Myw4OSwxMzIsMjI2LDU0LDIyNCwyNiwyNywyMiwxNzgsOTIsNDYsNDIsNjksMTAwLDU2LDExOCw4MywzOCwxOTgsMCwzNyw4NiwxMTgsMjI1LDQsNDcsMzMsMjMsMjA4LDE5MiwxMDQsMTAsNzMsNzcsMjE3LDExNywxNCwxNjUsMjEzLDE1MywzOCw4MywxNTAsMTM3LDI0MywyMDAsMjM3LDE3LDM0LDEyOSwxNzgsODcsNTMsMTQ5LDE1MCwxMTcsMTM0LDE4Niw3NCwyMjYsMTQyLDEyMCwyMTEsMTAzLDc3LDE0OSw3NSwzMSwyMzAsMTU1LDE2MSwyMjgsNyw1OCwxNjcsMTQ2LDE3NCwxMzMsNiwxOTgsMjEsNTAsMTQ0LDI1MiwxNDMsMjQ4LDk4LDQsMTYsMTM5LDIwNCwxMyw0OSwxMTIsODIsMTgyLDYsOTIsMTY5LDcxLDgwLDY0LDQ1LDE0MSwzOSwxODEsMjA0LDEzMywxNjYsODUsNDEsMTQsMjAzLDIyOSw1MSwyNTQsMjIsMTUyLDYwLDE5OSw4Miw0MiwxODYsMzcsMzMsMjYsMSwyMzYsNzIsMTU1LDk5LDEyMSwxNTksMjIwLDIxLDE2NiwxMTIsNjcsNDQsNDMsMTYsMzYsMTU3LDE0MCw0NCw1NywxNDYsNTIsMTAsMTY2LDE0MywxNDUsMzIsODAsMTU0LDkyLDAsNjQsNDgsMTQwLDIyOCwxOTIsMTcxLDE3MywxNzAsMTk2LDQ3LDEwNCw3NSwxMDQsODAsNTAsMTU3LDEzNiwyOSwxMjcsMTM4LDQ1LDUsMjE0LDIyLDcxLDExNiw2MSwyMTcsMjgsMjcsOTQsMTI5LDYsMTIsNzYsMTQ2LDkwLDU5LDEyNCw0NiwxNjYsODYsMjA4LDgzLDE5NSwyNDgsMTE1LDU4LDE1OCwyMTYsMTM4LDIyNywxMTQsNywyNDQsMzksMjYsMjcsMjMyLDM1LDk2LDIzLDgsMjAsMTUwLDg4LDEwMiwxMTgsMTczLDEwMywxNTEsMTI4LDMyLDEzMiw0NiwxMzksNjQsMTY4LDI0MCwxNDQsNDYsNCwyMSw2NywzLDIyOSwxNTQsNjgsMTE5LDcwLDEwOCwyNDgsMTc4LDIwNSwxODUsMSwzNCw2Nyw0MiwxNDksODEsMTUzLDEzNSwxMzksOTksMjM1LDE4MSwxLDE2OSwyNiwyMiwyMDYsNTAsMTYsNTUsMTYsOSwxLDAsMTk1LDIzNCwxODUsMjAzLDI0MCwxOTcsMTAxLDI0MywyNDQsOTcsMTc4LDIwMiwxODcsNDAsMzksMTQ0LDEyMiw3LDYxLDE2OCwxLDE2NSwxNzYsNzQsMTI0LDE2OSwxMzksMTYxLDE0NywyMTgsMTgzLDExMywyMCwyNiwxMjAsMTAsMTA5LDEyMiw4MSwxMDEsMTIzLDExNCwxNDIsOTYsMTU0LDE3NCwyMjgsNzEsNzEsMjQ2LDIzMCwxMTgsNzUsMTM0LDIwNiw4OSwyMDEsMTEwLDIzNywxNzksNDAsMTYzLDIwOSwxODcsOTksMCw1NCwxMDMsMTYxLDcyLDIyMCwxMiwyMDYsMTM1LDExNCwxMTQsMTYzLDM2LDE1OCwxMjEsMTAxLDU0LDE1MiwzMiwxNjcsMTE4LDExLDE5NCw4Nyw4NywyMDIsNTIsMjA4LDIwMCwyNTQsMjQ1LDEzLDIwMCwyMiwxNDksMjA1LDEwNSwxMjEsODAsMTY3LDM1LDEwOCwxMzIsMTUxLDIwOSwxNzAsNjIsMTczLDE0OSwxODIsNzksMjMsMTYsMSw2OSwxMDksMTYsMjUyLDE2NCw2OSwyNDIsMTkxLDI4LDUsMTI0LDMwLDE2MiwxNjEsNzAsMzIsMTk5LDEwNiw2OSwyMDMsOTcsMjUwLDgzLDIyNCwyMDQsMTkxLDE5MSwyMzUsOTksMTI4LDU3LDE1MCwxMzcsNTcsMTQ2LDEwMywxNTMsMTQzLDcxLDU1LDEwMSwyMDQsMTU1LDc3LDUsMjI2LDI0LDQ4LDEzNCw2NSwxMywyMDksMTgxLDQwLDgzLDEwNiwyMzQsMTE5LDY5LDUwLDE2MywzOCw3MiwyMDIsODksMTY4LDgsMjAzLDIyMiwyNDcsMTE3LDEzMiwxMjMsMTE1LDExNiwyNDUsMTg5LDM1LDE2OSwxNDIsMTIzLDQsMTI4LDQxLDIyNywxMTYsMTQwLDEwMiwxMSwyNDIsMjI2LDE4Miw0Myw1MiwyMDEsMTM2LDE3OCwxODQsMTU3LDQsMTMxLDk1LDUzLDcyLDIxMiwxODEsOTQsMjM4LDIxNiw2OCwyMDMsMzYsMTE1LDM4LDIwOCwxOTgsMjE5LDE0OCwxNjMsNzEsMTMwLDExMSwzNywxMzIsMTk0LDk2LDkwLDEwOCwxNzMsMCwxNjQsMTYwLDI0MCwxNjgsNiwxOTYsMzMsMTIyLDE5NSw3LDEyNSwyMTEsOTcsMTY4LDIzMCwxNzcsOTksMTcyLDEzOSw5OSwxMjksODEsMjU0LDE1NCwxNDYsNCwxNjMsMTE3LDQwLDcsMTIxLDE1MCwxMDcsMjQsMTczLDIwOSw2Nyw2NCwxNzIsMTg1LDYwLDI2LDE5NCwxMjIsMTg1LDE3Myw0OCwyMzYsMTEwLDI1MywxNzgsMTUsMjUzLDIzMiw1MCwxODksMTUxLDE0MCwyNDIsMTc4LDEyMCwyMzcsNzYsMTc5LDIxOSwxMzksNjUsMTk4LDU5LDYsMTg3LDIzMywxNjIsNDYsMTk3LDkzLDYsMTgwLDksMjE2LDI1MiwxOTUsMjQwLDI0LDE2OSwxNTQsMTk2LDE2MywxMjMsMjMzLDQ5LDM1LDEyMywxMCwyMTEsNCwxOTMsNTMsMTk1LDQ1LDU3LDE1NSw3Miw5MSw0MSwxNDMsODQsMjUsMiwxMjgsMTM1LDE4NSwxNTYsNTAsMTk1LDIzMyw4NiwxNjAsMTE2LDg1LDE4LDcyLDE2MiwzOSwxOTcsMjQwLDE3NSw2NSwxNTUsMTI5LDQyLDIxMiw5LDYxLDMsNTEsNzUsMTc2LDU1LDEzOCwxMzUsMjA3LDIzLDEyOCwxMzIsMTY2LDIxMiwxNTcsOTAsMTE2LDk3LDEwNCwyNDMsMTAsMTUwLDE0MCwxNjIsMTY2LDg1LDEzNCwxNTcsMzIsMTIzLDI1MSwxMDMsMTgzLDIxNCwxNzAsMTQsMjQ4LDcyLDE4OSw1MiwxNjQsMTg1LDY4LDE0NCwxMDIsNywzNywxMDYsNTIsMjIwLDE1NSwyMTAsODIsMjA3LDc3LDI0NSwxOTcsMjUsNTIsMjcsMjA5LDI1MSwyMSwxOSwxOTUsNjIsODksMTM4LDMwLDgzLDQsMTQ0LDc4LDI0Myw4NCwxMjksMjMyLDEsMjE3LDE0OCwxMDEsMTY4LDEwMiw4Nyw5OSw2NiwxNzIsOCwyLDE1NSwyMTUsMTA4LDUzLDEyOSw4MywzNCwxOTcsMTI4LDMwLDIyMCw5NiwxMjMsODMsMzcsMzcsMTQ4LDY2LDE0OSwxOTEsNTMsNTYsMTYwLDExMiwxNzcsMzgsMjE5LDIyOCwxNSwxNDUsMTQ0LDE4Nyw2MSw0NCwxMjEsMjcsMjI3LDQyLDMxLDUsMTk4LDE2NiwxNjMsMjE2LDE4NSwxNTUsMTk1LDE2OCwxMDgsMTY0LDIzMCwyNCwzNiw1Nyw2NCwxMTUsMTMyLDEwNSwyNDAsMjEsODIsMjMsMyw4MywyMTMsMjA3LDIzMiw2MF19fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6WzExNSwxLDIsOTUsMjQ1LDU4LDYxLDE5NywyMDIsNjgsMjQ0LDE4OSwxMjgsMTgyLDEyOSwyMSwxODIsMTIsOTIsMjI4LDYyLDIzNCwxNzYsMTg4LDYxLDIxMCwxNDAsMjIxLDE0Niw2NiwxOTUsNzIsMjUsMjE3LDE4NiwxMTYsNTQsMTA4LDEzNCwxNTYsMTIwLDE3NiwyNCwxMTMsOTksMTAwLDk5LDIwNCwyNDUsMTE3LDE2OSw2Myw0NCwxNzQsMTUxLDIzMCw1OCwxNzQsMTA4LDIwMCwxNjcsMTgwLDYzLDIwLDk4LDEwNiwyMzQsMTcyLDEwMywxODYsMjQ2LDE2MCwyMDMsMjQ1LDEzMiwxMjksMTgyLDExNSwxNDMsMTksMTE1LDI0MCw5OSwxOTYsMjMzLDI1MCwxOTQsMjE3LDE2Nyw5NCwyMjgsNDMsOCwyMDUsMjQxLDE1NSwxNTAsNTgsMjAsMTQ2LDE5LDUyLDcxLDExOCw1LDE3MywxMiwxMjYsNjMsMzksMTgyLDI5LDU5LDE2OSwxNTUsMjE1LDIwLDQyLDI0NywxMzAsMTA2LDUyLDE3MSw5MCwyNDAsMTEzLDE2OSwxMzIsMTA2LDI0Myw0MSwxMzIsOTksMTY4LDM0LDEwMSw0OSw0Miw3MiwyMDMsOTAsMjQ0LDM5LDE1MywyMzUsMTEsMjMsMjEyLDQyLDE5NywyMTIsMTE0LDE3MSwxOTEsODIsODEsMjAwLDI0NiwxODQsMTksMjAsMTE5LDIyNiw2NiwxNzAsMjE2LDU3LDE2NSwzMSwxMjksNTAsMjAsODAsMTU2LDEwOSwxMjQsMTk3LDE1NiwxNjAsMTQwLDE2NSwxNjgsMTI0LDAsNzYsNTUsNjQsMjEsNTcsMjA4LDEwMSwxMzIsMjI0LDM2LDEwLDIyNCw0NCwxNjQsMjA2LDIyNywxMTgsMTI2LDEsMzgsMTM3LDE2NSwxMDYsMTQ1LDYsOTIsNTUsMTU0LDE4Nyw3NiwyMjksNiwyMDUsMTg3LDEwNCwyMTksMTEsMTI4LDIwNyw1MywxMDksNzEsMTM1LDk3LDI1MSw0MCw0OCwxNywxMjMsMTQ3LDExMCwxNjksMTI0LDIzNSwzMiwxNTUsMTk2LDEwNSw0NSwxOTcsMTA2LDE1NiwxMiwxMzAsMTMyLDI0NCw4NywxNyw1OSw2OCwxNywyMDQsMTM5LDU2LDY3LDgsMjA1LDcxLDY3LDEsMTA2LDIwMSwxMSwxMTcsODAsNzQsMTU5LDE1NSwxMzMsMTExLDExNywzNCwyNCw4NCw5MCw3NCwxNjUsMTM0LDQsODMsMTUxLDE1MCwxNzksMTAyLDEyMyw5NywxMTUsOTYsMjAyLDE2MCwyMTQsMjcsMjgsMTY3LDEwLDMwLDIzNCwxNTEsMTA5LDExMCw4MiwxODgsMjM3LDE3OCwxMjcsODgsMTMwLDEyOSwxODMsMjMwLDUxLDI1Myw4LDk2LDE4MSwyNTEsOTQsMTkwLDIwLDQ3LDQsMTAzLDExMSwxNjcsMTYsMTE4LDU3LDE2NiwxLDM5LDIyNSw4MSwxMDksOTcsMTg3LDE5MCwxODIsMTY2LDE1NCw3MiwxNDEsMTUsMjMwLDIwNSwyNDMsMTk2LDIwNiw0MiwzMywxOTAsMTM4LDExNCwxMjcsMTgwLDE5LDk0LDg5LDgsMTQ1LDE2NCwyNDMsMjAxLDY3LDIwNCwxNDcsODEsNzEsMjA3LDIyNywxNzEsMTU1LDU4LDExLDIxLDEyMywxOTQsMzgsMTc3LDE3MCwxODMsMjQ3LDEzNiw4LDEyMywxMzksMTQ5LDYsMTYyLDg3LDE5MywxNTAsMTk5LDE4OSwxNzYsMTQyLDI1NCwyNDUsNjEsODEsMTM3LDQyLDE1LDIsMjUsMTE1LDIwMiwxMTYsNjQsMTAyLDMzLDE4MSwxNjgsNTIsMTg4LDE3MSwxMzksNjYsMjA4LDE0NCwxNTIsMTAxLDkyLDEwMiw1NSwxMDQsMjIxLDEwNywxODEsNDAsMTg1LDgwLDE0MCwyNDYsMTY0LDIwNiw5Miw2MSwxNjQsMzUsOTMsMTQxLDE3NywxMDcsMjI0LDEzOSw3LDIxMSwxMzgsMTk3LDI4LDg3LDE0Nyw1MCwxMTYsMTQ1LDIxMCw4MCwxOCwxMDEsMTE0LDE1MywxNDMsMTc4LDEwOCwxNTYsMTUwLDE3MSwxMzAsMTM3LDE5MiwzNCw4NSw1OCwyNDMsNTEsMTk2LDI0NSwxMDMsMjAzLDE2NywyMTcsMTkyLDM3LDM0LDE0NCwxOSwxMSw1NCwyNDQsNTEsMTUzLDIxMiwyNCwxMTYsMTQyLDEwNCw5OSwyMDcsNDIsMTYwLDQ5LDEyMiw1NSwyNTAsNjYsMTA2LDk2LDIxNSw5NSwzMSwxNTEsMzUsODAsMTk0LDEzMCwxOCwxODQsMzgsMTkxLDgsMTgxLDIxMSwxODEsNzIsMTU3LDE2LDE3NCw1LDU4LDEyLDIyNywxOTIsMTg3LDExNCwxMSwxNCw4NSwxMjEsMTg4LDEwLDEwMywxNjAsMTA0LDcxLDEwNywyMTEsNjgsMTEyLDQ4LDExMiwxMzQsMTAwLDg0LDEzMyw5OCw5LDk4LDI1MSw1MSw3OSwyMDEsNTQsMTIxLDI0Myw3NiwwLDI1MiwyNDIsMTc3LDEzLDk2LDEsODgsMTM0LDQwLDI0NywxNiwxMTcsMjIxLDUzLDExMywyNDMsMjQxLDI3LDE4MCwxMzQsMzIsMjM3LDIyLDE2NCwyNTEsMTUwLDQ2LDE1NCwxMjEsMTMxLDg0LDY0LDExMCwxODYsMTU0LDQ2LDIxNiwzNSwxMDgsMTEwLDE5NywxODAsMTQ1LDE0NSwxMSw5NiwyNywxNDAsMTMyLDIxMCw3NywxMzAsMjE3LDE0MywxNCwyMDQsOTQsNjcsMTI0LDEwNyw1OCwxLDMzLDk0LDUzLDE0MSwxNiwyMzMsOTksMTkzLDEzNiw2NCw2MCwxMTksMTYxLDQ2LDExNywxODUsNTMsMTgsMTQ1LDI0MiwxMSw4MywxOTgsMjAzLDEzMyw4OCwyMjgsMTM3LDQ3LDIzMSwxNTcsMTUsMTY4LDE5OCwyLDY0LDE4NCw0NSwyNDUsMTcwLDI5LDIwMiwxMjEsNjMsMjAxLDE3MSwyMTgsNjgsMzksMTA3LDE5OSwyMDQsODEsMjUxLDQ1LDc2LDgwLDIwMiwxODcsNTIsMjEsNzMsMTE1LDE2Nyw0NSw1NSwxMzYsMTM0LDU1LDY0LDYzLDExLDk4LDE1LDE2OSwxODQsMjE0LDY0LDIwNSw2MywyNTIsMTAsMTMsMjI4LDIwNCwyMDksNjYsMTM4LDkxLDE5NCwxMDAsMjU0LDM4LDE0MSw0MywyMzAsODgsMzMsMTIsMTc4LDk2LDE5NSwyMCw4NSwxMDUsMjA0LDgxLDE0NSw1Niw0NSwyMzYsMTgwLDE2OCwxNTUsMTU3LDk0LDIxMiw2OSw5NywxMjksOTcsMjA1LDk2LDgxLDIyMSwxNTEsMjAzLDIxNCw5LDIwMiwxMzMsMTkyLDkxLDQ3LDExNiw2MSw5NSw2NCwyMDEsMjM2LDIyOCwxMzQsMjMwLDIyNiwxOTcsMTE5LDcyLDE0NSwyMjUsNDQsNjAsMzQsMTQ5LDEyNiwxNDQsMTc4LDYxLDEwMSw5MCw1NCw2MiwxMjksOTcsMjI0LDUxLDE5Myw3MSw4OCwxNywwLDQwLDE1NiwyNTMsNDAsNTgsNjcsNTMsMTcsMjAwLDIyOSw0MCwyMzcsMjI4LDE2Miw0NiwyNTEsMTgxLDIxMyw2MCwxNywxOTYsMjQzLDE2MiwyMTIsMTg1LDI0LDIzOSwxNjAsMjAxLDQxLDM1LDk3LDEzOCwyMiwxNTYsOTEsNjAsMywzMywxMTcsMjcsMjE4LDEzOCwxMzgsMjU1LDI1LDEyNSwxNzUsMTkzLDQ1LDEyNyw5LDEyOCwyNTQsMjQ4LDg1LDY2LDE4OCw0MCwxMjcsMjA4LDM3LDE0NywxODgsNDcsNjgsMjE3LDgsNCwyMDQsMTQsMTMzLDEzNCw5Myw4OSwyNTAsOTgsMTA0LDQ4LDQyLDE3NiwxNTAsMTgsMjUyLDE4Myw1NywxNDYsMTY3LDE0NSwxNjAsMTgxLDE5MCwyMSwzOCwyMSwxNDQsMzMsODUsODQsMjQ1LDg2LDgsMjE1LDEyMywzNiw5LDExOSwyMjYsNDgsOTIsMTE3LDMsMTYyLDQ4LDEzNiwxNjEsMTAxLDE5NiwyMiwzOCw1OSw3MCwzMSwyNDYsMTY4LDEwNiw5OSwxNTcsMTU2LDI0OSwxOTIsMTcxLDI1MiwxNjUsMjA0LDE0MCwxNjUsMTk5LDExOSw0OCwxMzIsMTI0LDEzNCwyMzMsMjE5LDE0NCw1MywxNTQsOTMsMTUzLDQsMTgyLDE0NCw3NCw0NywyMjksMjEzLDE5NCwxMDEsNDQsODAsMTkzLDE4OCwxNDcsMTQ0LDExNiwxMDEsMjIxLDE5NCwxNDgsMjQwLDI1MSwxOTksNCwxMTQsNjEsNzksMTIyLDkxLDE3MSwxOTgsMTg3LDEyMCwyMzIsMiwxMDIsMjIwLDEyLDE2Niw1NCwxMSwxOTEsNDksNjMsMjE4LDE3MSwxNTcsMTgsNTEsMTE4LDk0LDU3LDE0MCw4MCwzNywxMzQsNjAsOTksMTEsMTc3LDUxLDEyMSwxMTUsMTg1LDE5Miw4OCw1MywxMTUsMjMzLDE5NSw3Myw3NSwyMTgsMTQyLDIsNDIsNTMsMTM4LDM0LDg4LDE3NiwxMDAsNTIsMTMxLDY5LDE4NSw5MSwxNTYsMTYyLDI0NiwyNywxOTMsMTQsMjMzLDMwLDIwNiwxNjEsNDQsNjgsMTksNzEsMTc1LDE1MiwxNDAsNTcsMTgyLDE3LDYwLDEyMSw4NiwxMDAsMjQ1LDMzLDE3NCwxMTIsMTI0LDE4MSwyNywxNDYsMTM3LDIyOCwxMDcsMTE1LDg3LDE0NywxODUsMTE0LDY3LDk3LDEzNCwxMjIsMTE2LDUyLDUxLDIxNCwxNjUsMjAyLDYyLDAsMTYyLDMxLDIwMywyMSwxNSwxMiw4MSwxNzQsMjI5LDE4OCwxOTcsMTk3LDExMCw1NywyNDEsMTI2LDI0Miw5OCw3MSwxODMsNzIsODQsNDMsMTcsMTA1LDg0LDg1LDQ2LDExMSwyNDQsNCwzNywxNTEsNSwyMDYsMTk3LDE4LDExMyw3MSw2MCwxMjIsMjAwLDE1NiwyMjcsMTMwLDE5OCwyMzYsMTc4LDExNiwzMiw1MSw0MywxMjAsOCwxMSwxMjcsNTksMTA0LDczLDE5NSwxNzgsMzQsMjEzLDEyNiwxMDIsMTgwLDE5Nyw3LDExOSw1LDE0OCwyMzEsNTcsMTU2LDg4LDE1NCwyNywxMDEsMSwxMTYsMTMyLDU0LDU4LDgzLDEzMCwyNDcsMjQ3LDczLDE3OCw0LDE0NCwxMjYsMjE2LDEwNSwyMzIsMTQwLDEzLDIzMiwyMjYsMTgsMjMxLDE2MywyMDcsMTU4LDIzMCwxMDYsODEsNSw0MywxMTgsODIsMiw3MCw0MCw0LDIwNiwxODcsMTU4LDE5OSwxMTgsODAsNTYsMjI0LDM5LDIxOSwxMTgsMTUzLDM3LDI0NSwyNSw0NiwyMjksMTkzLDEzMyw1MiwyMDQsMTU2LDM1LDIwNCwyMzksMTI0LDE3MywyMjAsNjUsMTY0LDE5OCwxNjYsMTUsMjIsMTA0LDE5Miw2OSwyMzYsMTQ4LDEwNiwxNzksMTc1LDM5LDk2LDE4LDI3LDU1LDE4MSwzNywxNiw2MCwxOSwxNzgsMTEyLDczLDIxNywxODMsMTc5LDEwOCwxNDksMjMwLDE3MiwyMDUsOTgsMTIwLDE0MiwyNTMsMTcsMTcwLDY3LDExNywxOTYsMTgyLDE3MiwxMDEsMjM2LDE3MCwxMjEsMTg2LDU3LDc3LDMzLDY2LDMyLDczLDExNywxNzIsMTIyLDE1MCwxMzQsODAsMjIwLDkyLDIzOSwyMjksOSw3MywyMTksMTY4LDMzLDI1MSwzMyw5NywxNzEsMjA0LDY2LDE0MCw2MywzNSwxNTMsMTg5LDIyOSwxMDYsMTM5LDEwMSwxNTUsMTg1LDE2MCwyMTAsMzgsNTAsNDEsMTgzLDY5LDU5LDE2MCw0OSwxMTIsMTY4LDIzNCwxMzQsOSwyMDMsMzYsMTk5LDE2MiwxMDgsNTEsMTc0LDI0MSwxMjcsNzMsMTcyLDE4Nyw1MSwyNiwxNTIsMTczLDE0OSw4MCw4NSw1OCwxNjUsMTgyLDg3LDIwMCwyMDcsMTI5LDEyNiwxMzUsMTE5LDE2NSwzMCwyMzEsMTM1LDIyNCwxOTMsMTY4LDAsMTYxLDEzOCw2MCwyNDgsMTAsMTg2LDQ4LDMxLDkzLDE3OCw3LDE5NywxOTksNTQsMjQ0LDE1MCwxNTcsMCwxMjEsNjgsMjQwLDI0NywxMTAsMTQ5LDY5LDExMiwxNzcsMTAsMTk4LDI0OSwxMjMsMTUzLDEyOCwxOTIsMjMsMjYsNTYsNzQsMjI3LDIxNyw5NywxMzIsMTgzLDE1LDIyLDEyMCwxNzUsOTMsNDgsMTgsMTE4LDE3OCwxMywyMzIsMTkyLDEzMSwxNTgsMTc2LDExNywxMjAsMTY1LDUyLDIzOSwyMjYsMTg1LDM2LDExNSwxMjEsMTU5LDE2MCw5MiwxMjEsMTQ2LDEwNiwxNzEsMTk5LDkzLDIzMiwyMywzNSwyNiwzLDQwLDUyLDUsMjA2LDE4MiwyMzMsNzQsMTg0LDkwLDYsMjQ2LDE4Nyw1LDE5NSwxODAsMTcsOTUsMjQyLDEwOSwxNjQsMzcsMTQ2LDgzLDE5NywxLDMyLDE3MSwxMjYsODMsODksMTAzLDksNzYsOSwxNzQsNjksMTY1LDkzLDE4Myw5LDczLDE2MCwxMTEsMTI4LDEyLDE0OSwxOTgsMjQ4LDExNywwLDI4LDIsMTY3LDIzNSwyMyw3Myw5NywxMTYsMTEzLDE1MCwxNDUsMTY5LDcsMjA1LDExMywxNDcsNywxMzgsMTgwLDgsOTcsMTAwLDEsOTUsMTY0LDUwLDU2LDY4LDE3MiwyNDQsNiwxMzAsOCwxOSwxNzgsMTEwLDI0MSwxNTIsMTM2LDEzNCwxOTYsNTYsMjAxLDE5NiwyMDgsNTMsODksMTMyLDIyNiw1NCwyMjQsMjYsMjcsMjIsMTc4LDkyLDQ2LDQyLDY5LDEwMCw1NiwxMTgsODMsMzgsMTk4LDAsMzcsODYsMTE4LDIyNSw0LDQ3LDMzLDIzLDIwOCwxOTIsMTA0LDEwLDczLDc3LDIxNywxMTcsMTQsMTY1LDIxMywxNTMsMzgsODMsMTUwLDEzNywyNDMsMjAwLDIzNywxNywzNCwxMjksMTc4LDg3LDUzLDE0OSwxNTAsMTE3LDEzNCwxODYsNzQsMjI2LDE0MiwxMjAsMjExLDEwMyw3NywxNDksNzUsMzEsMjMwLDE1NSwxNjEsMjI4LDcsNTgsMTY3LDE0NiwxNzQsMTMzLDYsMTk4LDIxLDUwLDE0NCwyNTIsMTQzLDI0OCw5OCw0LDE2LDEzOSwyMDQsMTMsNDksMTEyLDgyLDE4Miw2LDkyLDE2OSw3MSw4MCw2NCw0NSwxNDEsMzksMTgxLDIwNCwxMzMsMTY2LDg1LDQxLDE0LDIwMywyMjksNTEsMjU0LDIyLDE1Miw2MCwxOTksODIsNDIsMTg2LDM3LDMzLDI2LDEsMjM2LDcyLDE1NSw5OSwxMjEsMTU5LDIyMCwyMSwxNjYsMTEyLDY3LDQ0LDQzLDE2LDM2LDE1NywxNDAsNDQsNTcsMTQ2LDUyLDEwLDE2NiwxNDMsMTQ1LDMyLDgwLDE1NCw5MiwwLDY0LDQ4LDE0MCwyMjgsMTkyLDE3MSwxNzMsMTcwLDE5Niw0NywxMDQsNzUsMTA0LDgwLDUwLDE1NywxMzYsMjksMTI3LDEzOCw0NSw1LDIxNCwyMiw3MSwxMTYsNjEsMjE3LDI4LDI3LDk0LDEyOSw2LDEyLDc2LDE0Niw5MCw1OSwxMjQsNDYsMTY2LDg2LDIwOCw4MywxOTUsMjQ4LDExNSw1OCwxNTgsMjE2LDEzOCwyMjcsMTE0LDcsMjQ0LDM5LDI2LDI3LDIzMiwzNSw5NiwyMyw4LDIwLDE1MCw4OCwxMDIsMTE4LDE3MywxMDMsMTUxLDEyOCwzMiwxMzIsNDYsMTM5LDY0LDE2OCwyNDAsMTQ0LDQ2LDQsMjEsNjcsMywyMjksMTU0LDY4LDExOSw3MCwxMDgsMjQ4LDE3OCwyMDUsMTg1LDEsMzQsNjcsNDIsMTQ5LDgxLDE1MywxMzUsMTM5LDk5LDIzNSwxODEsMSwxNjksMjYsMjIsMjA2LDUwLDE2LDU1LDE2LDksMSwwLDE5NSwyMzQsMTg1LDIwMywyNDAsMTk3LDEwMSwyNDMsMjQ0LDk3LDE3OCwyMDIsMTg3LDQwLDM5LDE0NCwxMjIsNyw2MSwxNjgsMSwxNjUsMTc2LDc0LDEyNCwxNjksMTM5LDE2MSwxNDcsMjE4LDE4MywxMTMsMjAsMjYsMTIwLDEwLDEwOSwxMjIsODEsMTAxLDEyMywxMTQsMTQyLDk2LDE1NCwxNzQsMjI4LDcxLDcxLDI0NiwyMzAsMTE4LDc1LDEzNCwyMDYsODksMjAxLDExMCwyMzcsMTc5LDQwLDE2MywyMDksMTg3LDk5LDAsNTQsMTAzLDE2MSw3MiwyMjAsMTIsMjA2LDEzNSwxMTQsMTE0LDE2MywzNiwxNTgsMTIxLDEwMSw1NCwxNTIsMzIsMTY3LDExOCwxMSwxOTQsODcsODcsMjAyLDUyLDIwOCwyMDAsMjU0LDI0NSwxMywyMDAsMjIsMTQ5LDIwNSwxMDUsMTIxLDgwLDE2NywzNSwxMDgsMTMyLDE1MSwyMDksMTcwLDYyLDE3MywxNDksMTgyLDc5LDIzLDE2LDEsNjksMTA5LDE2LDI1MiwxNjQsNjksMjQyLDE5MSwyOCw1LDEyNCwzMCwxNjIsMTYxLDcwLDMyLDE5OSwxMDYsNjksMjAzLDk3LDI1MCw4MywyMjQsMjA0LDE5MSwxOTEsMjM1LDk5LDEyOCw1NywxNTAsMTM3LDU3LDE0NiwxMDMsMTUzLDE0Myw3MSw1NSwxMDEsMjA0LDE1NSw3Nyw1LDIyNiwyNCw0OCwxMzQsNjUsMTMsMjA5LDE4MSw0MCw4MywxMDYsMjM0LDExOSw2OSw1MCwxNjMsMzgsNzIsMjAyLDg5LDE2OCw4LDIwMywyMjIsMjQ3LDExNywxMzIsMTIzLDExNSwxMTYsMjQ1LDE4OSwzNSwxNjksMTQyLDEyMyw0LDEyOCw0MSwyMjcsMTE2LDE0MCwxMDIsMTEsMjQyLDIyNiwxODIsNDMsNTIsMjAxLDEzNiwxNzgsMTg0LDE1Nyw0LDEzMSw5NSw1Myw3MiwyMTIsMTgxLDk0LDIzOCwyMTYsNjgsMjAzLDM2LDExNSwzOCwyMDgsMTk4LDIxOSwxNDgsMTYzLDcxLDEzMCwxMTEsMzcsMTMyLDE5NCw5Niw5MCwxMDgsMTczLDAsMTY0LDE2MCwyNDAsMTY4LDYsMTk2LDMzLDEyMiwxOTUsNywxMjUsMjExLDk3LDE2OCwyMzAsMTc3LDk5LDE3MiwxMzksOTksMTI5LDgxLDI1NCwxNTQsMTQ2LDQsMTYzLDExNyw0MCw3LDEyMSwxNTAsMTA3LDI0LDE3MywyMDksNjcsNjQsMTcyLDE4NSw2MCwyNiwxOTQsMTIyLDE4NSwxNzMsNDgsMjM2LDExMCwyNTMsMTc4LDE1LDI1MywyMzIsNTAsMTg5LDE1MSwxNDAsMjQyLDE3OCwxMjAsMjM3LDc2LDE3OSwyMTksMTM5LDY1LDE5OCw1OSw2LDE4NywyMzMsMTYyLDQ2LDE5Nyw5Myw2LDE4MCw5LDIxNiwyNTIsMTk1LDI0MCwyNCwxNjksMTU0LDE5NiwxNjMsMTIzLDIzMyw0OSwzNSwxMjMsMTAsMjExLDQsMTkzLDUzLDE5NSw0NSw1NywxNTUsNzIsOTEsNDEsMTQzLDg0LDI1LDIsMTI4LDEzNSwxODUsMTU2LDUwLDE5NSwyMzMsODYsMTYwLDExNiw4NSwxOCw3MiwxNjIsMzksMTk3LDI0MCwxNzUsNjUsMTU1LDEyOSw0MiwyMTIsOSw2MSwzLDUxLDc1LDE3Niw1NSwxMzgsMTM1LDIwNywyMywxMjgsMTMyLDE2NiwyMTIsMTU3LDkwLDExNiw5NywxMDQsMjQzLDEwLDE1MCwxNDAsMTYyLDE2Niw4NSwxMzQsMTU3LDMyLDEyMywyNTEsMTAzLDE4MywyMTQsMTcwLDE0LDI0OCw3MiwxODksNTIsMTY0LDE4NSw2OCwxNDQsMTAyLDcsMzcsMTA2LDUyLDIyMCwxNTUsMjEwLDgyLDIwNyw3NywyNDUsMTk3LDI1LDUyLDI3LDIwOSwyNTEsMjEsMTksMTk1LDYyLDg5LDEzOCwzMCw4Myw0LDE0NCw3OCwyNDMsODQsMTI5LDIzMiwxLDIxNywxNDgsMTAxLDE2OCwxMDIsODcsOTksNjYsMTcyLDgsMiwxNTUsMjE1LDEwOCw1MywxMjksODMsMzQsMTk3LDEyOCwzMCwyMjAsOTYsMTIzLDgzLDM3LDM3LDE0OCw2NiwxNDksMTkxLDUzLDU2LDE2MCwxMTIsMTc3LDM4LDIxOSwyMjgsMTUsMTQ1LDE0NCwxODcsNjEsNDQsMTIxLDI3LDEyMCwyMTIsOTcsNzksMTYxLDE3OCw3Miw4MiwxOTEsNTksMTMwLDExMCwyMzYsMjM0LDE1NCw0OSwxMjAsNTAsMjMsMzIsMTQ4LDExMywxNjksNDYsMjEsMTEwLDExLDEsMTkwLDExLDI1NSwyNCwyMzIsMjUsMTkyLDE2Niw2NywxLDU5LDIyLDEwOCw1MiwyMjEsMjE3LDE5NCwzOSwxMjMsMTYzLDQxLDEwNywyMDgsNjAsMjUwLDY0LDU1LDE5MSwyMzgsMjI4LDEwNyw2Nyw1MCw2NiwxMzcsMTEyLDczLDExNSw4MiwyMTQsOTgsMjUwLDIwNCwxNTAsMjQyLDc5LDIyMSwxODEsMjQ1LDM2LDE1MSwyNSwyMTgsOTQsMjQ1LDE4MiwyNTMsMTcwLDgsMTE2LDEyNiwxODcsNjIsMjU0LDE1NSwzNywxMjcsNjAsMjI3LDQyLDMxLDUsMTk4LDE2NiwxNjMsMjE2LDE4NSwxNTUsMTk1LDE2OCwxMDgsMTY0LDIzMCwyNCwzNiw1Nyw2NCwxMTUsMTMyLDEwNSwyNDAsMjEsODIsMjMsMyw4MywyMTMsMjA3LDIzMiw2MF19fX0seyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOlsyMzcsMTQ3LDE0NSwyNTEsOTgsMTUsOSwxMiwxODcsMTAsMTkyLDE1NywxMTQsMjMsNjAsMSwyNDAsOTUsMjA1LDE4OCw1NCwyNDAsMzMsMTYwLDEyNSwyMjQsMTk2LDEzOSwxNjAsODQsMjE3LDE2NiwxMDUsMTE5LDExNiw5NiwyMDgsMTY3LDE4NiwxNjgsNDMsMTkyLDIxMywyMzAsMTQsMjksMTAsNTEsNjAsMTQ1LDE4OCw0NiwxMjEsMTk4LDMwLDU4LDE2Myw0LDI0NywxMTAsNzIsMTgyLDg2LDg2LDU4LDE1OSwxOTcsNTEsMTU3LDEwNSwzNCwxMzQsMTgwLDI4LDE3MywxOTQsMTMyLDEwNiwyNDcsMTMxLDE5Nyw2OCw4MywxMDAsMjQ0LDI0NCw1MCwzOCwyMTAsMjksNjgsMjUyLDM2LDcwLDI0OSw2NSw1MSwyMTIsODIsMTg1LDkwLDE1MiwxMzQsMzksMTMxLDQ5LDE4OCw2LDEwNSw5OCwxODMsNzIsMTA1LDkyLDIzNiw2NCwxMzgsNDAsMTksMjksMTUsNjAsOTgsODEsMTE3LDY1LDg3LDE1NiwxMCwxOTgsMTg2LDEzNiwxNzksMjQ0LDE3Niw0NSwyNiw1NSwyMzIsMTk0LDE4Nyw5NSw4MiwxNDUsNSwxMDAsNzEsMjA2LDEzMCwxOTgsMTA0LDIzNCwxODksMiwyMjUsMjEsMTI3LDM2LDE0LDEyLDE2Nyw1LDY1LDUwLDE1Miw0OCwxNDAsNTgsMzYsMjE4LDEyNCwxOTgsNiwyMDYsMTY5LDEwMiwxMDYsMTc2LDU2LDE5MiwxNzcsMTQ1LDE3Myw2MywzOCwxMTUsMTcsMjQ5LDE0LDE5NywyMTEsMTg2LDkyLDEwLDE2OCw1NSw2NSwxMDksMjE2LDIwMSw1NCwyLDEyMiwxMSwzMyw0LDE3Nyw1MSw5MCw5OCw3NSwxMTIsMTI0LDUyLDQyLDQxLDEyNywzNiwxNTIsNzMsOCwxMjAsNzksMTgzLDY5LDE3OCwyMjAsMTUyLDIxMSw3NiwxNjUsNDMsOTEsNjIsMTA0LDEzMiw3MSw0MCwzOCwxNDksMjQzLDEyMCwyMDcsMjIyLDEzNSwxNzgsMTk1LDEzMiwxNDQsNDUsMTY0LDIzLDE0MCw4OSw0NywxNjAsMTAsMTA5LDE0MCwyMDksMTA2LDEzOCwxNDQsMTY5LDE0MywxMiwzLDE5MSw3NCwxNTksMTk2LDIyNSwxMDEsMjE3LDIxMCwxNTksMTUzLDI0MCwyNiwyNTEsMjUxLDUsMTIsMTE5LDEyMywxMDYsMTcwLDAsMTc1LDcwLDk2LDE0OSwyMDgsOCwyMiw2NiwxOTEsMjA2LDEzNiwxMDAsMSw4Niw0NSwxNTQsMzcsMTg5LDExMiw2NywxNTQsMzEsMjUsOTUsNDAsMTY5LDE2MSwxMTEsMTY0LDM1LDIyOCwxMzcsNTcsMTI0LDIzNCw4OCw5Miw3NCw1MCwxNDgsNjAsMTY3LDUwLDIwOCw1Nyw4MywyMzEsMTA2LDIwMCwxMTIsMzEsNzksMTE5LDg4LDE0NiwxMjIsMjYsMTAzLDIxLDQwLDE1MCwxMzgsMTkyLDE1NywzNSwxMDIsMTIyLDEyOSwxNDYsMTI0LDIyNyw4MCw2NCwxNjUsNTksMTI5LDE1NSwzLDE4OSw5MCwyOCwxOTksMTUyLDkzLDMsMTEyLDEzOSwxOSw4OSwxNjAsMTAsMTYwLDEzNiw4LDIyNywxODcsMTc0LDU3LDE1MiwyMSw4NCw5Nyw3NSwxODEsMTEsNzEsMjA5LDgyLDEyNCwzMiw0NiwyOCwyNDYsNDQsMTIxLDgwLDYxLDExNywxMDUsOTAsMjMxLDEzMiwzNSwxOTMsNzEsMTQ2LDE1OCwyNywxNzksMjM4LDgzLDEwOCw2OSw4OSwxODgsMjI5LDIyNCwxMTAsMjM3LDExNSw5NCwxNTksMjAwLDUzLDEyOCwxOTIsMTI1LDEzMywyNTIsMTk4LDI0OCwzLDQsMCwxOTksMTIwLDE2NSwxODMsMTc3LDEzOCw4LDE2OCw5NywyMjUsOSwxOTksNDAsMTIxLDYwLDIwNCwxNCwyNDgsMjEwLDI1LDIzNSw4MSwxNCwyMTcsMTI4LDAsMTQxLDE5NCwxMjQsMTk4LDI0OSwxODAsNiw2NSwxMTgsMTMzLDE1MCw2Niw3OCw5MCwxNTUsMzAsNzEsMTYyLDE2NSw4Nyw2OCwxNDIsOTgsMTk4LDE1OCw4NCw0MSwxNTAsMzUsMTM5LDEwLDksMTQ0LDgsMTMzLDEwMiw3MCw3MSw1LDIwMCw2OSwxMjMsMTkxLDE2MSwzOCw5MSwyMTIsMzIsMjUyLDI0NywxNjIsMjE3LDEwNSwxODAsOTAsMTQwLDE0NiwxLDIxMywxNjAsNDcsMTM1LDE1OCwxMDIsMTE4LDIzLDI1MiwxNzAsNzQsNzEsNzUsNSwyMzQsNSw2NSwyMjgsMTA3LDM2LDg3LDEwLDExMiw5NywzOSwxMTUsMjE2LDMyLDU5LDE4MiwxMzksNTksMTc0LDIsMjMsMzAsMTA3LDc0LDU0LDE2OCwxNTAsOTIsMjEyLDE5MSwxMjUsMTAzLDE1NSwxNDMsMTQ2LDM4LDE4NCw5NywzMiwxMTQsMTk1LDcwLDQ5LDk2LDE4MSwxMDIsMjI5LDE4LDE2NywxNzksMTM1LDE2MywyNSw5MywyNywxMzMsOTAsMTkzLDUzLDE0MywxMTIsMzksMTI4LDE5OSwyOCwxNzMsMjA4LDQ4LDU0LDEyOCwxNjIsNDgsNDksMzksMTI0LDIzNCwyNDYsMTg1LDEzMiw2NCw2OCw5OCwxODAsMTE1LDk2LDEsMTg4LDM0LDgzLDk5LDE0OCwxNDcsMTQ5LDE4MCwxNywxMzAsMTc1LDksNDUsMjEsNjgsMTQxLDEwNiwxOTUsNjYsMjAyLDE2MSw1Myw3OSwyMDksMjcsMTEwLDY5LDUzLDg3LDE3NywxNzUsMjksMjQ2LDIwNSwxMTIsMjM1LDExMywyMzUsMTAxLDQyLDIxMywxMTksNCw5LDIzNiw0Miw2MCwxNDYsMTI4LDE1NywxODgsNTYsMjEzLDM2LDMwLDIzMSwzOSwxOTUsMjI0LDQ4LDE3MywyMTEsNDQsMTE1LDIyNSwxODYsOTMsMzQsNzQsMTkwLDEzMyw5MiwxNjEsMTE4LDI2LDE5NywxNDAsMzcsNTYsNDksMzcsMjYsMTA4LDI0MywxMTQsMjUxLDIyNywxMiwzLDU3LDUxLDIyMCwxNDUsMjIsMjMyLDQwLDI4LDM5LDEzNSwxNjksMTY2LDE3NiwyNCwxNTUsMTgsMTI2LDIxLDE5OCwxODMsMjUsNzYsNzQsMTQzLDM4LDY1LDIyNSwxNjAsMTEsMTcxLDE1NCw5NiwzOCwxMjIsMjksNywxNjgsMTc3LDYwLDUxLDExOSwyMjksMTA2LDg5LDIyLDE2LDEyMSwxNjEsMTMwLDEwMywxMDIsMjgsMjgsMjI1LDEwMCw4NiwxNSw1MCw3NSwxOTQsNDAsMTQxLDEzOSwxMTUsODYsNDcsMyw1NywxNzIsMTM1LDAsMiwyMzUsMjAxLDE0NywxNzIsMTY1LDE1MiwxNjYsMTQyLDE0LDI1Miw0NywyMDEsNDIsMTQ3LDEzMSwyMDQsNTAsNDEsMTksMTc5LDYsNTYsMTIwLDEyLDIzMCwxNjMsOTksMTI4LDE2LDEwMSwxODgsMTM1LDI1NCwyMzIsMTM3LDExMyw0MywxOTIsMjI1LDExMiwyMDAsMTYwLDIwLDIsMjU0LDE4MywyMSwyOCw1NSwxMzYsNjAsMjM1LDE1Nyw3NCwzNiwxMzksMjI2LDg2LDEzMCwyNTUsMjI1LDE2NywxODgsNDksOTEsMTc0LDE0MCwxMjksMyw4NCwxMDAsMTE1LDQzLDc1LDQsMTI0LDEzNSw0NSwxNjMsMzgsNDQsMTU2LDE0MCwxMTcsMTgwLDE3MSwxODAsMjgsMTkyLDUwLDEyOCwxMjcsNzcsMTksMTc4LDEzMCwxMzQsMTA3LDE4OSwxNzAsNzQsMjMzLDEwNSwxMjMsMjQ0LDEyMCwyMDcsMTMyLDEyMywxNzUsMTc4LDE4LDE4NCwyMjQsMzksMjEsMTgxLDEwMiwxOTUsMjE5LDE2MiwxMSwzNiwzNSwxMTYsNjYsMjEsMTY1LDE0MSwxMCw0NiwxMjMsMTcsMTkyLDcyLDM4LDE4MywxODksMTgxLDE3MSwyNTEsMTgzLDk2LDcxLDEzNCw0NiwzMCwyNDgsNDQsNjMsMTA4LDExNSw4MCwyMjAsMTQwLDEyNSwzNSwxMzIsMjI1LDIyLDUsMTA4LDI4LDE3OCw2MywxOTgsMTExLDIzNiw4NSwxNzksMTQ5LDEsMTgzLDE0MywxNjIsMTM5LDIyLDgwLDQ2LDIzNiwxMzksNjEsMTA4LDEzMywxMywxNzUsMjgsMTc5LDE2MywxODEsNzMsMTksMTAxLDQ3LDU1LDI0NSw0LDExMiwxMDAsNCwxNjcsMjI0LDEyNSwxNTAsMTQ5LDIwMSw1LDEyOSwxNzksMjM0LDIwMywxMzcsNTQsOTEsMTAxLDExOSwxNzEsOTgsNzUsOTksNjUsODUsMTI5LDE5NCw5LDksMTMwLDQsNTUsMTM1LDE2MywxNTMsNTEsMTM3LDIxLDMyLDIxMiwzOSw4MCwxMTcsNTQsOTUsNzcsMjAzLDExOSwxMjEsMTU0LDcsMjE0LDE0NCwxMjIsNzMsMTMxLDE2NiwxMjgsMTc3LDE4OCwxODMsMSwxNzQsMTUxLDE4NSw2NSw2MCw4Niw4MCw5OSw1OSwxNCwyNCw2Niw0MCwyMjEsNjgsNDcsNjUsNjUsMTc3LDEzMSwxOTIsMTQ0LDQ3LDcsMzcsMzMsNzYsMTY3LDI1NCwxNjcsMTIxLDIyMiwxNjYsMTU0LDYzLDk3LDE1OSwyNDAsMTY5LDEzNiwyMzMsMTIyLDExOCw1NywxMTIsMTk5LDEzMSwxNzcsMjgsNTEsMTQwLDE4MywxMTEsMjUyLDE1OSw5NCw3Niw1MywxMzAsNDEsMTcyLDExNCwxMTksMTMwLDE5NSwxMjQsNTYsMTIyLDIzMCwxMCwxMDgsMTEzLDEzNSwxNjcsMTU1LDQ3LDc3LDEwNyw2OSw4NCw3MCwxMDksMjUsMTYsMTE3LDE2Nyw3MiwxMzksMTMsMTAzLDE1NCwyNywyMTAsNjIsNDMsMCwxMjYsMTg0LDIwOCwxMDAsNDEsMjQwLDE4NSwxNjIsMjExLDU0LDU2LDIwNywxMTYsNDMsMTE3LDE4LDIxMCw0MiwyNTAsMjExLDI1MCwxMTIsMTM3LDExNywyNDcsMTUwLDExMyw0MywxNzMsMjI0LDE4MSw1NCwyNTEsNTIsMTMzLDEyMiw3NywzMSwxMzUsMjA3LDIwNSwyMzUsMjI0LDEzNCw1NCwxMzAsMjMzLDEwOCwyMDcsMTU1LDE1Myw5Nyw2Nyw3OSw5Miw0MCwyMDYsMjE2LDI0Myw4NywyMCwzMSwyMjEsNjUsODEsMjA2LDE3OSwyNTEsNDcsMzYsMTAsMTMxLDE3NSw1MF19fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6WzMsMTg3LDE2MSw2OCwyMDgsMTI5LDIwNSwyMzIsNTEsMjI1LDE4LDQsMTMwLDE2OSwyMDMsMTg4LDExNSwxODgsMjM2LDY3LDE2NywxMjIsMTg0LDE5OCwxMTUsOTYsMTU0LDI1MiwyNDIsMTEwLDE5MywxNTQsMTg1LDI5LDI0NywxMjIsMTQxLDQ0LDE1Myw5MywxNjQsMTkyLDEyMSw1NiwxMTQsMTU5LDEzNSwxNjYsMTIxLDEwNywxLDE5NiwyNyw1NSwyNDMsMjE5LDExMiwyNTQsMTIxLDUwLDQ1LDE5Miw3NSw0MCwzMiwyMDIsMjQ0LDksMTI5LDIyLDU3LDE3Miw0MSwyMzIsODQsOTAsNTIsNzksMTYzLDExNCwzNCwyMjMsOTYsMjksMjQ3LDE0Niw3NSwzNywyMTcsMTA5LDEyOSwxNzksMTksMjQ4LDE5MiwxMjcsMjE4LDQ0LDE3MCw3OCwyMjUsMTUzLDkxLDUwLDU5LDE1MywxODQsNDQsNjcsMTM4LDIwNiwxNzgsMjE1LDYsMTMxLDE1MSwyNCwzOCwxMjIsMTY2LDIzMCw2OSwxMiwxNTIsMTY1LDE3MywxNzIsMTE2LDE0MSw2OCwyMDIsMTg3LDExLDIyNyw3OSw5MywyMTIsNzEsNjYsNDgsNDMsMCwxOTcsOTMsMTYyLDIyLDEwOSwyMTQsOSw1NCwxMTEsNTEsMjYsOTQsODMsMywyMDMsMTk1LDMsMTYxLDExNywxOTAsMjI0LDk5LDIwMywxNzcsMTI0LDExOCw4MCwyLDE0MiwxNTIsMTk5LDE0MSwxMTEsODAsNTQsNDIsMTM3LDE0OCwzNiwxMzYsMTAwLDIyNiwxODQsNjgsNzEsMTIxLDU0LDQ2LDg4LDE0NiwxNywxMzYsMTE3LDI0NSw1OCw3NCwyMzYsMTQwLDM3LDIzMiwxNzksMTg1LDEwMywyMTgsMTk2LDEwMiwxNTEsMjMsMjMsMjE3LDMxLDY1LDEyLDYxLDEyMyw5Miw3NiwxMTYsMjA5LDkzLDIzMyw5OCwzLDUyLDI0Nyw5NiwxNSwyNDcsNDUsMTg2LDE3MSwxMzIsOCwyMTcsMTYsMjE4LDI3LDEyOSwyMjksMTI0LDIwNCw4MCwxNTEsNjMsMTQsMjAzLDM2LDg0LDk4LDE1NCw5MiwxMTIsMzgsMTgyLDI1MiwxNzIsMjA2LDE2NywxOTAsMjM4LDE0NiwxNTQsMTEyLDEwLDQxLDY5LDE3NywyOSwxMjEsMTc5LDE2NCwyMzgsMjI3LDMxLDk4LDIyNSwxNTAsMTE1LDIxMywxNjgsMTg0LDc1LDU0LDIzMSwxNDYsOTksMTM5LDIwOCw1MCwxNjMsODEsNTYsMTk5LDE3Nyw1LDIwMywyMjUsNDYsNTEsMTk4LDE2MiwxODksODQsMTQ1LDMsMjQ0LDE5Miw1MiwxMDUsMzYsMTM2LDIxNCw5OSwyMzksNzEsOTUsOTcsMTMzLDE1NywxNzIsMTk0LDE3OSw1NywxMzUsMTM2LDIzOCw2Niw5MiwxNTgsMTY5LDEzMiwxMTEsMTA1LDE1OCwyNTAsMjIsMTgwLDQ0LDI0LDczLDEwNyw1MSw0MiwyNTAsMTA0LDM0LDE4NCwyMjQsMTQ2LDM1LDEyMSw0NywxNDAsMzYsODIsMjQ0LDIxLDI0LDIzOSwyNTAsMTY2LDI0OSw2OSwxMjAsMTA5LDEwNywxMTgsMjA2LDUyLDEwNSwxNjMsNzMsMjUsMzcsMjAwLDE1MCwxLDE1NSw0OSw1LDIyNSw0Niw4OSwyMzUsMTExLDc5LDE1MSwxNzIsMTk0LDEzMiwzNiwxMCwxLDEyLDM0LDIyNyw2NiwxNjAsMjQ2LDc4LDE4LDEzOCwxNTMsNTEsMjM1LDE3LDk0LDEzNSwxOTMsMTEsMjE0LDUyLDMzLDE5NiwxMTEsMjEwLDI0Miw0MCwyMjcsMjYsODcsMTI1LDE1NCwxMjAsMTE2LDEzMyw4Miw5LDIxOSwxOTYsMTcwLDI3LDEwLDE4OSwyMiwzOSwxMDUsMTcwLDk4LDE1LDEzMSwyMDUsNDEsODksMTQzLDM2LDI0MSwxOTYsMjI1LDE3OSw3NSwxODgsMTQ0LDMxLDU1LDM5LDExNiw1LDIsMTEsMTQ1LDczLDExMiwxODIsMTE5LDIwMiwyMjMsNDQsMTUzLDgzLDI2LDE5OCwxMzgsMjEsNTYsMTU2LDE3OCwxODIsNjgsMjQ0LDE4LDE4NywyMzIsMTQ1LDc1LDIzNiwxMTIsMjQ5LDE1MCw0MCwyMywxOTYsMTg1LDI1NCwxNTEsMTUsMTY0LDI1MSw0OSwyNDMsMTg2LDcwLDIwNiwxMDUsNzEsMjQ5LDE0OSw0LDI0NCwyMzQsMTksNzQsNTQsMTgxLDE3Miw1NywzMSwxODQsMjE5LDEzMywyMTcsMTIwLDU0LDE4Miw3NCwxMjEsMSwxOSw5OCwxOTksMTAsMTIyLDI1NCwzNywzMCwyMCw3LDIsMTE4LDE2OCwxNSwxOTcsODQsMzcsMjE5LDIxNiwxNTQsNDAsMTU2LDUsOTIsMTEyLDE1Miw2MSwxLDE5OCwxNjMsMTkyLDE2NCwxMiw2NCwxNSw1OSwxODQsMTU1LDEwMywwLDkwLDE1MiwyMDAsOTgsOSwyLDYzLDE4MiwyMzEsODUsMTMwLDE2NywxMzQsMTE4LDYwLDE1NywyMjgsMjA5LDE5MywyMDcsMTE2LDE0NywxNCwzNiwxMzksNDEsMjIwLDE1MiwxODQsOSwzNSw4MywxMTYsMTA5LDIzNSwxNzksOTksNjEsNzUsMzQsOTgsMTAxLDMsMzQsNzQsMzIsMTY0LDE5OCw1OCwyNDIsMTk5LDE3MSw3MywyMiw0Myw2NSwyMjUsMTU2LDM1LDMyLDMxLDEyLDIzNiwyNiw2MCwxMTksMTY3LDE1OSwxMDcsNyw5OSwxODUsMTg0LDExMywxMDQsNDYsMjM2LDMsMTM3LDc4LDIxOSw5MCw4NCwyNDEsMTksMjAzLDUzLDEzOCw3NywxNyw2MCwxODIsMzQsNjcsMjEwLDczLDE3NiwyNCw2NSwxNTcsOTQsNDQsMTMzLDE3OCwyNDIsMTQ0LDE0MSwxMzgsMTIwLDE3MiwxODIsMTE2LDYxLDQyLDE1MSwxOTUsNjcsMTk0LDczLDEzMSw2MCwzLDI0Myw4MCw5OSwxNjMsMjA3LDIwMCwxOTMsNzUsMzIsMjI5LDEyMiw4Nyw0MCw3NiwyMjYsMTg4LDUxLDExNyw3MywxNTgsMjA3LDE3MCwxMzEsMTkzLDg4LDIzLDM1LDEyOCwxMTIsMTMwLDIyNywxNzAsNTcsNTAsMTg0LDQ3LDIzMSwxMjksMTYyLDcyLDYzLDIyMiwyMjcsMTA4LDgwLDMsMTY3LDU0LDEwMSwxNDQsMTk0LDIyMCw4MSwyMDgsMzksMTQsMTI3LDExNywxMDUsMTgxLDE0Nyw2LDE4NCwxMzAsMTcxLDIyOSwxMzAsNTAsMTIwLDE2MiwxNjYsMjQzLDg2LDEwMyw3NywzOSwxNjYsMTk2LDYsMTU1LDQ5LDE5OCw0NiwyNTIsMTMyLDI5LDkzLDIxMywxMDUsNjQsNTcsMTk5LDIyOSwzMiw5OSwyNywyMDksNzcsNTIsMTkzLDEzOCwxMzgsMTQ3LDY5LDkyLDE1MywxMTEsMjM5LDE1NSwxNjUsMjM4LDEwLDE2LDk2LDIxMywxMjUsMTQ4LDIzNSwxMTUsNCwxMTcsMTYwLDE2NSwxMzgsMTk4LDk2LDU3LDkzLDIzMywxMzksOTIsNTcsNDMsMTYwLDE2NiwxOSwxNzMsMiw5OSw1LDEwLDEwMSwxMDksOTMsMTcxLDI1LDIyLDY4LDEwNSwyMjMsMjMzLDc3LDE0Niw5NywzMCwxNTMsMTEzLDE3MywyNCwxOTMsMTEwLDI0OCwyNDcsMTk4LDIyMyw0MSwyMDQsMjQyLDI1MiwyMiwxOTUsMjA5LDU3LDE1LDM2LDc5LDM1LDc2LDE1Nyw4OCwxMzEsMTk0LDI1MywxNjksMTQsNywxMCwxMTYsMjM2LDExOCw2NCwxOTIsMjI0LDc4LDEyLDExNiw1MCwxNTAsNjUsMiwxNjgsMjMxLDE0MSw1Miw5Niw4NywyMDcsMTM4LDE5MSw3MCwxOSwxMCwyMTQsMTUzLDE5OCw5NCwyNSwxNzUsMTQsMTM1LDE0NCwxMyw1MiwxMTIsMjM0LDEzMSwxNzMsMTUwLDIxMywxMjEsMTY5LDMzLDQyLDE1MCw2Niw4Nyw4MywxMzksMTY2LDE2NiwzNSwxMzksOTAsMjI4LDExOCwxODQsMTc2LDQ2LDYyLDI0MSwyMDEsNTYsMTUwLDE5NSw1Myw1NiwxMjYsOTYsMTA1LDE4LDI1MCwyNTEsOTEsMTQ2LDIzMSwxODAsNDMsMTg1LDEzNCwyNCw1NSwxMzMsMTE2LDE1MCw2LDIxNywxMDQsOTMsMTk4LDEzNSw2MCwxNywxMjMsMjYsMTgzLDU1LDQyLDIyOSwxOTQsMzksNDUsMTM0LDkyLDI1NSw1MCwxOTMsMjE5LDIwMCwyMiwyMzEsODgsNDYsMjksMTgwLDc0LDkzLDIyNSwxNzgsMjE3LDEzOSw0MCwyMzYsMjM0LDEzLDE2NSwxNTEsMTU2LDY2LDExNCwyNSw2MCwzOSw0NywxMDQsMTY3LDg5LDEsMjI0LDE1MCwxNCwyNywxNjYsNDYsMTgwLDE0OCwyMDcsMTYsNzcsMTIzLDIzMiwyOSwyNTAsMjE2LDMwLDQyLDczLDE2OSwzNiw5Niw3NSw3NSw4NSwxNTQsOTQsMjQsMTQsNiwxNzEsMTQ0LDE4OSwyMzIsMTQ0LDIyMywxNTQsOTIsOTYsMjQ4LDIyLDE1LDE2NiwxMDMsMTk2LDk4LDQ5LDIzOSw2NCwxNzEsMTc4LDIxMCw3OSwyMzUsMjA0LDEwMCwxNyw4OSwxNDgsMTcsMTY2LDEwMCw4NSwxLDE0NiwxNjIsMjQsMTIwLDE2LDIzMCwyMDMsMzcsMTY0LDI2LDY5LDExNCw1MSwxOTgsMTI5LDY5LDE0Nyw4NywxMjMsMTk3LDE1NCw3MSwyMjgsMjE5LDMwLDY0LDMsMTAwLDIxNSwxOTgsMTU3LDE1OSwxLDI1LDY4LDQyLDQ2LDUyLDU4LDQ5LDE3NywyMTAsMjA1LDE0OCw4Nyw2Niw3MywxMDcsODUsMTIxLDE3MCwxOTcsNDIsMzcsMzUsMTU3LDE0NCw5OSwyMDQsODksOTEsMTgzLDE4MywxMTUsMTQ0LDEwOCwxNywyMCwyMTUsNzcsMjM3LDE0NywxNDUsMjUxLDk4LDE1LDksMTIsMTg3LDEwLDE5MiwxNTcsMTE0LDIzLDYwLDEsMjQwLDk1LDIwNSwxODgsNTQsMjQwLDMzLDE2MCwxMjUsMjI0LDE5NiwxMzksMTYwLDg0LDIxNywxNjYsMTA1LDExOSwxMTYsOTYsMjA4LDE2NywxODYsMTY4LDQzLDE5MiwyMTMsMjMwLDE0LDI5LDEwLDUxLDYwLDE0NSwxODgsNDYsMTIxLDE5OCwzMCw1OCwxNjMsNCwyNDcsMTEwLDcyLDE4Miw4Niw4Niw1OCwxNTksMTk3LDUxLDE1NywxMDUsMzQsMTM0LDE4MCwyOCwxNzMsMTk0LDEzMiwxMDYsMjQ3LDEzMSwxOTcsNjgsODMsMTAwLDI0NCwyNDQsNTAsMzgsMjEwLDI5LDY4LDI1MiwzNiw3MCwyNDksNjUsNTEsMjEyLDgyLDE4NSw5MCwxNTIsMTM0LDM5LDEzMSw0OSwxODgsNiwxMDUsOTgsMTgzLDcyLDEwNSw5MiwyMzYsNjQsMTM4LDQwLDE5LDI5LDE1LDYwLDk4LDgxLDExNyw2NSw4NywxNTYsMTAsMTk4LDE4NiwxMzYsMTc5LDI0NCwxNzYsNDUsMjYsNTUsMjMyLDE5NCwxODcsOTUsODIsMTQ1LDUsMTAwLDcxLDIwNiwxMzAsMTk4LDEwNCwyMzQsMTg5LDIsMjI1LDIxLDEyNywzNiwxNCwxMiwxNjcsNSw2NSw1MCwxNTIsNDgsMTQwLDU4LDM2LDIxOCwxMjQsMTk4LDYsMjA2LDE2OSwxMDIsMTA2LDE3Niw1NiwxOTIsMTc3LDE0NSwxNzMsNjMsMzgsMTE1LDE3LDI0OSwxNCwxOTcsMjExLDE4Niw5MiwxMCwxNjgsNTUsNjUsMTA5LDIxNiwyMDEsNTQsMiwxMjIsMTEsMzMsNCwxNzcsNTEsOTAsOTgsNzUsMTEyLDEyNCw1Miw0Miw0MSwxMjcsMzYsMTUyLDczLDgsMTIwLDc5LDE4Myw2OSwxNzgsMjIwLDE1MiwyMTEsNzYsMTY1LDQzLDkxLDYyLDEwNCwxMzIsNzEsNDAsMzgsMTQ5LDI0MywxMjAsMjA3LDIyMiwxMzUsMTc4LDE5NSwxMzIsMTQ0LDQ1LDE2NCwyMywxNDAsODksNDcsMTYwLDEwLDEwOSwxNDAsMjA5LDEwNiwxMzgsMTQ0LDE2OSwxNDMsMTIsMywxOTEsNzQsMTU5LDE5NiwyMjUsMTAxLDIxNywyMTAsMTU5LDE1MywyNDAsMjYsMjUxLDI1MSw1LDEyLDExOSwxMjMsMTA2LDE3MCwwLDE3NSw3MCw5NiwxNDksMjA4LDgsMjIsNjYsMTkxLDIwNiwxMzYsMTAwLDEsODYsNDUsMTU0LDM3LDE4OSwxMTIsNjcsMTU0LDMxLDI1LDk1LDQwLDE2OSwxNjEsMTExLDE2NCwzNSwyMjgsMTM3LDU3LDEyNCwyMzQsODgsOTIsNzQsNTAsMTQ4LDYwLDE2Nyw1MCwyMDgsNTcsODMsMjMxLDEwNiwyMDAsMTEyLDMxLDc5LDExOSw4OCwxNDYsMTIyLDI2LDEwMywyMSw0MCwxNTAsMTM4LDE5MiwxNTcsMzUsMTAyLDEyMiwxMjksMTQ2LDEyNCwyMjcsODAsNjQsMTY1LDU5LDEyOSwxNTUsMywxODksOTAsMjgsMTk5LDE1Miw5MywzLDExMiwxMzksMTksODksMTYwLDEwLDE2MCwxMzYsOCwyMjcsMTg3LDE3NCw1NywxNTIsMjEsODQsOTcsNzUsMTgxLDExLDcxLDIwOSw4MiwxMjQsMzIsNDYsMjgsMjQ2LDQ0LDEyMSw4MCw2MSwxMTcsMTA1LDkwLDIzMSwxMzIsMzUsMTkzLDcxLDE0NiwxNTgsMjcsMTc5LDIzOCw4MywxMDgsNjksODksMTg4LDIyOSwyMjQsMTEwLDIzNywxMTUsOTQsMTU5LDIwMCw1MywxMjgsMTkyLDEyNSwxMzMsMjUyLDE5OCwyNDgsMyw0LDAsMTk5LDEyMCwxNjUsMTgzLDE3NywxMzgsOCwxNjgsOTcsMjI1LDksMTk5LDQwLDEyMSw2MCwyMDQsMTQsMjQ4LDIxMCwyNSwyMzUsODEsMTQsMjE3LDEyOCwwLDE0MSwxOTQsMTI0LDE5OCwyNDksMTgwLDYsNjUsMTE4LDEzMywxNTAsNjYsNzgsOTAsMTU1LDMwLDcxLDE2MiwxNjUsODcsNjgsMTQyLDk4LDE5OCwxNTgsODQsNDEsMTUwLDM1LDEzOSwxMCw5LDE0NCw4LDEzMywxMDIsNzAsNzEsNSwyMDAsNjksMTIzLDE5MSwxNjEsMzgsOTEsMjEyLDMyLDI1MiwyNDcsMTYyLDIxNywxMDUsMTgwLDkwLDE0MCwxNDYsMSwyMTMsMTYwLDQ3LDEzNSwxNTgsMTAyLDExOCwyMywyNTIsMTcwLDc0LDcxLDc1LDUsMjM0LDUsNjUsMjI4LDEwNywzNiw4NywxMCwxMTIsOTcsMzksMTE1LDIxNiwzMiw1OSwxODIsMTM5LDU5LDE3NCwyLDIzLDMwLDEwNyw3NCw1NCwxNjgsMTUwLDkyLDIxMiwxOTEsMTI1LDEwMywxNTUsMTQzLDE0NiwzOCwxODQsOTcsMzIsMTE0LDE5NSw3MCw0OSw5NiwxODEsMTAyLDIyOSwxOCwxNjcsMTc5LDEzNSwxNjMsMjUsOTMsMjcsMTMzLDkwLDE5Myw1MywxNDMsMTEyLDM5LDEyOCwxOTksMjgsMTczLDIwOCw0OCw1NCwxMjgsMTYyLDQ4LDQ5LDM5LDEyNCwyMzQsMjQ2LDE4NSwxMzIsNjQsNjgsOTgsMTgwLDExNSw5NiwxLDE4OCwzNCw4Myw5OSwxNDgsMTQ3LDE0OSwxODAsMTcsMTMwLDE3NSw5LDQ1LDIxLDY4LDE0MSwxMDYsMTk1LDY2LDIwMiwxNjEsNTMsNzksMjA5LDI3LDExMCw2OSw1Myw4NywxNzcsMTc1LDI5LDI0NiwyMDUsMTEyLDIzNSwxMTMsMjM1LDEwMSw0MiwyMTMsMTE5LDQsOSwyMzYsNDIsNjAsMTQ2LDEyOCwxNTcsMTg4LDU2LDIxMywzNiwzMCwyMzEsMzksMTk1LDIyNCw0OCwxNzMsMjExLDQ0LDExNSwyMjUsMTg2LDkzLDM0LDc0LDE5MCwxMzMsOTIsMTYxLDExOCwyNiwxOTcsMTQwLDM3LDU2LDQ5LDM3LDI2LDEwOCwyNDMsMTE0LDI1MSwyMjcsMTIsMyw1Nyw1MSwyMjAsMTQ1LDIyLDIzMiw0MCwyOCwzOSwxMzUsMTY5LDE2NiwxNzYsMjQsMTU1LDE4LDEyNiwyMSwxOTgsMTgzLDI1LDc2LDc0LDE0MywzOCw2NSwyMjUsMTYwLDExLDE3MSwxNTQsOTYsMzgsMTIyLDI5LDcsMTY4LDE3Nyw2MCw1MSwxMTksMjI5LDEwNiw4OSwyMiwxNiwxMjEsMTYxLDEzMCwxMDMsMTAyLDI4LDI4LDIyNSwxMDAsODYsMTUsNTAsNzUsMTk0LDQwLDE0MSwxMzksMTE1LDg2LDQ3LDMsNTcsMTcyLDEzNSwwLDIsMjM1LDIwMSwxNDcsMTcyLDE2NSwxNTIsMTY2LDE0MiwxNCwyNTIsNDcsMjAxLDQyLDE0NywxMzEsMjA0LDUwLDQxLDE5LDE3OSw2LDU2LDEyMCwxMiwyMzAsMTYzLDk5LDEyOCwxNiwxMDEsMTg4LDEzNSwyNTQsMjMyLDEzNywxMTMsNDMsMTkyLDIyNSwxMTIsMjAwLDE2MCwyMCwyLDI1NCwxODMsMjEsMjgsNTUsMTM2LDYwLDIzNSwxNTcsNzQsMzYsMTM5LDIyNiw4NiwxMzAsMjU1LDIyNSwxNjcsMTg4LDQ5LDkxLDE3NCwxNDAsMTI5LDMsODQsMTAwLDExNSw0Myw3NSw0LDEyNCwxMzUsNDUsMTYzLDM4LDQ0LDE1NiwxNDAsMTE3LDE4MCwxNzEsMTgwLDI4LDE5Miw1MCwxMjgsMTI3LDc3LDE5LDE3OCwxMzAsMTM0LDEwNywxODksMTcwLDc0LDIzMywxMDUsMTIzLDI0NCwxMjAsMjA3LDEzMiwxMjMsMTc1LDE3OCwxOCwxODQsMjI0LDM5LDIxLDE4MSwxMDIsMTk1LDIxOSwxNjIsMTEsMzYsMzUsMTE2LDY2LDIxLDE2NSwxNDEsMTAsNDYsMTIzLDE3LDE5Miw3MiwzOCwxODMsMTg5LDE4MSwxNzEsMjUxLDE4Myw5Niw3MSwxMzQsNDYsMzAsMjQ4LDQ0LDYzLDEwOCwxMTUsODAsMjIwLDE0MCwxMjUsMzUsMTMyLDIyNSwyMiw1LDEwOCwyOCwxNzgsNjMsMTk4LDExMSwyMzYsODUsMTc5LDE0OSwxLDE4MywxNDMsMTYyLDEzOSwyMiw4MCw0NiwyMzYsMTM5LDYxLDEwOCwxMzMsMTMsMTc1LDI4LDE3OSwxNjMsMTgxLDczLDE5LDEwMSw0Nyw1NSwyNDUsNCwxMTIsMTAwLDQsMTY3LDIyNCwxMjUsMTUwLDE0OSwyMDEsNSwxMjksMTc5LDIzNCwyMDMsMTM3LDU0LDkxLDEwMSwxMTksMTcxLDk4LDc1LDk5LDY1LDg1LDEyOSwxOTQsOSw5LDEzMCw0LDU1LDEzNSwxNjMsMTUzLDUxLDEzNywyMSwzMiwyMTIsMzksODAsMTE3LDU0LDk1LDc3LDIwMywxMTksMTIxLDE1NCw3LDIxNCwxNDQsMTIyLDczLDEzMSwxNjYsMTI4LDE3NywxODgsMTgzLDEsMTc0LDE1MSwxODUsNjUsNjAsODYsODAsOTksNTksMTQsMjQsNjYsNDAsMjIxLDY4LDQ3LDY1LDY1LDE3NywxMzEsMTkyLDE0NCw0Nyw3LDM3LDMzLDc2LDE2NywyNTQsMTY3LDEyMSwyMjIsMTY2LDE1NCw2Myw5NywxNTksMjQwLDE2OSwxMzYsMjMzLDEyMiwxMTgsNTcsMTEyLDE5OSwxMzEsMTc3LDI4LDUxLDE0MCwxODMsMTExLDI1MiwxNTksOTQsNzYsNTMsMTMwLDQxLDE3MiwxMTQsMTE5LDEzMCwxOTUsMTI0LDU2LDEyMiwyMzAsMTAsMTA4LDExMywxMzUsMTY3LDE1NSw0Nyw3NywxMDcsNjksODQsNzAsMTA5LDI1LDE2LDExNywxNjcsNzIsMTM5LDEzLDEwMywxNTQsMjcsMjEwLDYyLDQzLDAsMTI2LDE4NCwyMDgsMTAwLDQxLDI0MCwxODUsMTYyLDIxMSw1NCw1NiwyMDcsMTE2LDQzLDExNywxOCwyMTAsNDIsMjUwLDIxMSwyNTAsMTEyLDEzNywxMTcsMjQ3LDE1MCwxMTMsNDMsMTczLDIyNCwxODEsNTQsMjUxLDUyLDEzMywxMjIsNzcsMzEsMTM1LDIwNywyMDUsMjM1LDE2NSw1NiwyMjYsMjI2LDY4LDI0OCwxNCw1MSw4OCw3LDIxMyw5NCwxNTEsMiwxNjcsMjAsMTYyLDU4LDczLDM4LDE4LDUzLDE0NCwyMDAsMjYsMTA2LDEyMiwyMDQsMjMwLDEzNSwxMDQsMjAyLDEzLDIwMywxMDIsMTg1LDIwLDI1MywyMTksMTI2LDEzNCwxODIsNjMsMTk2LDUsOCw1OCwyMSwyNDAsNTIsNDgsMjA0LDc0LDExNSwxOTIsMTcwLDI0Myw2MiwyNDQsMTg3LDUyLDMwLDIxMywxNTQsODAsMTg4LDI0MCw1NywyMjIsNiw3OCw5LDQsMTkyLDgwLDE0MCwxODIsMTU1LDIxMCwxMiwxMDEsMTczLDE1MCwxODMsMjQ2LDIwNCwxNjQsMCwxNiwxNCwxNDcsNTQsNCwxMjYsMTQ4LDE2MSwyMjQsMTM0LDU0LDEzMCwyMzMsMTA4LDIwNywxNTUsMTUzLDk3LDY3LDc5LDkyLDQwLDIwNiwyMTYsMjQzLDg3LDIwLDMxLDIyMSw2NSw4MSwyMDYsMTc5LDI1MSw0NywzNiwxMCwxMzEsMTc1LDUwXX19fV0AAAAAAAAAWgAAAAAAAAMmRXBvY2hTZWNyZXRzeyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJpbml0X3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTg0LDUxLDcxLDk2LDE3NSwyMTEsMTk4LDQsMTg3LDUzLDE0MiwxNzksMTUxLDksMzAsNjksMTQ3LDIwOSwxOTMsMTc5LDE4OCwxMzgsMTYyLDE4NCwxOTEsNjcsMTY1LDE2MiwxOTQsNjEsMjQ2LDE2M119fX0sImV4cG9ydGVyX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTkxLDIxOCw0Myw2NiwxNDQsOTIsMCwyMzAsMjI2LDMzLDE4OSwxNjUsNjksMSwyNTAsMjQ0LDI4LDIwMiwxNzMsMjI4LDkxLDg1LDEwMywyNDksMTI3LDQ1LDEwLDk5LDIyOCw4MywwLDEwNF19fX0sImVwb2NoX2F1dGhlbnRpY2F0b3IiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6Wzk2LDEyNiwyMjgsODQsMjA4LDEwNywxMDEsOTQsMTU5LDg0LDIzNywxNjMsNTksNDQsMTMxLDIxNywyNDcsNTYsMjE4LDEyMSwxMTQsMjU1LDMxLDY3LDcyLDM0LDEsNjcsMTYsMTY2LDE2Miw2NV19fX0sImV4dGVybmFsX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTgsMjE1LDQyLDIxNSwyNDUsNjMsMTM2LDEyMywxMiw0NiwxMjksMjA0LDUwLDE0OCwyMzQsMjIyLDQ0LDM2LDE2OCwxNjIsMjA3LDEwOCwyNSwxMzgsMTA5LDIzNSwxNTQsMiwyNDUsMzAsMTMxLDldfX19LCJyZXN1bXB0aW9uX3BzayI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbOTIsMzAsMTgsMzYsMTc2LDIyMCw0Niw0MywxOTAsNyw0NSw3OCwyNDEsMTAyLDE0MywyNDYsMjcsMTYsMTYwLDIyNCwyNCwxMTQsMjUsNTQsMTI4LDIyNywyMiw1Miw2MywyMDYsMTAyLDExXX19fX0AAAAAAAAA7AAAAAAAAAEeU2lnbmF0dXJlS2V5UGFpcnsidmFsdWUiOlsxNjQsMTgwLDEyNSwxMjYsNzksMjIwLDIyMSwyNTMsMTIzLDQyLDIwMSwxMjAsMTgwLDE2NCwyMDAsMjA4LDE3Nyw5OSw4Miw2MCw1NSwxNTYsMTI2LDc3LDExNywxMTUsMjAzLDIwMywxNDIsMjU1LDE2NiwzNCw4MiwxMTcsMTE1LDExNiw2NywxMTQsMTIxLDExMiwxMTYsMTExLDgzLDEwNSwxMDMsMTEwLDk3LDExNiwxMTcsMTE0LDEwMSw3NSwxMDEsMTIxLDgsN119AAF7InByaXZhdGUiOlsxODAsODQsNzIsMjQyLDEzNSw4LDE1OSwxNDcsOTksMTUsMTEsMTc3LDE0NiwxODUsMjI5LDE2LDE1NCwyMDMsNzUsMTM0LDUyLDIxOCwxNzYsNDEsMjUxLDE3LDE4Nyw2OCwxOSwxMjQsMzEsMjIwXSwicHVibGljIjpbMTY0LDE4MCwxMjUsMTI2LDc5LDIyMCwyMjEsMjUzLDEyMyw0MiwyMDEsMTIwLDE4MCwxNjQsMjAwLDIwOCwxNzcsOTksODIsNjAsNTUsMTU2LDEyNiw3NywxMTcsMTE1LDIwMywyMDMsMTQyLDI1NSwxNjYsMzRdLCJzaWduYXR1cmVfc2NoZW1lIjoiRUQyNTUxOSJ9","AAAAAAAAAA8AAAAAAAAAWgAAAAAAAAJiR3JvdXBDb250ZXh0eyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJwcm90b2NvbF92ZXJzaW9uIjoiTWxzMTAiLCJjaXBoZXJzdWl0ZSI6Ik1MU18yNTZfWFdJTkdfQ0hBQ0hBMjBQT0xZMTMwNV9TSEEyNTZfRWQyNTUxOSIsImdyb3VwX2lkIjp7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19LCJlcG9jaCI6MiwidHJlZV9oYXNoIjp7InZlYyI6WzIxNywxMTcsMTIxLDE4NiwxMTMsMTA4LDE2MCw5MSwyNSwxNjgsMjUzLDU4LDE4NywyMTQsMjQ4LDExMCwxNjcsMjUzLDQ5LDkwLDU4LDEwNCwxMzgsMSwyMCwxOTksMjUxLDIyNywxODksNDksMjAyLDE4MF19LCJjb25maXJtZWRfdHJhbnNjcmlwdF9oYXNoIjp7InZlYyI6WzE3LDIzOCwyNDgsMjQsMjM5LDE3OSwxNCwyNDEsMTg5LDAsMTUsMTQ0LDEwNCwxNyw4NiwxMTMsMTg3LDU3LDkxLDIwMSw3NCwyNDgsOTksMjU0LDc2LDIzMCwxMyw1MCwyMjEsMTQzLDc3LDUwXX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbeyJSZXF1aXJlZENhcGFiaWxpdGllcyI6eyJleHRlbnNpb25fdHlwZXMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FsX3R5cGVzIjpbXSwiY3JlZGVudGlhbF90eXBlcyI6W119fV19fQAAAAAAAABdAAAAAAAAAItDb25maXJtYXRpb25UYWd7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAF7Im1hY192YWx1ZSI6eyJ2ZWMiOlsxMCwyNTIsMTk4LDE0NiwxMTYsMzMsOTUsNSw4OCwxNTEsMzMsMTU1LDI0NiwyMzAsOTUsMTIxLDU4LDEwMCwxMjAsMTAxLDIyNyw0NSwyMDQsMjQ4LDIxNywyMjQsMTMwLDE2OCwxMyw5NywxMzEsMjA2XX19AAAAAAAAAFwAAAAAAAAGO01lc3NhZ2VTZWNyZXRzeyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJtYXhfZXBvY2hzIjowLCJwYXN0X2Vwb2NoX3RyZWVzIjpbXSwibWVzc2FnZV9zZWNyZXRzIjp7InNlbmRlcl9kYXRhX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMjAyLDExNywyNDcsMTAwLDY5LDIyMSwyMDMsMjEsMjA4LDE1OCwxMTEsMjQ5LDE2NSwzOCwyMzgsNDQsMTczLDE1MCwyMTEsMTQyLDIxMywyOSw5NiwyMDAsMTEwLDI1MSw0MywxOSwxODIsMjQ2LDI0Niw4XX19fSwibWVtYmVyc2hpcF9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE5MCwyNDUsMTEyLDE2MCwzMiwxMyw5OCwxNDAsNTMsMTA2LDIwLDIxNiwyMjksMTcwLDg3LDE5Myw0MywxMzgsOTgsMTQxLDEzMSwyMjEsMTYxLDEwMyw2MSwyNTAsOTAsNjEsNTYsMTEzLDEyMiwyMzVdfX19LCJjb25maXJtYXRpb25fa2V5Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOls0NCwyNDMsNTAsMTE0LDYzLDE3NiwxODcsOTIsMTEzLDQ3LDE1MiwyNSwzNiwxNzYsMjI5LDExNCwxODYsMjUyLDcyLDIyMiw3Miw3Miw5NCwxNDMsNjMsODMsMCwxODgsNDEsMjQ5LDIwMSwxNDhdfX19LCJzZXJpYWxpemVkX2NvbnRleHQiOlswLDEsMCw3NywxNiwyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMiwwLDAsMCwwLDAsMCwwLDIsMzIsMjE3LDExNywxMjEsMTg2LDExMywxMDgsMTYwLDkxLDI1LDE2OCwyNTMsNTgsMTg3LDIxNCwyNDgsMTEwLDE2NywyNTMsNDksOTAsNTgsMTA0LDEzOCwxLDIwLDE5OSwyNTEsMjI3LDE4OSw0OSwyMDIsMTgwLDMyLDE3LDIzOCwyNDgsMjQsMjM5LDE3OSwxNCwyNDEsMTg5LDAsMTUsMTQ0LDEwNCwxNyw4NiwxMTMsMTg3LDU3LDkxLDIwMSw3NCwyNDgsOTksMjU0LDc2LDIzMCwxMyw1MCwyMjEsMTQzLDc3LDUwLDgsMCwzLDUsMiwyNDAsNjYsMCwwXSwic2VjcmV0X3RyZWUiOnsib3duX2luZGV4IjowLCJsZWFmX25vZGVzIjpbbnVsbCx7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOls1NiwxNDcsMjE4LDI5LDE1MywyNTMsMjUzLDE1OSwxNDcsMCwzMSwyMTEsMjAzLDgsMjA0LDE1NiwxNzIsMTM0LDE5OSwyNTAsMTA4LDI0NCwxNDAsMjEzLDI0OSwyMjUsMjUsMTY1LDEzMiwxMDAsMjAsMjM3XX19fV0sInBhcmVudF9ub2RlcyI6W251bGwsbnVsbF0sImhhbmRzaGFrZV9zZW5kZXJfcmF0Y2hldHMiOlt7IkVuY3J5cHRpb25SYXRjaGV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyMTYsMzAsMzcsMjI2LDI1MiwxODAsMTUyLDEwNiwxMyw0NiwyMSwxOTIsMTc0LDE0MiwxMzcsMTAsMTA4LDE5MiwyMjgsNSwxMzIsMjM3LDIwNywxNjcsOCwxNDgsMTYxLDQsMTI1LDM0LDE2MCwxNjZdfX0sImdlbmVyYXRpb24iOjF9fSxudWxsXSwiYXBwbGljYXRpb25fc2VuZGVyX3JhdGNoZXRzIjpbeyJFbmNyeXB0aW9uUmF0Y2hldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbNzksMjUwLDI1MywxNDgsMjE0LDE2Nyw0OSwxNTUsNjksMTY1LDE4MCw5OSwyMDIsMTQzLDE2OSwxNzcsMzUsMTIwLDUyLDE3LDExMiwyMjMsMjUyLDE2MSwxNTMsMTY3LDE3MiwxNzcsNjYsMTAyLDE1LDEwXX19LCJnZW5lcmF0aW9uIjowfX0sbnVsbF0sInNpemUiOjN9fX0AAAAAAAAAXgAAAAAAAAABT3duTGVhZk5vZGVJbmRleHsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AATAAAAAAAAAAXwAAAAAAAAGcUHJvcG9zYWxRdWV1ZVJlZnN7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAFbWzEyMywzNCwxMTgsOTcsMTA4LDExNywxMDEsMzQsNTgsMTIzLDM0LDExOCwxMDEsOTksMzQsNTgsOTEsNDksNTcsNDQsNDksNTMsNDQsNDksNDgsNTUsNDQsNTAsNTEsNDksNDQsNTAsNDgsNDksNDQsNTcsNTYsNDQsNTAsNTIsNTIsNDQsNTEsNTAsNDQsNDksNTUsNTEsNDQsNDksNTUsNTcsNDQsNTUsNTEsNDQsNDksNTMsNTMsNDQsNDksNTIsNDQsNTIsNDQsNTEsNDksNDQsNTEsNTYsNDQsNTAsNTEsNTcsNDQsNDksNDksNTQsNDQsNDksNTQsNTIsNDQsNDksNTYsNTIsNDQsNDksNTAsNTMsNDQsNDksNDgsNTAsNDQsNDksNTAsNTIsNDQsNDksNTEsNTEsNDQsNTcsNTIsNDQsNTIsNTMsNDQsNTEsNTQsNDQsNTAsNTIsNDgsNDQsNDksNTEsNTEsNDQsNDksNDksNDgsNDQsNTAsNTMsNTEsNDQsNTIsNTIsOTMsMTI1LDEyNV1dAAAAAAAAAFgAAAAAAAAADUdyb3VwU3RhdGV7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAEiT3BlcmF0aW9uYWwiAAAAAAAAAFIAAAAAAAA6WFRyZWV7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAF7InRyZWUiOnsibGVhZl9ub2RlcyI6W3sibm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOlszNCwyMTMsMTI2LDEwMiwxODAsMTk3LDcsMTE5LDUsMTQ4LDIzMSw1NywxNTYsODgsMTU0LDI3LDEwMSwxLDExNiwxMzIsNTQsNTgsODMsMTMwLDI0NywyNDcsNzMsMTc4LDQsMTQ0LDEyNiwyMTYsMTA1LDIzMiwxNDAsMTMsMjMyLDIyNiwxOCwyMzEsMTYzLDIwNywxNTgsMjMwLDEwNiw4MSw1LDQzLDExOCw4MiwyLDcwLDQwLDQsMjA2LDE4NywxNTgsMTk5LDExOCw4MCw1NiwyMjQsMzksMjE5LDExOCwxNTMsMzcsMjQ1LDI1LDQ2LDIyOSwxOTMsMTMzLDUyLDIwNCwxNTYsMzUsMjA0LDIzOSwxMjQsMTczLDIyMCw2NSwxNjQsMTk4LDE2NiwxNSwyMiwxMDQsMTkyLDY5LDIzNiwxNDgsMTA2LDE3OSwxNzUsMzksOTYsMTgsMjcsNTUsMTgxLDM3LDE2LDYwLDE5LDE3OCwxMTIsNzMsMjE3LDE4MywxNzksMTA4LDE0OSwyMzAsMTcyLDIwNSw5OCwxMjAsMTQyLDI1MywxNywxNzAsNjcsMTE3LDE5NiwxODIsMTcyLDEwMSwyMzYsMTcwLDEyMSwxODYsNTcsNzcsMzMsNjYsMzIsNzMsMTE3LDE3MiwxMjIsMTUwLDEzNCw4MCwyMjAsOTIsMjM5LDIyOSw5LDczLDIxOSwxNjgsMzMsMjUxLDMzLDk3LDE3MSwyMDQsNjYsMTQwLDYzLDM1LDE1MywxODksMjI5LDEwNiwxMzksMTAxLDE1NSwxODUsMTYwLDIxMCwzOCw1MCw0MSwxODMsNjksNTksMTYwLDQ5LDExMiwxNjgsMjM0LDEzNCw5LDIwMywzNiwxOTksMTYyLDEwOCw1MSwxNzQsMjQxLDEyNyw3MywxNzIsMTg3LDUxLDI2LDE1MiwxNzMsMTQ5LDgwLDg1LDU4LDE2NSwxODIsODcsMjAwLDIwNywxMjksMTI2LDEzNSwxMTksMTY1LDMwLDIzMSwxMzUsMjI0LDE5MywxNjgsMCwxNjEsMTM4LDYwLDI0OCwxMCwxODYsNDgsMzEsOTMsMTc4LDcsMTk3LDE5OSw1NCwyNDQsMTUwLDE1NywwLDEyMSw2OCwyNDAsMjQ3LDExMCwxNDksNjksMTEyLDE3NywxMCwxOTgsMjQ5LDEyMywxNTMsMTI4LDE5MiwyMywyNiw1Niw3NCwyMjcsMjE3LDk3LDEzMiwxODMsMTUsMjIsMTIwLDE3NSw5Myw0OCwxOCwxMTgsMTc4LDEzLDIzMiwxOTIsMTMxLDE1OCwxNzYsMTE3LDEyMCwxNjUsNTIsMjM5LDIyNiwxODUsMzYsMTE1LDEyMSwxNTksMTYwLDkyLDEyMSwxNDYsMTA2LDE3MSwxOTksOTMsMjMyLDIzLDM1LDI2LDMsNDAsNTIsNSwyMDYsMTgyLDIzMyw3NCwxODQsOTAsNiwyNDYsMTg3LDUsMTk1LDE4MCwxNyw5NSwyNDIsMTA5LDE2NCwzNywxNDYsODMsMTk3LDEsMzIsMTcxLDEyNiw4Myw4OSwxMDMsOSw3Niw5LDE3NCw2OSwxNjUsOTMsMTgzLDksNzMsMTYwLDExMSwxMjgsMTIsMTQ5LDE5OCwyNDgsMTE3LDAsMjgsMiwxNjcsMjM1LDIzLDczLDk3LDExNiwxMTMsMTUwLDE0NSwxNjksNywyMDUsMTEzLDE0Nyw3LDEzOCwxODAsOCw5NywxMDAsMSw5NSwxNjQsNTAsNTYsNjgsMTcyLDI0NCw2LDEzMCw4LDE5LDE3OCwxMTAsMjQxLDE1MiwxMzYsMTM0LDE5Niw1NiwyMDEsMTk2LDIwOCw1Myw4OSwxMzIsMjI2LDU0LDIyNCwyNiwyNywyMiwxNzgsOTIsNDYsNDIsNjksMTAwLDU2LDExOCw4MywzOCwxOTgsMCwzNyw4NiwxMTgsMjI1LDQsNDcsMzMsMjMsMjA4LDE5MiwxMDQsMTAsNzMsNzcsMjE3LDExNywxNCwxNjUsMjEzLDE1MywzOCw4MywxNTAsMTM3LDI0MywyMDAsMjM3LDE3LDM0LDEyOSwxNzgsODcsNTMsMTQ5LDE1MCwxMTcsMTM0LDE4Niw3NCwyMjYsMTQyLDEyMCwyMTEsMTAzLDc3LDE0OSw3NSwzMSwyMzAsMTU1LDE2MSwyMjgsNyw1OCwxNjcsMTQ2LDE3NCwxMzMsNiwxOTgsMjEsNTAsMTQ0LDI1MiwxNDMsMjQ4LDk4LDQsMTYsMTM5LDIwNCwxMyw0OSwxMTIsODIsMTgyLDYsOTIsMTY5LDcxLDgwLDY0LDQ1LDE0MSwzOSwxODEsMjA0LDEzMywxNjYsODUsNDEsMTQsMjAzLDIyOSw1MSwyNTQsMjIsMTUyLDYwLDE5OSw4Miw0MiwxODYsMzcsMzMsMjYsMSwyMzYsNzIsMTU1LDk5LDEyMSwxNTksMjIwLDIxLDE2NiwxMTIsNjcsNDQsNDMsMTYsMzYsMTU3LDE0MCw0NCw1NywxNDYsNTIsMTAsMTY2LDE0MywxNDUsMzIsODAsMTU0LDkyLDAsNjQsNDgsMTQwLDIyOCwxOTIsMTcxLDE3MywxNzAsMTk2LDQ3LDEwNCw3NSwxMDQsODAsNTAsMTU3LDEzNiwyOSwxMjcsMTM4LDQ1LDUsMjE0LDIyLDcxLDExNiw2MSwyMTcsMjgsMjcsOTQsMTI5LDYsMTIsNzYsMTQ2LDkwLDU5LDEyNCw0NiwxNjYsODYsMjA4LDgzLDE5NSwyNDgsMTE1LDU4LDE1OCwyMTYsMTM4LDIyNywxMTQsNywyNDQsMzksMjYsMjcsMjMyLDM1LDk2LDIzLDgsMjAsMTUwLDg4LDEwMiwxMTgsMTczLDEwMywxNTEsMTI4LDMyLDEzMiw0NiwxMzksNjQsMTY4LDI0MCwxNDQsNDYsNCwyMSw2NywzLDIyOSwxNTQsNjgsMTE5LDcwLDEwOCwyNDgsMTc4LDIwNSwxODUsMSwzNCw2Nyw0MiwxNDksODEsMTUzLDEzNSwxMzksOTksMjM1LDE4MSwxLDE2OSwyNiwyMiwyMDYsNTAsMTYsNTUsMTYsOSwxLDAsMTk1LDIzNCwxODUsMjAzLDI0MCwxOTcsMTAxLDI0MywyNDQsOTcsMTc4LDIwMiwxODcsNDAsMzksMTQ0LDEyMiw3LDYxLDE2OCwxLDE2NSwxNzYsNzQsMTI0LDE2OSwxMzksMTYxLDE0NywyMTgsMTgzLDExMywyMCwyNiwxMjAsMTAsMTA5LDEyMiw4MSwxMDEsMTIzLDExNCwxNDIsOTYsMTU0LDE3NCwyMjgsNzEsNzEsMjQ2LDIzMCwxMTgsNzUsMTM0LDIwNiw4OSwyMDEsMTEwLDIzNywxNzksNDAsMTYzLDIwOSwxODcsOTksMCw1NCwxMDMsMTYxLDcyLDIyMCwxMiwyMDYsMTM1LDExNCwxMTQsMTYzLDM2LDE1OCwxMjEsMTAxLDU0LDE1MiwzMiwxNjcsMTE4LDExLDE5NCw4Nyw4NywyMDIsNTIsMjA4LDIwMCwyNTQsMjQ1LDEzLDIwMCwyMiwxNDksMjA1LDEwNSwxMjEsODAsMTY3LDM1LDEwOCwxMzIsMTUxLDIwOSwxNzAsNjIsMTczLDE0OSwxODIsNzksMjMsMTYsMSw2OSwxMDksMTYsMjUyLDE2NCw2OSwyNDIsMTkxLDI4LDUsMTI0LDMwLDE2MiwxNjEsNzAsMzIsMTk5LDEwNiw2OSwyMDMsOTcsMjUwLDgzLDIyNCwyMDQsMTkxLDE5MSwyMzUsOTksMTI4LDU3LDE1MCwxMzcsNTcsMTQ2LDEwMywxNTMsMTQzLDcxLDU1LDEwMSwyMDQsMTU1LDc3LDUsMjI2LDI0LDQ4LDEzNCw2NSwxMywyMDksMTgxLDQwLDgzLDEwNiwyMzQsMTE5LDY5LDUwLDE2MywzOCw3MiwyMDIsODksMTY4LDgsMjAzLDIyMiwyNDcsMTE3LDEzMiwxMjMsMTE1LDExNiwyNDUsMTg5LDM1LDE2OSwxNDIsMTIzLDQsMTI4LDQxLDIyNywxMTYsMTQwLDEwMiwxMSwyNDIsMjI2LDE4Miw0Myw1MiwyMDEsMTM2LDE3OCwxODQsMTU3LDQsMTMxLDk1LDUzLDcyLDIxMiwxODEsOTQsMjM4LDIxNiw2OCwyMDMsMzYsMTE1LDM4LDIwOCwxOTgsMjE5LDE0OCwxNjMsNzEsMTMwLDExMSwzNywxMzIsMTk0LDk2LDkwLDEwOCwxNzMsMCwxNjQsMTYwLDI0MCwxNjgsNiwxOTYsMzMsMTIyLDE5NSw3LDEyNSwyMTEsOTcsMTY4LDIzMCwxNzcsOTksMTcyLDEzOSw5OSwxMjksODEsMjU0LDE1NCwxNDYsNCwxNjMsMTE3LDQwLDcsMTIxLDE1MCwxMDcsMjQsMTczLDIwOSw2Nyw2NCwxNzIsMTg1LDYwLDI2LDE5NCwxMjIsMTg1LDE3Myw0OCwyMzYsMTEwLDI1MywxNzgsMTUsMjUzLDIzMiw1MCwxODksMTUxLDE0MCwyNDIsMTc4LDEyMCwyMzcsNzYsMTc5LDIxOSwxMzksNjUsMTk4LDU5LDYsMTg3LDIzMywxNjIsNDYsMTk3LDkzLDYsMTgwLDksMjE2LDI1MiwxOTUsMjQwLDI0LDE2OSwxNTQsMTk2LDE2MywxMjMsMjMzLDQ5LDM1LDEyMywxMCwyMTEsNCwxOTMsNTMsMTk1LDQ1LDU3LDE1NSw3Miw5MSw0MSwxNDMsODQsMjUsMiwxMjgsMTM1LDE4NSwxNTYsNTAsMTk1LDIzMyw4NiwxNjAsMTE2LDg1LDE4LDcyLDE2MiwzOSwxOTcsMjQwLDE3NSw2NSwxNTUsMTI5LDQyLDIxMiw5LDYxLDMsNTEsNzUsMTc2LDU1LDEzOCwxMzUsMjA3LDIzLDEyOCwxMzIsMTY2LDIxMiwxNTcsOTAsMTE2LDk3LDEwNCwyNDMsMTAsMTUwLDE0MCwxNjIsMTY2LDg1LDEzNCwxNTcsMzIsMTIzLDI1MSwxMDMsMTgzLDIxNCwxNzAsMTQsMjQ4LDcyLDE4OSw1MiwxNjQsMTg1LDY4LDE0NCwxMDIsNywzNywxMDYsNTIsMjIwLDE1NSwyMTAsODIsMjA3LDc3LDI0NSwxOTcsMjUsNTIsMjcsMjA5LDI1MSwyMSwxOSwxOTUsNjIsODksMTM4LDMwLDgzLDQsMTQ0LDc4LDI0Myw4NCwxMjksMjMyLDEsMjE3LDE0OCwxMDEsMTY4LDEwMiw4Nyw5OSw2NiwxNzIsOCwyLDE1NSwyMTUsMTA4LDUzLDEyOSw4MywzNCwxOTcsMTI4LDMwLDIyMCw5NiwxMjMsODMsMzcsMzcsMTQ4LDY2LDE0OSwxOTEsNTMsNTYsMTYwLDExMiwxNzcsMzgsMjE5LDIyOCwxNSwxNDUsMTQ0LDE4Nyw2MSw0NCwxMjEsMjcsMjI3LDQyLDMxLDUsMTk4LDE2NiwxNjMsMjE2LDE4NSwxNTUsMTk1LDE2OCwxMDgsMTY0LDIzMCwyNCwzNiw1Nyw2NCwxMTUsMTMyLDEwNSwyNDAsMjEsODIsMjMsMyw4MywyMTMsMjA3LDIzMiw2MF19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNjQsMTgwLDEyNSwxMjYsNzksMjIwLDIyMSwyNTMsMTIzLDQyLDIwMSwxMjAsMTgwLDE2NCwyMDAsMjA4LDE3Nyw5OSw4Miw2MCw1NSwxNTYsMTI2LDc3LDExNywxMTUsMjAzLDIwMywxNDIsMjU1LDE2NiwzNF19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJDb21taXQiOnsidmVjIjpbNjcsMjQxLDE2NiwyMjIsMTAsMTUzLDIzOSwxNTQsMTQxLDQ3LDMxLDE0MiwyMjMsMTc4LDI0Myw1NywxNTcsMTIyLDE1NiwxMDIsMTksMTE2LDIwMSwyMTcsMjQ3LDIyOSwxMTgsMTY2LDE0MywzNiwxMjgsMjM0XX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzIxOCwxMDUsMTQxLDE4MiwyMDAsMjI0LDE3MiwxMTAsMTI2LDE5LDEwMSwyNiwyNDcsNDUsMTk1LDE3MywyMTMsMTYyLDg0LDIyOSwxMDksOCwxNzMsMjUxLDE0NSwyMTgsMjQyLDMyLDAsMjE0LDIsMTAsMjQ0LDIwNiwzMywwLDUwLDI0Nyw4MSwyMDksNDIsMCwxMjMsMjA2LDIxMiwzNCw4Miw3NCw1OSw3MywxODcsMTM5LDIxLDY1LDE3NywxMjgsMTE3LDE3NSwxMTcsODQsMTQzLDIzLDE1OCw3XX19fX0seyJub2RlIjp7InBheWxvYWQiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzcwLDE4MCwxMzgsNzEsMjQyLDEwOCw2MywyNDAsMTg5LDE5OSw0MSwxMTAsODksODksMTk1LDE0NSw4OSw3NCwzMywyMTMsMTQsMTY3LDkxLDEwMywxNjMsNjYsNywyMTAsMjM2LDksNTAsMjQwLDEwMCwxNTMsMTAxLDI4LDg1LDksMTYsMTYzLDE3NywxMjAsNjQsMjQ3LDExLDksMTMzLDk1LDE1OCw4OCw2MiwxNDUsMjUyLDEwOSwxMzQsMjMwLDkyLDIzMiwyMDQsMTAxLDIxNyw2MCwxNjksMTI2LDkyLDIwMywyMzgsODYsMjEsMjMzLDg0LDQ1LDE1NSwxMjksNDIsMTM3LDE1MCw1OCwxMDgsNDEsMTYxLDExMywxNDgsMTc1LDg2LDE1NiwxNiw5OCw3NSwxMzgsMTIyLDcsMzMsMTM1LDkxLDc3LDI0MiwyMywxOTEsMjQzLDQ4LDksMjUsMTAwLDQ0LDI0OCw3MywxMjQsNzEsNzQsMTQ3LDIyMCw0OSw0MywyMjgsNTEsMTg2LDEyMCw5NiwxODksMTc1LDM4LDExNSwxMDgsMTEyLDE2MiwxMDMsNTgsNDcsOTQsMjQ2LDQ4LDI0Niw2NiwxMDksMCw2Nyw2NywyMjksMTQ3LDY0LDEzNywzLDE2MywxMTksMTc5LDYzLDEwNSwyMzEsNDYsMTgwLDk4LDEzMSw4OCw0OCwxNDYsMTA0LDIwOCwxMzQsNiwyMCw1LDcsMjMzLDE0NiwyNDgsMTM1LDExNSwxNjcsODEsNzMsMTE5LDEzNyw4MSw5MCwxNzcsNDMsMTY3LDIyLDQ5LDIxLDI1LDExNiwzMywxMzAsNjIsMTEwLDIxNywxOTUsMTU2LDEwLDE3MiwxMzAsODYsNTgsMjEzLDU4LDEyOCw1Miw2NywzMywxNiwyMTksODMsOCw0LDE4MCwxMTksMTc2LDE5NywxMDcsMyw3OSwyMTYsMjQ0LDEwOCwyNDIsMzksNjQsMTY3LDI0OSw0NiwyMzksMTM2LDE2MSwxODAsMjI4LDE2NywxOTMsNSw0MSwxNTYsMTQ5LDEzOCwyMjAsMTQ3LDE0NywxMDcsMTI4LDY1LDgzLDE4MiwxMzIsMjUxLDIzNSwxNjAsMTk0LDIyOCw3OSwxNTIsMTQ1LDE3MCwxNDYsMTIyLDE2LDIwNiwxNzgsNjEsODQsMjE5LDIxLDksMjUxLDE4OCwyMTcsNjcsMzUsMTQ3LDIzMiwyNyw4NiwxNiwxMTAsMTMzLDE1Myw2MywzMCwxOTMsMjAxLDg4LDIzNSw3MiwyNTQsMTY3LDIxLDkzLDg1LDUsNjIsMjQ3LDc2LDE0LDg3LDEwNCwxNzYsMTY0LDEzLDE1NCwyMTUsMTA0LDEzNiwxMzIsMTQyLDU2LDIzMSw5NiwxNTksMTY4LDI0LDE2NywxMDEsMTQyLDEyNyw5MiwxMywyMzYsNjUsNTUsMTAwLDE3NiwxNDAsMTY5LDY3LDY4LDY4LDcyLDExNCwxOTcsMjExLDExOSw5MiwxMzgsMTk3LDIxMCwxOTksMTMyLDE2Niw1MCw1NCwxNDYsMTE1LDQwLDM4LDE3LDY4LDIzNiw0Myw4NSwxOCw4OCwxNDksMjQyLDgyLDgyLDIwMCw5NywxODAsOTcsNTEsOCwxMTcsMTk4LDExNywyMDEsMTYwLDU1LDExNiwxOTMsMTQwLDE0OCwxNyw0LDYyLDUzLDExNywyMTgsNTQsNzcsMTY3LDIxNCwxMSwyMDEsNDEsMSwxNSwxODYsMTcxLDIyNyw0NCwzNiwxMSwxOTksMjA0LDM2LDI0LDE3OSwyMjAsNTMsOTksMTgwLDEzNCwxNiwxNzgsMjI4LDQyLDE3OCw2OSwxNTEsMjA3LDEyMCw4MSwyMDIsMTE4LDE2MywxMDUsMjA0LDU0LDU5LDE5MywxMDQsMjAwLDE2OCwxNzYsNzMsMjUwLDY3LDI0NSwxNzIsMjksNzMsMTAxLDExMCwzOSwxMDQsMjUsNTksMTMzLDkyLDc1LDEwMSw4NSwxMzksMTE4LDE3NSwzNSw3LDEwNywyMTQsMTIsMTU0LDI0Niw1NiwyMCwxMDksNTMsNDgsNzksNzIsMTEyLDE1Niw4LDkxLDI1MiwzMiw3MSwxNzcsMjQzLDEzOSwxODQsMTk2LDEzNSw3Miw2NywxMjEsNDYsMjQ0LDEzMCwxMjEsMjQ4LDE1NSwyMjUsMiwxMDgsMTY4LDUwLDEwOCwxLDEwMiw1Nyw1OCwxNTAsMTI2LDEyMCwxMDUsNDgsOCwxOTksMTAsMTYwLDE4MSwxMzIsMywxMjMsNTMsMTYyLDE3LDE5MywyMDIsMTg4LDE0OSwyMjUsMjYsODMsMTMyLDExNSwxMDcsMTg2LDExMyw5OSwyOSwyNTIsNTQsMjQ3LDE1MywxNjUsMTQ4LDE0NywzOSwzMCw0OSw2Niw5NywxNjIsMTMwLDQsMTA1LDE2MywyMDAsNzMsMjA2LDc0LDE4Myw2Miw4NiwxNjYsMTg4LDEwMywyMjAsNTgsMTgwLDE2Miw1MCwxMTksMjA5LDExNSwxNjksNjQsMTMwLDEwLDkwLDQ3LDc0LDgsMTYwLDM3LDY0LDExOCwxOTMsMTUwLDEyLDQxLDI1MSwxMSw3NSwxNjQsMTMyLDE5NywyMzYsMTQ2LDIzNiwxMzQsMTMyLDI0MCwzOSwxMDYsMjQ0LDI0NSwyMCwxMzQsMjI1LDgxLDI1LDE0MCw3MiwyNTIsMTM3LDI4LDUyLDEzMSwxNjUsMTcyLDEwOCwyMDMsMjgsMjA4LDc3LDIyMCwxODMsNzYsMjA4LDczLDM4LDIzNiwxODAsMCwxOTksMTE5LDM4LDM5LDQ5LDYwLDQzLDIxNywyOCwxNiwzNiwxODAsMjM1LDExOSwxMjksMTcwLDcxLDE4OSwxNzcsMTM5LDcxLDE1MiwxMjAsMTc2LDEyNiw1OCwxMTQsMTMyLDczLDUwLDE5Niw3LDE3NCw0NSw4NCwxMDMsNzAsOTEsMTgyLDEzNSw2OSw5NSwxODUsMjUwLDEzNSwxNjYsMTYyLDE0NywxOTQsMTk3LDExNCw5MiwyNyw5OCwyMzQsMjMyLDE0MywxMDAsMTQ4LDEzNCwyMDgsMjI3LDMwLDUzLDI0OCwxMTAsMTc1LDI0NCwxODYsMzIsMTI0LDcsMTY4LDI0MCw1MSwyMDMsMjQ5LDIyLDYsMTk0LDcwLDExMSwyMSwxMTgsMywxOTIsNDIsMTc3LDI0MCwxNiwxMTcsMTgxLDI3LDQxLDIwMiwxNSwzOSw2NiwxODEsMjAxLDY2LDg3LDE3OSwxMjksMTAwLDExNCwxNDQsNzcsMTI2LDkyLDIwMiwyMjAsNjQsMTE3LDE0MiwyOCwxMzIsMjE2LDI0OSwxNzcsNTEsMTUwLDEwMiwyMzksMTIzLDMwLDE5LDgwLDIwNCwxNjAsMjMsMTM3LDExNiwxNTYsMTI1LDEyOCwxMzEsOTksMTg4LDYsMjAsMTQ0LDE1MywyNCwyMjcsMjEzLDgwLDI0OSw0MSw2Nyw2NSwxLDQyLDI0NCwxNDYsMTI5LDE4Myw4MywxLDE5NCwxNjQsMTQsMTcxLDE4NCwxMjQsMTI4LDExNyw3MywxMTQsNDksMTc3LDE5Myw4NCwxNTUsMTUyLDAsNTgsNTksMjQ1LDEyMSwxMjcsMjEzLDEzMCwxMDYsMTc5LDcsMjE5LDE2OSwyOCw3MiwxMTcsNSwxOCw5MCwxODQsMjQwLDgyLDE3MCwyNTAsMjQ1LDYzLDQwLDE4Miw2OCw4NCwxNTUsMTc0LDUxLDE3NiwxMjgsMTAwLDExLDE1MSw4NSwyNTAsMTg2LDExNiwyNywyNSwxNTYsMTcxLDUxLDE2NCwxOTcsMjAzLDE4NywxODAsNDYsMTQ3LDIxNSw2NCw3MCwxMTYsMTYsMjE3LDIyOSw5OCw1MSwxNTAsMTQ3LDIxNiwxNzcsMTQ2LDE5MSwxNTMsMTQzLDM2LDIzLDMxLDIxOCwxOTksMTYyLDIwLDIxMiwxMCw3MCwxNjQsNTQsMTYsNjUsMjQsMTE5LDE3Niw0LDIwOCwxNTEsMTg4LDUxLDcxLDE4OSwxMDksMTY2LDE1NiwyMTEsMTU2LDE4NywxOTgsMTM4LDUzLDEzOSwxNTQsNDMsODcsMTUwLDQ5LDE3OSwyNDAsNTEsMTEwLDExOCwxMzIsMjEwLDkwLDEzMCwxNTQsNjQsMTMwLDIxMywyMjcsMTg2LDUxLDEwNywxOTEsOTEsMTU0LDQ3LDEzNCwyMDgsMjA1LDIxMywyMTIsMjA2LDUsMTI4LDE4NywxMDcsMTMzLDEwMSwxOTEsMTE1LDE4LDEzOCwxMDUsMjcsOTgsMjI1LDEzMywyMTgsODEsMzgsMTE5LDIxNyw0OCwxMzYsMjEwLDIwNCwxMjAsMTY3LDcyLDk3LDEzNSwxMDYsMjAzLDM0LDE2LDQ1LDE1NCwxOTAsOTIsNTEsNDYsMjA5LDk2LDE4MCwxNjgsMTAwLDQwLDI1MCwxOTIsMTQ3LDIxOSwxMDUsMTgzLDg3LDQzLDE1OSwxODUsMjQ3LDUzLDIzOCw0NCwxODAsNDYsMTgsMjgsMjE2LDE2NSwxMDEsMTYwLDIzMSw1Myw2MywxMTIsMTAzLDIxNywxODYsMTAyLDEyOSwxOCwxNDEsNzYsMTE5LDczLDIxMiw4MCwxNDcsMTU3LDk4LDEyNSwxMjIsMjAzLDU3LDI1LDE5NywxNSwxODcsMjE5LDMsMTI1LDgyLDEwMyw0MCwwLDQ3LDIyOSwyNSwxMTcsMjQ2LDIwLDE5MiwzLDIwMCwxLDE4MCwxNTAsMjA1LDIwMSw1NCwxMDYsMTgxLDExMyw0Myw4Myw0Myw1NCw3MiwxMDUsODAsMjUsNTksMzcsMTc1LDIxNCwxMjMsMzMsMTUzLDExLDIyMSwxOSwxMzEsMTMyLDI0MCw4MCw5NSwyNTEsNCwyNTQsMjUwLDgwLDEzMywxODcsMTgyLDExMiwyNDUsNzUsMTI0LDEwNywxMjEsNCwyNDAsMTk4LDI0MCwxNjIsNzIsMjI4LDI1MiwxMjAsNzcsMCw3MiwxODEsMTk4LDI5LDEwMiwzNywxODEsNDUsMTk3LDk3LDE1LDIzLDE4NCwxNjgsMTAyLDUxLDY0LDExNSwxMTMsMjM3LDIyNSwxMzgsODksMiwxMjgsMjM5LDE4MSwxNzUsMTAyLDIxMSwxNjAsNTQsMTgyLDM1LDIzMyw1MCw5LDEwNCwxMDAsMTMxLDI2LDg1LDQ4LDE1Nyw2Nyw2OSw3MywyMDMsMTI4LDQsMTcyLDE1OSwyNDMsNzQsMTQyLDE5NiwxNjksMTksNzksMTUyLDIsNiwzMCwxMzIsMTcxLDEwMywyMjEsNywyMTEsMTY5LDc4LDIzNSwyMDYsNjksMjgsMjUyLDEzLDY5LDEyNSw2NCwyNTQsMjQ3LDE3LDE2MCwyMCwyMDIsMTQ2LDAsMjMyLDAsMTIsMTcxLDk2LDc2LDEzMywxMzQsMjQzLDU5LDI0MCwxNTAsMTQ5LDk1LDIwOSwyMTksMTk5LDczLDE4OCwxMDUsMTAzLDEwMSwxODUsMjQ1LDEzLDk1LDIyMiwyMDQsMTYyLDQ1LDEzOSwzMiwxMDUsNV19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyMzksMjM3LDI1MSwxNTIsMjMxLDE0MCwyNTIsMzMsMjM3LDE3NCwyNDIsMjQxLDEyNCwxMDMsMTMwLDI0LDc2LDEwNiwxNDUsMjI3LDAsNTEsNjgsMTEyLDE2MCw0Niw0Miw0OSw4MiwyMzMsNzcsMTE3XX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTgsMTExLDk4XX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJLZXlQYWNrYWdlIjp7Im5vdF9iZWZvcmUiOjE3MjA2ODg5NTAsIm5vdF9hZnRlciI6MTcyNzk1MDE1MH19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzIyMiwxNzksMywzMiw5NCwxMjcsNjYsMjQ5LDE4OCwxMDcsNzcsMTg2LDEyNiwxODksMTM1LDUyLDY4LDQwLDE3MiwxMTAsMTM1LDI0NCwyMDgsOTUsMTY3LDIyMywxNzcsMTgyLDE2MCw0NiwxLDQ1LDEwOCwxOTEsNzIsMTE5LDE5NiwyMiwxNTAsMTk0LDUzLDIyLDIwMyw5MSwyMjMsMjA0LDE1MSwxNDQsMTI2LDIwMywyNDksMTIxLDYyLDQ1LDQsMTQ0LDg5LDI3LDE4MCw4NCwyMzYsNjYsNTksMV19fX19XSwicGFyZW50X25vZGVzIjpbeyJub2RlIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOlsyMzcsMTQ3LDE0NSwyNTEsOTgsMTUsOSwxMiwxODcsMTAsMTkyLDE1NywxMTQsMjMsNjAsMSwyNDAsOTUsMjA1LDE4OCw1NCwyNDAsMzMsMTYwLDEyNSwyMjQsMTk2LDEzOSwxNjAsODQsMjE3LDE2NiwxMDUsMTE5LDExNiw5NiwyMDgsMTY3LDE4NiwxNjgsNDMsMTkyLDIxMywyMzAsMTQsMjksMTAsNTEsNjAsMTQ1LDE4OCw0NiwxMjEsMTk4LDMwLDU4LDE2Myw0LDI0NywxMTAsNzIsMTgyLDg2LDg2LDU4LDE1OSwxOTcsNTEsMTU3LDEwNSwzNCwxMzQsMTgwLDI4LDE3MywxOTQsMTMyLDEwNiwyNDcsMTMxLDE5Nyw2OCw4MywxMDAsMjQ0LDI0NCw1MCwzOCwyMTAsMjksNjgsMjUyLDM2LDcwLDI0OSw2NSw1MSwyMTIsODIsMTg1LDkwLDE1MiwxMzQsMzksMTMxLDQ5LDE4OCw2LDEwNSw5OCwxODMsNzIsMTA1LDkyLDIzNiw2NCwxMzgsNDAsMTksMjksMTUsNjAsOTgsODEsMTE3LDY1LDg3LDE1NiwxMCwxOTgsMTg2LDEzNiwxNzksMjQ0LDE3Niw0NSwyNiw1NSwyMzIsMTk0LDE4Nyw5NSw4MiwxNDUsNSwxMDAsNzEsMjA2LDEzMCwxOTgsMTA0LDIzNCwxODksMiwyMjUsMjEsMTI3LDM2LDE0LDEyLDE2Nyw1LDY1LDUwLDE1Miw0OCwxNDAsNTgsMzYsMjE4LDEyNCwxOTgsNiwyMDYsMTY5LDEwMiwxMDYsMTc2LDU2LDE5MiwxNzcsMTQ1LDE3Myw2MywzOCwxMTUsMTcsMjQ5LDE0LDE5NywyMTEsMTg2LDkyLDEwLDE2OCw1NSw2NSwxMDksMjE2LDIwMSw1NCwyLDEyMiwxMSwzMyw0LDE3Nyw1MSw5MCw5OCw3NSwxMTIsMTI0LDUyLDQyLDQxLDEyNywzNiwxNTIsNzMsOCwxMjAsNzksMTgzLDY5LDE3OCwyMjAsMTUyLDIxMSw3NiwxNjUsNDMsOTEsNjIsMTA0LDEzMiw3MSw0MCwzOCwxNDksMjQzLDEyMCwyMDcsMjIyLDEzNSwxNzgsMTk1LDEzMiwxNDQsNDUsMTY0LDIzLDE0MCw4OSw0NywxNjAsMTAsMTA5LDE0MCwyMDksMTA2LDEzOCwxNDQsMTY5LDE0MywxMiwzLDE5MSw3NCwxNTksMTk2LDIyNSwxMDEsMjE3LDIxMCwxNTksMTUzLDI0MCwyNiwyNTEsMjUxLDUsMTIsMTE5LDEyMywxMDYsMTcwLDAsMTc1LDcwLDk2LDE0OSwyMDgsOCwyMiw2NiwxOTEsMjA2LDEzNiwxMDAsMSw4Niw0NSwxNTQsMzcsMTg5LDExMiw2NywxNTQsMzEsMjUsOTUsNDAsMTY5LDE2MSwxMTEsMTY0LDM1LDIyOCwxMzcsNTcsMTI0LDIzNCw4OCw5Miw3NCw1MCwxNDgsNjAsMTY3LDUwLDIwOCw1Nyw4MywyMzEsMTA2LDIwMCwxMTIsMzEsNzksMTE5LDg4LDE0NiwxMjIsMjYsMTAzLDIxLDQwLDE1MCwxMzgsMTkyLDE1NywzNSwxMDIsMTIyLDEyOSwxNDYsMTI0LDIyNyw4MCw2NCwxNjUsNTksMTI5LDE1NSwzLDE4OSw5MCwyOCwxOTksMTUyLDkzLDMsMTEyLDEzOSwxOSw4OSwxNjAsMTAsMTYwLDEzNiw4LDIyNywxODcsMTc0LDU3LDE1MiwyMSw4NCw5Nyw3NSwxODEsMTEsNzEsMjA5LDgyLDEyNCwzMiw0NiwyOCwyNDYsNDQsMTIxLDgwLDYxLDExNywxMDUsOTAsMjMxLDEzMiwzNSwxOTMsNzEsMTQ2LDE1OCwyNywxNzksMjM4LDgzLDEwOCw2OSw4OSwxODgsMjI5LDIyNCwxMTAsMjM3LDExNSw5NCwxNTksMjAwLDUzLDEyOCwxOTIsMTI1LDEzMywyNTIsMTk4LDI0OCwzLDQsMCwxOTksMTIwLDE2NSwxODMsMTc3LDEzOCw4LDE2OCw5NywyMjUsOSwxOTksNDAsMTIxLDYwLDIwNCwxNCwyNDgsMjEwLDI1LDIzNSw4MSwxNCwyMTcsMTI4LDAsMTQxLDE5NCwxMjQsMTk4LDI0OSwxODAsNiw2NSwxMTgsMTMzLDE1MCw2Niw3OCw5MCwxNTUsMzAsNzEsMTYyLDE2NSw4Nyw2OCwxNDIsOTgsMTk4LDE1OCw4NCw0MSwxNTAsMzUsMTM5LDEwLDksMTQ0LDgsMTMzLDEwMiw3MCw3MSw1LDIwMCw2OSwxMjMsMTkxLDE2MSwzOCw5MSwyMTIsMzIsMjUyLDI0NywxNjIsMjE3LDEwNSwxODAsOTAsMTQwLDE0NiwxLDIxMywxNjAsNDcsMTM1LDE1OCwxMDIsMTE4LDIzLDI1MiwxNzAsNzQsNzEsNzUsNSwyMzQsNSw2NSwyMjgsMTA3LDM2LDg3LDEwLDExMiw5NywzOSwxMTUsMjE2LDMyLDU5LDE4MiwxMzksNTksMTc0LDIsMjMsMzAsMTA3LDc0LDU0LDE2OCwxNTAsOTIsMjEyLDE5MSwxMjUsMTAzLDE1NSwxNDMsMTQ2LDM4LDE4NCw5NywzMiwxMTQsMTk1LDcwLDQ5LDk2LDE4MSwxMDIsMjI5LDE4LDE2NywxNzksMTM1LDE2MywyNSw5MywyNywxMzMsOTAsMTkzLDUzLDE0MywxMTIsMzksMTI4LDE5OSwyOCwxNzMsMjA4LDQ4LDU0LDEyOCwxNjIsNDgsNDksMzksMTI0LDIzNCwyNDYsMTg1LDEzMiw2NCw2OCw5OCwxODAsMTE1LDk2LDEsMTg4LDM0LDgzLDk5LDE0OCwxNDcsMTQ5LDE4MCwxNywxMzAsMTc1LDksNDUsMjEsNjgsMTQxLDEwNiwxOTUsNjYsMjAyLDE2MSw1Myw3OSwyMDksMjcsMTEwLDY5LDUzLDg3LDE3NywxNzUsMjksMjQ2LDIwNSwxMTIsMjM1LDExMywyMzUsMTAxLDQyLDIxMywxMTksNCw5LDIzNiw0Miw2MCwxNDYsMTI4LDE1NywxODgsNTYsMjEzLDM2LDMwLDIzMSwzOSwxOTUsMjI0LDQ4LDE3MywyMTEsNDQsMTE1LDIyNSwxODYsOTMsMzQsNzQsMTkwLDEzMyw5MiwxNjEsMTE4LDI2LDE5NywxNDAsMzcsNTYsNDksMzcsMjYsMTA4LDI0MywxMTQsMjUxLDIyNywxMiwzLDU3LDUxLDIyMCwxNDUsMjIsMjMyLDQwLDI4LDM5LDEzNSwxNjksMTY2LDE3NiwyNCwxNTUsMTgsMTI2LDIxLDE5OCwxODMsMjUsNzYsNzQsMTQzLDM4LDY1LDIyNSwxNjAsMTEsMTcxLDE1NCw5NiwzOCwxMjIsMjksNywxNjgsMTc3LDYwLDUxLDExOSwyMjksMTA2LDg5LDIyLDE2LDEyMSwxNjEsMTMwLDEwMywxMDIsMjgsMjgsMjI1LDEwMCw4NiwxNSw1MCw3NSwxOTQsNDAsMTQxLDEzOSwxMTUsODYsNDcsMyw1NywxNzIsMTM1LDAsMiwyMzUsMjAxLDE0NywxNzIsMTY1LDE1MiwxNjYsMTQyLDE0LDI1Miw0NywyMDEsNDIsMTQ3LDEzMSwyMDQsNTAsNDEsMTksMTc5LDYsNTYsMTIwLDEyLDIzMCwxNjMsOTksMTI4LDE2LDEwMSwxODgsMTM1LDI1NCwyMzIsMTM3LDExMyw0MywxOTIsMjI1LDExMiwyMDAsMTYwLDIwLDIsMjU0LDE4MywyMSwyOCw1NSwxMzYsNjAsMjM1LDE1Nyw3NCwzNiwxMzksMjI2LDg2LDEzMCwyNTUsMjI1LDE2NywxODgsNDksOTEsMTc0LDE0MCwxMjksMyw4NCwxMDAsMTE1LDQzLDc1LDQsMTI0LDEzNSw0NSwxNjMsMzgsNDQsMTU2LDE0MCwxMTcsMTgwLDE3MSwxODAsMjgsMTkyLDUwLDEyOCwxMjcsNzcsMTksMTc4LDEzMCwxMzQsMTA3LDE4OSwxNzAsNzQsMjMzLDEwNSwxMjMsMjQ0LDEyMCwyMDcsMTMyLDEyMywxNzUsMTc4LDE4LDE4NCwyMjQsMzksMjEsMTgxLDEwMiwxOTUsMjE5LDE2MiwxMSwzNiwzNSwxMTYsNjYsMjEsMTY1LDE0MSwxMCw0NiwxMjMsMTcsMTkyLDcyLDM4LDE4MywxODksMTgxLDE3MSwyNTEsMTgzLDk2LDcxLDEzNCw0NiwzMCwyNDgsNDQsNjMsMTA4LDExNSw4MCwyMjAsMTQwLDEyNSwzNSwxMzIsMjI1LDIyLDUsMTA4LDI4LDE3OCw2MywxOTgsMTExLDIzNiw4NSwxNzksMTQ5LDEsMTgzLDE0MywxNjIsMTM5LDIyLDgwLDQ2LDIzNiwxMzksNjEsMTA4LDEzMywxMywxNzUsMjgsMTc5LDE2MywxODEsNzMsMTksMTAxLDQ3LDU1LDI0NSw0LDExMiwxMDAsNCwxNjcsMjI0LDEyNSwxNTAsMTQ5LDIwMSw1LDEyOSwxNzksMjM0LDIwMywxMzcsNTQsOTEsMTAxLDExOSwxNzEsOTgsNzUsOTksNjUsODUsMTI5LDE5NCw5LDksMTMwLDQsNTUsMTM1LDE2MywxNTMsNTEsMTM3LDIxLDMyLDIxMiwzOSw4MCwxMTcsNTQsOTUsNzcsMjAzLDExOSwxMjEsMTU0LDcsMjE0LDE0NCwxMjIsNzMsMTMxLDE2NiwxMjgsMTc3LDE4OCwxODMsMSwxNzQsMTUxLDE4NSw2NSw2MCw4Niw4MCw5OSw1OSwxNCwyNCw2Niw0MCwyMjEsNjgsNDcsNjUsNjUsMTc3LDEzMSwxOTIsMTQ0LDQ3LDcsMzcsMzMsNzYsMTY3LDI1NCwxNjcsMTIxLDIyMiwxNjYsMTU0LDYzLDk3LDE1OSwyNDAsMTY5LDEzNiwyMzMsMTIyLDExOCw1NywxMTIsMTk5LDEzMSwxNzcsMjgsNTEsMTQwLDE4MywxMTEsMjUyLDE1OSw5NCw3Niw1MywxMzAsNDEsMTcyLDExNCwxMTksMTMwLDE5NSwxMjQsNTYsMTIyLDIzMCwxMCwxMDgsMTEzLDEzNSwxNjcsMTU1LDQ3LDc3LDEwNyw2OSw4NCw3MCwxMDksMjUsMTYsMTE3LDE2Nyw3MiwxMzksMTMsMTAzLDE1NCwyNywyMTAsNjIsNDMsMCwxMjYsMTg0LDIwOCwxMDAsNDEsMjQwLDE4NSwxNjIsMjExLDU0LDU2LDIwNywxMTYsNDMsMTE3LDE4LDIxMCw0MiwyNTAsMjExLDI1MCwxMTIsMTM3LDExNywyNDcsMTUwLDExMyw0MywxNzMsMjI0LDE4MSw1NCwyNTEsNTIsMTMzLDEyMiw3NywzMSwxMzUsMjA3LDIwNSwyMzUsMjI0LDEzNCw1NCwxMzAsMjMzLDEwOCwyMDcsMTU1LDE1Myw5Nyw2Nyw3OSw5Miw0MCwyMDYsMjE2LDI0Myw4NywyMCwzMSwyMjEsNjUsODEsMjA2LDE3OSwyNTEsNDcsMzYsMTAsMTMxLDE3NSw1MF19fSwicGFyZW50X2hhc2giOnsidmVjIjpbXX0sInVubWVyZ2VkX2xlYXZlcyI6eyJsaXN0IjpbXX19fV0sImRlZmF1bHRfbGVhZiI6eyJub2RlIjpudWxsfSwiZGVmYXVsdF9wYXJlbnQiOnsibm9kZSI6bnVsbH19LCJ0cmVlX2hhc2giOlsyMTcsMTE3LDEyMSwxODYsMTEzLDEwOCwxNjAsOTEsMjUsMTY4LDI1Myw1OCwxODcsMjE0LDI0OCwxMTAsMTY3LDI1Myw0OSw5MCw1OCwxMDQsMTM4LDEsMjAsMTk5LDI1MSwyMjcsMTg5LDQ5LDIwMiwxODBdfQAAAAAAAABdAAAAAAAAZhJFcG9jaEtleVBhaXJzeyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fTIwAAFbeyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOlszNCwyMTMsMTI2LDEwMiwxODAsMTk3LDcsMTE5LDUsMTQ4LDIzMSw1NywxNTYsODgsMTU0LDI3LDEwMSwxLDExNiwxMzIsNTQsNTgsODMsMTMwLDI0NywyNDcsNzMsMTc4LDQsMTQ0LDEyNiwyMTYsMTA1LDIzMiwxNDAsMTMsMjMyLDIyNiwxOCwyMzEsMTYzLDIwNywxNTgsMjMwLDEwNiw4MSw1LDQzLDExOCw4MiwyLDcwLDQwLDQsMjA2LDE4NywxNTgsMTk5LDExOCw4MCw1NiwyMjQsMzksMjE5LDExOCwxNTMsMzcsMjQ1LDI1LDQ2LDIyOSwxOTMsMTMzLDUyLDIwNCwxNTYsMzUsMjA0LDIzOSwxMjQsMTczLDIyMCw2NSwxNjQsMTk4LDE2NiwxNSwyMiwxMDQsMTkyLDY5LDIzNiwxNDgsMTA2LDE3OSwxNzUsMzksOTYsMTgsMjcsNTUsMTgxLDM3LDE2LDYwLDE5LDE3OCwxMTIsNzMsMjE3LDE4MywxNzksMTA4LDE0OSwyMzAsMTcyLDIwNSw5OCwxMjAsMTQyLDI1MywxNywxNzAsNjcsMTE3LDE5NiwxODIsMTcyLDEwMSwyMzYsMTcwLDEyMSwxODYsNTcsNzcsMzMsNjYsMzIsNzMsMTE3LDE3MiwxMjIsMTUwLDEzNCw4MCwyMjAsOTIsMjM5LDIyOSw5LDczLDIxOSwxNjgsMzMsMjUxLDMzLDk3LDE3MSwyMDQsNjYsMTQwLDYzLDM1LDE1MywxODksMjI5LDEwNiwxMzksMTAxLDE1NSwxODUsMTYwLDIxMCwzOCw1MCw0MSwxODMsNjksNTksMTYwLDQ5LDExMiwxNjgsMjM0LDEzNCw5LDIwMywzNiwxOTksMTYyLDEwOCw1MSwxNzQsMjQxLDEyNyw3MywxNzIsMTg3LDUxLDI2LDE1MiwxNzMsMTQ5LDgwLDg1LDU4LDE2NSwxODIsODcsMjAwLDIwNywxMjksMTI2LDEzNSwxMTksMTY1LDMwLDIzMSwxMzUsMjI0LDE5MywxNjgsMCwxNjEsMTM4LDYwLDI0OCwxMCwxODYsNDgsMzEsOTMsMTc4LDcsMTk3LDE5OSw1NCwyNDQsMTUwLDE1NywwLDEyMSw2OCwyNDAsMjQ3LDExMCwxNDksNjksMTEyLDE3NywxMCwxOTgsMjQ5LDEyMywxNTMsMTI4LDE5MiwyMywyNiw1Niw3NCwyMjcsMjE3LDk3LDEzMiwxODMsMTUsMjIsMTIwLDE3NSw5Myw0OCwxOCwxMTgsMTc4LDEzLDIzMiwxOTIsMTMxLDE1OCwxNzYsMTE3LDEyMCwxNjUsNTIsMjM5LDIyNiwxODUsMzYsMTE1LDEyMSwxNTksMTYwLDkyLDEyMSwxNDYsMTA2LDE3MSwxOTksOTMsMjMyLDIzLDM1LDI2LDMsNDAsNTIsNSwyMDYsMTgyLDIzMyw3NCwxODQsOTAsNiwyNDYsMTg3LDUsMTk1LDE4MCwxNyw5NSwyNDIsMTA5LDE2NCwzNywxNDYsODMsMTk3LDEsMzIsMTcxLDEyNiw4Myw4OSwxMDMsOSw3Niw5LDE3NCw2OSwxNjUsOTMsMTgzLDksNzMsMTYwLDExMSwxMjgsMTIsMTQ5LDE5OCwyNDgsMTE3LDAsMjgsMiwxNjcsMjM1LDIzLDczLDk3LDExNiwxMTMsMTUwLDE0NSwxNjksNywyMDUsMTEzLDE0Nyw3LDEzOCwxODAsOCw5NywxMDAsMSw5NSwxNjQsNTAsNTYsNjgsMTcyLDI0NCw2LDEzMCw4LDE5LDE3OCwxMTAsMjQxLDE1MiwxMzYsMTM0LDE5Niw1NiwyMDEsMTk2LDIwOCw1Myw4OSwxMzIsMjI2LDU0LDIyNCwyNiwyNywyMiwxNzgsOTIsNDYsNDIsNjksMTAwLDU2LDExOCw4MywzOCwxOTgsMCwzNyw4NiwxMTgsMjI1LDQsNDcsMzMsMjMsMjA4LDE5MiwxMDQsMTAsNzMsNzcsMjE3LDExNywxNCwxNjUsMjEzLDE1MywzOCw4MywxNTAsMTM3LDI0MywyMDAsMjM3LDE3LDM0LDEyOSwxNzgsODcsNTMsMTQ5LDE1MCwxMTcsMTM0LDE4Niw3NCwyMjYsMTQyLDEyMCwyMTEsMTAzLDc3LDE0OSw3NSwzMSwyMzAsMTU1LDE2MSwyMjgsNyw1OCwxNjcsMTQ2LDE3NCwxMzMsNiwxOTgsMjEsNTAsMTQ0LDI1MiwxNDMsMjQ4LDk4LDQsMTYsMTM5LDIwNCwxMyw0OSwxMTIsODIsMTgyLDYsOTIsMTY5LDcxLDgwLDY0LDQ1LDE0MSwzOSwxODEsMjA0LDEzMywxNjYsODUsNDEsMTQsMjAzLDIyOSw1MSwyNTQsMjIsMTUyLDYwLDE5OSw4Miw0MiwxODYsMzcsMzMsMjYsMSwyMzYsNzIsMTU1LDk5LDEyMSwxNTksMjIwLDIxLDE2NiwxMTIsNjcsNDQsNDMsMTYsMzYsMTU3LDE0MCw0NCw1NywxNDYsNTIsMTAsMTY2LDE0MywxNDUsMzIsODAsMTU0LDkyLDAsNjQsNDgsMTQwLDIyOCwxOTIsMTcxLDE3MywxNzAsMTk2LDQ3LDEwNCw3NSwxMDQsODAsNTAsMTU3LDEzNiwyOSwxMjcsMTM4LDQ1LDUsMjE0LDIyLDcxLDExNiw2MSwyMTcsMjgsMjcsOTQsMTI5LDYsMTIsNzYsMTQ2LDkwLDU5LDEyNCw0NiwxNjYsODYsMjA4LDgzLDE5NSwyNDgsMTE1LDU4LDE1OCwyMTYsMTM4LDIyNywxMTQsNywyNDQsMzksMjYsMjcsMjMyLDM1LDk2LDIzLDgsMjAsMTUwLDg4LDEwMiwxMTgsMTczLDEwMywxNTEsMTI4LDMyLDEzMiw0NiwxMzksNjQsMTY4LDI0MCwxNDQsNDYsNCwyMSw2NywzLDIyOSwxNTQsNjgsMTE5LDcwLDEwOCwyNDgsMTc4LDIwNSwxODUsMSwzNCw2Nyw0MiwxNDksODEsMTUzLDEzNSwxMzksOTksMjM1LDE4MSwxLDE2OSwyNiwyMiwyMDYsNTAsMTYsNTUsMTYsOSwxLDAsMTk1LDIzNCwxODUsMjAzLDI0MCwxOTcsMTAxLDI0MywyNDQsOTcsMTc4LDIwMiwxODcsNDAsMzksMTQ0LDEyMiw3LDYxLDE2OCwxLDE2NSwxNzYsNzQsMTI0LDE2OSwxMzksMTYxLDE0NywyMTgsMTgzLDExMywyMCwyNiwxMjAsMTAsMTA5LDEyMiw4MSwxMDEsMTIzLDExNCwxNDIsOTYsMTU0LDE3NCwyMjgsNzEsNzEsMjQ2LDIzMCwxMTgsNzUsMTM0LDIwNiw4OSwyMDEsMTEwLDIzNywxNzksNDAsMTYzLDIwOSwxODcsOTksMCw1NCwxMDMsMTYxLDcyLDIyMCwxMiwyMDYsMTM1LDExNCwxMTQsMTYzLDM2LDE1OCwxMjEsMTAxLDU0LDE1MiwzMiwxNjcsMTE4LDExLDE5NCw4Nyw4NywyMDIsNTIsMjA4LDIwMCwyNTQsMjQ1LDEzLDIwMCwyMiwxNDksMjA1LDEwNSwxMjEsODAsMTY3LDM1LDEwOCwxMzIsMTUxLDIwOSwxNzAsNjIsMTczLDE0OSwxODIsNzksMjMsMTYsMSw2OSwxMDksMTYsMjUyLDE2NCw2OSwyNDIsMTkxLDI4LDUsMTI0LDMwLDE2MiwxNjEsNzAsMzIsMTk5LDEwNiw2OSwyMDMsOTcsMjUwLDgzLDIyNCwyMDQsMTkxLDE5MSwyMzUsOTksMTI4LDU3LDE1MCwxMzcsNTcsMTQ2LDEwMywxNTMsMTQzLDcxLDU1LDEwMSwyMDQsMTU1LDc3LDUsMjI2LDI0LDQ4LDEzNCw2NSwxMywyMDksMTgxLDQwLDgzLDEwNiwyMzQsMTE5LDY5LDUwLDE2MywzOCw3MiwyMDIsODksMTY4LDgsMjAzLDIyMiwyNDcsMTE3LDEzMiwxMjMsMTE1LDExNiwyNDUsMTg5LDM1LDE2OSwxNDIsMTIzLDQsMTI4LDQxLDIyNywxMTYsMTQwLDEwMiwxMSwyNDIsMjI2LDE4Miw0Myw1MiwyMDEsMTM2LDE3OCwxODQsMTU3LDQsMTMxLDk1LDUzLDcyLDIxMiwxODEsOTQsMjM4LDIxNiw2OCwyMDMsMzYsMTE1LDM4LDIwOCwxOTgsMjE5LDE0OCwxNjMsNzEsMTMwLDExMSwzNywxMzIsMTk0LDk2LDkwLDEwOCwxNzMsMCwxNjQsMTYwLDI0MCwxNjgsNiwxOTYsMzMsMTIyLDE5NSw3LDEyNSwyMTEsOTcsMTY4LDIzMCwxNzcsOTksMTcyLDEzOSw5OSwxMjksODEsMjU0LDE1NCwxNDYsNCwxNjMsMTE3LDQwLDcsMTIxLDE1MCwxMDcsMjQsMTczLDIwOSw2Nyw2NCwxNzIsMTg1LDYwLDI2LDE5NCwxMjIsMTg1LDE3Myw0OCwyMzYsMTEwLDI1MywxNzgsMTUsMjUzLDIzMiw1MCwxODksMTUxLDE0MCwyNDIsMTc4LDEyMCwyMzcsNzYsMTc5LDIxOSwxMzksNjUsMTk4LDU5LDYsMTg3LDIzMywxNjIsNDYsMTk3LDkzLDYsMTgwLDksMjE2LDI1MiwxOTUsMjQwLDI0LDE2OSwxNTQsMTk2LDE2MywxMjMsMjMzLDQ5LDM1LDEyMywxMCwyMTEsNCwxOTMsNTMsMTk1LDQ1LDU3LDE1NSw3Miw5MSw0MSwxNDMsODQsMjUsMiwxMjgsMTM1LDE4NSwxNTYsNTAsMTk1LDIzMyw4NiwxNjAsMTE2LDg1LDE4LDcyLDE2MiwzOSwxOTcsMjQwLDE3NSw2NSwxNTUsMTI5LDQyLDIxMiw5LDYxLDMsNTEsNzUsMTc2LDU1LDEzOCwxMzUsMjA3LDIzLDEyOCwxMzIsMTY2LDIxMiwxNTcsOTAsMTE2LDk3LDEwNCwyNDMsMTAsMTUwLDE0MCwxNjIsMTY2LDg1LDEzNCwxNTcsMzIsMTIzLDI1MSwxMDMsMTgzLDIxNCwxNzAsMTQsMjQ4LDcyLDE4OSw1MiwxNjQsMTg1LDY4LDE0NCwxMDIsNywzNywxMDYsNTIsMjIwLDE1NSwyMTAsODIsMjA3LDc3LDI0NSwxOTcsMjUsNTIsMjcsMjA5LDI1MSwyMSwxOSwxOTUsNjIsODksMTM4LDMwLDgzLDQsMTQ0LDc4LDI0Myw4NCwxMjksMjMyLDEsMjE3LDE0OCwxMDEsMTY4LDEwMiw4Nyw5OSw2NiwxNzIsOCwyLDE1NSwyMTUsMTA4LDUzLDEyOSw4MywzNCwxOTcsMTI4LDMwLDIyMCw5NiwxMjMsODMsMzcsMzcsMTQ4LDY2LDE0OSwxOTEsNTMsNTYsMTYwLDExMiwxNzcsMzgsMjE5LDIyOCwxNSwxNDUsMTQ0LDE4Nyw2MSw0NCwxMjEsMjcsMjI3LDQyLDMxLDUsMTk4LDE2NiwxNjMsMjE2LDE4NSwxNTUsMTk1LDE2OCwxMDgsMTY0LDIzMCwyNCwzNiw1Nyw2NCwxMTUsMTMyLDEwNSwyNDAsMjEsODIsMjMsMyw4MywyMTMsMjA3LDIzMiw2MF19fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6WzExNSwxLDIsOTUsMjQ1LDU4LDYxLDE5NywyMDIsNjgsMjQ0LDE4OSwxMjgsMTgyLDEyOSwyMSwxODIsMTIsOTIsMjI4LDYyLDIzNCwxNzYsMTg4LDYxLDIxMCwxNDAsMjIxLDE0Niw2NiwxOTUsNzIsMjUsMjE3LDE4NiwxMTYsNTQsMTA4LDEzNCwxNTYsMTIwLDE3NiwyNCwxMTMsOTksMTAwLDk5LDIwNCwyNDUsMTE3LDE2OSw2Myw0NCwxNzQsMTUxLDIzMCw1OCwxNzQsMTA4LDIwMCwxNjcsMTgwLDYzLDIwLDk4LDEwNiwyMzQsMTcyLDEwMywxODYsMjQ2LDE2MCwyMDMsMjQ1LDEzMiwxMjksMTgyLDExNSwxNDMsMTksMTE1LDI0MCw5OSwxOTYsMjMzLDI1MCwxOTQsMjE3LDE2Nyw5NCwyMjgsNDMsOCwyMDUsMjQxLDE1NSwxNTAsNTgsMjAsMTQ2LDE5LDUyLDcxLDExOCw1LDE3MywxMiwxMjYsNjMsMzksMTgyLDI5LDU5LDE2OSwxNTUsMjE1LDIwLDQyLDI0NywxMzAsMTA2LDUyLDE3MSw5MCwyNDAsMTEzLDE2OSwxMzIsMTA2LDI0Myw0MSwxMzIsOTksMTY4LDM0LDEwMSw0OSw0Miw3MiwyMDMsOTAsMjQ0LDM5LDE1MywyMzUsMTEsMjMsMjEyLDQyLDE5NywyMTIsMTE0LDE3MSwxOTEsODIsODEsMjAwLDI0NiwxODQsMTksMjAsMTE5LDIyNiw2NiwxNzAsMjE2LDU3LDE2NSwzMSwxMjksNTAsMjAsODAsMTU2LDEwOSwxMjQsMTk3LDE1NiwxNjAsMTQwLDE2NSwxNjgsMTI0LDAsNzYsNTUsNjQsMjEsNTcsMjA4LDEwMSwxMzIsMjI0LDM2LDEwLDIyNCw0NCwxNjQsMjA2LDIyNywxMTgsMTI2LDEsMzgsMTM3LDE2NSwxMDYsMTQ1LDYsOTIsNTUsMTU0LDE4Nyw3NiwyMjksNiwyMDUsMTg3LDEwNCwyMTksMTEsMTI4LDIwNyw1MywxMDksNzEsMTM1LDk3LDI1MSw0MCw0OCwxNywxMjMsMTQ3LDExMCwxNjksMTI0LDIzNSwzMiwxNTUsMTk2LDEwNSw0NSwxOTcsMTA2LDE1NiwxMiwxMzAsMTMyLDI0NCw4NywxNyw1OSw2OCwxNywyMDQsMTM5LDU2LDY3LDgsMjA1LDcxLDY3LDEsMTA2LDIwMSwxMSwxMTcsODAsNzQsMTU5LDE1NSwxMzMsMTExLDExNywzNCwyNCw4NCw5MCw3NCwxNjUsMTM0LDQsODMsMTUxLDE1MCwxNzksMTAyLDEyMyw5NywxMTUsOTYsMjAyLDE2MCwyMTQsMjcsMjgsMTY3LDEwLDMwLDIzNCwxNTEsMTA5LDExMCw4MiwxODgsMjM3LDE3OCwxMjcsODgsMTMwLDEyOSwxODMsMjMwLDUxLDI1Myw4LDk2LDE4MSwyNTEsOTQsMTkwLDIwLDQ3LDQsMTAzLDExMSwxNjcsMTYsMTE4LDU3LDE2NiwxLDM5LDIyNSw4MSwxMDksOTcsMTg3LDE5MCwxODIsMTY2LDE1NCw3MiwxNDEsMTUsMjMwLDIwNSwyNDMsMTk2LDIwNiw0MiwzMywxOTAsMTM4LDExNCwxMjcsMTgwLDE5LDk0LDg5LDgsMTQ1LDE2NCwyNDMsMjAxLDY3LDIwNCwxNDcsODEsNzEsMjA3LDIyNywxNzEsMTU1LDU4LDExLDIxLDEyMywxOTQsMzgsMTc3LDE3MCwxODMsMjQ3LDEzNiw4LDEyMywxMzksMTQ5LDYsMTYyLDg3LDE5MywxNTAsMTk5LDE4OSwxNzYsMTQyLDI1NCwyNDUsNjEsODEsMTM3LDQyLDE1LDIsMjUsMTE1LDIwMiwxMTYsNjQsMTAyLDMzLDE4MSwxNjgsNTIsMTg4LDE3MSwxMzksNjYsMjA4LDE0NCwxNTIsMTAxLDkyLDEwMiw1NSwxMDQsMjIxLDEwNywxODEsNDAsMTg1LDgwLDE0MCwyNDYsMTY0LDIwNiw5Miw2MSwxNjQsMzUsOTMsMTQxLDE3NywxMDcsMjI0LDEzOSw3LDIxMSwxMzgsMTk3LDI4LDg3LDE0Nyw1MCwxMTYsMTQ1LDIxMCw4MCwxOCwxMDEsMTE0LDE1MywxNDMsMTc4LDEwOCwxNTYsMTUwLDE3MSwxMzAsMTM3LDE5MiwzNCw4NSw1OCwyNDMsNTEsMTk2LDI0NSwxMDMsMjAzLDE2NywyMTcsMTkyLDM3LDM0LDE0NCwxOSwxMSw1NCwyNDQsNTEsMTUzLDIxMiwyNCwxMTYsMTQyLDEwNCw5OSwyMDcsNDIsMTYwLDQ5LDEyMiw1NSwyNTAsNjYsMTA2LDk2LDIxNSw5NSwzMSwxNTEsMzUsODAsMTk0LDEzMCwxOCwxODQsMzgsMTkxLDgsMTgxLDIxMSwxODEsNzIsMTU3LDE2LDE3NCw1LDU4LDEyLDIyNywxOTIsMTg3LDExNCwxMSwxNCw4NSwxMjEsMTg4LDEwLDEwMywxNjAsMTA0LDcxLDEwNywyMTEsNjgsMTEyLDQ4LDExMiwxMzQsMTAwLDg0LDEzMyw5OCw5LDk4LDI1MSw1MSw3OSwyMDEsNTQsMTIxLDI0Myw3NiwwLDI1MiwyNDIsMTc3LDEzLDk2LDEsODgsMTM0LDQwLDI0NywxNiwxMTcsMjIxLDUzLDExMywyNDMsMjQxLDI3LDE4MCwxMzQsMzIsMjM3LDIyLDE2NCwyNTEsMTUwLDQ2LDE1NCwxMjEsMTMxLDg0LDY0LDExMCwxODYsMTU0LDQ2LDIxNiwzNSwxMDgsMTEwLDE5NywxODAsMTQ1LDE0NSwxMSw5NiwyNywxNDAsMTMyLDIxMCw3NywxMzAsMjE3LDE0MywxNCwyMDQsOTQsNjcsMTI0LDEwNyw1OCwxLDMzLDk0LDUzLDE0MSwxNiwyMzMsOTksMTkzLDEzNiw2NCw2MCwxMTksMTYxLDQ2LDExNywxODUsNTMsMTgsMTQ1LDI0MiwxMSw4MywxOTgsMjAzLDEzMyw4OCwyMjgsMTM3LDQ3LDIzMSwxNTcsMTUsMTY4LDE5OCwyLDY0LDE4NCw0NSwyNDUsMTcwLDI5LDIwMiwxMjEsNjMsMjAxLDE3MSwyMTgsNjgsMzksMTA3LDE5OSwyMDQsODEsMjUxLDQ1LDc2LDgwLDIwMiwxODcsNTIsMjEsNzMsMTE1LDE2Nyw0NSw1NSwxMzYsMTM0LDU1LDY0LDYzLDExLDk4LDE1LDE2OSwxODQsMjE0LDY0LDIwNSw2MywyNTIsMTAsMTMsMjI4LDIwNCwyMDksNjYsMTM4LDkxLDE5NCwxMDAsMjU0LDM4LDE0MSw0MywyMzAsODgsMzMsMTIsMTc4LDk2LDE5NSwyMCw4NSwxMDUsMjA0LDgxLDE0NSw1Niw0NSwyMzYsMTgwLDE2OCwxNTUsMTU3LDk0LDIxMiw2OSw5NywxMjksOTcsMjA1LDk2LDgxLDIyMSwxNTEsMjAzLDIxNCw5LDIwMiwxMzMsMTkyLDkxLDQ3LDExNiw2MSw5NSw2NCwyMDEsMjM2LDIyOCwxMzQsMjMwLDIyNiwxOTcsMTE5LDcyLDE0NSwyMjUsNDQsNjAsMzQsMTQ5LDEyNiwxNDQsMTc4LDYxLDEwMSw5MCw1NCw2MiwxMjksOTcsMjI0LDUxLDE5Myw3MSw4OCwxNywwLDQwLDE1NiwyNTMsNDAsNTgsNjcsNTMsMTcsMjAwLDIyOSw0MCwyMzcsMjI4LDE2Miw0NiwyNTEsMTgxLDIxMyw2MCwxNywxOTYsMjQzLDE2MiwyMTIsMTg1LDI0LDIzOSwxNjAsMjAxLDQxLDM1LDk3LDEzOCwyMiwxNTYsOTEsNjAsMywzMywxMTcsMjcsMjE4LDEzOCwxMzgsMjU1LDI1LDEyNSwxNzUsMTkzLDQ1LDEyNyw5LDEyOCwyNTQsMjQ4LDg1LDY2LDE4OCw0MCwxMjcsMjA4LDM3LDE0NywxODgsNDcsNjgsMjE3LDgsNCwyMDQsMTQsMTMzLDEzNCw5Myw4OSwyNTAsOTgsMTA0LDQ4LDQyLDE3NiwxNTAsMTgsMjUyLDE4Myw1NywxNDYsMTY3LDE0NSwxNjAsMTgxLDE5MCwyMSwzOCwyMSwxNDQsMzMsODUsODQsMjQ1LDg2LDgsMjE1LDEyMywzNiw5LDExOSwyMjYsNDgsOTIsMTE3LDMsMTYyLDQ4LDEzNiwxNjEsMTAxLDE5NiwyMiwzOCw1OSw3MCwzMSwyNDYsMTY4LDEwNiw5OSwxNTcsMTU2LDI0OSwxOTIsMTcxLDI1MiwxNjUsMjA0LDE0MCwxNjUsMTk5LDExOSw0OCwxMzIsMTI0LDEzNCwyMzMsMjE5LDE0NCw1MywxNTQsOTMsMTUzLDQsMTgyLDE0NCw3NCw0NywyMjksMjEzLDE5NCwxMDEsNDQsODAsMTkzLDE4OCwxNDcsMTQ0LDExNiwxMDEsMjIxLDE5NCwxNDgsMjQwLDI1MSwxOTksNCwxMTQsNjEsNzksMTIyLDkxLDE3MSwxOTgsMTg3LDEyMCwyMzIsMiwxMDIsMjIwLDEyLDE2Niw1NCwxMSwxOTEsNDksNjMsMjE4LDE3MSwxNTcsMTgsNTEsMTE4LDk0LDU3LDE0MCw4MCwzNywxMzQsNjAsOTksMTEsMTc3LDUxLDEyMSwxMTUsMTg1LDE5Miw4OCw1MywxMTUsMjMzLDE5NSw3Myw3NSwyMTgsMTQyLDIsNDIsNTMsMTM4LDM0LDg4LDE3NiwxMDAsNTIsMTMxLDY5LDE4NSw5MSwxNTYsMTYyLDI0NiwyNywxOTMsMTQsMjMzLDMwLDIwNiwxNjEsNDQsNjgsMTksNzEsMTc1LDE1MiwxNDAsNTcsMTgyLDE3LDYwLDEyMSw4NiwxMDAsMjQ1LDMzLDE3NCwxMTIsMTI0LDE4MSwyNywxNDYsMTM3LDIyOCwxMDcsMTE1LDg3LDE0NywxODUsMTE0LDY3LDk3LDEzNCwxMjIsMTE2LDUyLDUxLDIxNCwxNjUsMjAyLDYyLDAsMTYyLDMxLDIwMywyMSwxNSwxMiw4MSwxNzQsMjI5LDE4OCwxOTcsMTk3LDExMCw1NywyNDEsMTI2LDI0Miw5OCw3MSwxODMsNzIsODQsNDMsMTcsMTA1LDg0LDg1LDQ2LDExMSwyNDQsNCwzNywxNTEsNSwyMDYsMTk3LDE4LDExMyw3MSw2MCwxMjIsMjAwLDE1NiwyMjcsMTMwLDE5OCwyMzYsMTc4LDExNiwzMiw1MSw0MywxMjAsOCwxMSwxMjcsNTksMTA0LDczLDE5NSwxNzgsMzQsMjEzLDEyNiwxMDIsMTgwLDE5Nyw3LDExOSw1LDE0OCwyMzEsNTcsMTU2LDg4LDE1NCwyNywxMDEsMSwxMTYsMTMyLDU0LDU4LDgzLDEzMCwyNDcsMjQ3LDczLDE3OCw0LDE0NCwxMjYsMjE2LDEwNSwyMzIsMTQwLDEzLDIzMiwyMjYsMTgsMjMxLDE2MywyMDcsMTU4LDIzMCwxMDYsODEsNSw0MywxMTgsODIsMiw3MCw0MCw0LDIwNiwxODcsMTU4LDE5OSwxMTgsODAsNTYsMjI0LDM5LDIxOSwxMTgsMTUzLDM3LDI0NSwyNSw0NiwyMjksMTkzLDEzMyw1MiwyMDQsMTU2LDM1LDIwNCwyMzksMTI0LDE3MywyMjAsNjUsMTY0LDE5OCwxNjYsMTUsMjIsMTA0LDE5Miw2OSwyMzYsMTQ4LDEwNiwxNzksMTc1LDM5LDk2LDE4LDI3LDU1LDE4MSwzNywxNiw2MCwxOSwxNzgsMTEyLDczLDIxNywxODMsMTc5LDEwOCwxNDksMjMwLDE3MiwyMDUsOTgsMTIwLDE0MiwyNTMsMTcsMTcwLDY3LDExNywxOTYsMTgyLDE3MiwxMDEsMjM2LDE3MCwxMjEsMTg2LDU3LDc3LDMzLDY2LDMyLDczLDExNywxNzIsMTIyLDE1MCwxMzQsODAsMjIwLDkyLDIzOSwyMjksOSw3MywyMTksMTY4LDMzLDI1MSwzMyw5NywxNzEsMjA0LDY2LDE0MCw2MywzNSwxNTMsMTg5LDIyOSwxMDYsMTM5LDEwMSwxNTUsMTg1LDE2MCwyMTAsMzgsNTAsNDEsMTgzLDY5LDU5LDE2MCw0OSwxMTIsMTY4LDIzNCwxMzQsOSwyMDMsMzYsMTk5LDE2MiwxMDgsNTEsMTc0LDI0MSwxMjcsNzMsMTcyLDE4Nyw1MSwyNiwxNTIsMTczLDE0OSw4MCw4NSw1OCwxNjUsMTgyLDg3LDIwMCwyMDcsMTI5LDEyNiwxMzUsMTE5LDE2NSwzMCwyMzEsMTM1LDIyNCwxOTMsMTY4LDAsMTYxLDEzOCw2MCwyNDgsMTAsMTg2LDQ4LDMxLDkzLDE3OCw3LDE5NywxOTksNTQsMjQ0LDE1MCwxNTcsMCwxMjEsNjgsMjQwLDI0NywxMTAsMTQ5LDY5LDExMiwxNzcsMTAsMTk4LDI0OSwxMjMsMTUzLDEyOCwxOTIsMjMsMjYsNTYsNzQsMjI3LDIxNyw5NywxMzIsMTgzLDE1LDIyLDEyMCwxNzUsOTMsNDgsMTgsMTE4LDE3OCwxMywyMzIsMTkyLDEzMSwxNTgsMTc2LDExNywxMjAsMTY1LDUyLDIzOSwyMjYsMTg1LDM2LDExNSwxMjEsMTU5LDE2MCw5MiwxMjEsMTQ2LDEwNiwxNzEsMTk5LDkzLDIzMiwyMywzNSwyNiwzLDQwLDUyLDUsMjA2LDE4MiwyMzMsNzQsMTg0LDkwLDYsMjQ2LDE4Nyw1LDE5NSwxODAsMTcsOTUsMjQyLDEwOSwxNjQsMzcsMTQ2LDgzLDE5NywxLDMyLDE3MSwxMjYsODMsODksMTAzLDksNzYsOSwxNzQsNjksMTY1LDkzLDE4Myw5LDczLDE2MCwxMTEsMTI4LDEyLDE0OSwxOTgsMjQ4LDExNywwLDI4LDIsMTY3LDIzNSwyMyw3Myw5NywxMTYsMTEzLDE1MCwxNDUsMTY5LDcsMjA1LDExMywxNDcsNywxMzgsMTgwLDgsOTcsMTAwLDEsOTUsMTY0LDUwLDU2LDY4LDE3MiwyNDQsNiwxMzAsOCwxOSwxNzgsMTEwLDI0MSwxNTIsMTM2LDEzNCwxOTYsNTYsMjAxLDE5NiwyMDgsNTMsODksMTMyLDIyNiw1NCwyMjQsMjYsMjcsMjIsMTc4LDkyLDQ2LDQyLDY5LDEwMCw1NiwxMTgsODMsMzgsMTk4LDAsMzcsODYsMTE4LDIyNSw0LDQ3LDMzLDIzLDIwOCwxOTIsMTA0LDEwLDczLDc3LDIxNywxMTcsMTQsMTY1LDIxMywxNTMsMzgsODMsMTUwLDEzNywyNDMsMjAwLDIzNywxNywzNCwxMjksMTc4LDg3LDUzLDE0OSwxNTAsMTE3LDEzNCwxODYsNzQsMjI2LDE0MiwxMjAsMjExLDEwMyw3NywxNDksNzUsMzEsMjMwLDE1NSwxNjEsMjI4LDcsNTgsMTY3LDE0NiwxNzQsMTMzLDYsMTk4LDIxLDUwLDE0NCwyNTIsMTQzLDI0OCw5OCw0LDE2LDEzOSwyMDQsMTMsNDksMTEyLDgyLDE4Miw2LDkyLDE2OSw3MSw4MCw2NCw0NSwxNDEsMzksMTgxLDIwNCwxMzMsMTY2LDg1LDQxLDE0LDIwMywyMjksNTEsMjU0LDIyLDE1Miw2MCwxOTksODIsNDIsMTg2LDM3LDMzLDI2LDEsMjM2LDcyLDE1NSw5OSwxMjEsMTU5LDIyMCwyMSwxNjYsMTEyLDY3LDQ0LDQzLDE2LDM2LDE1NywxNDAsNDQsNTcsMTQ2LDUyLDEwLDE2NiwxNDMsMTQ1LDMyLDgwLDE1NCw5MiwwLDY0LDQ4LDE0MCwyMjgsMTkyLDE3MSwxNzMsMTcwLDE5Niw0NywxMDQsNzUsMTA0LDgwLDUwLDE1NywxMzYsMjksMTI3LDEzOCw0NSw1LDIxNCwyMiw3MSwxMTYsNjEsMjE3LDI4LDI3LDk0LDEyOSw2LDEyLDc2LDE0Niw5MCw1OSwxMjQsNDYsMTY2LDg2LDIwOCw4MywxOTUsMjQ4LDExNSw1OCwxNTgsMjE2LDEzOCwyMjcsMTE0LDcsMjQ0LDM5LDI2LDI3LDIzMiwzNSw5NiwyMyw4LDIwLDE1MCw4OCwxMDIsMTE4LDE3MywxMDMsMTUxLDEyOCwzMiwxMzIsNDYsMTM5LDY0LDE2OCwyNDAsMTQ0LDQ2LDQsMjEsNjcsMywyMjksMTU0LDY4LDExOSw3MCwxMDgsMjQ4LDE3OCwyMDUsMTg1LDEsMzQsNjcsNDIsMTQ5LDgxLDE1MywxMzUsMTM5LDk5LDIzNSwxODEsMSwxNjksMjYsMjIsMjA2LDUwLDE2LDU1LDE2LDksMSwwLDE5NSwyMzQsMTg1LDIwMywyNDAsMTk3LDEwMSwyNDMsMjQ0LDk3LDE3OCwyMDIsMTg3LDQwLDM5LDE0NCwxMjIsNyw2MSwxNjgsMSwxNjUsMTc2LDc0LDEyNCwxNjksMTM5LDE2MSwxNDcsMjE4LDE4MywxMTMsMjAsMjYsMTIwLDEwLDEwOSwxMjIsODEsMTAxLDEyMywxMTQsMTQyLDk2LDE1NCwxNzQsMjI4LDcxLDcxLDI0NiwyMzAsMTE4LDc1LDEzNCwyMDYsODksMjAxLDExMCwyMzcsMTc5LDQwLDE2MywyMDksMTg3LDk5LDAsNTQsMTAzLDE2MSw3MiwyMjAsMTIsMjA2LDEzNSwxMTQsMTE0LDE2MywzNiwxNTgsMTIxLDEwMSw1NCwxNTIsMzIsMTY3LDExOCwxMSwxOTQsODcsODcsMjAyLDUyLDIwOCwyMDAsMjU0LDI0NSwxMywyMDAsMjIsMTQ5LDIwNSwxMDUsMTIxLDgwLDE2NywzNSwxMDgsMTMyLDE1MSwyMDksMTcwLDYyLDE3MywxNDksMTgyLDc5LDIzLDE2LDEsNjksMTA5LDE2LDI1MiwxNjQsNjksMjQyLDE5MSwyOCw1LDEyNCwzMCwxNjIsMTYxLDcwLDMyLDE5OSwxMDYsNjksMjAzLDk3LDI1MCw4MywyMjQsMjA0LDE5MSwxOTEsMjM1LDk5LDEyOCw1NywxNTAsMTM3LDU3LDE0NiwxMDMsMTUzLDE0Myw3MSw1NSwxMDEsMjA0LDE1NSw3Nyw1LDIyNiwyNCw0OCwxMzQsNjUsMTMsMjA5LDE4MSw0MCw4MywxMDYsMjM0LDExOSw2OSw1MCwxNjMsMzgsNzIsMjAyLDg5LDE2OCw4LDIwMywyMjIsMjQ3LDExNywxMzIsMTIzLDExNSwxMTYsMjQ1LDE4OSwzNSwxNjksMTQyLDEyMyw0LDEyOCw0MSwyMjcsMTE2LDE0MCwxMDIsMTEsMjQyLDIyNiwxODIsNDMsNTIsMjAxLDEzNiwxNzgsMTg0LDE1Nyw0LDEzMSw5NSw1Myw3MiwyMTIsMTgxLDk0LDIzOCwyMTYsNjgsMjAzLDM2LDExNSwzOCwyMDgsMTk4LDIxOSwxNDgsMTYzLDcxLDEzMCwxMTEsMzcsMTMyLDE5NCw5Niw5MCwxMDgsMTczLDAsMTY0LDE2MCwyNDAsMTY4LDYsMTk2LDMzLDEyMiwxOTUsNywxMjUsMjExLDk3LDE2OCwyMzAsMTc3LDk5LDE3MiwxMzksOTksMTI5LDgxLDI1NCwxNTQsMTQ2LDQsMTYzLDExNyw0MCw3LDEyMSwxNTAsMTA3LDI0LDE3MywyMDksNjcsNjQsMTcyLDE4NSw2MCwyNiwxOTQsMTIyLDE4NSwxNzMsNDgsMjM2LDExMCwyNTMsMTc4LDE1LDI1MywyMzIsNTAsMTg5LDE1MSwxNDAsMjQyLDE3OCwxMjAsMjM3LDc2LDE3OSwyMTksMTM5LDY1LDE5OCw1OSw2LDE4NywyMzMsMTYyLDQ2LDE5Nyw5Myw2LDE4MCw5LDIxNiwyNTIsMTk1LDI0MCwyNCwxNjksMTU0LDE5NiwxNjMsMTIzLDIzMyw0OSwzNSwxMjMsMTAsMjExLDQsMTkzLDUzLDE5NSw0NSw1NywxNTUsNzIsOTEsNDEsMTQzLDg0LDI1LDIsMTI4LDEzNSwxODUsMTU2LDUwLDE5NSwyMzMsODYsMTYwLDExNiw4NSwxOCw3MiwxNjIsMzksMTk3LDI0MCwxNzUsNjUsMTU1LDEyOSw0MiwyMTIsOSw2MSwzLDUxLDc1LDE3Niw1NSwxMzgsMTM1LDIwNywyMywxMjgsMTMyLDE2NiwyMTIsMTU3LDkwLDExNiw5NywxMDQsMjQzLDEwLDE1MCwxNDAsMTYyLDE2Niw4NSwxMzQsMTU3LDMyLDEyMywyNTEsMTAzLDE4MywyMTQsMTcwLDE0LDI0OCw3MiwxODksNTIsMTY0LDE4NSw2OCwxNDQsMTAyLDcsMzcsMTA2LDUyLDIyMCwxNTUsMjEwLDgyLDIwNyw3NywyNDUsMTk3LDI1LDUyLDI3LDIwOSwyNTEsMjEsMTksMTk1LDYyLDg5LDEzOCwzMCw4Myw0LDE0NCw3OCwyNDMsODQsMTI5LDIzMiwxLDIxNywxNDgsMTAxLDE2OCwxMDIsODcsOTksNjYsMTcyLDgsMiwxNTUsMjE1LDEwOCw1MywxMjksODMsMzQsMTk3LDEyOCwzMCwyMjAsOTYsMTIzLDgzLDM3LDM3LDE0OCw2NiwxNDksMTkxLDUzLDU2LDE2MCwxMTIsMTc3LDM4LDIxOSwyMjgsMTUsMTQ1LDE0NCwxODcsNjEsNDQsMTIxLDI3LDEyMCwyMTIsOTcsNzksMTYxLDE3OCw3Miw4MiwxOTEsNTksMTMwLDExMCwyMzYsMjM0LDE1NCw0OSwxMjAsNTAsMjMsMzIsMTQ4LDExMywxNjksNDYsMjEsMTEwLDExLDEsMTkwLDExLDI1NSwyNCwyMzIsMjUsMTkyLDE2Niw2NywxLDU5LDIyLDEwOCw1MiwyMjEsMjE3LDE5NCwzOSwxMjMsMTYzLDQxLDEwNywyMDgsNjAsMjUwLDY0LDU1LDE5MSwyMzgsMjI4LDEwNyw2Nyw1MCw2NiwxMzcsMTEyLDczLDExNSw4MiwyMTQsOTgsMjUwLDIwNCwxNTAsMjQyLDc5LDIyMSwxODEsMjQ1LDM2LDE1MSwyNSwyMTgsOTQsMjQ1LDE4MiwyNTMsMTcwLDgsMTE2LDEyNiwxODcsNjIsMjU0LDE1NSwzNywxMjcsNjAsMjI3LDQyLDMxLDUsMTk4LDE2NiwxNjMsMjE2LDE4NSwxNTUsMTk1LDE2OCwxMDgsMTY0LDIzMCwyNCwzNiw1Nyw2NCwxMTUsMTMyLDEwNSwyNDAsMjEsODIsMjMsMyw4MywyMTMsMjA3LDIzMiw2MF19fX0seyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOlsyMzcsMTQ3LDE0NSwyNTEsOTgsMTUsOSwxMiwxODcsMTAsMTkyLDE1NywxMTQsMjMsNjAsMSwyNDAsOTUsMjA1LDE4OCw1NCwyNDAsMzMsMTYwLDEyNSwyMjQsMTk2LDEzOSwxNjAsODQsMjE3LDE2NiwxMDUsMTE5LDExNiw5NiwyMDgsMTY3LDE4NiwxNjgsNDMsMTkyLDIxMywyMzAsMTQsMjksMTAsNTEsNjAsMTQ1LDE4OCw0NiwxMjEsMTk4LDMwLDU4LDE2Myw0LDI0NywxMTAsNzIsMTgyLDg2LDg2LDU4LDE1OSwxOTcsNTEsMTU3LDEwNSwzNCwxMzQsMTgwLDI4LDE3MywxOTQsMTMyLDEwNiwyNDcsMTMxLDE5Nyw2OCw4MywxMDAsMjQ0LDI0NCw1MCwzOCwyMTAsMjksNjgsMjUyLDM2LDcwLDI0OSw2NSw1MSwyMTIsODIsMTg1LDkwLDE1MiwxMzQsMzksMTMxLDQ5LDE4OCw2LDEwNSw5OCwxODMsNzIsMTA1LDkyLDIzNiw2NCwxMzgsNDAsMTksMjksMTUsNjAsOTgsODEsMTE3LDY1LDg3LDE1NiwxMCwxOTgsMTg2LDEzNiwxNzksMjQ0LDE3Niw0NSwyNiw1NSwyMzIsMTk0LDE4Nyw5NSw4MiwxNDUsNSwxMDAsNzEsMjA2LDEzMCwxOTgsMTA0LDIzNCwxODksMiwyMjUsMjEsMTI3LDM2LDE0LDEyLDE2Nyw1LDY1LDUwLDE1Miw0OCwxNDAsNTgsMzYsMjE4LDEyNCwxOTgsNiwyMDYsMTY5LDEwMiwxMDYsMTc2LDU2LDE5MiwxNzcsMTQ1LDE3Myw2MywzOCwxMTUsMTcsMjQ5LDE0LDE5NywyMTEsMTg2LDkyLDEwLDE2OCw1NSw2NSwxMDksMjE2LDIwMSw1NCwyLDEyMiwxMSwzMyw0LDE3Nyw1MSw5MCw5OCw3NSwxMTIsMTI0LDUyLDQyLDQxLDEyNywzNiwxNTIsNzMsOCwxMjAsNzksMTgzLDY5LDE3OCwyMjAsMTUyLDIxMSw3NiwxNjUsNDMsOTEsNjIsMTA0LDEzMiw3MSw0MCwzOCwxNDksMjQzLDEyMCwyMDcsMjIyLDEzNSwxNzgsMTk1LDEzMiwxNDQsNDUsMTY0LDIzLDE0MCw4OSw0NywxNjAsMTAsMTA5LDE0MCwyMDksMTA2LDEzOCwxNDQsMTY5LDE0MywxMiwzLDE5MSw3NCwxNTksMTk2LDIyNSwxMDEsMjE3LDIxMCwxNTksMTUzLDI0MCwyNiwyNTEsMjUxLDUsMTIsMTE5LDEyMywxMDYsMTcwLDAsMTc1LDcwLDk2LDE0OSwyMDgsOCwyMiw2NiwxOTEsMjA2LDEzNiwxMDAsMSw4Niw0NSwxNTQsMzcsMTg5LDExMiw2NywxNTQsMzEsMjUsOTUsNDAsMTY5LDE2MSwxMTEsMTY0LDM1LDIyOCwxMzcsNTcsMTI0LDIzNCw4OCw5Miw3NCw1MCwxNDgsNjAsMTY3LDUwLDIwOCw1Nyw4MywyMzEsMTA2LDIwMCwxMTIsMzEsNzksMTE5LDg4LDE0NiwxMjIsMjYsMTAzLDIxLDQwLDE1MCwxMzgsMTkyLDE1NywzNSwxMDIsMTIyLDEyOSwxNDYsMTI0LDIyNyw4MCw2NCwxNjUsNTksMTI5LDE1NSwzLDE4OSw5MCwyOCwxOTksMTUyLDkzLDMsMTEyLDEzOSwxOSw4OSwxNjAsMTAsMTYwLDEzNiw4LDIyNywxODcsMTc0LDU3LDE1MiwyMSw4NCw5Nyw3NSwxODEsMTEsNzEsMjA5LDgyLDEyNCwzMiw0NiwyOCwyNDYsNDQsMTIxLDgwLDYxLDExNywxMDUsOTAsMjMxLDEzMiwzNSwxOTMsNzEsMTQ2LDE1OCwyNywxNzksMjM4LDgzLDEwOCw2OSw4OSwxODgsMjI5LDIyNCwxMTAsMjM3LDExNSw5NCwxNTksMjAwLDUzLDEyOCwxOTIsMTI1LDEzMywyNTIsMTk4LDI0OCwzLDQsMCwxOTksMTIwLDE2NSwxODMsMTc3LDEzOCw4LDE2OCw5NywyMjUsOSwxOTksNDAsMTIxLDYwLDIwNCwxNCwyNDgsMjEwLDI1LDIzNSw4MSwxNCwyMTcsMTI4LDAsMTQxLDE5NCwxMjQsMTk4LDI0OSwxODAsNiw2NSwxMTgsMTMzLDE1MCw2Niw3OCw5MCwxNTUsMzAsNzEsMTYyLDE2NSw4Nyw2OCwxNDIsOTgsMTk4LDE1OCw4NCw0MSwxNTAsMzUsMTM5LDEwLDksMTQ0LDgsMTMzLDEwMiw3MCw3MSw1LDIwMCw2OSwxMjMsMTkxLDE2MSwzOCw5MSwyMTIsMzIsMjUyLDI0NywxNjIsMjE3LDEwNSwxODAsOTAsMTQwLDE0NiwxLDIxMywxNjAsNDcsMTM1LDE1OCwxMDIsMTE4LDIzLDI1MiwxNzAsNzQsNzEsNzUsNSwyMzQsNSw2NSwyMjgsMTA3LDM2LDg3LDEwLDExMiw5NywzOSwxMTUsMjE2LDMyLDU5LDE4MiwxMzksNTksMTc0LDIsMjMsMzAsMTA3LDc0LDU0LDE2OCwxNTAsOTIsMjEyLDE5MSwxMjUsMTAzLDE1NSwxNDMsMTQ2LDM4LDE4NCw5NywzMiwxMTQsMTk1LDcwLDQ5LDk2LDE4MSwxMDIsMjI5LDE4LDE2NywxNzksMTM1LDE2MywyNSw5MywyNywxMzMsOTAsMTkzLDUzLDE0MywxMTIsMzksMTI4LDE5OSwyOCwxNzMsMjA4LDQ4LDU0LDEyOCwxNjIsNDgsNDksMzksMTI0LDIzNCwyNDYsMTg1LDEzMiw2NCw2OCw5OCwxODAsMTE1LDk2LDEsMTg4LDM0LDgzLDk5LDE0OCwxNDcsMTQ5LDE4MCwxNywxMzAsMTc1LDksNDUsMjEsNjgsMTQxLDEwNiwxOTUsNjYsMjAyLDE2MSw1Myw3OSwyMDksMjcsMTEwLDY5LDUzLDg3LDE3NywxNzUsMjksMjQ2LDIwNSwxMTIsMjM1LDExMywyMzUsMTAxLDQyLDIxMywxMTksNCw5LDIzNiw0Miw2MCwxNDYsMTI4LDE1NywxODgsNTYsMjEzLDM2LDMwLDIzMSwzOSwxOTUsMjI0LDQ4LDE3MywyMTEsNDQsMTE1LDIyNSwxODYsOTMsMzQsNzQsMTkwLDEzMyw5MiwxNjEsMTE4LDI2LDE5NywxNDAsMzcsNTYsNDksMzcsMjYsMTA4LDI0MywxMTQsMjUxLDIyNywxMiwzLDU3LDUxLDIyMCwxNDUsMjIsMjMyLDQwLDI4LDM5LDEzNSwxNjksMTY2LDE3NiwyNCwxNTUsMTgsMTI2LDIxLDE5OCwxODMsMjUsNzYsNzQsMTQzLDM4LDY1LDIyNSwxNjAsMTEsMTcxLDE1NCw5NiwzOCwxMjIsMjksNywxNjgsMTc3LDYwLDUxLDExOSwyMjksMTA2LDg5LDIyLDE2LDEyMSwxNjEsMTMwLDEwMywxMDIsMjgsMjgsMjI1LDEwMCw4NiwxNSw1MCw3NSwxOTQsNDAsMTQxLDEzOSwxMTUsODYsNDcsMyw1NywxNzIsMTM1LDAsMiwyMzUsMjAxLDE0NywxNzIsMTY1LDE1MiwxNjYsMTQyLDE0LDI1Miw0NywyMDEsNDIsMTQ3LDEzMSwyMDQsNTAsNDEsMTksMTc5LDYsNTYsMTIwLDEyLDIzMCwxNjMsOTksMTI4LDE2LDEwMSwxODgsMTM1LDI1NCwyMzIsMTM3LDExMyw0MywxOTIsMjI1LDExMiwyMDAsMTYwLDIwLDIsMjU0LDE4MywyMSwyOCw1NSwxMzYsNjAsMjM1LDE1Nyw3NCwzNiwxMzksMjI2LDg2LDEzMCwyNTUsMjI1LDE2NywxODgsNDksOTEsMTc0LDE0MCwxMjksMyw4NCwxMDAsMTE1LDQzLDc1LDQsMTI0LDEzNSw0NSwxNjMsMzgsNDQsMTU2LDE0MCwxMTcsMTgwLDE3MSwxODAsMjgsMTkyLDUwLDEyOCwxMjcsNzcsMTksMTc4LDEzMCwxMzQsMTA3LDE4OSwxNzAsNzQsMjMzLDEwNSwxMjMsMjQ0LDEyMCwyMDcsMTMyLDEyMywxNzUsMTc4LDE4LDE4NCwyMjQsMzksMjEsMTgxLDEwMiwxOTUsMjE5LDE2MiwxMSwzNiwzNSwxMTYsNjYsMjEsMTY1LDE0MSwxMCw0NiwxMjMsMTcsMTkyLDcyLDM4LDE4MywxODksMTgxLDE3MSwyNTEsMTgzLDk2LDcxLDEzNCw0NiwzMCwyNDgsNDQsNjMsMTA4LDExNSw4MCwyMjAsMTQwLDEyNSwzNSwxMzIsMjI1LDIyLDUsMTA4LDI4LDE3OCw2MywxOTgsMTExLDIzNiw4NSwxNzksMTQ5LDEsMTgzLDE0MywxNjIsMTM5LDIyLDgwLDQ2LDIzNiwxMzksNjEsMTA4LDEzMywxMywxNzUsMjgsMTc5LDE2MywxODEsNzMsMTksMTAxLDQ3LDU1LDI0NSw0LDExMiwxMDAsNCwxNjcsMjI0LDEyNSwxNTAsMTQ5LDIwMSw1LDEyOSwxNzksMjM0LDIwMywxMzcsNTQsOTEsMTAxLDExOSwxNzEsOTgsNzUsOTksNjUsODUsMTI5LDE5NCw5LDksMTMwLDQsNTUsMTM1LDE2MywxNTMsNTEsMTM3LDIxLDMyLDIxMiwzOSw4MCwxMTcsNTQsOTUsNzcsMjAzLDExOSwxMjEsMTU0LDcsMjE0LDE0NCwxMjIsNzMsMTMxLDE2NiwxMjgsMTc3LDE4OCwxODMsMSwxNzQsMTUxLDE4NSw2NSw2MCw4Niw4MCw5OSw1OSwxNCwyNCw2Niw0MCwyMjEsNjgsNDcsNjUsNjUsMTc3LDEzMSwxOTIsMTQ0LDQ3LDcsMzcsMzMsNzYsMTY3LDI1NCwxNjcsMTIxLDIyMiwxNjYsMTU0LDYzLDk3LDE1OSwyNDAsMTY5LDEzNiwyMzMsMTIyLDExOCw1NywxMTIsMTk5LDEzMSwxNzcsMjgsNTEsMTQwLDE4MywxMTEsMjUyLDE1OSw5NCw3Niw1MywxMzAsNDEsMTcyLDExNCwxMTksMTMwLDE5NSwxMjQsNTYsMTIyLDIzMCwxMCwxMDgsMTEzLDEzNSwxNjcsMTU1LDQ3LDc3LDEwNyw2OSw4NCw3MCwxMDksMjUsMTYsMTE3LDE2Nyw3MiwxMzksMTMsMTAzLDE1NCwyNywyMTAsNjIsNDMsMCwxMjYsMTg0LDIwOCwxMDAsNDEsMjQwLDE4NSwxNjIsMjExLDU0LDU2LDIwNywxMTYsNDMsMTE3LDE4LDIxMCw0MiwyNTAsMjExLDI1MCwxMTIsMTM3LDExNywyNDcsMTUwLDExMyw0MywxNzMsMjI0LDE4MSw1NCwyNTEsNTIsMTMzLDEyMiw3NywzMSwxMzUsMjA3LDIwNSwyMzUsMjI0LDEzNCw1NCwxMzAsMjMzLDEwOCwyMDcsMTU1LDE1Myw5Nyw2Nyw3OSw5Miw0MCwyMDYsMjE2LDI0Myw4NywyMCwzMSwyMjEsNjUsODEsMjA2LDE3OSwyNTEsNDcsMzYsMTAsMTMxLDE3NSw1MF19fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6WzMsMTg3LDE2MSw2OCwyMDgsMTI5LDIwNSwyMzIsNTEsMjI1LDE4LDQsMTMwLDE2OSwyMDMsMTg4LDExNSwxODgsMjM2LDY3LDE2NywxMjIsMTg0LDE5OCwxMTUsOTYsMTU0LDI1MiwyNDIsMTEwLDE5MywxNTQsMTg1LDI5LDI0NywxMjIsMTQxLDQ0LDE1Myw5MywxNjQsMTkyLDEyMSw1NiwxMTQsMTU5LDEzNSwxNjYsMTIxLDEwNywxLDE5NiwyNyw1NSwyNDMsMjE5LDExMiwyNTQsMTIxLDUwLDQ1LDE5Miw3NSw0MCwzMiwyMDIsMjQ0LDksMTI5LDIyLDU3LDE3Miw0MSwyMzIsODQsOTAsNTIsNzksMTYzLDExNCwzNCwyMjMsOTYsMjksMjQ3LDE0Niw3NSwzNywyMTcsMTA5LDEyOSwxNzksMTksMjQ4LDE5MiwxMjcsMjE4LDQ0LDE3MCw3OCwyMjUsMTUzLDkxLDUwLDU5LDE1MywxODQsNDQsNjcsMTM4LDIwNiwxNzgsMjE1LDYsMTMxLDE1MSwyNCwzOCwxMjIsMTY2LDIzMCw2OSwxMiwxNTIsMTY1LDE3MywxNzIsMTE2LDE0MSw2OCwyMDIsMTg3LDExLDIyNyw3OSw5MywyMTIsNzEsNjYsNDgsNDMsMCwxOTcsOTMsMTYyLDIyLDEwOSwyMTQsOSw1NCwxMTEsNTEsMjYsOTQsODMsMywyMDMsMTk1LDMsMTYxLDExNywxOTAsMjI0LDk5LDIwMywxNzcsMTI0LDExOCw4MCwyLDE0MiwxNTIsMTk5LDE0MSwxMTEsODAsNTQsNDIsMTM3LDE0OCwzNiwxMzYsMTAwLDIyNiwxODQsNjgsNzEsMTIxLDU0LDQ2LDg4LDE0NiwxNywxMzYsMTE3LDI0NSw1OCw3NCwyMzYsMTQwLDM3LDIzMiwxNzksMTg1LDEwMywyMTgsMTk2LDEwMiwxNTEsMjMsMjMsMjE3LDMxLDY1LDEyLDYxLDEyMyw5Miw3NiwxMTYsMjA5LDkzLDIzMyw5OCwzLDUyLDI0Nyw5NiwxNSwyNDcsNDUsMTg2LDE3MSwxMzIsOCwyMTcsMTYsMjE4LDI3LDEyOSwyMjksMTI0LDIwNCw4MCwxNTEsNjMsMTQsMjAzLDM2LDg0LDk4LDE1NCw5MiwxMTIsMzgsMTgyLDI1MiwxNzIsMjA2LDE2NywxOTAsMjM4LDE0NiwxNTQsMTEyLDEwLDQxLDY5LDE3NywyOSwxMjEsMTc5LDE2NCwyMzgsMjI3LDMxLDk4LDIyNSwxNTAsMTE1LDIxMywxNjgsMTg0LDc1LDU0LDIzMSwxNDYsOTksMTM5LDIwOCw1MCwxNjMsODEsNTYsMTk5LDE3Nyw1LDIwMywyMjUsNDYsNTEsMTk4LDE2MiwxODksODQsMTQ1LDMsMjQ0LDE5Miw1MiwxMDUsMzYsMTM2LDIxNCw5OSwyMzksNzEsOTUsOTcsMTMzLDE1NywxNzIsMTk0LDE3OSw1NywxMzUsMTM2LDIzOCw2Niw5MiwxNTgsMTY5LDEzMiwxMTEsMTA1LDE1OCwyNTAsMjIsMTgwLDQ0LDI0LDczLDEwNyw1MSw0MiwyNTAsMTA0LDM0LDE4NCwyMjQsMTQ2LDM1LDEyMSw0NywxNDAsMzYsODIsMjQ0LDIxLDI0LDIzOSwyNTAsMTY2LDI0OSw2OSwxMjAsMTA5LDEwNywxMTgsMjA2LDUyLDEwNSwxNjMsNzMsMjUsMzcsMjAwLDE1MCwxLDE1NSw0OSw1LDIyNSw0Niw4OSwyMzUsMTExLDc5LDE1MSwxNzIsMTk0LDEzMiwzNiwxMCwxLDEyLDM0LDIyNyw2NiwxNjAsMjQ2LDc4LDE4LDEzOCwxNTMsNTEsMjM1LDE3LDk0LDEzNSwxOTMsMTEsMjE0LDUyLDMzLDE5NiwxMTEsMjEwLDI0Miw0MCwyMjcsMjYsODcsMTI1LDE1NCwxMjAsMTE2LDEzMyw4Miw5LDIxOSwxOTYsMTcwLDI3LDEwLDE4OSwyMiwzOSwxMDUsMTcwLDk4LDE1LDEzMSwyMDUsNDEsODksMTQzLDM2LDI0MSwxOTYsMjI1LDE3OSw3NSwxODgsMTQ0LDMxLDU1LDM5LDExNiw1LDIsMTEsMTQ1LDczLDExMiwxODIsMTE5LDIwMiwyMjMsNDQsMTUzLDgzLDI2LDE5OCwxMzgsMjEsNTYsMTU2LDE3OCwxODIsNjgsMjQ0LDE4LDE4NywyMzIsMTQ1LDc1LDIzNiwxMTIsMjQ5LDE1MCw0MCwyMywxOTYsMTg1LDI1NCwxNTEsMTUsMTY0LDI1MSw0OSwyNDMsMTg2LDcwLDIwNiwxMDUsNzEsMjQ5LDE0OSw0LDI0NCwyMzQsMTksNzQsNTQsMTgxLDE3Miw1NywzMSwxODQsMjE5LDEzMywyMTcsMTIwLDU0LDE4Miw3NCwxMjEsMSwxOSw5OCwxOTksMTAsMTIyLDI1NCwzNywzMCwyMCw3LDIsMTE4LDE2OCwxNSwxOTcsODQsMzcsMjE5LDIxNiwxNTQsNDAsMTU2LDUsOTIsMTEyLDE1Miw2MSwxLDE5OCwxNjMsMTkyLDE2NCwxMiw2NCwxNSw1OSwxODQsMTU1LDEwMywwLDkwLDE1MiwyMDAsOTgsOSwyLDYzLDE4MiwyMzEsODUsMTMwLDE2NywxMzQsMTE4LDYwLDE1NywyMjgsMjA5LDE5MywyMDcsMTE2LDE0NywxNCwzNiwxMzksNDEsMjIwLDE1MiwxODQsOSwzNSw4MywxMTYsMTA5LDIzNSwxNzksOTksNjEsNzUsMzQsOTgsMTAxLDMsMzQsNzQsMzIsMTY0LDE5OCw1OCwyNDIsMTk5LDE3MSw3MywyMiw0Myw2NSwyMjUsMTU2LDM1LDMyLDMxLDEyLDIzNiwyNiw2MCwxMTksMTY3LDE1OSwxMDcsNyw5OSwxODUsMTg0LDExMywxMDQsNDYsMjM2LDMsMTM3LDc4LDIxOSw5MCw4NCwyNDEsMTksMjAzLDUzLDEzOCw3NywxNyw2MCwxODIsMzQsNjcsMjEwLDczLDE3NiwyNCw2NSwxNTcsOTQsNDQsMTMzLDE3OCwyNDIsMTQ0LDE0MSwxMzgsMTIwLDE3MiwxODIsMTE2LDYxLDQyLDE1MSwxOTUsNjcsMTk0LDczLDEzMSw2MCwzLDI0Myw4MCw5OSwxNjMsMjA3LDIwMCwxOTMsNzUsMzIsMjI5LDEyMiw4Nyw0MCw3NiwyMjYsMTg4LDUxLDExNyw3MywxNTgsMjA3LDE3MCwxMzEsMTkzLDg4LDIzLDM1LDEyOCwxMTIsMTMwLDIyNywxNzAsNTcsNTAsMTg0LDQ3LDIzMSwxMjksMTYyLDcyLDYzLDIyMiwyMjcsMTA4LDgwLDMsMTY3LDU0LDEwMSwxNDQsMTk0LDIyMCw4MSwyMDgsMzksMTQsMTI3LDExNywxMDUsMTgxLDE0Nyw2LDE4NCwxMzAsMTcxLDIyOSwxMzAsNTAsMTIwLDE2MiwxNjYsMjQzLDg2LDEwMyw3NywzOSwxNjYsMTk2LDYsMTU1LDQ5LDE5OCw0NiwyNTIsMTMyLDI5LDkzLDIxMywxMDUsNjQsNTcsMTk5LDIyOSwzMiw5OSwyNywyMDksNzcsNTIsMTkzLDEzOCwxMzgsMTQ3LDY5LDkyLDE1MywxMTEsMjM5LDE1NSwxNjUsMjM4LDEwLDE2LDk2LDIxMywxMjUsMTQ4LDIzNSwxMTUsNCwxMTcsMTYwLDE2NSwxMzgsMTk4LDk2LDU3LDkzLDIzMywxMzksOTIsNTcsNDMsMTYwLDE2NiwxOSwxNzMsMiw5OSw1LDEwLDEwMSwxMDksOTMsMTcxLDI1LDIyLDY4LDEwNSwyMjMsMjMzLDc3LDE0Niw5NywzMCwxNTMsMTEzLDE3MywyNCwxOTMsMTEwLDI0OCwyNDcsMTk4LDIyMyw0MSwyMDQsMjQyLDI1MiwyMiwxOTUsMjA5LDU3LDE1LDM2LDc5LDM1LDc2LDE1Nyw4OCwxMzEsMTk0LDI1MywxNjksMTQsNywxMCwxMTYsMjM2LDExOCw2NCwxOTIsMjI0LDc4LDEyLDExNiw1MCwxNTAsNjUsMiwxNjgsMjMxLDE0MSw1Miw5Niw4NywyMDcsMTM4LDE5MSw3MCwxOSwxMCwyMTQsMTUzLDE5OCw5NCwyNSwxNzUsMTQsMTM1LDE0NCwxMyw1MiwxMTIsMjM0LDEzMSwxNzMsMTUwLDIxMywxMjEsMTY5LDMzLDQyLDE1MCw2Niw4Nyw4MywxMzksMTY2LDE2NiwzNSwxMzksOTAsMjI4LDExOCwxODQsMTc2LDQ2LDYyLDI0MSwyMDEsNTYsMTUwLDE5NSw1Myw1NiwxMjYsOTYsMTA1LDE4LDI1MCwyNTEsOTEsMTQ2LDIzMSwxODAsNDMsMTg1LDEzNCwyNCw1NSwxMzMsMTE2LDE1MCw2LDIxNywxMDQsOTMsMTk4LDEzNSw2MCwxNywxMjMsMjYsMTgzLDU1LDQyLDIyOSwxOTQsMzksNDUsMTM0LDkyLDI1NSw1MCwxOTMsMjE5LDIwMCwyMiwyMzEsODgsNDYsMjksMTgwLDc0LDkzLDIyNSwxNzgsMjE3LDEzOSw0MCwyMzYsMjM0LDEzLDE2NSwxNTEsMTU2LDY2LDExNCwyNSw2MCwzOSw0NywxMDQsMTY3LDg5LDEsMjI0LDE1MCwxNCwyNywxNjYsNDYsMTgwLDE0OCwyMDcsMTYsNzcsMTIzLDIzMiwyOSwyNTAsMjE2LDMwLDQyLDczLDE2OSwzNiw5Niw3NSw3NSw4NSwxNTQsOTQsMjQsMTQsNiwxNzEsMTQ0LDE4OSwyMzIsMTQ0LDIyMywxNTQsOTIsOTYsMjQ4LDIyLDE1LDE2NiwxMDMsMTk2LDk4LDQ5LDIzOSw2NCwxNzEsMTc4LDIxMCw3OSwyMzUsMjA0LDEwMCwxNyw4OSwxNDgsMTcsMTY2LDEwMCw4NSwxLDE0NiwxNjIsMjQsMTIwLDE2LDIzMCwyMDMsMzcsMTY0LDI2LDY5LDExNCw1MSwxOTgsMTI5LDY5LDE0Nyw4NywxMjMsMTk3LDE1NCw3MSwyMjgsMjE5LDMwLDY0LDMsMTAwLDIxNSwxOTgsMTU3LDE1OSwxLDI1LDY4LDQyLDQ2LDUyLDU4LDQ5LDE3NywyMTAsMjA1LDE0OCw4Nyw2Niw3MywxMDcsODUsMTIxLDE3MCwxOTcsNDIsMzcsMzUsMTU3LDE0NCw5OSwyMDQsODksOTEsMTgzLDE4MywxMTUsMTQ0LDEwOCwxNywyMCwyMTUsNzcsMjM3LDE0NywxNDUsMjUxLDk4LDE1LDksMTIsMTg3LDEwLDE5MiwxNTcsMTE0LDIzLDYwLDEsMjQwLDk1LDIwNSwxODgsNTQsMjQwLDMzLDE2MCwxMjUsMjI0LDE5NiwxMzksMTYwLDg0LDIxNywxNjYsMTA1LDExOSwxMTYsOTYsMjA4LDE2NywxODYsMTY4LDQzLDE5MiwyMTMsMjMwLDE0LDI5LDEwLDUxLDYwLDE0NSwxODgsNDYsMTIxLDE5OCwzMCw1OCwxNjMsNCwyNDcsMTEwLDcyLDE4Miw4Niw4Niw1OCwxNTksMTk3LDUxLDE1NywxMDUsMzQsMTM0LDE4MCwyOCwxNzMsMTk0LDEzMiwxMDYsMjQ3LDEzMSwxOTcsNjgsODMsMTAwLDI0NCwyNDQsNTAsMzgsMjEwLDI5LDY4LDI1MiwzNiw3MCwyNDksNjUsNTEsMjEyLDgyLDE4NSw5MCwxNTIsMTM0LDM5LDEzMSw0OSwxODgsNiwxMDUsOTgsMTgzLDcyLDEwNSw5MiwyMzYsNjQsMTM4LDQwLDE5LDI5LDE1LDYwLDk4LDgxLDExNyw2NSw4NywxNTYsMTAsMTk4LDE4NiwxMzYsMTc5LDI0NCwxNzYsNDUsMjYsNTUsMjMyLDE5NCwxODcsOTUsODIsMTQ1LDUsMTAwLDcxLDIwNiwxMzAsMTk4LDEwNCwyMzQsMTg5LDIsMjI1LDIxLDEyNywzNiwxNCwxMiwxNjcsNSw2NSw1MCwxNTIsNDgsMTQwLDU4LDM2LDIxOCwxMjQsMTk4LDYsMjA2LDE2OSwxMDIsMTA2LDE3Niw1NiwxOTIsMTc3LDE0NSwxNzMsNjMsMzgsMTE1LDE3LDI0OSwxNCwxOTcsMjExLDE4Niw5MiwxMCwxNjgsNTUsNjUsMTA5LDIxNiwyMDEsNTQsMiwxMjIsMTEsMzMsNCwxNzcsNTEsOTAsOTgsNzUsMTEyLDEyNCw1Miw0Miw0MSwxMjcsMzYsMTUyLDczLDgsMTIwLDc5LDE4Myw2OSwxNzgsMjIwLDE1MiwyMTEsNzYsMTY1LDQzLDkxLDYyLDEwNCwxMzIsNzEsNDAsMzgsMTQ5LDI0MywxMjAsMjA3LDIyMiwxMzUsMTc4LDE5NSwxMzIsMTQ0LDQ1LDE2NCwyMywxNDAsODksNDcsMTYwLDEwLDEwOSwxNDAsMjA5LDEwNiwxMzgsMTQ0LDE2OSwxNDMsMTIsMywxOTEsNzQsMTU5LDE5NiwyMjUsMTAxLDIxNywyMTAsMTU5LDE1MywyNDAsMjYsMjUxLDI1MSw1LDEyLDExOSwxMjMsMTA2LDE3MCwwLDE3NSw3MCw5NiwxNDksMjA4LDgsMjIsNjYsMTkxLDIwNiwxMzYsMTAwLDEsODYsNDUsMTU0LDM3LDE4OSwxMTIsNjcsMTU0LDMxLDI1LDk1LDQwLDE2OSwxNjEsMTExLDE2NCwzNSwyMjgsMTM3LDU3LDEyNCwyMzQsODgsOTIsNzQsNTAsMTQ4LDYwLDE2Nyw1MCwyMDgsNTcsODMsMjMxLDEwNiwyMDAsMTEyLDMxLDc5LDExOSw4OCwxNDYsMTIyLDI2LDEwMywyMSw0MCwxNTAsMTM4LDE5MiwxNTcsMzUsMTAyLDEyMiwxMjksMTQ2LDEyNCwyMjcsODAsNjQsMTY1LDU5LDEyOSwxNTUsMywxODksOTAsMjgsMTk5LDE1Miw5MywzLDExMiwxMzksMTksODksMTYwLDEwLDE2MCwxMzYsOCwyMjcsMTg3LDE3NCw1NywxNTIsMjEsODQsOTcsNzUsMTgxLDExLDcxLDIwOSw4MiwxMjQsMzIsNDYsMjgsMjQ2LDQ0LDEyMSw4MCw2MSwxMTcsMTA1LDkwLDIzMSwxMzIsMzUsMTkzLDcxLDE0NiwxNTgsMjcsMTc5LDIzOCw4MywxMDgsNjksODksMTg4LDIyOSwyMjQsMTEwLDIzNywxMTUsOTQsMTU5LDIwMCw1MywxMjgsMTkyLDEyNSwxMzMsMjUyLDE5OCwyNDgsMyw0LDAsMTk5LDEyMCwxNjUsMTgzLDE3NywxMzgsOCwxNjgsOTcsMjI1LDksMTk5LDQwLDEyMSw2MCwyMDQsMTQsMjQ4LDIxMCwyNSwyMzUsODEsMTQsMjE3LDEyOCwwLDE0MSwxOTQsMTI0LDE5OCwyNDksMTgwLDYsNjUsMTE4LDEzMywxNTAsNjYsNzgsOTAsMTU1LDMwLDcxLDE2MiwxNjUsODcsNjgsMTQyLDk4LDE5OCwxNTgsODQsNDEsMTUwLDM1LDEzOSwxMCw5LDE0NCw4LDEzMywxMDIsNzAsNzEsNSwyMDAsNjksMTIzLDE5MSwxNjEsMzgsOTEsMjEyLDMyLDI1MiwyNDcsMTYyLDIxNywxMDUsMTgwLDkwLDE0MCwxNDYsMSwyMTMsMTYwLDQ3LDEzNSwxNTgsMTAyLDExOCwyMywyNTIsMTcwLDc0LDcxLDc1LDUsMjM0LDUsNjUsMjI4LDEwNywzNiw4NywxMCwxMTIsOTcsMzksMTE1LDIxNiwzMiw1OSwxODIsMTM5LDU5LDE3NCwyLDIzLDMwLDEwNyw3NCw1NCwxNjgsMTUwLDkyLDIxMiwxOTEsMTI1LDEwMywxNTUsMTQzLDE0NiwzOCwxODQsOTcsMzIsMTE0LDE5NSw3MCw0OSw5NiwxODEsMTAyLDIyOSwxOCwxNjcsMTc5LDEzNSwxNjMsMjUsOTMsMjcsMTMzLDkwLDE5Myw1MywxNDMsMTEyLDM5LDEyOCwxOTksMjgsMTczLDIwOCw0OCw1NCwxMjgsMTYyLDQ4LDQ5LDM5LDEyNCwyMzQsMjQ2LDE4NSwxMzIsNjQsNjgsOTgsMTgwLDExNSw5NiwxLDE4OCwzNCw4Myw5OSwxNDgsMTQ3LDE0OSwxODAsMTcsMTMwLDE3NSw5LDQ1LDIxLDY4LDE0MSwxMDYsMTk1LDY2LDIwMiwxNjEsNTMsNzksMjA5LDI3LDExMCw2OSw1Myw4NywxNzcsMTc1LDI5LDI0NiwyMDUsMTEyLDIzNSwxMTMsMjM1LDEwMSw0MiwyMTMsMTE5LDQsOSwyMzYsNDIsNjAsMTQ2LDEyOCwxNTcsMTg4LDU2LDIxMywzNiwzMCwyMzEsMzksMTk1LDIyNCw0OCwxNzMsMjExLDQ0LDExNSwyMjUsMTg2LDkzLDM0LDc0LDE5MCwxMzMsOTIsMTYxLDExOCwyNiwxOTcsMTQwLDM3LDU2LDQ5LDM3LDI2LDEwOCwyNDMsMTE0LDI1MSwyMjcsMTIsMyw1Nyw1MSwyMjAsMTQ1LDIyLDIzMiw0MCwyOCwzOSwxMzUsMTY5LDE2NiwxNzYsMjQsMTU1LDE4LDEyNiwyMSwxOTgsMTgzLDI1LDc2LDc0LDE0MywzOCw2NSwyMjUsMTYwLDExLDE3MSwxNTQsOTYsMzgsMTIyLDI5LDcsMTY4LDE3Nyw2MCw1MSwxMTksMjI5LDEwNiw4OSwyMiwxNiwxMjEsMTYxLDEzMCwxMDMsMTAyLDI4LDI4LDIyNSwxMDAsODYsMTUsNTAsNzUsMTk0LDQwLDE0MSwxMzksMTE1LDg2LDQ3LDMsNTcsMTcyLDEzNSwwLDIsMjM1LDIwMSwxNDcsMTcyLDE2NSwxNTIsMTY2LDE0MiwxNCwyNTIsNDcsMjAxLDQyLDE0NywxMzEsMjA0LDUwLDQxLDE5LDE3OSw2LDU2LDEyMCwxMiwyMzAsMTYzLDk5LDEyOCwxNiwxMDEsMTg4LDEzNSwyNTQsMjMyLDEzNywxMTMsNDMsMTkyLDIyNSwxMTIsMjAwLDE2MCwyMCwyLDI1NCwxODMsMjEsMjgsNTUsMTM2LDYwLDIzNSwxNTcsNzQsMzYsMTM5LDIyNiw4NiwxMzAsMjU1LDIyNSwxNjcsMTg4LDQ5LDkxLDE3NCwxNDAsMTI5LDMsODQsMTAwLDExNSw0Myw3NSw0LDEyNCwxMzUsNDUsMTYzLDM4LDQ0LDE1NiwxNDAsMTE3LDE4MCwxNzEsMTgwLDI4LDE5Miw1MCwxMjgsMTI3LDc3LDE5LDE3OCwxMzAsMTM0LDEwNywxODksMTcwLDc0LDIzMywxMDUsMTIzLDI0NCwxMjAsMjA3LDEzMiwxMjMsMTc1LDE3OCwxOCwxODQsMjI0LDM5LDIxLDE4MSwxMDIsMTk1LDIxOSwxNjIsMTEsMzYsMzUsMTE2LDY2LDIxLDE2NSwxNDEsMTAsNDYsMTIzLDE3LDE5Miw3MiwzOCwxODMsMTg5LDE4MSwxNzEsMjUxLDE4Myw5Niw3MSwxMzQsNDYsMzAsMjQ4LDQ0LDYzLDEwOCwxMTUsODAsMjIwLDE0MCwxMjUsMzUsMTMyLDIyNSwyMiw1LDEwOCwyOCwxNzgsNjMsMTk4LDExMSwyMzYsODUsMTc5LDE0OSwxLDE4MywxNDMsMTYyLDEzOSwyMiw4MCw0NiwyMzYsMTM5LDYxLDEwOCwxMzMsMTMsMTc1LDI4LDE3OSwxNjMsMTgxLDczLDE5LDEwMSw0Nyw1NSwyNDUsNCwxMTIsMTAwLDQsMTY3LDIyNCwxMjUsMTUwLDE0OSwyMDEsNSwxMjksMTc5LDIzNCwyMDMsMTM3LDU0LDkxLDEwMSwxMTksMTcxLDk4LDc1LDk5LDY1LDg1LDEyOSwxOTQsOSw5LDEzMCw0LDU1LDEzNSwxNjMsMTUzLDUxLDEzNywyMSwzMiwyMTIsMzksODAsMTE3LDU0LDk1LDc3LDIwMywxMTksMTIxLDE1NCw3LDIxNCwxNDQsMTIyLDczLDEzMSwxNjYsMTI4LDE3NywxODgsMTgzLDEsMTc0LDE1MSwxODUsNjUsNjAsODYsODAsOTksNTksMTQsMjQsNjYsNDAsMjIxLDY4LDQ3LDY1LDY1LDE3NywxMzEsMTkyLDE0NCw0Nyw3LDM3LDMzLDc2LDE2NywyNTQsMTY3LDEyMSwyMjIsMTY2LDE1NCw2Myw5NywxNTksMjQwLDE2OSwxMzYsMjMzLDEyMiwxMTgsNTcsMTEyLDE5OSwxMzEsMTc3LDI4LDUxLDE0MCwxODMsMTExLDI1MiwxNTksOTQsNzYsNTMsMTMwLDQxLDE3MiwxMTQsMTE5LDEzMCwxOTUsMTI0LDU2LDEyMiwyMzAsMTAsMTA4LDExMywxMzUsMTY3LDE1NSw0Nyw3NywxMDcsNjksODQsNzAsMTA5LDI1LDE2LDExNywxNjcsNzIsMTM5LDEzLDEwMywxNTQsMjcsMjEwLDYyLDQzLDAsMTI2LDE4NCwy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MzYsMjQwLDEzMywxMTAsMjUzLDQ0XX19XQABeyJwcm9wb3NhbCI6eyJBZGQiOnsia2V5X3BhY2thZ2UiOnsicGF5bG9hZCI6eyJwcm90b2NvbF92ZXJzaW9uIjoiTWxzMTAiLCJjaXBoZXJzdWl0ZSI6Ik1MU18yNTZfWFdJTkdfQ0hBQ0hBMjBQT0xZMTMwNV9TSEEyNTZfRWQyNTUxOSIsImluaXRfa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxOCwxMDQsMTIsOTYsMTEsNzgsODUsMjQ5LDIwNiwyMjQsNjcsMTg3LDQxLDg0LDQ3LDE5MiwyMTYsMTQ1LDEzOCwxMzAsMjA2LDI0Myw1NywyNywxMzMsMTM1LDIwNSwxNiwyNTEsNzgsNDAsMjI0LDUzLDcyLDksMTU1LDIyOSw5MSw1NiwyMTksMTQ2LDE5MSwyMzYsMjI2LDMyLDI1Miw1NywxOTMsMTc2LDE2OSwxODYsMjQ1LDg4LDE0Miw1MiwxNTYsMjUsOCwxOTMsMTE0LDEyNyw4MCw2MCwzLDcwLDc3LDkxLDkxLDE0MSwxMDcsNTEsMTY3LDE5NCwxNDcsNTUsMTg3LDE3MiwxMDYsMTYyLDk5LDU1LDE5Nyw4MCwzMCwyMDMsNzQsMTk2LDUwLDgyLDE5OCw5NCwyMTUsMTU3LDI1NCwyMCw3LDE1Miw5MCwxMjMsMCwxMTcsMjAwLDE4OSw1LDEwOCw4OSw1Miw1LDE1NSw1NSwxMzIsMjI0LDgwLDE0OSwyMjUsODQsNDQsMjMyLDExNywxNzAsMjMwLDg3LDUwLDEyOCwxNTEsNzUsMTA2LDI1MiwxMTEsMTk0LDE0NiwxMjIsODMsMTM5LDg0LDMzLDMzLDg4LDE1NiwxMTksMTAsNDMsMTUzLDIwMyw3MiwxMDUsNDAsMTYsMTcsMTcsMTAyLDE1NSwzNywyMTksMTg0LDYzLDIxNiwxODAsMTAwLDIzNSw5OCwxMTMsMjM3LDU4LDQyLDMyLDE2NCwzOSw4NywyMjAsMTQ0LDI1MSwxNjAsNjQsMTE3LDEwNCwzMCwxODgsNTYsMTQ0LDg0LDEyMCwxNzgsMTQ4LDgwLDE0Nyw0Nyw1Niw4NiwyNDgsNjUsODAsMTMwLDE2OCw4Myw2NCwxMDcsMTUyLDIwMSwxODUsOTMsMjQ2LDQzLDEzMSw5OCwxNzgsMTI4LDE0NiwyMDksOTIsMjU1LDc2LDE2MiwyNDcsMTQ5LDY4LDE3LDE5MiwxMzQsMjYsMTE1LDk4LDE0MiwxMjgsMTE2LDE2MCwzNCwxMiw5OCwxNTEsNTMsMjM1LDE0NSw3MywyMiw1MCw3NSwxNDAsMjAsMjAsMjA2LDEzMCwyMDAsMjAsMTEsNjMsMTI3LDkxLDYzLDEwMiwxOTgsNjcsNDAsNTgsNDUsNjksOTIsMTU3LDE2LDEzMCwxOTAsMjIsMTIxLDQ4LDc5LDE4Miw1NSwzLDE0NCwxODgsMjI5LDQzLDg0LDE3MSwxOTYsMTg0LDEsMTE5LDE1NywyMjYsMTM4LDI4LDE3OCw4LDMzLDIwNSwyNTIsNjMsMTc1LDE3OSwzLDEzNCwxOTYsMTgyLDIzMCwxNDgsMTcwLDExNCwxNTUsMTU2LDE0Myw3LDExMywyMywyMTYsMTgsMTIyLDI0NSwxMTMsMjE2LDE4MSwxMDUsMTk4LDEzOSwxMjksNTYsMjM1LDg2LDIxNCwxNzIsMTg0LDQ5LDIzMiwxMiwyMzcsMTEzLDIwNyw3NCwyNCw5MiwxMDAsMTYsMjAsMjMzLDIzNiwzLDEwNSwxMTgsMTg4LDE4OSw1MiwxODUsMjAsMjQ4LDE0NywyMTgsMTk2LDIyLDE5LDIxNCwxMDcsMjgsMTU2LDExMSw4MiwyMzMsMTAyLDE5MSw1NiwxMjksMjAwLDY2LDgwLDEzNywxNzYsMTQ4LDEwMCwyMTksMjYsMjA4LDEzMSwxNTQsMjksNzYsMTUyLDMyLDU2LDE1MiwyMDIsNDIsMTY4LDE3NywzNCwxMjQsMiw0NCw1LDE2MiwxODQsMzQsNjksMTksMTc4LDQwLDIxMSwxOTIsMTgwLDMzLDcwLDM3LDgsODQsMTQ1LDEwMSwyMCwzNCwyMjAsMTI0LDMyLDczLDk0LDE0MCwxMzIsMTU2LDU4LDIxMiwxMzEsMTY1LDEzNCwxMzEsMTY5LDE4NCwxODIsOTQsMTU1LDM3LDE2MywyNDAsMzAsMjQ4LDEwNSw3NCw4MCw5MSwxNjIsMjQzLDE4MCw1LDE4NSwxODAsMjcsMTI4LDE3OSw0NCwxMDgsOTcsOTgsMTEyLDE1Niw5NSwzNCwyNywxNDcsMTIsNTgsNSwxMjEsMTk4LDUxLDIwNywxMzksMTA1LDExNCwxODIsNzMsMTYzLDE4MSw3MSwyMjAsMjUxLDE3NSwxOTEsMywxNjcsMjI0LDY2LDE3NCwyMjEsMjI0LDEzNCwyLDQzLDIwNSwzNCw0OCwxMiw0NiwxMjMsMTIsMTUzLDAsMTEsMTksMTI4LDk5LDc0LDE0NywyMDMsMTA5LDEwMywxMDcsMzAsMTUwLDE0OSwxODgsMjEzLDEzMiwzNywxMjksNDEsMTUwLDIxMyw1OCwxNDEsNjUsMTIwLDQwLDU3LDg4LDEzNCwyMjcsNDIsMjA4LDIyOCwxODQsMTE1LDE5NSwxNTAsMjUsMjE5LDEzMCw1LDExMyw2NCwxNTEsMTM5LDU0LDIxNCwxMCwxMzgsMjA1LDEzMSwxMzAsMjksMTYzLDExOSwxOCwxOTQsMTA4LDMwLDEwNiwxMzcsMTAzLDksODQsMjI2LDUsMTc3LDE0MSwxNywxOTAsNywxNjIsNzQsMTk2LDE0NSwxNCwzMCwxNDcsMTgyLDcsMjMwLDE5MCwxMDUsMjQ4LDQxLDI0NywxNTMsMzcsMTI4LDE3MSwxNDIsMTcwLDEwMiwxMzksMSwxNjQsMTcwLDE1NiwxNTEsMjA0LDExNiwyMDAsNzYsNTksMTE0LDE3NCwxOTksMTcsNzUsMTU0LDIxLDYzLDMyLDE5OCwxNzQsMjMsMTQ2LDU4LDI0NCwyNSwxOTAsMjI1LDEyMywxMjMsMjI5LDE3OCw4NiwyNDUsNzAsMTI5LDI1NCwxMjAsNjksNzIsMjUwLDksMzEsNzQsODAsMjEsNSw5MSwyMzQsNzYsMTA0LDIyNiwxOTIsNzYsMjAsOCwxNjIsMTAsOTEsMTcwLDg3LDExNywxNiwyLDIwLDU3LDU0LDIxMiw4NCw3MywxNDAsMTE5LDIzOSw0NCwxNjcsNDcsMjUwLDYyLDE2Myw4OSw5NywxMzIsNDEsOTksNjcsMjI2LDEyLDIxNyw4LDc4LDYsODgsMTMsNjEsNDEsMTI3LDE2MiwxODgsMTkxLDQzLDE4MywxMSwyNywyMTEsMjcsMTksNSwxODIsMTk3LDIzMCwxNjQsNDUsNTcsMjA3LDIwMCwxMDIsNTcsMjI0LDExLDIwNSwxNTAsMjE3LDEyNSw2NiwxNjEsMTM4LDE1OCw0MSw0OSwxNTYsNDQsNiwxNTgsMjA5LDE1NCwxMDYsNTQsMTc5LDEwOCwxMjQsOTQsMjI4LDEyMCwxNjIsMjQ3LDI0NCwxMDEsMjA4LDE5MywxMzcsMTI1LDcwLDUsMjMzLDIyMCwyMDcsMjEsMTI0LDE3NCw0MSwxNTYsMTE3LDcwLDE4MywxMzUsMTkwLDE2Nyw3OCwyNywxOTIsMTg5LDI0MywyMTEsMjAzLDE0MywzLDM0LDE3LDEyOSwxODIsNjUsMTg3LDg5LDE4MCwxNzksMTAsODcsMTIsMTY3LDIxMiwxMzIsMzQsOTYsMTI0LDU5LDI1MywyMiwxMTQsMTc1LDE2OCwxMjgsNCwxODgsMTE5LDEzNSwxLDEyNiwxNTYsMjAyLDE4MiwxMDcsMjQ2LDQyLDE5MCwxNTMsNzYsMTU2LDEyMSwxNzEsODIsMzgsMTgwLDYxLDY0LDYzLDcyLDEwMyw2OSwxNiw0Myw2OCw5NCwxNTAsMTAsMTksNTUsMTcsMTUwLDg5LDc4LDAsMywxMTgsMTA1LDE3MSwxNzUsMTkwLDI1MCw4OSw1Myw5Miw2MywxMjYsOTgsMTE3LDUzLDIwMCwxMzQsMzYsMTk4LDEwNiwxODgsMTgzLDEyMiwyMjcsMTM5LDg5LDIxNSw2NywxMjMsNCwyMjcsMTQ4LDI3LDE5Nyw0NiwxODksODcsMTQ0LDE0NiwxNzksODEsMzEsMjE3LDgwLDE2LDE3OCwxMDUsMTcsMTA2LDE1OCwxMDEsMTU2LDIwNywxMjksMTE3LDc1LDE5NSw5NiwxNTgsMTIzLDEzMiwxNzcsMTEzLDIzMCw0NSwyMTEsMzMsMzYsMTcwLDI4LDE2NiwxOTUsMjEwLDQwLDE4OSw2LDE0NywyMDAsODYsMzAsMjE2LDc1LDE4OCwyMSwyNTAsMTU1LDEyMCw5Niw2MywyMDcsNjUsOTIsMTQsMTcwLDI5LDEyOSw5MSwxOTYsMiwxMTgsNDgsOTQsMTI4LDQ5LDEzMCwyMDgsODgsMjI5LDE4NCw3OCwyMTYsMjM1LDIwMCwxMiwxNjksNjYsMTQyLDM3LDM3LDE1OCwxOTcsMTQxLDIwNyw3LDM5LDIxLDE0NywxNTYsMjM0LDEzMiwxNDIsMSwxODAsMTAxLDk0LDIzMCwxOTIsNjMsMzUsMTQ1LDE3LDQ0LDEwNSw0MywyMywyNSw3MiwxOTIsOCwyMTQsOTAsMTYsMTk0LDEzNywwLDE5MiwxMiw5Niw5MSw4MSwxMTEsMTQ5LDE4Miw3OCwxMjcsMTQ1LDEzMCwxMDIsNTEsMzEsODQsMzksMTQyLDE1NywxNjYsMTYsMTksNjgsMTc0LDkwLDk4LDg2LDExMSwxMzQsMTM4LDEwLDI0MywxMTAsMjM0LDEyMiwyMDUsMjIwLDcxLDU1LDEyNSwxNTUsMTgwLDIzNSwxNTMsMTM2LDEwNiw3NiwxNjUsMjQ4LDkyLDkxLDE4OCwxMjIsMTUwLDEzMSwyMjgsMTA5LDExNCwxMDMsMTcwLDcxLDI0NywxNzcsMTAyLDE4NiwxMjQsNDEsMTUxLDcsMzYsMjcsOTYsMjUyLDQ4LDY5LDIyMywyNTIsMTEzLDExNiwxNzIsOTAsMjMwLDAsMiwxOTAsMTgxLDAsMTIyLDE2NywxNjgsMTc1LDMsMTQ0LDE2MCwyNSw4NiwxNTYsMTcyLDYxLDE5LDIyOSwyMDAsMjE0LDE2NiwxNjEsNTksMzcsNTQsMTkxLDE2Nyw5MSwyNiwzMyw3NiwxNzYsMTE3LDY0LDE3OSwxOTgsMTAzLDEyMCwxMiw4LDEzLDE2MSwyNyw0MCwyNDMsMTc1LDAsMTA4LDcwLDE5OSwxOTgsMTkwLDIyLDI0OCwxMjYsMTc1LDE3OSwxMjYsMTY5LDEzMyw2MiwxNzAsNTMsNiwxOTYsMjAyLDcyLDc2LDE0NSwyMCwxOTUsODAsNzgsNzUsMjUxLDE1OCw4NCwxMDgsMTI4LDEzOSw3MCwxNiw1NSwxNjUsMTY1LDUzLDE2MywxOTQsMjUsMjA2LDE2NywxNTMsMTI1LDE5MywxMDIsMjAsOTEsNjQsMTcsMTY5LDI1NSw5OCwxODIsMTk5LDIwOSw4NSwyNDgsMjM3LDkwLDEwMiwxMzAsMjIyLDEyMiw3MSwxNzAsMTI2LDE5NywyMzgsNTksMjE1LDE3MCwyNTUsMjE4LDMxLDEyMywxMjUsMTU0LDEzMSwyMywxLDUsMjE0LDE4NSwxMjgsMjQzLDE1NiwyMCwxNTUsMTYwLDM5LDUwLDI0MywxMDQsMTU3LDExNiw2LDMwLDg0LDIzLDg4LDEyMywxMDhdfX0sImxlYWZfbm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxOCwxMSwxNjUsMTY1LDEyOSwxNjMsOTksOTcsMTMwLDEzNCwyNTAsMTE3LDE4Myw1OCwxMzUsMTI2LDQ0LDIwMSw0LDIyLDExNywxMTUsMTE4LDE4Myw2LDczLDE3Miw0MywxMTYsMTE3LDE2LDIwMSwyMDMsMzksNjksMjgsMTEyLDE4LDgyLDcyLDQzLDE1MSwxMzMsMjQzLDUzLDIwNywwLDE5MywyMDksODksMTg2LDY2LDIxNiwxNDYsMjA1LDkwLDE0OCw3OCwxNTEsMTM3LDc2LDE0OSw5LDIyOSw4LDE2NCwxNjksMTkzLDIsMTkyLDk3LDE5MywyMTYsMTg2LDEwOCwxNjksMTg3LDExMiwyMTcsMjEwLDExNCw0NiwyMzMsMjAsMjIxLDkxLDE1LDI0Myw5LDEyOSwyMTEsMjIwLDE3OCw3NCwxNDgsMTAwLDc2LDI0NSw0MywxMTQsMTI0LDE2OSwxMzIsMTE3LDM1LDE4MywyNDgsMzMsMTY1LDIsMTIsMjM1LDEyMCw5MywxMDUsMzcsNjMsMTYwLDIzNCw4Nyw4LDU3LDE1OSw3Miw3Miw2OCwyMTYsNSwxMjQsMTM3LDEzMSwxNTAsMTgyLDEzMyw2NSwxLDEwNiw1NiwxNjIsMTM5LDg2LDIwNSwxNiw5MywxMjcsNSwxMzUsMjE5LDE2NSwxNywxNjIsMjcsMjIsMTgsMzMsMTgsMjIzLDI0MSwxMzgsMjAyLDE0MCw0OCwxMDIsODIsMTE4LDE3MCwyMTAsMTcyLDE5MiwxNjQsOTYsMjQ2LDU1LDgxLDE1MSw2Niw2OSw3LDg2LDM3LDE1NywzNCw5MSw3OCwyOCwxNjAsMTA2LDIsMTg1LDE5MSwyNDIsMTk1LDE2MSwxMDYsODIsMjMyLDQyLDExNSwxOTAsMTAzLDg5LDIwMCw1Niw0MiwzNiwxMzIsMTgsMTg2LDI0MSwxNjQsOCwyMTMsODQsNTYsMjExLDEwNywxNzUsMTAzLDUyLDEyMSw1NywxMzcsNjQsMTM1LDQ4LDIyMywxODQsOTYsODcsMjE5LDMwLDE4MSwxNTIsMTg3LDE5MiwxODgsMTQ3LDI0OSw5MiwxMDcsNzEsMjMzLDgzLDEzMiwyMTcsNTUsMjQwLDI0MywxNDIsNDIsMTM4LDE0MiwxMzYsMjQ0LDE5NCwyMTAsMTM1LDUwLDMwLDE3MiwxNjIsMjUyLDE3NiwxMDksOTQsODYsMTU2LDMwLDExOCwyMiwyNTQsMjQxLDExNywxNjUsMTE1LDY4LDE1NywyMTMsMTQzLDI0NywxOTcsNDUsMTQsMTQ0LDg4LDIxMSwxNTYsMjA3LDE1NSwxMDIsMTI4LDI3LDIwOSwxMSwxNjgsNDAsMSwzOCwyMzYsNjIsNCw0MiwxNCwxOTcsMTE0LDY3LDIzOCw3NiwxODQsODksMTYzLDE5LDI0Nyw4OCw2MiwxNTMsMTY1LDEwMCwxNzcsNDgsOTYsNzUsODUsNTMsNzUsMjAxLDE3LDcyLDIxOCw4NCwxNTMsMTU2LDk5LDE0NSw3MywxMjAsMjYsNjksMTY3LDIwNSwxNjcsMTQwLDc3LDEyOSwxOTgsMTk3LDAsMTYxLDE1NCwyMjksMTIyLDQ3LDg1LDE3MiwyNTMsNjksNzcsOTAsNTYsNiwxNCwxMjAsMTIzLDE5NywyNiw0MiwxMTUsMTE4LDY3LDYsMjQ2LDEwNCwyMzAsOTIsNDEsMTQ2LDEwMywxNzcsNDEsMTcyLDE2NiwxMTYsMjQ1LDEwNywxMzgsMTIxLDAsMTExLDEyMiw4MiwyNDEsODEsMTAwLDE4MSwyNDQsNzYsMTUwLDE2MSwyMDEsNSw2OCw1NSwxMjksMTYxLDExMCwxOTEsMjM0LDEzMSwyMzAsMjI3LDE4MSwxNDcsMTM4LDk0LDQsMjgsMTAsMTIxLDMyLDMsMjIsMjQxLDM4LDE2MSwxMjIsMTMyLDczLDExMiw1MiwxODQsMTcsMSwxNTUsMiw0Myw4NCwxOTcsMTgxLDExOCwxNDAsMTc2LDIwMiwxMjgsMTMyLDY0LDE0NywxMjEsMTI5LDMsMzQsOTYsMTE1LDg5LDI0NCwyNDcsMTQ5LDI1LDk2LDIwLDEyOCwyMTAsNiwxMiwyMjksMTIzLDQ5LDIxMCwxMSwyNDYsMTE2LDIwMSwxNzIsMTIxLDEwNywxMzEsNCwxNTQsMTMwLDE3LDE2NywyMjMsMTc3LDE2OCw3OSwxMCwxMTAsMTYxLDIyNCw1LDIzNywyMjQsMTYsMjEyLDM4LDE3NCwxOTIsOSw4OSwxNjIsNTgsNTgsMjU0LDEzOSwyOSwzNCwxNjIsOTYsMTQ2LDE4Niw2LDIxNiwxNTIsNDgsMTA5LDEwNSw2MSwyOSwxMjIsMTIyLDQ1LDE5MywxMDAsMTEsODgsMTc3LDI1MSwyMzEsMTA2LDI2LDk3LDQzLDI0OSwyNDEsNzAsNzIsNzEsMTQyLDQ1LDc2LDI0LDc0LDY5LDkyLDI1Myw1MSw0MywxOTUsMTg4LDIwLDI5LDE5OSwxOTIsMSwxODYsMSwxNjIsMTE2LDE3NSwyMTcsMjMxLDY5LDE4OSwxNzIsMiwyNTIsMTQwLDU1LDYxLDc1LDE2MSw2NSwyMCwxMjIsNzEsMTYyLDY0LDE3MywxOTMsMTY1LDE0LDM1LDEyMSwxMjcsMTMxLDYyLDkyLDExMiwxMzEsMTQyLDEzMCw2NSw1NiwyNTIsMjIsOTAsMjQyLDIwNiw1Myw1MSw1MSwxNzksMzgsMTkwLDEyMCwxMTQsMTYxLDI0OSwwLDE0MiwyMDQsODAsNjUsMTMzLDIzNiwyLDI0NSwyMzAsNzksNzMsOTYsMjAzLDUxLDM3LDIwMSwxOCwxODQsNjMsMjcsOTcsNDMsMTQ4LDg3LDM1LDE3LDI3LDE1MCw1OCwyNDgsMTcwLDIyMywyMjksMTg5LDE3OCwxMzEsODksMTczLDI1MiwxODQsMjMwLDIwMSw4OCw4MywyNDIsODcsMTY1LDEyOCw5NywyOCwxODgsMTU1LDEzNCwxMjEsODAsNywyMzEsNDMsNTUsMjcsMTM3LDczLDQxLDI2LDE1LDEyMCw4OCwxODQsMjA0LDcyLDI0MiwxNzEsNDAsMjI3LDE5LDIzLDIxMCwyMTAsMTkzLDEwMSw4MSwzMSwxNiwxMjEsNDUsMTAyLDE3LDE5LDE3LDEwNiwxMTIsMTk1LDE3OCw0MywxMDQsNiwxMDMsMjksMjI1LDExMiwyMTcsMTk5LDgyLDcxLDAsMTM1LDI1MCwxMzYsMTc3LDEwLDUxLDE3LDEwNSwxODQsMTUwLDE0NywyMTEsMjA1LDY4LDUsMTQwLDI0Nyw0LDM0LDE4OSwxOSwyMiw5NywxNDksMTYsMTMxLDIwLDI4LDI1NCwxOTksNzEsNjMsMTE1LDEwMiwyMDYsODksMzQsOTcsMTQ0LDEzMywxODEsMTQ4LDE4LDYxLDIzMyw2NiwyNDUsMTI5LDE0OSw1NywxMTYsMTgwLDAsNjQsMTM0LDE1NywxMjEsMTUzLDExNSwxMTgsMTM1LDE5NSw0OSwxNTIsMTAxLDY3LDEyNSw4LDEzMSwxMTIsMTY0LDEwNCwxMTEsMjE2LDc0LDE1OSwyNDMsOTgsMTEsMTUwLDEzNSwyMywxNTYsOTAsNDEsODYsMjQxLDIzLDE1OSwyNDAsMjAyLDIyMywxLDk3LDIzNCw0MCw0MiwxNjYsODUsOTksMjIsNTksNzEsODcsMTIyLDM1LDEwMSwxMTksMTI2LDEwOCwyMDksNDIsMjU0LDQyLDEwNywxMTAsMjIsMTIyLDE0Miw5OSwxMTAsMTI3LDE5NywyNywyMzMsMTcyLDEyNSw0NSwxNjksMTUzLDE0LDEzMywxNjAsMjA5LDEwNCw1MiwzMywxMzAsNTUsMjQ3LDEzNywxNzMsNDUsMTA2LDQ0LDQsMjAxLDEzMiwyOSwxOTksOTgsNTIsMTA3LDE4NywxNjMsNDEsMTM1LDI0MywxMzEsMTE3LDI0LDY3LDIwNywxNzAsMTYyLDE0MiwyNCw2NSwxLDE4NCw4MywxNzksMjYsMTAzLDEwNiwwLDQsMywzNSwzNiw1NiwyMTQsMTk3LDIwLDE0NCwxOCw2OCwxMzIsMjMwLDUzLDUyLDU1LDkwLDQsMTg2LDEzOSw4Niw1MSwxOTYsMTgzLDE2NCw5NiwxMDgsMTE3LDU5LDIyOCwyMTEsOTgsMTQ1LDIzNSwxMjEsMTgzLDY4LDg5LDEyNCwxNjAsMTc3LDE5MywyMzMsMTM0LDMyLDE0NCwxMjIsMTIwLDI0MiwxNjgsMjE2LDIxLDg3LDI4LDM5LDUsMjUxLDEyNCwxODAsMTUwLDQ5LDQ4LDcxLDIzMiwxODEsMyw2LDEyLDEwMiwyMjksMjA0LDE2OSwyMzUsNjMsMjUsMTE0LDgxLDM4LDI0MCwxNjksODgsODcsODQsMTM5LDE5OSwyMiwxODcsMTM3LDk0LDE1MiwxOTUsMTg3LDIxMiwxODIsMTI5LDk3LDIxMiwxNTgsMzEsNywxNjgsMjUxLDIwMSwxNTMsMTEwLDIxNSw0NywxMTgsMjQ1LDQwLDIzLDEwNCwxMTQsMTU0LDEzOSwwLDIyOCwzNyw3MSw5MCwxODgsNzEsMzEsMTg1LDE1NywxMzIsMTg4LDE0NSwyNDQsMTEzLDE3MywyNDksMTUzLDg5LDEzOSw4MywxMywxNywxODIsMTMyLDIwMCwyOCwxODgsNzUsMTk1LDE5MCwyOCwxMjEsMTk4LDc4LDM0LDIxLDIxLDUxLDE4MywzMiw5OCwxOTAsMTk4LDEzMSwxNzEsMjMsMjMsMTk2LDE1MSwyNDAsMTk3LDE0Myw0MSwxMiw4MSwzNCwyMywxNDQsMjYsODUsMTUsMTI0LDE2Miw3Myw5NiwxNDUsMjM4LDgsNjMsMTksMTAxLDQwLDIwOSwzNCwxMDAsMjE3LDY2LDU1LDQzLDIxMywyNiwxOTAsMTU2LDY4LDY3LDE3Nyw1LDExNSwxMzAsMTcwLDk4LDk3LDEyMywxNzYsMjgsMTQ1LDE2Myw2NSwxNyw0OSw1MSwxOTgsNTksMTU2LDExMCw1NSwyNSw5MCw4MiwxNDgsMTc4LDE3Nyw3LDEwMSwxMzIsMjM1LDgyLDE1LDI1MSwzMCwxNTQsMTg4LDE2NywxODUsMTk0LDE3NCw4OCwyNDUsMTA2LDUyLDM4LDE5NywyNTAsMjAxLDEyNywxMjIsODcsMTE1LDE2MCw3MCwyOSwxNjEsMTEyLDc4LDUzLDI0MCwyNCwyNDIsMTIsMjUwLDE3OSw5MSwxMzcsNjksMTk4LDgwLDU0LDI0NSwyNSwzLDc3LDEyMiwxMTUsMTc0LDEzLDE4LDE0MCwxMjQsNzYsMTc1LDIwMCw0MywyLDU2LDI0MSwxNjgsMTgsMjksODAsMTk3LDIwMSw1NiwyMTcsNTksNTYsNTIsNDIsMTA4LDU2LDE4NCw2NywxOTgsMTE1LDI3LDIyNSwyMDQsNywyMTQsMTEyLDE5MSwyMjYsMjI1LDEyMiwxOTgsNjIsMTY2LDE1NiwxNTIsMjQwLDMzLDM1XX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6WzE0OCw3OSw5OCwyMDIsMjUxLDEzNywxMDEsMTQ1LDEzOCwyNDIsMjQ4LDE1MywyNiwxNDYsMTg2LDIzLDI0NywzMCwyMjIsMTE4LDIxMywyNTUsMjExLDY5LDI0MSwxNjAsMjU1LDIxNywxMTcsMjgsMjQ4LDIyOF19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk5LDEwNCw5NywxMTQsMTA4LDEwNSwxMDFdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IktleVBhY2thZ2UiOnsibm90X2JlZm9yZSI6MTcyMDY4ODk1MCwibm90X2FmdGVyIjoxNzI3OTUwMTUwfX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbMyw0NCwyNDQsMyw4OSw1NSw2MiwyNSwxNzUsMTg2LDQ4LDE3OSwxMzEsNDIsMTc5LDEyNCw3MSwyMTQsMTI4LDE3MSwxMTgsNDQsMTk4LDE3OSwxOTYsMzMsMTcxLDE5Myw2Nyw5Miw4NSwxMjQsMTY3LDE5Nyw0MiwyMDgsMjU1LDE0Nyw4NCwxNjMsNTcsMjI4LDE2OSwyNTAsODYsOTcsNzgsODgsMTgyLDEzLDIyMCwxMDAsMjQzLDE3MSwyMzUsMTYyLDE5OSwzMSwxNjEsMjA0LDEyNyw1MCwxNDYsNF19fX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbMTAyLDExOSwyNTAsNzEsMTI2LDIxLDIwMSw5NSwxNTUsOTQsMjQsMjAyLDg0LDM1LDIyNywxNDksMjksOSwyMzMsMjgsMTM1LDY3LDY0LDE1MiwxOTAsMTEsODMsMjEsMjU0LDE2NywyMjcsMTkzLDE3OSwyNTUsMTc3LDIxMSwxODcsNDcsMjUwLDMsMjMyLDE1NCwxMzksNjUsNjQsOTUsOCwyNTMsNzYsMTA0LDE1NSwxMzYsMTQ2LDEyNSw5Myw1MywxMiwyNCwyMDgsOTMsMjA0LDIxNCw4MiwxXX19fX19LCJwcm9wb3NhbF9yZWZlcmVuY2UiOnsidmFsdWUiOnsidmVjIjpbMTksMTUsMTA3LDIzMSwyMDEsOTgsMjQ0LDMyLDE3MywxNzksNzMsMTU1LDE0LDQsMzEsMzgsMjM5LDExNiwxNjQsMTg0LDEyNSwxMDIsMTI0LDEzMyw5NCw0NSwzNiwyNDAsMTMzLDExMCwyNTMsNDRdfX0sInNlbmRlciI6eyJNZW1iZXIiOjB9LCJwcm9wb3NhbF9vcl9yZWZfdHlwZSI6IlJlZmVyZW5jZSJ9AAAAAAAAAFoAAAAAAAADJkVwb2NoU2VjcmV0c3sidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsiaW5pdF9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE4NCw1MSw3MSw5NiwxNzUsMjExLDE5OCw0LDE4Nyw1MywxNDIsMTc5LDE1MSw5LDMwLDY5LDE0NywyMDksMTkzLDE3OSwxODgsMTM4LDE2MiwxODQsMTkxLDY3LDE2NSwxNjIsMTk0LDYxLDI0NiwxNjNdfX19LCJleHBvcnRlcl9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE5MSwyMTgsNDMsNjYsMTQ0LDkyLDAsMjMwLDIyNiwzMywxODksMTY1LDY5LDEsMjUwLDI0NCwyOCwyMDIsMTczLDIyOCw5MSw4NSwxMDMsMjQ5LDEyNyw0NSwxMCw5OSwyMjgsODMsMCwxMDRdfX19LCJlcG9jaF9hdXRoZW50aWNhdG9yIjp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOls5NiwxMjYsMjI4LDg0LDIwOCwxMDcsMTAxLDk0LDE1OSw4NCwyMzcsMTYzLDU5LDQ0LDEzMSwyMTcsMjQ3LDU2LDIxOCwxMjEsMTE0LDI1NSwzMSw2Nyw3MiwzNCwxLDY3LDE2LDE2NiwxNjIsNjVdfX19LCJleHRlcm5hbF9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE4LDIxNSw0MiwyMTUsMjQ1LDYzLDEzNiwxMjMsMTIsNDYsMTI5LDIwNCw1MCwxNDgsMjM0LDIyMiw0NCwzNiwxNjgsMTYyLDIwNywxMDgsMjUsMTM4LDEwOSwyMzUsMTU0LDIsMjQ1LDMwLDEzMSw5XX19fSwicmVzdW1wdGlvbl9wc2siOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzkyLDMwLDE4LDM2LDE3NiwyMjAsNDYsNDMsMTkwLDcsNDUsNzgsMjQxLDEwMiwxNDMsMjQ2LDI3LDE2LDE2MCwyMjQsMjQsMTE0LDI1LDU0LDEyOCwyMjcsMjIsNTIsNjMsMjA2LDEwMiwxMV19fX19"]},"MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519":{"group_id":{"value":{"vec":[214,206,173,27,206,87,231,4,172,30,130,210,232,69,61,222]}},"storages":["AAAAAAAAAA0AAAAAAAAAXQAAAAAAAACBQ29uZmlybWF0aW9uVGFneyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJtYWNfdmFsdWUiOnsidmVjIjpbMTk1LDUzLDIzLDc2LDQ0LDE3MSwyMSw1LDE3MCwxMzAsNCwxODIsMjI3LDM4LDIxNSwxMTgsNTUsMjQ4LDY4LDEwMywyMiw5MCwwLDEyOCwxODAsNDgsMTkwLDM1LDE2LDUsMjE1LDY5XX19AAAAAAAAAFoAAAAAAAABhkdyb3VwQ29udGV4dHsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsicHJvdG9jb2xfdmVyc2lvbiI6Ik1sczEwIiwiY2lwaGVyc3VpdGUiOiJNTFNfMTI4X0RIS0VNWDI1NTE5X0FFUzEyOEdDTV9TSEEyNTZfRWQyNTUxOSIsImdyb3VwX2lkIjp7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19LCJlcG9jaCI6MCwidHJlZV9oYXNoIjp7InZlYyI6WzE2NSw3MSwxMCwxMDAsOTMsMTg0LDI0NiwyMzksMTc2LDIzNiwzMCwxMjEsMTY2LDU1LDE2MCwxNyw4NywxNjcsMTAsMjI5LDM5LDE2MywxNzEsMjIyLDIyNCwxNzEsOTQsNDEsMTUxLDkxLDExNyw1NF19LCJjb25maXJtZWRfdHJhbnNjcmlwdF9oYXNoIjp7InZlYyI6W119LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fQAAAAAAAABcAAAAAAAABCtNZXNzYWdlU2VjcmV0c3sidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsibWF4X2Vwb2NocyI6MCwicGFzdF9lcG9jaF90cmVlcyI6W10sIm1lc3NhZ2Vfc2VjcmV0cyI6eyJzZW5kZXJfZGF0YV9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzIzMyw1MSwxNTMsMTQwLDI5LDQ1LDI1MiwyNTIsOTQsMTk3LDQ0LDEwMSwxNzAsMTc5LDI5LDI3LDE1MCw3OCwxNjEsMzEsMTksMjUsMTQ5LDEwOSwyMDMsMjE1LDUzLDI0LDE5MCw1LDE3MiwxNzddfX19LCJtZW1iZXJzaGlwX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbODAsMTU3LDE0MywzMSwyMDQsMjI5LDI0Myw0OCw2MCw4MiwxODEsMjcsMjI5LDEwNSwxODgsNjYsNTEsOTEsODAsMTUwLDg1LDEzOCwzMSwyNDMsNTksMTI0LDEwMSwxMTcsMjQ5LDE3MywxMjgsNjRdfX19LCJjb25maXJtYXRpb25fa2V5Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyLDEyNiwzMywxMDIsMTgzLDMsNDksNDMsMjEwLDE0OCwyNTMsMjAyLDE5OSw4MSw0MCw4MCwzLDExNSw4LDE0OSwyNCwyMTgsMTk1LDc5LDQzLDExNywxMTEsODMsMTg2LDEsMTc0LDI1NV19fX0sInNlcmlhbGl6ZWRfY29udGV4dCI6WzAsMSwwLDEsMTYsMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjIsMCwwLDAsMCwwLDAsMCwwLDMyLDE2NSw3MSwxMCwxMDAsOTMsMTg0LDI0NiwyMzksMTc2LDIzNiwzMCwxMjEsMTY2LDU1LDE2MCwxNyw4NywxNjcsMTAsMjI5LDM5LDE2MywxNzEsMjIyLDIyNCwxNzEsOTQsNDEsMTUxLDkxLDExNyw1NCwwLDBdLCJzZWNyZXRfdHJlZSI6eyJvd25faW5kZXgiOjAsImxlYWZfbm9kZXMiOlt7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxOTQsODcsMjA3LDE4LDE0MCwxMjksMTYxLDEwLDkyLDIxOSwxMDgsMTY4LDIzNSwyMDEsODEsMTE1LDQxLDk2LDIxMywxNCwyMzQsMTM1LDE3Niw0OSwxMTgsMjI4LDU1LDM4LDU3LDExMCwx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cmV0cyI6eyJzZW5kZXJfZGF0YV9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzIzMyw1MSwxNTMsMTQwLDI5LDQ1LDI1MiwyNTIsOTQsMTk3LDQ0LDEwMSwxNzAsMTc5LDI5LDI3LDE1MCw3OCwxNjEsMzEsMTksMjUsMTQ5LDEwOSwyMDMsMjE1LDUzLDI0LDE5MCw1LDE3MiwxNzddfX19LCJtZW1iZXJzaGlwX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbODAsMTU3LDE0MywzMSwyMDQsMjI5LDI0Myw0OCw2MCw4MiwxODEsMjcsMjI5LDEwNSwxODgsNjYsNTEsOTEsODAsMTUwLDg1LDEzOCwzMSwyNDMsNTksMTI0LDEwMSwxMTcsMjQ5LDE3MywxMjgsNjRdfX19LCJjb25maXJtYXRpb25fa2V5Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyLDEyNiwzMywxMDIsMTgzLDMsNDksNDMsMjEwLDE0OCwyNTMsMjAyLDE5OSw4MSw0MCw4MCwzLDExNSw4LDE0OSwyNCwyMTgsMTk1LDc5LDQzLDExNywxMTEsODMsMTg2LDEsMTc0LDI1NV19fX0sInNlcmlhbGl6ZWRfY29udGV4dCI6WzAsMSwwLDEsMTYsMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjIsMCwwLDAsMCwwLDAsMCwwLDMyLDE2NSw3MSwxMCwxMDAsOTMsMTg0LDI0NiwyMzksMTc2LDIzNiwzMCwxMjEsMTY2LDU1LDE2MCwxNyw4NywxNjcsMTAsMjI5LDM5LDE2MywxNzEsMjIyLDIyNCwxNzEsOTQsNDEsMTUxLDkxLDExNyw1NCwwLDBdLCJzZWNyZXRfdHJlZSI6eyJvd25faW5kZXgiOjAsImxlYWZfbm9kZXMiOltudWxsXSwicGFyZW50X25vZGVzIjpbbnVsbF0sImhhbmRzaGFrZV9zZW5kZXJfcmF0Y2hldHMiOlt7IkVuY3J5cHRpb25SYXRjaGV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNjEsOTAsMTI2LDI1NCwxMTcsMzEsMTAsMTMsODQs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MCwxNzQsMTE4LDIwNCwyNTEsMjAyLDE3NiwyMDMsMTQyLDk1LDEyMywzOSwzNSwxMDEsMTA0LDE3Miw5OSw1NiwxMDYsMTMwLDE1NSwwLDI0XX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6Wzg0LDE2OSw2NSwxNDksNzUsMjI2LDE5MSwzMywyNTQsMTQxLDE3LDIxMSwxODEsNDgsOTEsMTU5LDEwMCw0NSw3OCwxMTIsNzksMTQ4LDEzLDE1LDIyMiwxOTYsMjExLDY5LDE1NiwzNiwxOTEsMTBdfX0sImNyZWRlbnRpYWwiOnsiY3JlZGVudGlhbF90eXBlIjoiQmFzaWMiLCJzZXJpYWxpemVkX2NyZWRlbnRpYWxfY29udGVudCI6eyJ2ZWMiOls5NywxMDgsMTA1LDk5LDEwMV19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiS2V5UGFja2FnZSI6eyJub3RfYmVmb3JlIjoxNzIwNjg4OTQ5LCJub3RfYWZ0ZXIiOjE3Mjc5NTAxNDl9fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMTIsMjQ5LDIyMCwxNjYsMTg1LDU2LDE1MCw5NywxNDAsMjE0LDIxMiwyMjAsMTczLDE4OSwxNDcsMTI1LDE0NywyMTAsNTcsNjYsNDgsMTQ0LDE1MCwyMDUsMjgsMzYsMTMyLDM5LDE0MiwxNDYsMTMxLDkzLDEzNCwxODgsODcsMTQ4LDAsMjIsMTM0LDM4LDYsMTMzLDUwLDIzNyw3MywxNzUsMjM2LDIxNCwxNjIsMywxMTUsMTIxLDU5LDI0MSwxNiwxNzEsOTksMTA1LDg0LDE2OSwyNDgsMjUsMTk2LDhdfX19fV0sInBhcmVudF9ub2RlcyI6W10sImRlZmF1bHRfbGVhZiI6eyJub2RlIjpudWxsfSwiZGVmYXVs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eyJ2YWx1ZSI6eyJ2ZWMiOls5MiwyMTgsMTg4LDE1OCw0OCw4Myw3OSw4MywxNjYsMTM2LDEzOCwxODMsMzIsMTE4LDQ5LDEzMywxODYsMTY0LDg1LDg5LDE5MiwxMDQsNjEsNjksMTU0LDExMywyMTQsMjI1LDIwNCwxNjEsMTg5LDQ4XX19LHsicHJvcG9zYWwiOnsiQWRkIjp7ImtleV9wYWNrYWdlIjp7InBheWxvYWQiOnsicHJvdG9jb2xfdmVyc2lvbiI6Ik1sczEwIiwiY2lwaGVyc3VpdGUiOiJNTFNfMTI4X0RIS0VNWDI1NTE5X0FFUzEyOEdDTV9TSEEyNTZfRWQyNTUxOSIsImluaXRfa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxODAsMjI0LDc1LDg3LDE0LDM1LDEzNCw2MCwzNiw5MSwzMCwyNDUsMTQsMjA3LDk1LDE2MSwxMzYsMjAwLDEwNywxNDEsMjU0LDk2LDE5Miw1NCwxODUsMTU5LDI0MSw3NywxMjIsMTA0LDI0Niw3NF19fSwibGVhZl9ub2RlIjp7InBheWxvYWQiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzcxLDEwLDY5LDIwLDIsOTIsNzAsODksMjI0LDQ4LDEyNiw3OCwxMjQsMTg2LDE0OCwxNTksMjQ1LDE3NSwxMjIsMTU1LDE2LDIwOSwxNTMsMjE2LDIyLDE0MSwxMTcsNzUsOTcsNzIsMjQ3LDM2XX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6WzI1NCwxODIsOTUsMTg3LDI5LDEwNiwyNDEsMjgsMTk0LDIwMyw1NiwzNywyMDcsNjAsNiw4LDExOCwxNzcsMzksMTU0LDIyMSwxNiwxNywyNTIsNjAsMjE5LDEyMiwyMjIsMTYzLDIzMywxMzIsMjVdfX0sImNyZWRlbnRpYWwiOnsiY3JlZGVudGlhbF90eXBlIjoiQmFzaWMiLCJzZXJpYWxpemVkX2NyZWRlbnRpYWxfY29udGVudCI6eyJ2ZWMiOls5OCwxMTEsOThdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IktleVBhY2thZ2UiOnsibm90X2JlZm9yZSI6MTcyMDY4ODk0OSwibm90X2FmdGVyIjoxNzI3OTUwMTQ5fX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbNDksMTAxLDE5MSw2MCwxNjcsMjQ1LDIyMiwyMDIsMjA4LDMwLDIxMiwxMzksNjUsMTAsMjksMjM4LDE5Niw3NCw4Nyw1MCw3LDE2MywyMTgsMTA2LDYzLDMsODcsMjAzLDEzLDIzLDEwLDIyLDEzLDgxLDE0MCwxNzgsOTEsMTE0LDQ0LDIyNSw3NSw3LDIyOSw4MSwxMzcsNjMsMTI0LDE1NSwxNjAsMjQsMTgyLDQyLDkzLDUyLDI0LDE2NywxOTksMjAyLDE3OSwxNjAsMTU4LDYyLDE2LDEzXX19fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNjMsMTEwLDE3Miw1NiwyMTgsMjI2LDU4LDU5LDE5NSwyMDksMTI3LDI0NCw1OSwyMDQsMTg2LDgwLDE3Miw4LDE4MSwyMjksMTcsMTAwLDIyOCw5MCwyMjUsNjIsMjQxLDI0OCwxMjEsMTMxLDEwNSwxNDcsMjI3LDE5OCwxNzgsODgsMjMzLDExOCw5MCw5NywyNDQsMTQsMTk2LDI5LDEwNiwxODgsMjYsMTI1LDEyMiwxMzksMjMwLDc0LDk3LDIwNSw1Miw0OCwyNCwyMTUsOTgsMTc3LDE1LDg0LDcwLDldfX19fX0sInByb3Bvc2FsX3JlZmVyZW5jZSI6eyJ2YWx1ZSI6eyJ2ZWMiOls5MiwyMTgsMTg4LDE1OCw0OCw4Myw3OSw4MywxNjYsMTM2LDEzOCwxODMsMzIsMTE4LDQ5LDEzMywxODYsMTY0LDg1LDg5LDE5MiwxMDQsNjEsNjksMTU0LDExMywyMTQsMjI1LDIwNCwxNjEsMTg5LDQ4XX19LCJzZW5kZXIiOnsiTWVtYmVyIjowfSwicHJvcG9zYWxfb3JfcmVmX3R5cGUiOiJQcm9wb3NhbCJ9XV19LCJzdGF0ZSI6eyJHcm91cE1lbWJlciI6eyJncm91cF9lcG9jaF9zZWNyZXRzIjp7ImluaXRfc2VjcmV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyMiw4NSwxMzksOTQsMTM5LDE5MSwxMCw1MCwyMDMsMjE2LDU1LDc4LDEzLDI1MSw3NSw5MywxOTMsMTY3LDQxLDk1LDE3NywzMSwyNDEsMTE3LDE3MCwyMDUsMTIyLDEwNSwxMzIsMTcyLDEwNSwxMTddfX19LCJleHBvcnRlcl9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6Wzc5LDIzMCwxMzUsMTEyLDEzOCwyNDQsMjU1LDI1MSwyMjIsMTA3LDUyLDEwMSwxMDcsMzgsMTIyLDM2LDE4Niw4OCwyMTAsMTk2LDE0OSwyMTEsMTU0LDk0LDEwOSwwLDE0OSwxNywxNDksMTQ2LDY0LDEwMV19fX0sImVwb2NoX2F1dGhlbnRpY2F0b3IiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzIyNiw1MSw0OSwxNzQsMjM5LDc3LDQwLDExNSwyNTUsMTc1LDM4LDkwLDIwMiwxOTcsODYsMTQxLDE2NiwyMjMsMjQ3LDIyOSwxODksMjI4LDExMywyMzMsODAsMTM4LDg4LDIwLDY2LDE3Niw5MCw1Ml19fX0sImV4dGVybmFsX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTIwLDIzNywxMTksMTIyLDY3LDExMCw4OSwyNDYsMjA1LDE0OCwxOTYsMjQxLDE0NiwxMzksNDksMiwyNDgsMTk1LDUxLDY2LDk2LDEwNiwxMzksMzAsMjQyLDE5OCw5OSwyMTcsODIsMjQ5LDE2Nyw3Ml19fX0sInJlc3VtcHRpb25fcHNrIjp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMSw3NSwyMzksMjQsMjM2LDE2OSwyNTAsMTQ0LDg3LDEzMyw4MywxMjAsOTEsMjA0LDE4NCw4NiwxNDQsMTEwLDIzMiwyMDEsMTU2LDQsMjExLDE1NiwxNzcsMzksMzUsMjMwLDIxOSwxNywxMDcsNTBdfX19fSwibWVzc2FnZV9zZWNyZXRzIjp7InNlbmRlcl9kYXRhX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMzYsMTk1LDcyLDc3LDE2NCwyMCwyNSwyMTgsMjQ4LDExLDEwNiwyMTMsMjI5LDYsNjksNzYsMTA2LDg2LDEwNiwxNywyNTIsMjM1LDgyLDIxMCw1NiwxMTgsMzYsODAsMCwxMzYsMTU4LDQzXX19fSwibWVtYmVyc2hpcF9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzExLDEwNSw5MCwxMiwyMTAsODgsNDksODEsMTY4LDEyMywxNDgsMTE5LDk4LDQwLDE4Nyw4NSwyMDIsMjAxLDE3NCw0MywxMjgsMzYsMTI1LDE3MywxMjQsMywzOCwyMDYsOTcsMTk5LDExMywxMTldfX19LCJjb25maXJtYXRpb25fa2V5Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOls0MCwxNTcsOTUsMTU1LDE2OCwxNTYsMTk5LDQ3LDIwMCwxMTMsODQsMjM1LDE0MCwyNSw3NSw1Myw2NiwxNzEsMjM1LDE2NSwxODIsMjEwLDEwOCwxNjQsMjE1LDEwNCwxMzEsNjAsMTIsNSwxMTgsMTIzXX19fSwic2VyaWFsaXplZF9jb250ZXh0IjpbMCwxLDAsMSwxNiwyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMiwwLDAsMCwwLDAsMCwwLDEsMzIsMiwxNjMsMTExLDIzNywxNDYsMjI4LDEyNCwyMDUsMTUyLDQyLDc2LDQ4LDkyLDk5LDQxLDE0NSwyMjQsMzksOSwxNDUsMTgzLDE2NCwyMjEsMTA4LDE2LDIsNTcsMjUwLDYsMTM0LDIyMywyNDksMzIsMjEsMTM1LDE5NCwxMjIsMjQ4LDExMCwxMDMsMTE3LDExNSw1OSwyMSwyMDQsNjEsMTA3LDE5NiwxMzMsMzEsMjQxLDE2LDEzNiwxMjMsMTUyLDEzNSwxNTQsMTc1LDE2NywyMDUsOTcsMTMyLDE4NywzLDMsMF0sInNlY3JldF90cmVlIjp7Im93bl9pbmRleCI6MCwibGVhZl9ub2RlcyI6W251bGwsbnVsbF0sInBhcmVudF9ub2RlcyI6W3sic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE4OSwyNDIsNTYsODUsODksMTg3LDExMSwyMTUsMTYzLDE5NSwyMTIsMjYsMjAxLDExOCwyNDcsNjEsNTIsNjgsMjI3LDEwNSw1NSwxNTEsODEsMjQzLDY3LDIzNiwxNjksMjEyLDExNiwxNTksMjEsMTc2XX19fSxudWxsXSwiaGFuZHNoYWtlX3NlbmRlcl9yYXRjaGV0cyI6W251bGwsbnVsbF0sImFwcGxpY2F0aW9uX3NlbmRlcl9yYXRjaGV0cyI6W251bGwsbnVsbF0sInNpemUiOjN9fSwic3RhZ2VkX2RpZmYiOnsic3RhZ2VkX2RpZmYiOnsiZGlmZiI6eyJsZWFmX2RpZmYiOnsiMCI6eyJub2RlIjp7InBheWxvYWQiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzE2NiwyMzksMjUsMTk0LDIxNSwxMTcsOTcsMjM5LDAsMjI0LDE5LDUyLDEyNiwyMDIsMTA5LDI1NCwyMywxMzYsMTU2LDM5LDE2MSwxMzMsOTUsMzgsMzUsMTIzLDEyNCwxMzgsMjUsMjM2LDg4LDEwMF19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOls4NCwxNjksNjUsMTQ5LDc1LDIyNiwxOTEsMzMsMjU0LDE0MSwxNywyMTEsMTgxLDQ4LDkxLDE1OSwxMDAsNDUsNzgsMTEyLDc5LDE0OCwxMywxNSwyMjIsMTk2LDIxMSw2OSwxNTYsMzYsMTkxLDEwXX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTcsMTA4LDEwNSw5OSwxMDFdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IkNvbW1pdCI6eyJ2ZWMiOls3LDE4Nyw2OCwxNyw0MiwyMTMsMTkzLDMwLDE0OCwxMzUsNjEsNDQsMjQ3LDEzNiwxODYsMTIwLDIwMywxNjQsMjI2LDExMyw0OSwxNzYsMTUxLDEyOSwxNzAsMTkwLDE5MSw2OCwxNDYsMjI0LDE0OCwxOTJdfX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbOTksMjQzLDIzMiw3NSwxMzgsNjUsMTQ3LDI0OSwyMTcsNzgsMjA3LDEzMSwxMiwxNjQsMTc0LDg4LDE0LDIwLDEyMSw5OSw2MCwyMDksMjM4LDkyLDI4LDIyLDE0NiwxNjQsOTUsMTAxLDU0LDEzNCwxMyw3MCwxNCwxNTIsMjQyLDkzLDE0NywxLDE2MiwxNDgsMTU0LDE0MCw0NSwxNDksMTI1LDE4NSwxMjksMjA0LDg4LDIwMiwyNSw1NywzMiwxMjAsMTQxLDE0OSwyMDksMTAsMTU4LDE5MywyMTQsOF19fX19LCIxIjp7Im5vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbNzEsMTAsNjksMjAsMiw5Miw3MCw4OSwyMjQsNDgsMTI2LDc4LDEyNCwxODYsMTQ4LDE1OSwyNDUsMTc1LDEyMiwxNTUsMTYsMjA5LDE1MywyMTYsMjIsMTQxLDExNyw3NSw5Nyw3MiwyNDcsMzZdfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbMjU0LDE4Miw5NSwxODcsMjksMTA2LDI0MSwyOCwxOTQsMjAzLDU2LDM3LDIwNyw2MCw2LDgsMTE4LDE3NywzOSwxNTQsMjIxLDE2LDE3LDI1Miw2MCwyMTksMTIyLDIyMiwxNjMsMjMzLDEzMiwyNV19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk4LDExMSw5OF19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiS2V5UGFja2FnZSI6eyJub3RfYmVmb3JlIjoxNzIwNjg4OTQ5LCJub3RfYWZ0ZXIiOjE3Mjc5NTAxNDl9fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0OSwxMDEsMTkxLDYwLDE2NywyNDUsMjIyLDIwMiwyMDgsMzAsMjEyLDEzOSw2NSwxMCwyOSwyMzgsMTk2LDc0LDg3LDUwLDcsMTYzLDIxOCwxMDYsNjMsMyw4NywyMDMsMTMsMjMsMTAsMjIsMTMsODEsMTQwLDE3OCw5MSwxMTQsNDQsMjI1LDc1LDcsMjI5LDgxLDEzNyw2MywxMjQsMTU1LDE2MCwyNCwxODIsNDIsOTMsNTIsMjQsMTY3LDE5OSwyMDIsMTc5LDE2MCwxNTgsNjIsMTYsMTNdfX19fX0sInBhcmVudF9kaWZmIjp7IjAiOnsibm9kZSI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbMTMsMTgxLDYyLDE1OSwyNywyNTUsMjQzLDIxMSwyNDcsNTIsMjQ3LDEzOCwzNywyNTUsNjAsMzAsMTI0LDUwLDY0LDc5LDI0MSwyMjEsMTU1LDM1LDIwNiwyMjksMTQwLDczLDE4LDI0NiwyNDYsODVdfX0sInBhcmVudF9oYXNoIjp7InZlYyI6W119LCJ1bm1lcmdlZF9sZWF2ZXMiOnsibGlzdCI6W119fX19LCJzaXplIjozfSwibmV3X3RyZWVfaGFzaCI6WzIsMTYzLDExMSwyMzcsMTQ2LDIyOCwxMjQsMjA1LDE1Miw0Miw3Niw0OCw5Miw5OSw0MSwxNDUsMjI0LDM5LDksMTQ1LDE4MywxNjQsMjIxLDEwOCwxNiwyLDU3LDI1MCw2LDEzNCwyMjMsMjQ5XX0sImdyb3VwX2NvbnRleHQiOnsicHJvdG9jb2xfdmVyc2lvbiI6Ik1sczEwIiwiY2lwaGVyc3VpdGUiOiJNTFNfMTI4X0RIS0VNWDI1NTE5X0FFUzEyOEdDTV9TSEEyNTZfRWQyNTUxOSIsImdyb3VwX2lkIjp7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19LCJlcG9jaCI6MSwidHJlZV9oYXNoIjp7InZlYyI6WzIsMTYzLDExMSwyMzcsMTQ2LDIyOCwxMjQsMjA1LDE1Miw0Miw3Niw0OCw5Miw5OSw0MSwxNDUsMjI0LDM5LDksMTQ1LDE4MywxNjQsMjIxLDEwOCwxNiwyLDU3LDI1MCw2LDEzNCwyMjMsMjQ5XX0sImNvbmZpcm1lZF90cmFuc2NyaXB0X2hhc2giOnsidmVjIjpbMjEsMTM1LDE5NCwxMjIsMjQ4LDExMCwxMDMsMTE3LDExNSw1OSwyMSwyMDQsNjEsMTA3LDE5NiwxMzMsMzEsMjQxLDE2LDEzNiwxMjMsMTUyLDEzNSwxNTQsMTc1LDE2NywyMDUsOTcsMTMyLDE4NywzLDNdfSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sImludGVyaW1fdHJhbnNjcmlwdF9oYXNoIjpbOTcsMiwyOCwzNiwxMDksNSw0MSw0MywxMywxNDgsMjMxLDEyLDE4NywyMjksMjUwLDIxOCw0MiwxMDMsOTMsMTQ0LDExNCwxOTksMTIxLDI1MCwxMTAsMTM2LDIxMyw4NCwyNTAsMTI3LDQyLDY3XSwiY29uZmlybWF0aW9uX3RhZyI6eyJtYWNfdmFsdWUiOnsidmVjIjpbNDMsMjQwLDE4OCwyMzUsNzksNjIsNiwxNzksMTk1LDE0MCwzMSwxNDgsMjEsMjA1LDIzNSw3NSwxOTEsMjA2LDE1NywxODIsMTEwLDMyLDExMywxNTksMTYsNzEsMTU2LDEyNSwxNjgsMjAxLDEyNiwyMjRdfX19LCJuZXdfa2V5cGFpcnMiOlt7InB1YmxpY19rZXkiOnsia2V5Ijp7InZlYyI6WzE2NiwyMzksMjUsMTk0LDIxNSwxMTcsOTcsMjM5LDAsMjI0LDE5LDUyLDEyNiwyMDIsMTA5LDI1NCwyMywxMzYsMTU2LDM5LDE2MSwxMzMsOTUsMzgsMzUsMTIzLDEyNCwxMzgsMjUsMjM2LDg4LDEwMF19fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6WzI0Niw5OCwxMzgsNywyLDIyLDQ0LDE2MSwxNTEsMTI0LDQ5LDEzMCwxNjgsMTksMTMxLDczLDE0OCwyMzAsMTEwLDU5LDE3OCw5NywyMiwxNjcsMjQyLDg1LDIzNCwxMDEsNjMsNTgsMjM5LDI0NF19fX0seyJwdWJsaWNfa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxMywxODEsNjIsMTU5LDI3LDI1NSwyNDMsMjExLDI0Nyw1MiwyNDcsMTM4LDM3LDI1NSw2MCwzMCwxMjQsNTAsNjQsNzksMjQxLDIyMSwxNTUsMzUsMjA2LDIyOSwxNDAsNzMsMTgsMjQ2LDI0Niw4NV19fSwicHJpdmF0ZV9rZXkiOnsia2V5Ijp7InZlYyI6WzI3LDIyOSwxNDIsODMsMzQsMTQxLDMwLDYyLDExNSwxMywxOTAsNzgsODEsMTUxLDk4LDE4LDI5LDU0LDIxOCw2MSw2MCwyMzAsMzMsNzgsMTM0LDE5OSwxMTgsNjIsMTk1LDI0MiwxMjYsMjMzXX19fV0sIm5ld19sZWFmX2tleXBhaXJfb3B0aW9uIjpudWxsLCJ1cGRhdGVfcGF0aF9sZWFmX25vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbMTY2LDIzOSwyNSwxOTQsMjE1LDExNyw5NywyMzksMCwyMjQsMTksNTIsMTI2LDIwMiwxMDksMjU0LDIzLDEzNiwxNTYsMzksMTYxLDEzMyw5NSwzOCwzNSwxMjMsMTI0LDEzOCwyNSwyMzYsODgsMTAwXX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6Wzg0LDE2OSw2NSwxNDksNzUsMjI2LDE5MSwzMywyNTQsMTQxLDE3LDIxMSwxODEsNDgsOTEsMTU5LDEwMCw0NSw3OCwxMTIsNzksMTQ4LDEzLDE1LDIyMiwxOTYsMjExLDY5LDE1NiwzNiwxOTEsMTBdfX0sImNyZWRlbnRpYWwiOnsiY3JlZGVudGlhbF90eXBlIjoiQmFzaWMiLCJzZXJpYWxpemVkX2NyZWRlbnRpYWxfY29udGVudCI6eyJ2ZWMiOls5NywxMDgsMTA1LDk5LDEw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dWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsibWF4X2Vwb2NocyI6MCwicGFzdF9lcG9jaF90cmVlcyI6W10sIm1lc3NhZ2Vfc2VjcmV0cyI6eyJzZW5kZXJfZGF0YV9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzM2LDE5NSw3Miw3NywxNjQsMjAsMjUsMjE4LDI0OCwxMSwxMDYsMjEzLDIyOSw2LDY5LDc2LDEwNiw4NiwxMDYsMTcsMjUyLDIzNSw4MiwyMTAsNTYsMTE4LDM2LDgwLDAsMTM2LDE1OCw0M119fX0sIm1lbWJlcnNoaXBfa2V5Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMSwxMDUsOTAsMTIsMjEwLDg4LDQ5LDgxLDE2OCwxMjMsMTQ4LDExOSw5OCw0MCwxODcsODUsMjAyLDIwMSwxNzQsNDMsMTI4LDM2LDEyNSwxNzMsMTI0LDMsMzgsMjA2LDk3LDE5OSwxMTMsMTE5XX19fSwiY29uZmlybWF0aW9uX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbNDAsMTU3LDk1LDE1NSwxNjgsMTU2LDE5OSw0NywyMDAsMTEzLDg0LDIzNSwxNDAsMjUsNzUsNTMsNjYsMTcxLDIzNSwxNjUsMTgyLDIxMCwxMDgsMTY0LDIxNSwxMDQsMTMxLDYwLDEyLDUsMTE4LDEyM119fX0sInNlcmlhbGl6ZWRfY29udGV4dCI6WzAsMSwwLDEsMTYsMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjIsMCwwLDAsMCwwLDAsMCwxLDMyLDIsMTYzLDExMSwyMzcsMTQ2LDIyOCwxMjQsMjA1LDE1Miw0Miw3Niw0OCw5Miw5OSw0MSwxNDUsMjI0LDM5LDksMTQ1LDE4MywxNjQsMjIxLDEwOCwxNiwyLDU3LDI1MCw2LDEzNCwyMjMsMjQ5LDMyLDIxLDEzNSwxOTQsMTIyLDI0OCwxMTAsMTAzLDExNywxMTUsNTksMjEsMjA0LDYxLDEwNywxOTYsMTMz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eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IkNvbW1pdCI6eyJ2ZWMiOls3LDE4Nyw2OCwxNyw0MiwyMTMsMTkzLDMwLDE0OCwxMzUsNjEsNDQsMjQ3LDEzNiwxODYsMTIwLDIwMywxNjQsMjI2LDExMyw0OSwxNzYsMTUxLDEyOSwxNzAsMTkwLDE5MSw2OCwxNDYsMjI0LDE0OCwxOTJdfX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbOTksMjQzLDIzMiw3NSwxMzgsNjUsMTQ3LDI0OSwyMTcsNzgsMjA3LDEzMSwxMiwxNjQsMTc0LDg4LDE0LDIwLDEyMSw5OSw2MCwyMDksMjM4LDkyLDI4LDIyLDE0NiwxNjQsOTUsMTAxLDU0LDEzNCwxMyw3MCwxNCwxNTIsMjQyLDkzLDE0NywxLDE2MiwxNDgsMTU0LDE0MCw0NSwxNDksMTI1LDE4NSwxMjksMjA0LDg4LDIwMiwyNSw1NywzMiwxMjAsMTQxLDE0OSwyMDksMTAsMTU4LDE5MywyMTQsOF19fX19LHsibm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOls3MSwxMCw2OSwyMCwyLDkyLDcwLDg5LDIyNCw0OCwxMjYsNzgsMTI0LDE4NiwxNDgsMTU5LDI0NSwxNzUsMTIyLDE1NSwxNiwyMDksMTUzLDIxNiwyMiwxNDEsMTE3LDc1LDk3LDcyLDI0NywzNl19fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsyNTQsMTgyLDk1LDE4NywyOSwxMDYsMjQxLDI4LDE5NCwyMDMsNTYsMzcsMjA3LDYwLDYsOCwxMTgsMTc3LDM5LDE1NCwyMjEsMTYsMTcsMjUyLDYwLDIxOSwxMjIsMjIyLDE2MywyMzMsMTMyLDI1XX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTgsMTExLDk4XX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJLZXlQYWNrYWdlIjp7Im5vdF9iZWZvcmUiOjE3MjA2ODg5NDksIm5vdF9hZnRlciI6MTcyNzk1MDE0OX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzQ5LDEwMSwxOTEsNjAsMTY3LDI0NSwyMjIsMjAyLDIwOCwzMCwyMTIsMTM5LDY1LDEwLDI5LDIzOCwxOTYsNzQsODcsNTAsNywxNjMsMjE4LDEwNiw2MywzLDg3LDIwMywxMywyMywxMCwyMiwxMyw4MSwxNDAsMTc4LDkxLDExNCw0NCwyMjUsNzUsNywyMjksODEsMTM3LDYzLDEyNCwxNTUsMTYwLDI0LDE4Miw0Miw5Myw1MiwyNCwxNjcsMTk5LDIwMiwxNzksMTYwLDE1OCw2MiwxNiwxM119fX19XSwicGFyZW50X25vZGVzIjpbeyJub2RlIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxMywxODEsNjIsMTU5LDI3LDI1NSwyNDMsMjExLDI0Nyw1MiwyNDcsMTM4LDM3LDI1NSw2MCwzMCwxMjQsNTAsNjQsNzksMjQxLDIyMSwxNTUsMzUsMjA2LDIyOSwxNDAsNzMsMTgsMjQ2LDI0Niw4NV19fSwicGFyZW50X2hhc2giOnsidmVjIjpbXX0sInVubWVyZ2VkX2xlYXZlcyI6eyJsaXN0IjpbXX19fV0sImRlZmF1bHRfbGVhZiI6eyJub2RlIjpudWxsfSwiZGVmYXVsdF9wYXJlbnQiOnsibm9kZSI6bnVsbH19LCJ0cmVlX2hhc2giOlsyLDE2MywxMTEsMjM3LDE0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dWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsibWF4X2Vwb2NocyI6MCwicGFzdF9lcG9jaF90cmVlcyI6W10sIm1lc3NhZ2Vfc2VjcmV0cyI6eyJzZW5kZXJfZGF0YV9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzM2LDE5NSw3Miw3NywxNjQsMjAsMjUsMjE4LDI0OCwxMSwxMDYsMjEzLDIyOSw2LDY5LDc2LDEwNiw4NiwxMDYsMTcsMjUyLDIzNSw4MiwyMTAsNTYsMTE4LDM2LDgwLDAsMTM2LDE1OCw0M119fX0sIm1lbWJlcnNoaXBfa2V5Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMSwxMDUsOTAsMTIsMjEwLDg4LDQ5LDgxLDE2OCwxMjMsMTQ4LDExOSw5OCw0MCwxODcsODUsMjAyLDIwMSwxNzQsNDMsMTI4LDM2LDEyNSwxNzMsMTI0LDMsMzgsMjA2LDk3LDE5OSwxMTMsMTE5XX19fSwiY29uZmlybWF0aW9uX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbNDAsMTU3LDk1LDE1NSwxNjgsMTU2LDE5OSw0NywyMDAsMTEzLDg0LDIzNSwxNDAsMjUsNzUsNTMsNjYsMTcxLDIzNSwxNjUsMTgyLDIxMCwxMDgsMTY0LDIxNSwxMDQsMTMxLDYwLDEyLDUsMTE4LDEyM119fX0sInNlcmlhbGl6ZWRfY29udGV4dCI6WzAsMSwwLDEsMTYsMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjIsMCwwLDAsMCwwLDAsMCwxLDMyLDIsMTYzLDExMSwyMzcsMTQ2LDIyOCwxMjQsMjA1LDE1Miw0Miw3Niw0OCw5Miw5OSw0MSwxNDUsMjI0LDM5LDksMTQ1LDE4MywxNjQsMjIxLDEwOCwxNiwyLDU3LDI1MCw2LDEzNCwyMjMsMjQ5LDMyLDIxLDEzNSwxOTQsMTIyLDI0OCwxMTAsMTAzLDExNywxMTUsNTksMjEsMjA0LDYxLDEwNywxOTYsMTMz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LDIzOSwwLDIyNCwxOSw1MiwxMjYsMjAyLDEwOSwyNTQsMjMsMTM2LDE1NiwzOSwxNjEsMTMzLDk1LDM4LDM1LDEyMywxMjQsMTM4LDI1LDIzNiw4OCwxMDBdfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbODQsMTY5LDY1LDE0OSw3NSwyMjYsMTkxLDMzLDI1NCwxNDEsMTcsMjExLDE4MSw0OCw5MSwxNTksMTAwLDQ1LDc4LDExMiw3OSwxNDgsMTMsMTUsMjIyLDE5NiwyMTEsNjksMTU2LDM2LDE5MSwxMF19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJDb21taXQiOnsidmVjIjpbNywxODcsNjgsMTcsNDIsMjEzLDE5MywzMCwxNDgsMTM1LDYxLDQ0LDI0NywxMzYsMTg2LDEyMCwyMDMsMTY0LDIyNiwxMTMsNDksMTc2LDE1MSwxMjksMTcwLDE5MCwxOTEsNjgsMTQ2LDIyNCwxNDgsMTkyXX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6Wzk5LDI0MywyMzIsNzUsMTM4LDY1LDE0NywyNDksMjE3LDc4LDIwNywxMzEsMTIsMTY0LDE3NCw4OCwxNCwyMCwxMjEsOTksNjAsMjA5LDIzOCw5MiwyOCwyMiwxNDYsMTY0LDk1LDEwMSw1NCwxMzQsMTMsNzAsMTQsMTUyLDI0Miw5MywxNDcsMSwxNjIsMTQ4LDE1NCwxNDAsNDUsMTQ5LDEyNSwxODUsMTI5LDIwNCw4OCwyMDIsMjUsNTcsMzIsMTIwLDE0MSwxNDksMjA5LDEwLDE1OCwxOTMsMjE0LDhdfX19fSx7Im5vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbNzEsMTAsNjksMjAsMiw5Miw3MCw4OSwyMjQsNDgsMTI2LDc4LDEyNCwxODYsMTQ4LDE1OSwyNDUsMTc1LDEyMiwxNTUsMTYsMjA5LDE1MywyMTYsMjIsMTQxLDExNyw3NSw5Nyw3MiwyNDcsMzZdfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbMjU0LDE4Miw5NSwxODcsMjksMTA2LDI0MSwyOCwxOTQsMjAzLDU2LDM3LDIwNyw2MCw2LDgsMTE4LDE3NywzOSwxNTQsMjIxLDE2LDE3LDI1Miw2MCwyMTksMTIyLDIyMiwxNjMsMjMzLDEzMiwyNV19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk4LDExMSw5OF19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiS2V5UGFja2FnZSI6eyJub3RfYmVmb3JlIjoxNzIwNjg4OTQ5LCJub3RfYWZ0ZXIiOjE3Mjc5NTAxNDl9fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0OSwxMDEsMTkxLDYwLDE2NywyNDUsMjIyLDIwMiwyMDgsMzAsMjEyLDEzOSw2NSwxMCwyOSwyMzgsMTk2LDc0LDg3LDUwLDcsMTYzLDIxOCwxMDYsNjMsMyw4NywyMDMsMTMsMjMsMTAsMjIsMTMsODEsMTQwLDE3OCw5MSwxMTQsNDQsMjI1LDc1LDcsMjI5LDgxLDEzNyw2MywxMjQsMTU1LDE2MCwyNCwxODIsNDIsOTMsNTIsMjQsMTY3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eyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fQABeyJQZW5kaW5nQ29tbWl0Ijp7Ik1lbWJlciI6eyJzdGFnZWRfcHJvcG9zYWxfcXVldWUiOnsicHJvcG9zYWxfcmVmZXJlbmNlcyI6W3sidmFsdWUiOnsidmVjIjpbMTQ4LDEwNiwyNSwxMDQsMjA3LDE3Myw1NCw4OCwxNzMsNjAsMTg4LDE4MSwxMiwyNTEsOTAsMTM2LDIxNCwyMDIsMiwxNSwxNzgsNSwxMzIsOCw1LDU3LDIsNDUsNjcsMTk0LDcwLDgxXX19XSwicXVldWVkX3Byb3Bvc2FscyI6W1t7InZhbHVlIjp7InZlYyI6WzE0OCwxMDYsMjUsMTA0LDIwNywxNzMsNTQsODgsMTczLDYwLDE4OCwxODEsMTIsMjUxLDkwLDEzNiwyMTQsMjAyLDIsMTUsMTc4LDUsMTMyLDgsNSw1NywyLDQ1LDY3LDE5NCw3MCw4MV19fSx7InByb3Bvc2FsIjp7Ikdyb3VwQ29udGV4dEV4dGVuc2lvbnMiOnsiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOlt7IlJlcXVpcmVkQ2FwYWJpbGl0aWVzIjp7ImV4dGVuc2lvbl90eXBlcyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxfdHlwZXMiOltdLCJjcmVkZW50aWFsX3R5cGVzIjpbXX19XX19fSwicHJvcG9zYWxfcmVmZXJlbmNlIjp7InZhbHVlIjp7InZlYyI6WzE0OCwxMDYsMjUsMTA0LDIwNywxNzMsNTQsODgsMTczLDYwLDE4OCwxODEsMTIsMjUxLDkwLDEzNiwyMTQsMjAyLDIsMTUsMTc4LDUsMTMyLDgsNSw1NywyLDQ1LDY3LDE5NCw3MCw4MV19fSwic2VuZGVyIjp7Ik1lbWJlciI6MH0sInByb3Bvc2FsX29yX3JlZl90eXBlIjoiUHJvcG9zYWwifV1dfSwic3RhdGUiOnsiR3JvdXBNZW1iZXIiOnsiZ3JvdXBfZXBvY2hfc2VjcmV0cyI6eyJpbml0X3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTU5LDI0NiwyNTAsMjI1LDIzMCwxMiwxNDAsMzksMjAxLDEyNCwxODQsNzUsMjI2LDE1MCwxNDQsODUsMTc4LDIzOCwyMiwxNzEsMTc1LDExNSwxMzAsNjAsMTAsNDAsNTcsMTgsMjM4LDEyOSw4NywxOF19fX0sImV4cG9ydGVyX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTU0LDIzNSwyOSwyMTgsMjQ4LDEyNiw4NSwyOCwxNjksNDAsODEsMTgwLDIwMSwxNTAsMiwzNiw1MywyNSwxOTEsNTMsMTM5LDcwLDEyOSwxMTUsMjA2LDE3NSwyMSwxNzIsMTI4LDExOSwxMzEsOTNdfX19LCJlcG9jaF9hdXRoZW50aWNhdG9yIjp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxMjcsMTI1LDIyMyw4Myw5NCwxMTUsMjExLDE3OSwwLDIyNiwxMDksMTE0LDkzLDE3NiwxNjIsMTAzLDI4LDE1NSw3Niw3NywxNjUsMTcsNzAsMjM1LDIzOSwxNjIsMTcwLDYzLDIzNSw0MCwxMzMsNjFdfX19LCJleHRlcm5hbF9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6Wzc0LDg1LDQ2LDYxLDEsMTY2LDE4MSwyMTAsMTgyLDksMTk4LDUzLDIwLDIxMCwyMjYsMTcsMjEwLDc3LDEwOCwyMjUsMTk5LDEzOSwzNywyMTMsMjIyLDIyNiwyMjAsMTIyLDE3LDEzMywyMjYsMzBdfX19LCJyZXN1bXB0aW9uX3BzayI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTk5LDE5MCw4Nyw4OCw2LDIzNiwxNTMsMTcwLDEzMiwyNTUsMTU5LDE0MSw0MiwxNjYsMTE4LDEyMSwxODMsMTY1LDQyLDE3OSw0MywxMzgsMTkyLDE5OCwyOSwxMTUsMTM5LDIwMywyMzksNywxNjYsOTBdfX19fSwibWVzc2FnZV9zZWNyZXRzIjp7InNlbmRlcl9kYXRhX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTEyLDE0MiwyMjQsMTI0LDE4NSw5NiwzOCw4OCwwLDEyNiwyMzcsODksNDQsMTEwLDE5OCw0OCwxMzMsMTU1LDE4Miw4OSwxNCw5OCwyMDEsMTIyLDUsNzYsOTUsMjEsMTcyLDQ1LDE2NiwxNzRdfX19LCJtZW1iZXJzaGlwX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMiwxMywyMDMsMzEsODcsMjAwLDE3MiwyMzAsNzEsNyw1Niw1LDE0Niw5OSwxOTUsMCwxMjgsNjgsMjUwLDU4LDkwLDM1LDE4MCwxNjYsODUsOTEsMTE1LDE2OCwxODAsMTMzLDg1LDUzXX19fSwiY29uZmlybWF0aW9uX2tleSI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTc1LDE2MCwxMDksNzAsMjAsMjMyLDIzNCwyNTIsMTA3LDY1LDUxLDIzOCwxNyw5OSwxNjcsMjQyLDEyMywxNzUsMjAsMTc1LDE1OCwxNzQsNiwxMjQsMjQ2LDE0OSwxNTAsMzEsMTA4LDgwLDQ5LDhdfX19LCJzZXJpYWxpemVkX2NvbnRleHQiOlswLDEsMCwxLDE2LDIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyLDAsMCwwLDAsMCwwLDAsMiwzMiw3Nyw0NywyMjUsMjAxLDE2NCw2MiwxMTAsMjUzLDEyLDMsMTk1LDEzMiwxNjYsMTgsNjIsMjIxLDg2LDEwMCw2LDExMiwxNjEsMTczLDg1LDI0OCwyMjQsODksMTI5LDIxMyw0NiwxMzksNTYsNDgsMzIsMTA0LDI1MCwyOCwyLDE3MSw5MCwyMTksMTM1LDE1OCwxNjMsMjQyLDI0NywyMjUsMjMsMTkyLDE5NSw4NSwyMDIsMTQ4LDczLDI1MiwxNDAsNywyNDgsNjYsMTgyLDIyNCw3Miw2NywxNjcsMTA2LDIxOSw4LDAsMyw1LDIsMjQwLDY2LDAsMF0sInNlY3JldF90cmVlIjp7Im93bl9pbmRleCI6MCwibGVhZl9ub2RlcyI6W251bGwsbnVsbF0sInBhcmVudF9ub2RlcyI6W3sic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzM3LDM5LDE3MCw3LDE0MCwyMzgsMjA0LDgxLDI0MywzOSwyMTgsNTEsMTA5LDUsMTMwLDM0LDUxLDI0OCwyNDcsMTksMTY3LDI1NCwxMzksMTkxLDUxLDMsMjcsMjIxLDEyLDEzNSwyNiw1OF19fX0sbnVsbF0sImhhbmRzaGFrZV9zZW5kZXJfcmF0Y2hldHMiOltudWxsLG51bGxdLCJhcHBsaWNhdGlvbl9zZW5kZXJfcmF0Y2hldHMiOltudWxsLG51bGxdLCJzaXplIjozfX0sInN0YWdlZF9kaWZmIjp7InN0YWdlZF9kaWZmIjp7ImRpZmYiOnsibGVhZl9kaWZmIjp7IjAiOnsibm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxNSwyNTIsNzIsMTEwLDkyLDU0LDg5LDMyLDI0MCwxMzEsNjYsMTU3LDk4LDE3MCwyNDQsNjYsNzIsMTkxLDQ5LDIwMiwxOTYsMTYxLDE3MywxNywyMjIsMTQyLDY0LDIzMSwxODcsMTcyLDE2OSwxN119fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOls4NCwxNjksNjUsMTQ5LDc1LDIyNiwxOTEsMzMsMjU0LDE0MSwxNywyMTEsMTgxLDQ4LDkxLDE1OSwxMDAsNDUsNzgsMTEyLDc5LDE0OCwxMywxNSwyMjIsMTk2LDIxMSw2OSwxNTYsMzYsMTkxLDEwXX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTcsMTA4LDEwNSw5OSwxMDFdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IkNvbW1pdCI6eyJ2ZWMiOls3Niw3LDIxOCwyNDEsOTUsMTk2LDE0NSwxNzQsMzQsMTkwLDU3LDIzLDI1NSw0MywyMTgsMTk3LDIwMywxMzIsMTMwLDEzMCwyMzgsMjA3LDQ0LDEwNiwxOTcsNzgsNzEsNTgsMTY3LDE4MCwxMzksMTkyXX19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W119fSwic2lnbmF0dXJlIjp7InZhbHVlIjp7InZlYyI6WzE3NiwxMDMsMjE2LDk4LDgsODIsMTI1LDE5NiwyNDgsMTM3LDg3LDIxNiwyNTAsMTk2LDE5MSw1LDE1LDIxOSwxNjEsMTAsMzQsMjI2LDkzLDE4MCwxNTYsMTQyLDk2LDU4LDE5OSwxODEsMTM0LDE2NiwxNTYsMTM4LDE4NywxNywxNjQsMTk4LDM2LDgzLDExOCwxMTMsMTE3LDEwMSwyNTMsNjQsNzEsNzgsMjI5LDEzOSw4Niw4MiwxNCwxNTYsMTU0LDUzLDIxOSw4OSw1Miw0LDE5LDk1LDksN119fX19fSwicGFyZW50X2RpZmYiOnsiMCI6eyJub2RlIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxNzEsMTgwLDIyOCwxODgsMTA0LDIwMSwxOTQsMTcxLDM0LDIxNSwyMDcsMjQ3LDI0MCw4NywyMiwxNjIsNTEsMjE2LDEwLDE5NCw0MCw0OSwxNzcsMTk2LDE1NiwyMjMsMTI4LDIwLDIwOCwxMzQsMjE0LDc2XX19LCJwYXJlbnRfaGFzaCI6eyJ2ZWMiOltdfSwidW5tZXJnZWRfbGVhdmVzIjp7Imxpc3QiOltdfX19fSwic2l6ZSI6M30sIm5ld190cmVlX2hhc2giOls3Nyw0NywyMjUsMjAxLDE2NCw2MiwxMTAsMjUzLDEyLDMsMTk1LDEzMiwxNjYsMTgsNjIsMjIxLDg2LDEwMCw2LDExMiwxNjEsMTczLDg1LDI0OCwyMjQsODksMTI5LDIxMyw0NiwxMzksNTYsNDhdfSwiZ3JvdXBfY29udGV4dCI6eyJwcm90b2NvbF92ZXJzaW9uIjoiTWxzMTAiLCJjaXBoZXJzdWl0ZSI6Ik1MU18xMjhfREhLRU1YMjU1MTlfQUVTMTI4R0NNX1NIQTI1Nl9FZDI1NTE5IiwiZ3JvdXBfaWQiOnsidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0sImVwb2NoIjoyLCJ0cmVlX2hhc2giOnsidmVjIjpbNzcsNDcsMjI1LDIwMSwxNjQsNjIsMTEwLDI1MywxMiwzLDE5NSwxMzIsMTY2LDE4LDYyLDIyMSw4NiwxMDAsNiwxMTIsMTYxLDE3Myw4NSwyNDgsMjI0LDg5LDEyOSwyMTMsNDYsMTM5LDU2LDQ4XX0sImNvbmZpcm1lZF90cmFuc2NyaXB0X2hhc2giOnsidmVjIjpbMTA0LDI1MCwyOCwyLDE3MSw5MCwyMTksMTM1LDE1OCwxNjMsMjQyLDI0NywyMjUsMjMsMTkyLDE5NSw4NSwyMDIsMTQ4LDczLDI1MiwxNDAsNywyNDgsNjYsMTgyLDIyNCw3Miw2NywxNjcsMTA2LDIxOV19LCJleHRlbnNpb25zIjp7InVuaXF1ZSI6W3siUmVxdWlyZWRDYXBhYmlsaXRpZXMiOnsiZXh0ZW5zaW9uX3R5cGVzIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbF90eXBlcyI6W10sImNyZWRlbnRpYWxfdHlwZXMiOltdfX1dfX0sImludGVyaW1fdHJhbnNjcmlwdF9oYXNoIjpbMTI2LDIzMSw5Miw1MywyMiwxMTMsNjUsMjksMTk2LDEzOSwxMjUsMjgsODgsMTU3LDgxLDExLDc4LDQ1LDQsMTI5LDE3NiwxOTYsMTEyLDI1MywxMjksMTI1LDExMSwyMzQsOSwxNzMsMTEzLDI0M10sImNvbmZpcm1hdGlvbl90YWciOnsibWFjX3ZhbHVlIjp7InZlYyI6WzE2NCwyMjcsNTksMTI4LDEsMTU0LDIzMiwxMTQsODMsMTAsMTY5LDIxNSwyNDMsMjE2LDI0MiwxNzUsODEsMzYsMTc4LDE3MSwxMzYsMTI5LDI5LDE3LDU0LDIwLDU5LDk3LDE1LDM5LDIxNywxNDRdfX19LCJuZXdfa2V5cGFpcnMiOlt7InB1YmxpY19rZXkiOnsia2V5Ijp7InZlYyI6WzE1LDI1Miw3MiwxMTAsOTIsNTQsODksMzIsMjQwLDEzMSw2NiwxNTcsOTgsMTcwLDI0NCw2Niw3MiwxOTEsNDksMjAyLDE5NiwxNjEsMTczLDE3LDIyMiwxNDIsNjQsMjMxLDE4NywxNzIsMTY5LDE3XX19LCJwcml2YXRlX2tleSI6eyJrZXkiOnsidmVjIjpbMTc0LDU4LDg2LDE5OCwxMzYsMjA2LDIzMiwyNTMsMzYsMTIsMzAsMTQ2LDEyOSwxMDYsMTA4LDEyMSwyMDIsMjUzLDI0MiwxNTksOTcsMTkzLDIxMywyMSwxNzAsMjM0LDY4LDM1LDE1NCwyMjUsNTMsMTA4XX19fSx7InB1YmxpY19rZXkiOnsia2V5Ijp7InZlYyI6WzE3MSwxODAsMjI4LDE4OCwxMDQsMjAxLDE5NCwxNzEsMzQsMjE1LDIwNywyNDcsMjQwLDg3LDIyLDE2Miw1MSwyMTYsMTAsMTk0LDQwLDQ5LDE3NywxOTYsMTU2LDIyMywxMjgsMjAsMjA4LDEzNCwyMTQsNzZdfX0sInByaXZhdGVfa2V5Ijp7ImtleSI6eyJ2ZWMiOlswLDI0LDE4OSwyNDAsMzAsNSwyNTUsMjIxLDEyNyw1OCwxODQsMTA4LDIwMywyMzAsMTgsMjgsNTEsNDMsMjUwLDEyNywxODUsMTI1LDI1MiwxMDQsMjUyLDMyLDE2NywyMCw5MSw3MiwzMSwxODFdfX19XSwibmV3X2xlYWZfa2V5cGFpcl9vcHRpb24iOm51bGwsInVwZGF0ZV9wYXRoX2xlYWZfbm9kZSI6eyJwYXlsb2FkIjp7ImVuY3J5cHRpb25fa2V5Ijp7ImtleSI6eyJ2ZWMiOlsxNSwyNTIsNzIsMTEwLDkyLDU0LDg5LDMyLDI0MCwxMzEsNjYsMTU3LDk4LDE3MCwyNDQsNjYsNzIsMTkxLDQ5LDIwMiwxOTYsMTYxLDE3MywxNywyMjIsMTQyLDY0LDIzMSwxODcsMTcyLDE2OSwxN119fSwic2lnbmF0dXJlX2tleSI6eyJ2YWx1ZSI6eyJ2ZWMiOls4NCwxNjksNjUsMTQ5LDc1LDIyNiwxOTEsMzMsMjU0LDE0MSwxNywyMTEsMTgxLDQ4LDkxLDE1OSwxMDAsNDUsNzgsMTEyLDc5LDE0OCwxMywxNSwyMjIsMTk2LDIxMSw2OSwxNTYsMzYsMTkxLDEwXX19LCJjcmVkZW50aWFsIjp7ImNyZWRlbnRpYWxfdHlwZSI6IkJhc2ljIiwic2VyaWFsaXplZF9jcmVkZW50aWFsX2NvbnRlbnQiOnsidmVjIjpbOTcsMTA4LDEwNSw5OSwxMDFdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJz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bCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJDb21taXQiOnsidmVjIjpbNzYsNywyMTgsMjQxLDk1LDE5NiwxNDUsMTc0LDM0LDE5MCw1NywyMywyNTUsNDMsMjE4LDE5NywyMDMsMTMyLDEzMCwxMzAsMjM4LDIwNyw0NCwxMDYsMTk3LDc4LDcxLDU4LDE2NywxODAsMTM5LDE5Ml19fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNzYsMTAzLDIxNiw5OCw4LDgyLDEyNSwxOTYsMjQ4LDEzNyw4NywyMTYsMjUwLDE5NiwxOTEsNSwxNSwyMTksMTYxLDEwLDM0LDIyNiw5MywxODAsMTU2LDE0Miw5Niw1OCwxOTksMTgxLDEzNCwxNjYsMTU2LDEzOCwxODcsMTcsMTY0LDE5OCwzNiw4MywxMTgsMTEzLDExNywxMDEsMjUzLDY0LDcxLDc4LDIyOSwxMzksODYsODIsMTQsMTU2LDE1NCw1MywyMTksODksNTIsNCwxOSw5NSw5LDddfX19fSx7Im5vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbNzEsMTAsNjksMjAsMiw5Miw3MCw4OSwyMjQsNDgsMTI2LDc4LDEyNCwxODYsMTQ4LDE1OSwyNDUsMTc1LDEyMiwxNTUsMTYsMjA5LDE1MywyMTYsMjIsMTQxLDExNyw3NSw5Nyw3MiwyNDcsMzZdfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbMjU0LDE4Miw5NSwxODcsMjksMTA2LDI0MSwyOCwxOTQsMjAzLDU2LDM3LDIwNyw2MCw2LDgsMTE4LDE3NywzOSwxNTQsMjIxLDE2LDE3LDI1Miw2MCwyMTksMTIyLDIyMiwxNjMsMjMzLDEzMiwyNV19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk4LDExMSw5OF19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiS2V5UGFja2FnZSI6eyJub3RfYmVmb3JlIjoxNzIwNjg4OTQ5LCJub3RfYWZ0ZXIiOjE3Mjc5NTAxNDl9fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0OSwxMDEsMTkxLDYwLDE2NywyNDUsMjIyLDIwMiwyMDgsMzAsMjEyLDEzOSw2NSwxMCwyOSwyMzgsMTk2LDc0LDg3LDUwLDcsMTYzLDIxOCwxMDYsNjMsMyw4NywyMDMsMTMsMjMsMTAsMjIsMTMsODEsMTQwLDE3OCw5MSwxMTQsNDQsMjI1LDc1LDcsMjI5LDgxLDEzNyw2MywxMjQsMTU1LDE2MCwyNCwxODIsNDIsOTMsNTIsMjQsMTY3LDE5OSwyMDIsMTc5LDE2MCwxNTgsNjIsMTYsMTNdfX19fV0sInBhcmVudF9ub2RlcyI6W3sibm9kZSI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbMTcxLDE4MCwyMjgsMTg4LDEwNCwyMDEsMTk0LDE3MSwzNCwyMTUsMjA3LDI0NywyNDAsODcsMjIsMTYyLDUxLDIxNiwxMCwxOTQsNDAsNDksMTc3LDE5NiwxNTYsMjIzLDEyOCwyMCwyMDgsMTM0LDIxNCw3Nl19fSwicGFyZW50X2hhc2giOnsidmVjIjpbXX0sInVubWVyZ2VkX2xlYXZlcyI6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NiwxODMsMTMxLDI0Miw5LDE3OCwxMDUsMiwxNzUsMTcyLDg4LDEzMSwyMzMsMjMzXX19fV0sWzEseyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTEsNzUsMjM5LDI0LDIzNiwxNjksMjUwLDE0NCw4NywxMzMsODMsMTIwLDkxLDIwNCwxODQsODYsMTQ0LDExMCwyMzIsMjAxLDE1Niw0LDIxMSwxNTYsMTc3LDM5LDM1LDIzMCwyMTksMTcsMTA3LDUwXX19fV0sWzIseyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbMTk5LDE5MCw4Nyw4OCw2LDIzNiwxNTMsMTcwLDEzMiwyNTUsMTU5LDE0MSw0MiwxNjYsMTE4LDEyMSwxODMsMTY1LDQyLDE3OSw0MywxMzgsMTkyLDE5OCwyOSwxMTUsMTM5LDIwMywyMzksNywxNjYsOTBdfX19XV0sImN1cnNvciI6M30=","AAAAAAAAAA8AAAAAAAAA5QAAAAAAAAayUXVldWVkUHJvcG9zYWxbeyJ2YWx1ZSI6eyJ2ZWMiOlsyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMl19fSx7InZhbHVlIjp7InZlYyI6Wzk1LDE0MywyNSw5NCwxODgsMTU4LDE4LDE0MiwxNDcsMjI1LDEwMCwyMDQsMTUxLDgzLDEsMTksMTM5LDYyLDg3LDIwNCwxNjMsMTA1LDI0NSwxODYsMTU1LDkxLDE1LDExNyw5NCwyMTUsMTAwLDIyNl19fV0AAXsicHJvcG9zYWwiOnsiQWRkIjp7ImtleV9wYWNrYWdlIjp7InBheWxvYWQiOnsicHJvdG9jb2xfdmVyc2lvbiI6Ik1sczEwIiwiY2lwaGVyc3VpdGUiOiJNTFNfMTI4X0RIS0VNWDI1NTE5X0FFUzEyOEdDTV9TSEEyNTZfRWQyNTUxOSIsImluaXRfa2V5Ijp7ImtleSI6eyJ2ZWMiOls4NCwxMzAsNTcsMjI1LDI2LDE3OSwyNDgsMjA3LDU3LDE5NiwxNDksMTYxLDEzOSwxNCwxNDgsMjQ3LDIsMTQ5LDc1LDIyNiwxMTAsMjUxLDEzMiwxNzAsMTYyLDE4NywxNTAsNjQsMjYsMjQyLDIyOSwzN119fSwibGVhZl9ub2RlIjp7InBheWxvYWQiOnsiZW5jcnlwdGlvbl9rZXkiOnsia2V5Ijp7InZlYyI6WzEwLDgzLDIzNiwxNTUsMTkyLDIxNiw0NSwxNjYsMTc0LDEwMSwxMDIsNDMsMTI4LDkxLDI0LDExOCwxNDYsNTcsMTg4LDExMSwyMiwyMSw0MiwxNDQsNjIsMjA1LDU5LDE1MiwzOCwyMDYsMTg1LDc3XX19LCJzaWduYXR1cmVfa2V5Ijp7InZhbHVlIjp7InZlYyI6WzQsMTIsMTczLDE3MSwxMjcsMTgsMjA0LDQzLDE1LDk5LDIyNiw2OCw4NCwxMzksNjUsMTQyLDI2LDQxLDg3LDE3MCwxNjYsNTQsMjQ3LDEyMiw0OSwxOTEsMTIxLDUyLDIsMjI3LDU5LDIzMl19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk5LDEwNCw5NywxMTQsMTA4LDEwNSwxMDFdfX0sImNhcGFiaWxpdGllcyI6eyJ2ZXJzaW9ucyI6WyJNbHMxMCJdLCJjaXBoZXJzdWl0ZXMiOlsxLDIsMyw3N10sImV4dGVuc2lvbnMiOlt7IlVua25vd24iOjYxNTA2fV0sInByb3Bvc2FscyI6W10sImNyZWRlbnRpYWxzIjpbIkJhc2ljIl19LCJsZWFmX25vZGVfc291cmNlIjp7IktleVBhY2thZ2UiOnsibm90X2JlZm9yZSI6MTcyMDY4ODk0OSwibm90X2FmdGVyIjoxNzI3OTUwMTQ5fX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbMjA4LDcyLDIyLDE0MCwxOTgsMTg1LDM5LDEyMywxMDYsNDAsMTc4LDE5NCw4OSwxMzAsMjI3LDEzMCw2MiwxNCw4Nyw1MywxNSwxOTcsMTQsMTY4LDI0MywyNDEsNjIsMTM1LDIxMiwyMjEsMTIzLDUyLDU5LDU3LDI5LDIsMjMwLDIyNiwxNTQsMTU3LDY5LDE4NywxODQsMTg2LDE5NiwxNjUsMzYsODMsMTg0LDU1LDEzNiwxNTYsMTY2LDYxLDgyLDI1NCwyMTMsMTI3LDEzNywyMTEsMTA2LDM5LDI0NSwxMV19fX0sImV4dGVuc2lvbnMiOnsidW5pcXVlIjpbXX19LCJzaWduYXR1cmUiOnsidmFsdWUiOnsidmVjIjpbNTYsMTU2LDEwMiwxMTEsMTA1LDEyNCwyMjEsMjAyLDM5LDEwNywzLDExNSwyMjUsNjksMjM1LDEzMCwyNTIsMjE0LDIwMCwyNSwzMCwyNDksMTE2LDEyMywzNCwyMjQsNyw4MSwyNDUsNDAsMTMzLDI0Niw5NywzNywxLDI1MSw5MiwxNywxMTMsNzMsNzMsNDUsMzAsMjEsMjA0LDI0NSwxMSwyMDksODEsMzEsOTQsMjAzLDEyOCwxODIsMjM1LDc2LDQ3LDAsMTY4LDEzLDE3NCwyMjYsOTYsMl19fX19fSwicHJvcG9zYWxfcmVmZXJlbmNlIjp7InZhbHVlIjp7InZlYyI6Wzk1LDE0Mywy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AAAAAAAABipNZXNzYWdlU2VjcmV0c3sidmFsdWUiOnsidmVjIjpbMjE0LDIwNiwxNzMsMjcsMjA2LDg3LDIzMSw0LDE3MiwzMCwxMzAsMjEwLDIzMiw2OSw2MSwyMjJdfX0AAXsibWF4X2Vwb2NocyI6MCwicGFzdF9lcG9jaF90cmVlcyI6W10sIm1lc3NhZ2Vfc2VjcmV0cyI6eyJzZW5kZXJfZGF0YV9zZWNyZXQiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzExMiwxNDIsMjI0LDEyNCwxODUsOTYsMzgsODgsMCwxMjYsMjM3LDg5LDQ0LDExMCwxOTgsNDgsMTMzLDE1NSwxODIsODksMTQsOTgsMjAxLDEyMiw1LDc2LDk1LDIxLDE3Miw0NSwxNjYsMTc0XX19fSwibWVtYmVyc2hpcF9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzIsMTMsMjAzLDMxLDg3LDIwMCwxNzIsMjMwLDcxLDcsNTYsNSwxNDYsOTksMTk1LDAsMTI4LDY4LDI1MCw1OCw5MCwzNSwxODAsMTY2LDg1LDkxLDExNSwxNjgsMTgwLDEzMyw4NSw1M119fX0sImNvbmZpcm1hdGlvbl9rZXkiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzE3NSwxNjAsMTA5LDcwLDIwLDIzMiwyMzQsMjUyLDEwNyw2NSw1MSwyMzgsMTcsOTksMTY3LDI0MiwxMjMsMTc1LDIwLDE3NSwxNTgsMTc0LDYsMTI0LDI0NiwxNDksMTUwLDMxLDEwOCw4MCw0OSw4XX19fSwic2VyaWFsaXplZF9jb250ZXh0IjpbMCwxLDAsMSwxNiwyMTQsMjA2LDE3MywyNywyMDYsODcsMjMxLDQsMTcyLDMwLDEzMCwyMTAsMjMyLDY5LDYxLDIyMiwwLDAsMCwwLDAsMCwwLDIsMzIsNzcsNDcsMjI1LDIwMSwxNjQsNjIsMTEwLDI1MywxMiwzLDE5NSwxMzIsMTY2LDE4LDYyLDIyMSw4NiwxMDAsNiwxMTIsMTYxLDE3Myw4NSwyNDgsMjI0LDg5LDEyOSwyMTMsNDYsMTM5LDU2LDQ4LDMyLDEwNCwyNTAsMjgsMiwxNzEsOTAsMjE5LDEzNSwxNTgsMTYzLDI0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eSI6eyJrZXkiOnsidmVjIjpbMTUsMjUyLDcyLDExMCw5Miw1NCw4OSwzMiwyNDAsMTMxLDY2LDE1Nyw5OCwxNzAsMjQ0LDY2LDcyLDE5MSw0OSwyMDIsMTk2LDE2MSwxNzMsMTcsMjIyLDE0Miw2NCwyMzEsMTg3LDE3MiwxNjksMTddfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbODQsMTY5LDY1LDE0OSw3NSwyMjYsMTkxLDMzLDI1NCwxNDEsMTcsMjExLDE4MSw0OCw5MSwxNTksMTAwLDQ1LDc4LDExMiw3OSwxNDgsMTMsMTUsMjIyLDE5NiwyMTEsNjksMTU2LDM2LDE5MSwxMF19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk3LDEwOCwxMDUsOTksMTAxXX19LCJjYXBhYmlsaXRpZXMiOnsidmVyc2lvbnMiOlsiTWxzMTAiXSwiY2lwaGVyc3VpdGVzIjpbMSwyLDMsNzddLCJleHRlbnNpb25zIjpbeyJVbmtub3duIjo2MTUwNn1dLCJwcm9wb3NhbHMiOltdLCJjcmVkZW50aWFscyI6WyJCYXNpYyJdfSwibGVhZl9ub2RlX3NvdXJjZSI6eyJDb21taXQiOnsidmVjIjpbNzYsNywyMTgsMjQxLDk1LDE5NiwxNDUsMTc0LDM0LDE5MCw1NywyMywyNTUsNDMsMjE4LDE5NywyMDMsMTMyLDEzMCwxMzAsMjM4LDIwNyw0NCwxMDYsMTk3LDc4LDcxLDU4LDE2NywxODAsMTM5LDE5Ml19fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNzYsMTAzLDIxNiw5OCw4LDgyLDEyNSwxOTYsMjQ4LDEzNyw4NywyMTYsMjUwLDE5NiwxOTEsNSwxNSwyMTksMTYxLDEwLDM0LDIyNiw5MywxODAsMTU2LDE0Miw5Niw1OCwxOTksMTgxLDEzNCwxNjYsMTU2LDEzOCwxODcsMTcsMTY0LDE5OCwzNiw4MywxMTgsMTEzLDExNywxMDEsMjUzLDY0LDcxLDc4LDIyOSwxMzksODYsODIsMTQsMTU2LDE1NCw1MywyMTksODksNTIsNCwxOSw5NSw5LDddfX19fSx7Im5vZGUiOnsicGF5bG9hZCI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbNzEsMTAsNjksMjAsMiw5Miw3MCw4OSwyMjQsNDgsMTI2LDc4LDEyNCwxODYsMTQ4LDE1OSwyNDUsMTc1LDEyMiwxNTUsMTYsMjA5LDE1MywyMTYsMjIsMTQxLDExNyw3NSw5Nyw3MiwyNDcsMzZdfX0sInNpZ25hdHVyZV9rZXkiOnsidmFsdWUiOnsidmVjIjpbMjU0LDE4Miw5NSwxODcsMjksMTA2LDI0MSwyOCwxOTQsMjAzLDU2LDM3LDIwNyw2MCw2LDgsMTE4LDE3NywzOSwxNTQsMjIxLDE2LDE3LDI1Miw2MCwyMTksMTIyLDIyMiwxNjMsMjMzLDEzMiwyNV19fSwiY3JlZGVudGlhbCI6eyJjcmVkZW50aWFsX3R5cGUiOiJCYXNpYyIsInNlcmlhbGl6ZWRfY3JlZGVudGlhbF9jb250ZW50Ijp7InZlYyI6Wzk4LDExMSw5OF19fSwiY2FwYWJpbGl0aWVzIjp7InZlcnNpb25zIjpbIk1sczEwIl0sImNpcGhlcnN1aXRlcyI6WzEsMiwzLDc3XSwiZXh0ZW5zaW9ucyI6W3siVW5rbm93biI6NjE1MDZ9XSwicHJvcG9zYWxzIjpbXSwiY3JlZGVudGlhbHMiOlsiQmFzaWMiXX0sImxlYWZfbm9kZV9zb3VyY2UiOnsiS2V5UGFja2FnZSI6eyJub3RfYmVmb3JlIjoxNzIwNjg4OTQ5LCJub3RfYWZ0ZXIiOjE3Mjc5NTAxNDl9fSwiZXh0ZW5zaW9ucyI6eyJ1bmlxdWUiOltdfX0sInNpZ25hdHVyZSI6eyJ2YWx1ZSI6eyJ2ZWMiOls0OSwxMDEsMTkxLDYwLDE2NywyNDUsMjIyLDIwMiwyMDgsMzAsMjEyLDEzOSw2NSwxMCwyOSwyMzgsMTk2LDc0LDg3LDUwLDcsMTYzLDIxOCwxMDYsNjMsMyw4NywyMDMsMTMsMjMsMTAsMjIsMTMsODEsMTQwLDE3OCw5MSwxMTQsNDQsMjI1LDc1LDcsMjI5LDgxLDEzNyw2MywxMjQsMTU1LDE2MCwyNCwxODIsNDIsOTMsNTIsMjQsMTY3LDE5OSwyMDIsMTc5LDE2MCwxNTgsNjIsMTYsMTNdfX19fV0sInBhcmVudF9ub2RlcyI6W3sibm9kZSI6eyJlbmNyeXB0aW9uX2tleSI6eyJrZXkiOnsidmVjIjpbMTcxLDE4MCwyMjgsMTg4LDEwNCwyMDEsMTk0LDE3MSwzNCwyMTUsMjA3LDI0NywyNDAsODcsMjIsMTYyLDUxLDIxNiwxMCwxOTQsNDAsNDksMTc3LDE5NiwxNTYsMjIzLDEyOCwyMCwyMDgsMTM0LDIxNCw3Nl19fSwicGFyZW50X2hhc2giOnsidmVjIjpbXX0sInVubWVyZ2VkX2xlYXZlcyI6eyJsaXN0IjpbXX19fV0sImRlZmF1bHRfbGVhZiI6eyJub2RlIjpudWxsfSwiZGVmYXVsdF9wYXJlbnQiOnsibm9kZSI6bnVsbH19LCJ0cmVlX2hhc2giOls3Nyw0NywyMjUsMjAxLDE2NCw2MiwxMTAsMjUzLDEyLDMsMTk1LDEzMiwxNjYsMTgsNjIsMjIxLDg2LDEwMCw2LDExMiwxNjEsMTczLDg1LDI0OCwyMjQsODksMTI5LDIxMyw0NiwxMzksNTYsNDhdfQAAAAAAAABaAAAAAAAAAzRFcG9jaFNlY3JldHN7InZhbHVlIjp7InZlYyI6WzIxNCwyMDYsMTczLDI3LDIwNiw4NywyMzEsNCwxNzIsMzAsMTMwLDIxMCwyMzIsNjksNjEsMjIyXX19AAF7ImluaXRfc2VjcmV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNTksMjQ2LDI1MCwyMjUsMjMwLDEyLDE0MCwzOSwyMDEsMTI0LDE4NCw3NSwyMjYsMTUwLDE0NCw4NSwxNzgsMjM4LDIyLDE3MSwxNzUsMTE1LDEzMCw2MCwxMCw0MCw1NywxOCwyMzgsMTI5LDg3LDE4XX19fSwiZXhwb3J0ZXJfc2VjcmV0Ijp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxNTQsMjM1LDI5LDIxOCwyNDgsMTI2LDg1LDI4LDE2OSw0MCw4MSwxODAsMjAxLDE1MCwyLDM2LDUzLDI1LDE5MSw1MywxMzksNzAsMTI5LDExNSwyMDYsMTc1LDIxLDE3MiwxMjgsMTE5LDEzMSw5M119fX0sImVwb2NoX2F1dGhlbnRpY2F0b3IiOnsic2VjcmV0Ijp7InZhbHVlIjp7InZlYyI6WzEyNywxMjUsMjIzLDgzLDk0LDExNSwyMTEsMTc5LDAsMjI2LDEwOSwxMTQsOTMsMTc2LDE2MiwxMDMsMjgsMTU1LDc2LDc3LDE2NSwxNyw3MCwyMzUsMjM5LDE2MiwxNzAsNjMsMjM1LDQwLDEzMyw2MV19fX0sImV4dGVybmFsX3NlY3JldCI6eyJzZWNyZXQiOnsidmFsdWUiOnsidmVjIjpbNzQsODUsNDYsNjEsMSwxNjYsMTgxLDIxMCwxODIsOSwxOTgsNTMsMjAsMjEwLDIyNiwxNywyMTAsNzcsMTA4LDIyNSwxOTksMTM5LDM3LDIxMywyMjIsMjI2LDIyMCwxMjIsMTcsMTMzLDIyNiwzMF19fX0sInJlc3VtcHRpb25fcHNrIjp7InNlY3JldCI6eyJ2YWx1ZSI6eyJ2ZWMiOlsxOTksMTkwLDg3LDg4LDYsMjM2LDE1MywxNzAsMTMyLDI1NSwxNTksMTQxLDQyLDE2NiwxMTgsMTIxLDE4MywxNjUsNDIsMTc5LDQzLDEzOCwxOTIsMTk4LDI5LDExNSwxMzksMjAzLDIzOSw3LDE2Niw5MF19fX19"]}} \ No newline at end of file diff --git a/openmls/tests/book_code.rs b/openmls/tests/book_code.rs index 65ede1c720..ce5a84b3e9 100644 --- a/openmls/tests/book_code.rs +++ b/openmls/tests/book_code.rs @@ -6,6 +6,7 @@ use openmls::{ use openmls_basic_credential::SignatureKeyPair; use openmls_test::openmls_test; use openmls_traits::{signatures::Signer, types::SignatureScheme}; +use treesync::LeafNodeParameters; #[test] fn create_provider_rust_crypto() { @@ -292,9 +293,11 @@ fn book_operations() { let (mut dave_group, _out, _group_info) = MlsGroup::join_by_external_commit( provider, &dave_signature_keys, - None, + None, // No ratchtet tree extension verifiable_group_info, &mls_group_config, + None, // No special capabilities + None, // No special extensions &[], dave_credential, ) @@ -354,10 +357,40 @@ fn book_operations() { unreachable!("Expected an ApplicationMessage."); } + // ANCHOR: set_aad + alice_group.set_aad(b"Additional Authenticated Data".to_vec()); + + assert_eq!(alice_group.aad(), b"Additional Authenticated Data"); + // ANCHOR_END: set_aad + + let message_alice = b"Hi, I'm Alice!"; + let mls_message_out = alice_group + .create_message(provider, &alice_signature_keys, message_alice) + .expect("Error creating application message."); + + let bytes = mls_message_out + .to_bytes() + .expect("Could not serialize message."); + + let mls_message = + MlsMessageIn::tls_deserialize_exact(bytes).expect("Could not deserialize message."); + + let protocol_message: ProtocolMessage = mls_message + .try_into_protocol_message() + .expect("Expected a PublicMessage or a PrivateMessage"); + + // ANCHOR: inspect_aad + let processed_message = bob_group + .process_message(provider, protocol_message) + .expect("Could not process message."); + + assert_eq!(processed_message.aad(), b"Additional Authenticated Data"); + // ANCHOR_END: inspect_aad + // === Bob updates and commits === // ANCHOR: self_update let (mls_message_out, welcome_option, _group_info) = bob_group - .self_update(provider, &bob_signature_keys) + .self_update(provider, &bob_signature_keys, LeafNodeParameters::default()) .expect("Could not update own key package."); // ANCHOR_END: self_update @@ -407,7 +440,7 @@ fn book_operations() { .propose_self_update( provider, &alice_signature_keys, - None, // We don't provide a leaf node, it will be created on the fly instead + LeafNodeParameters::default(), ) .expect("Could not create update proposal."); // ANCHOR_END: propose_self_update @@ -602,7 +635,11 @@ fn book_operations() { // === Charlie updates and commits === let (queued_message, welcome_option, _group_info) = charlie_group - .self_update(provider, &charlie_signature_keys) + .self_update( + provider, + &charlie_signature_keys, + LeafNodeParameters::default(), + ) .unwrap(); let alice_processed_message = alice_group @@ -906,7 +943,7 @@ fn book_operations() { ) .expect("Could not create proposal to add Bob"); alice_group - .remove_pending_proposal(provider.storage(), proposal_ref) + .remove_pending_proposal(provider.storage(), &proposal_ref) .expect("The proposal was not found"); // ANCHOR_END: rollback_proposal_by_ref @@ -1080,9 +1117,7 @@ fn book_operations() { assert_eq!(sender_cred_from_msg, sender_cred_from_group); assert_eq!( &sender_cred_from_msg, - alice_group - .credential::() - .expect("Expected a credential.") + alice_group.credential().expect("Expected a credential.") ); } else { unreachable!("Expected an ApplicationMessage."); diff --git a/openmls/tests/test_decryption_key_index.rs b/openmls/tests/decryption_key_index.rs similarity index 100% rename from openmls/tests/test_decryption_key_index.rs rename to openmls/tests/decryption_key_index.rs diff --git a/openmls/tests/test_external_commit.rs b/openmls/tests/external_commit.rs similarity index 94% rename from openmls/tests/test_external_commit.rs rename to openmls/tests/external_commit.rs index a358c168d1..dd85fc5bc4 100644 --- a/openmls/tests/test_external_commit.rs +++ b/openmls/tests/external_commit.rs @@ -2,6 +2,7 @@ use openmls::{ credentials::test_utils::new_credential, messages::group_info::VerifiableGroupInfo, prelude::{tls_codec::*, *}, + treesync::LeafNodeParameters, }; use openmls_basic_credential::SignatureKeyPair; use openmls_test::openmls_test; @@ -83,6 +84,8 @@ fn test_external_commit() { None, verifiable_group_info, &MlsGroupJoinConfig::default(), + None, + None, b"", bob_credential, ) @@ -100,6 +103,8 @@ fn test_external_commit() { None, verifiable_group_info_broken, &MlsGroupJoinConfig::default(), + None, + None, b"", bob_credential, ) @@ -120,7 +125,9 @@ fn test_group_info() { let (mut alice_group, _, alice_signer) = create_alice_group(ciphersuite, provider, true); // Self update Alice's to get a group info from a commit - let (.., group_info) = alice_group.self_update(provider, &alice_signer).unwrap(); + let (.., group_info) = alice_group + .self_update(provider, &alice_signer, LeafNodeParameters::default()) + .unwrap(); alice_group.merge_pending_commit(provider).unwrap(); // Bob wants to join @@ -138,6 +145,8 @@ fn test_group_info() { None, verifiable_group_info, &MlsGroupJoinConfig::default(), + None, + None, b"", bob_credential, ) @@ -187,6 +196,8 @@ fn test_group_info() { None, verifiable_group_info, &MlsGroupJoinConfig::default(), + None, + None, b"", bob_credential, ) @@ -203,7 +214,9 @@ fn test_not_present_group_info( let (mut alice_group, _, alice_signer) = create_alice_group(ciphersuite, provider, false); // Self update Alice's to get a group info from a commit - let (.., group_info) = alice_group.self_update(provider, &alice_signer).unwrap(); + let (.., group_info) = alice_group + .self_update(provider, &alice_signer, LeafNodeParameters::default()) + .unwrap(); alice_group.merge_pending_commit(provider).unwrap(); assert!(group_info.is_none()); diff --git a/openmls/tests/test_interop_scenarios.rs b/openmls/tests/interop_scenarios.rs similarity index 98% rename from openmls/tests/test_interop_scenarios.rs rename to openmls/tests/interop_scenarios.rs index baf3e0ab12..09d8a3864f 100644 --- a/openmls/tests/test_interop_scenarios.rs +++ b/openmls/tests/interop_scenarios.rs @@ -3,6 +3,7 @@ use openmls::{ test_utils::test_framework::{ noop_authentication_service, ActionType, CodecUse, MlsGroupTestSetup, }, + treesync::LeafNodeParameters, }; use openmls_test::openmls_test; @@ -218,7 +219,7 @@ fn update() { ActionType::Commit, group, &alice_id, - None, + LeafNodeParameters::default(), &noop_authentication_service, ) .expect("Error self-updating."); @@ -323,7 +324,7 @@ fn large_group_lifecycle() { ActionType::Commit, group, member_id, - None, + LeafNodeParameters::default(), &noop_authentication_service, ) .expect("Error while updating group.") diff --git a/openmls/tests/test_managed_api.rs b/openmls/tests/managed_api.rs similarity index 100% rename from openmls/tests/test_managed_api.rs rename to openmls/tests/managed_api.rs diff --git a/openmls/tests/test_mls_group.rs b/openmls/tests/mls_group.rs similarity index 87% rename from openmls/tests/test_mls_group.rs rename to openmls/tests/mls_group.rs index 3f83faff72..cae9cb49cc 100644 --- a/openmls/tests/test_mls_group.rs +++ b/openmls/tests/mls_group.rs @@ -1,6 +1,7 @@ use openmls::{ prelude::{test_utils::new_credential, *}, storage::OpenMlsProvider, + treesync::LeafNodeParameters, }; use openmls_traits::OpenMlsProvider as _; @@ -41,21 +42,28 @@ fn mls_group_operations() { for wire_format_policy in WIRE_FORMAT_POLICIES.iter() { let group_id = GroupId::from_slice(b"Test Group"); + let alice_provider = &Provider::default(); + let bob_provider = &Provider::default(); + let charlie_provider = &Provider::default(); + // Generate credentials with keys let (alice_credential, alice_signer) = - new_credential(provider, b"Alice", ciphersuite.signature_algorithm()); + new_credential(alice_provider, b"Alice", ciphersuite.signature_algorithm()); let (bob_credential, bob_signer) = - new_credential(provider, b"Bob", ciphersuite.signature_algorithm()); + new_credential(bob_provider, b"Bob", ciphersuite.signature_algorithm()); - let (charlie_credential, charlie_signer) = - new_credential(provider, b"Charlie", ciphersuite.signature_algorithm()); + let (charlie_credential, charlie_signer) = new_credential( + charlie_provider, + b"Charlie", + ciphersuite.signature_algorithm(), + ); // Generate KeyPackages let bob_key_package = generate_key_package( ciphersuite, Extensions::empty(), - provider, + bob_provider, bob_credential.clone(), &bob_signer, ); @@ -69,7 +77,7 @@ fn mls_group_operations() { // === Alice creates a group === let mut alice_group = MlsGroup::new_with_group_id( - provider, + alice_provider, &alice_signer, &mls_group_create_config, group_id.clone(), @@ -78,10 +86,11 @@ fn mls_group_operations() { .expect("An unexpected error occurred."); // === Alice adds Bob === - let welcome = match alice_group.add_members(provider, &alice_signer, &[bob_key_package]) { - Ok((_, welcome, _)) => welcome, - Err(e) => panic!("Could not add member to group: {e:?}"), - }; + let welcome = + match alice_group.add_members(alice_provider, &alice_signer, &[bob_key_package]) { + Ok((_, welcome, _)) => welcome, + Err(e) => panic!("Could not add member to group: {e:?}"), + }; // Check that we received the correct proposals if let Some(staged_commit) = alice_group.pending_commit() { @@ -103,7 +112,7 @@ fn mls_group_operations() { } alice_group - .merge_pending_commit(provider) + .merge_pending_commit(alice_provider) .expect("error merging pending commit"); // Check that the group now has two members @@ -122,13 +131,13 @@ fn mls_group_operations() { .expect("expected the message to be a welcome message"); let mut bob_group = StagedWelcome::new_from_welcome( - provider, + bob_provider, mls_group_create_config.join_config(), welcome, Some(alice_group.export_ratchet_tree().into()), ) .expect("Error creating StagedWelcome from Welcome") - .into_group(provider) + .into_group(bob_provider) .expect("Error creating group from StagedWelcome"); // Make sure that both groups have the same members @@ -143,12 +152,12 @@ fn mls_group_operations() { // === Alice sends a message to Bob === let message_alice = b"Hi, I'm Alice!"; let queued_message = alice_group - .create_message(provider, &alice_signer, message_alice) + .create_message(alice_provider, &alice_signer, message_alice) .expect("Error creating application message"); let processed_message = bob_group .process_message( - provider, + bob_provider, queued_message .clone() .into_protocol_message() @@ -167,7 +176,7 @@ fn mls_group_operations() { assert_eq!( &sender, alice_group - .credential::() + .credential() .expect("An unexpected error occurred.") ); } else { @@ -175,12 +184,13 @@ fn mls_group_operations() { } // === Bob updates and commits === - let (queued_message, welcome_option, _group_info) = - bob_group.self_update(provider, &bob_signer).unwrap(); + let (queued_message, welcome_option, _group_info) = bob_group + .self_update(bob_provider, &bob_signer, LeafNodeParameters::default()) + .unwrap(); let alice_processed_message = alice_group .process_message( - provider, + alice_provider, queued_message .clone() .into_protocol_message() @@ -194,14 +204,14 @@ fn mls_group_operations() { { // Merge staged Commit alice_group - .merge_staged_commit(provider, *staged_commit) + .merge_staged_commit(alice_provider, *staged_commit) .unwrap(); } else { unreachable!("Expected a StagedCommit."); } bob_group - .merge_pending_commit(provider) + .merge_pending_commit(bob_provider) .expect("error merging pending commit"); // Check we didn't receive a Welcome message @@ -209,8 +219,10 @@ fn mls_group_operations() { // Check that both groups have the same state assert_eq!( - alice_group.export_secret(provider, "", &[], 32).unwrap(), - bob_group.export_secret(provider, "", &[], 32).unwrap() + alice_group + .export_secret(alice_provider, "", &[], 32) + .unwrap(), + bob_group.export_secret(bob_provider, "", &[], 32).unwrap() ); // Make sure that both groups have the same public tree @@ -221,12 +233,12 @@ fn mls_group_operations() { // === Alice updates and commits === let (queued_message, _) = alice_group - .propose_self_update(provider, &alice_signer, None) + .propose_self_update(alice_provider, &alice_signer, LeafNodeParameters::default()) .unwrap(); let bob_processed_message = bob_group .process_message( - provider, + bob_provider, queued_message .clone() .into_protocol_message() @@ -246,7 +258,7 @@ fn mls_group_operations() { ); // Store proposal alice_group - .store_pending_proposal(provider.storage(), *staged_proposal.clone()) + .store_pending_proposal(alice_provider.storage(), *staged_proposal.clone()) .unwrap(); } else { unreachable!("Expected a Proposal."); @@ -259,19 +271,19 @@ fn mls_group_operations() { )); bob_group - .store_pending_proposal(provider.storage(), *staged_proposal) + .store_pending_proposal(bob_provider.storage(), *staged_proposal) .unwrap(); } else { unreachable!("Expected a QueuedProposal."); } let (queued_message, _welcome_option, _group_info) = alice_group - .commit_to_pending_proposals(provider, &alice_signer) + .commit_to_pending_proposals(alice_provider, &alice_signer) .unwrap(); let bob_processed_message = bob_group .process_message( - provider, + bob_provider, queued_message .clone() .into_protocol_message() @@ -284,20 +296,22 @@ fn mls_group_operations() { bob_processed_message.into_content() { bob_group - .merge_staged_commit(provider, *staged_commit) + .merge_staged_commit(bob_provider, *staged_commit) .unwrap(); } else { unreachable!("Expected a StagedCommit."); } alice_group - .merge_pending_commit(provider) + .merge_pending_commit(alice_provider) .expect("error merging pending commit"); // Check that both groups have the same state assert_eq!( - alice_group.export_secret(provider, "", &[], 32).unwrap(), - bob_group.export_secret(provider, "", &[], 32).unwrap() + alice_group + .export_secret(alice_provider, "", &[], 32) + .unwrap(), + bob_group.export_secret(bob_provider, "", &[], 32).unwrap() ); // Make sure that both groups have the same public tree @@ -310,18 +324,18 @@ fn mls_group_operations() { let charlie_key_package = generate_key_package( ciphersuite, Extensions::empty(), - provider, + charlie_provider, charlie_credential, &charlie_signer, ); let (queued_message, welcome, _group_info) = bob_group - .add_members(provider, &bob_signer, &[charlie_key_package]) + .add_members(bob_provider, &bob_signer, &[charlie_key_package]) .unwrap(); let alice_processed_message = alice_group .process_message( - provider, + alice_provider, queued_message .clone() .into_protocol_message() @@ -329,7 +343,7 @@ fn mls_group_operations() { ) .expect("Could not process message."); bob_group - .merge_pending_commit(provider) + .merge_pending_commit(bob_provider) .expect("error merging pending commit"); // Merge Commit @@ -337,7 +351,7 @@ fn mls_group_operations() { alice_processed_message.into_content() { alice_group - .merge_staged_commit(provider, *staged_commit) + .merge_staged_commit(alice_provider, *staged_commit) .unwrap(); } else { unreachable!("Expected a StagedCommit."); @@ -349,13 +363,13 @@ fn mls_group_operations() { .expect("expected the message to be a welcome message"); let mut charlie_group = StagedWelcome::new_from_welcome( - provider, + charlie_provider, mls_group_create_config.join_config(), welcome, Some(bob_group.export_ratchet_tree().into()), ) .expect("Error creating staged join from Welcome") - .into_group(provider) + .into_group(charlie_provider) .expect("Error creating group from staged join"); // Make sure that all groups have the same public tree @@ -380,12 +394,12 @@ fn mls_group_operations() { // === Charlie sends a message to the group === let message_charlie = b"Hi, I'm Charlie!"; let queued_message = charlie_group - .create_message(provider, &charlie_signer, message_charlie) + .create_message(charlie_provider, &charlie_signer, message_charlie) .expect("Error creating application message"); let _alice_processed_message = alice_group .process_message( - provider, + alice_provider, queued_message .clone() .into_protocol_message() @@ -394,7 +408,7 @@ fn mls_group_operations() { .expect("Could not process message."); let _bob_processed_message = bob_group .process_message( - provider, + bob_provider, queued_message .clone() .into_protocol_message() @@ -404,12 +418,16 @@ fn mls_group_operations() { // === Charlie updates and commits === let (queued_message, welcome_option, _group_info) = charlie_group - .self_update(provider, &charlie_signer) + .self_update( + charlie_provider, + &charlie_signer, + LeafNodeParameters::default(), + ) .unwrap(); let alice_processed_message = alice_group .process_message( - provider, + alice_provider, queued_message .clone() .into_protocol_message() @@ -418,7 +436,7 @@ fn mls_group_operations() { .expect("Could not process message."); let bob_processed_message = bob_group .process_message( - provider, + bob_provider, queued_message .clone() .into_protocol_message() @@ -426,7 +444,7 @@ fn mls_group_operations() { ) .expect("Could not process message."); charlie_group - .merge_pending_commit(provider) + .merge_pending_commit(charlie_provider) .expect("error merging pending commit"); // Merge Commit @@ -434,7 +452,7 @@ fn mls_group_operations() { alice_processed_message.into_content() { alice_group - .merge_staged_commit(provider, *staged_commit) + .merge_staged_commit(alice_provider, *staged_commit) .unwrap(); } else { unreachable!("Expected a StagedCommit."); @@ -445,7 +463,7 @@ fn mls_group_operations() { bob_processed_message.into_content() { bob_group - .merge_staged_commit(provider, *staged_commit) + .merge_staged_commit(bob_provider, *staged_commit) .unwrap(); } else { unreachable!("Expected a StagedCommit."); @@ -456,12 +474,18 @@ fn mls_group_operations() { // Check that all groups have the same state assert_eq!( - alice_group.export_secret(provider, "", &[], 32).unwrap(), - bob_group.export_secret(provider, "", &[], 32).unwrap() + alice_group + .export_secret(alice_provider, "", &[], 32) + .unwrap(), + bob_group.export_secret(bob_provider, "", &[], 32).unwrap() ); assert_eq!( - alice_group.export_secret(provider, "", &[], 32).unwrap(), - charlie_group.export_secret(provider, "", &[], 32).unwrap() + alice_group + .export_secret(alice_provider, "", &[], 32) + .unwrap(), + charlie_group + .export_secret(charlie_provider, "", &[], 32) + .unwrap() ); // Make sure that all groups have the same public tree @@ -477,7 +501,11 @@ fn mls_group_operations() { // === Charlie removes Bob === println!(" >>> Charlie is removing bob"); let (queued_message, welcome_option, _group_info) = charlie_group - .remove_members(provider, &charlie_signer, &[bob_group.own_leaf_index()]) + .remove_members( + charlie_provider, + &charlie_signer, + &[bob_group.own_leaf_index()], + ) .expect("Could not remove member from group."); // Check that Bob's group is still active @@ -485,7 +513,7 @@ fn mls_group_operations() { let alice_processed_message = alice_group .process_message( - provider, + alice_provider, queued_message .clone() .into_protocol_message() @@ -494,7 +522,7 @@ fn mls_group_operations() { .expect("Could not process message."); let bob_processed_message = bob_group .process_message( - provider, + bob_provider, queued_message .clone() .into_protocol_message() @@ -502,7 +530,7 @@ fn mls_group_operations() { ) .expect("Could not process message."); charlie_group - .merge_pending_commit(provider) + .merge_pending_commit(charlie_provider) .expect("error merging pending commit"); // Check that we receive the correct proposal for Alice @@ -522,7 +550,7 @@ fn mls_group_operations() { // Merge staged Commit alice_group - .merge_staged_commit(provider, *staged_commit) + .merge_staged_commit(alice_provider, *staged_commit) .unwrap(); } else { unreachable!("Expected a StagedCommit."); @@ -545,7 +573,7 @@ fn mls_group_operations() { // Merge staged Commit bob_group - .merge_staged_commit(provider, *staged_commit) + .merge_staged_commit(bob_provider, *staged_commit) .unwrap(); } else { unreachable!("Expected a StagedCommit."); @@ -575,7 +603,7 @@ fn mls_group_operations() { // Check that Bob can no longer send messages assert!(bob_group - .create_message(provider, &bob_signer, b"Should not go through") + .create_message(bob_provider, &bob_signer, b"Should not go through") .is_err()); // === Alice removes Charlie and re-adds Bob === @@ -584,19 +612,23 @@ fn mls_group_operations() { let bob_key_package = generate_key_package( ciphersuite, Extensions::empty(), - provider, + bob_provider, bob_credential.clone(), &bob_signer, ); // Create RemoveProposal and process it let (queued_message, _) = alice_group - .propose_remove_member(provider, &alice_signer, charlie_group.own_leaf_index()) + .propose_remove_member( + alice_provider, + &alice_signer, + charlie_group.own_leaf_index(), + ) .expect("Could not create proposal to remove Charlie"); let charlie_processed_message = charlie_group .process_message( - provider, + charlie_provider, queued_message .clone() .into_protocol_message() @@ -613,7 +645,7 @@ fn mls_group_operations() { assert_eq!(remove_proposal.removed(), members[1].index); // Store proposal charlie_group - .store_pending_proposal(provider.storage(), *staged_proposal.clone()) + .store_pending_proposal(charlie_provider.storage(), *staged_proposal.clone()) .unwrap(); } else { unreachable!("Expected a Proposal."); @@ -630,12 +662,12 @@ fn mls_group_operations() { // Create AddProposal and process it let (queued_message, _) = alice_group - .propose_add_member(provider, &alice_signer, &bob_key_package) + .propose_add_member(alice_provider, &alice_signer, &bob_key_package) .expect("Could not create proposal to add Bob"); let charlie_processed_message = charlie_group .process_message( - provider, + charlie_provider, queued_message .clone() .into_protocol_message() @@ -664,7 +696,7 @@ fn mls_group_operations() { )); // Store proposal charlie_group - .store_pending_proposal(provider.storage(), *staged_proposal) + .store_pending_proposal(charlie_provider.storage(), *staged_proposal) .unwrap(); } else { unreachable!("Expected a QueuedProposal."); @@ -672,12 +704,12 @@ fn mls_group_operations() { // Commit to the proposals and process it let (queued_message, welcome_option, _group_info) = alice_group - .commit_to_pending_proposals(provider, &alice_signer) + .commit_to_pending_proposals(alice_provider, &alice_signer) .expect("Could not flush proposals"); let charlie_processed_message = charlie_group .process_message( - provider, + charlie_provider, queued_message .clone() .into_protocol_message() @@ -687,7 +719,7 @@ fn mls_group_operations() { // Merge Commit alice_group - .merge_pending_commit(provider) + .merge_pending_commit(alice_provider) .expect("error merging pending commit"); // Merge Commit @@ -695,7 +727,7 @@ fn mls_group_operations() { charlie_processed_message.into_content() { charlie_group - .merge_staged_commit(provider, *staged_commit) + .merge_staged_commit(charlie_provider, *staged_commit) .unwrap(); } else { unreachable!("Expected a StagedCommit."); @@ -718,13 +750,13 @@ fn mls_group_operations() { // Bob creates a new group let mut bob_group = StagedWelcome::new_from_welcome( - provider, + bob_provider, mls_group_create_config.join_config(), welcome, Some(alice_group.export_ratchet_tree().into()), ) .expect("Error creating staged join from Welcome") - .into_group(provider) + .into_group(bob_provider) .expect("Error creating group from staged join"); // Make sure the group contains two members @@ -750,12 +782,12 @@ fn mls_group_operations() { // === Alice sends a message to the group === let message_alice = b"Hi, I'm Alice!"; let queued_message = alice_group - .create_message(provider, &alice_signer, message_alice) + .create_message(alice_provider, &alice_signer, message_alice) .expect("Error creating application message"); let bob_processed_message = bob_group .process_message( - provider, + bob_provider, queued_message .clone() .into_protocol_message() @@ -773,9 +805,7 @@ fn mls_group_operations() { // Check that Alice sent the message assert_eq!( &sender, - alice_group - .credential::() - .expect("Expected a credential") + alice_group.credential().expect("Expected a credential") ); } else { unreachable!("Expected an ApplicationMessage."); @@ -784,12 +814,12 @@ fn mls_group_operations() { // === Bob leaves the group === let queued_message = bob_group - .leave_group(provider, &bob_signer) + .leave_group(bob_provider, &bob_signer) .expect("Could not leave group"); let alice_processed_message = alice_group .process_message( - provider, + alice_provider, queued_message .clone() .into_protocol_message() @@ -803,7 +833,7 @@ fn mls_group_operations() { { // Store proposal alice_group - .store_pending_proposal(provider.storage(), *staged_proposal) + .store_pending_proposal(alice_provider.storage(), *staged_proposal) .unwrap(); } else { unreachable!("Expected a QueuedProposal."); @@ -811,14 +841,14 @@ fn mls_group_operations() { // Should fail because you cannot remove yourself from a group assert!(matches!( - bob_group.commit_to_pending_proposals(provider, &bob_signer), + bob_group.commit_to_pending_proposals(bob_provider, &bob_signer), Err(CommitToPendingProposalsError::CreateCommitError( CreateCommitError::CannotRemoveSelf )) )); let (queued_message, _welcome_option, _group_info) = alice_group - .commit_to_pending_proposals(provider, &alice_signer) + .commit_to_pending_proposals(alice_provider, &alice_signer) .expect("Could not commit to proposals."); // Check that Bob's group is still active @@ -842,12 +872,12 @@ fn mls_group_operations() { } alice_group - .merge_pending_commit(provider) + .merge_pending_commit(alice_provider) .expect("Could not merge Commit."); let bob_processed_message = bob_group .process_message( - provider, + bob_provider, queued_message .clone() .into_protocol_message() @@ -871,7 +901,7 @@ fn mls_group_operations() { assert!(staged_commit.self_removed()); // Merge staged Commit bob_group - .merge_staged_commit(provider, *staged_commit) + .merge_staged_commit(bob_provider, *staged_commit) .unwrap(); } else { unreachable!("Expected a StagedCommit."); @@ -894,23 +924,23 @@ fn mls_group_operations() { let bob_key_package = generate_key_package( ciphersuite, Extensions::empty(), - provider, + bob_provider, bob_credential, &bob_signer, ); // Add Bob to the group let (_queued_message, welcome, _group_info) = alice_group - .add_members(provider, &alice_signer, &[bob_key_package]) + .add_members(alice_provider, &alice_signer, &[bob_key_package]) .expect("Could not add Bob"); - let _test_group = MlsGroup::load(provider.storage(), &group_id) + let _test_group = MlsGroup::load(alice_provider.storage(), &group_id) .expect("Could not load the group state due to an error.") .expect("Could not load the group state because the group does not exist."); // Merge Commit alice_group - .merge_pending_commit(provider) + .merge_pending_commit(alice_provider) .expect("error merging pending commit"); let welcome: MlsMessageIn = welcome.into(); @@ -919,35 +949,35 @@ fn mls_group_operations() { .expect("expected the message to be a welcome message"); let mut bob_group = StagedWelcome::new_from_welcome( - provider, + bob_provider, mls_group_create_config.join_config(), welcome, Some(alice_group.export_ratchet_tree().into()), ) .expect("Could not create staged join from Welcome") - .into_group(provider) + .into_group(bob_provider) .expect("Could not create group from staged join"); assert_eq!( alice_group - .export_secret(provider, "before load", &[], 32) + .export_secret(alice_provider, "before load", &[], 32) .unwrap(), bob_group - .export_secret(provider, "before load", &[], 32) + .export_secret(bob_provider, "before load", &[], 32) .unwrap() ); - bob_group = MlsGroup::load(provider.storage(), &group_id) + bob_group = MlsGroup::load(bob_provider.storage(), &group_id) .expect("Could not load group from file because of an error") .expect("Could not load group from file because there is no group with given id"); // Make sure the state is still the same assert_eq!( alice_group - .export_secret(provider, "after load", &[], 32) + .export_secret(alice_provider, "after load", &[], 32) .unwrap(), bob_group - .export_secret(provider, "after load", &[], 32) + .export_secret(bob_provider, "after load", &[], 32) .unwrap() ); } diff --git a/openmls_rust_crypto/Cargo.toml b/openmls_rust_crypto/Cargo.toml index b9594cd36c..d255445424 100644 --- a/openmls_rust_crypto/Cargo.toml +++ b/openmls_rust_crypto/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "openmls_rust_crypto" authors = ["OpenMLS Authors"] -version = "0.2.0" +version = "0.3.0-pre.1" edition = "2021" description = "A crypto backend for OpenMLS implementing openmls_traits using RustCrypto primitives." license = "MIT" @@ -10,8 +10,8 @@ repository = "https://github.com/openmls/openmls/tree/main/openmls_rust_crypto" readme = "README.md" [dependencies] -openmls_traits = { version = "0.2.0", path = "../traits" } -openmls_memory_storage = { version = "0.2.0", path = "../memory_storage" } +openmls_traits = { version = "0.3.0-pre.2", path = "../traits" } +openmls_memory_storage = { version = "0.3.0-pre.2", path = "../memory_storage" } hpke = { version = "0.2.0", package = "hpke-rs", default-features = false, features = [ "hazmat", "serialization", @@ -31,3 +31,6 @@ hpke-rs-rust-crypto = { version = "0.2.0" } tls_codec = { workspace = true } thiserror = "1.0" serde = { version = "^1.0", features = ["derive"] } + +[features] +test-utils = [] diff --git a/openmls_rust_crypto/src/lib.rs b/openmls_rust_crypto/src/lib.rs index d9e437330e..58f7b5d300 100644 --- a/openmls_rust_crypto/src/lib.rs +++ b/openmls_rust_crypto/src/lib.rs @@ -10,6 +10,7 @@ mod provider; pub use provider::*; #[derive(Default, Debug)] +#[cfg_attr(feature = "test-utils", derive(Clone))] pub struct OpenMlsRustCrypto { crypto: RustCrypto, key_store: MemoryStorage, diff --git a/openmls_rust_crypto/src/provider.rs b/openmls_rust_crypto/src/provider.rs index 23222c8827..bdb2799f8e 100644 --- a/openmls_rust_crypto/src/provider.rs +++ b/openmls_rust_crypto/src/provider.rs @@ -31,6 +31,15 @@ pub struct RustCrypto { rng: RwLock, } +// For testing we want to clone. +// But really we just create a new Rng. +#[cfg(feature = "test-utils")] +impl Clone for RustCrypto { + fn clone(&self) -> Self { + Self::default() + } +} + impl Default for RustCrypto { fn default() -> Self { Self { diff --git a/openmls_test/Cargo.toml b/openmls_test/Cargo.toml index be54b59fc4..02b9cbe1c8 100644 --- a/openmls_test/Cargo.toml +++ b/openmls_test/Cargo.toml @@ -1,8 +1,13 @@ [package] name = "openmls_test" -version = "0.1.0" +version = "0.1.0-pre.1" +authors = ["OpenMLS Authors"] edition = "2021" -authors = ["Franziskus Kiefer "] +description = "Test utility used by OpenMLS" +license = "MIT" +documentation = "https://docs.rs/openmls_test" +repository = "https://github.com/openmls/openmls/tree/main/openmls_test" +readme = "Readme.md" [lib] proc-macro = true @@ -18,6 +23,6 @@ ansi_term = "0.12.1" quote = "1.0" rstest = { version = "0.17" } rstest_reuse = { version = "0.5" } -openmls_rust_crypto = { version = "=0.2.0", path = "../openmls_rust_crypto" } -openmls_libcrux_crypto = { version = "=0.1.0", path = "../libcrux_crypto", optional = true } -openmls_traits = { path = "../traits" } +openmls_rust_crypto = { version = "0.3.0-pre.1", path = "../openmls_rust_crypto" } +openmls_libcrux_crypto = { version = "0.1.0-pre.2", path = "../libcrux_crypto", optional = true } +openmls_traits = { version = "0.3.0-pre.2", path = "../traits" } diff --git a/traits/Cargo.toml b/traits/Cargo.toml index 440a3d64a0..dad103802b 100644 --- a/traits/Cargo.toml +++ b/traits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openmls_traits" -version = "0.2.0" +version = "0.3.0-pre.2" authors = ["OpenMLS Authors"] edition = "2021" description = "Traits used by OpenMLS" diff --git a/traits/src/public_storage.rs b/traits/src/public_storage.rs new file mode 100644 index 0000000000..56a7f12f3a --- /dev/null +++ b/traits/src/public_storage.rs @@ -0,0 +1,326 @@ +//! This module describes the public storage provider and type traits. +//! Applications that only want to use the `PublicGroup` only need to implement +//! the `PublicStorageProvider` trait, and not the `StorageProvider` trait. + +use crate::storage::StorageProvider; + +pub trait PublicStorageProvider { + /// An opaque error returned by all methods on this trait. + type PublicError: core::fmt::Debug + std::error::Error; + + /// Get the version of this provider. + fn version() -> u16 { + VERSION + } + + /// Write the TreeSync tree. + fn write_tree< + GroupId: crate::storage::traits::GroupId, + TreeSync: crate::storage::traits::TreeSync, + >( + &self, + group_id: &GroupId, + tree: &TreeSync, + ) -> Result<(), Self::PublicError>; + + /// Write the interim transcript hash. + fn write_interim_transcript_hash< + GroupId: crate::storage::traits::GroupId, + InterimTranscriptHash: crate::storage::traits::InterimTranscriptHash, + >( + &self, + group_id: &GroupId, + interim_transcript_hash: &InterimTranscriptHash, + ) -> Result<(), Self::PublicError>; + + /// Write the group context. + fn write_context< + GroupId: crate::storage::traits::GroupId, + GroupContext: crate::storage::traits::GroupContext, + >( + &self, + group_id: &GroupId, + group_context: &GroupContext, + ) -> Result<(), Self::PublicError>; + + /// Write the confirmation tag. + fn write_confirmation_tag< + GroupId: crate::storage::traits::GroupId, + ConfirmationTag: crate::storage::traits::ConfirmationTag, + >( + &self, + group_id: &GroupId, + confirmation_tag: &ConfirmationTag, + ) -> Result<(), Self::PublicError>; + + /// Enqueue a proposal. + fn queue_proposal< + GroupId: crate::storage::traits::GroupId, + ProposalRef: crate::storage::traits::ProposalRef, + QueuedProposal: crate::storage::traits::QueuedProposal, + >( + &self, + group_id: &GroupId, + proposal_ref: &ProposalRef, + proposal: &QueuedProposal, + ) -> Result<(), Self::PublicError>; + + /// Returns all queued proposals for the group with group id `group_id`, or an empty vector of none are stored. + fn queued_proposals< + GroupId: crate::storage::traits::GroupId, + ProposalRef: crate::storage::traits::ProposalRef, + QueuedProposal: crate::storage::traits::QueuedProposal, + >( + &self, + group_id: &GroupId, + ) -> Result, Self::PublicError>; + + /// Returns the TreeSync tree for the group with group id `group_id`. + fn treesync< + GroupId: crate::storage::traits::GroupId, + TreeSync: crate::storage::traits::TreeSync, + >( + &self, + group_id: &GroupId, + ) -> Result, Self::PublicError>; + + /// Returns the group context for the group with group id `group_id`. + fn group_context< + GroupId: crate::storage::traits::GroupId, + GroupContext: crate::storage::traits::GroupContext, + >( + &self, + group_id: &GroupId, + ) -> Result, Self::PublicError>; + + /// Returns the interim transcript hash for the group with group id `group_id`. + fn interim_transcript_hash< + GroupId: crate::storage::traits::GroupId, + InterimTranscriptHash: crate::storage::traits::InterimTranscriptHash, + >( + &self, + group_id: &GroupId, + ) -> Result, Self::PublicError>; + + /// Returns the confirmation tag for the group with group id `group_id`. + fn confirmation_tag< + GroupId: crate::storage::traits::GroupId, + ConfirmationTag: crate::storage::traits::ConfirmationTag, + >( + &self, + group_id: &GroupId, + ) -> Result, Self::PublicError>; + + /// Deletes the tree from storage + fn delete_tree>( + &self, + group_id: &GroupId, + ) -> Result<(), Self::PublicError>; + + /// Deletes the confirmation tag from storage + fn delete_confirmation_tag>( + &self, + group_id: &GroupId, + ) -> Result<(), Self::PublicError>; + + /// Deletes the group context for the group with given id + fn delete_context>( + &self, + group_id: &GroupId, + ) -> Result<(), Self::PublicError>; + + /// Deletes the interim transcript hash for the group with given id + fn delete_interim_transcript_hash>( + &self, + group_id: &GroupId, + ) -> Result<(), Self::PublicError>; + + /// Removes an individual proposal from the proposal queue of the group with the provided id + fn remove_proposal< + GroupId: crate::storage::traits::GroupId, + ProposalRef: crate::storage::traits::ProposalRef, + >( + &self, + group_id: &GroupId, + proposal_ref: &ProposalRef, + ) -> Result<(), Self::PublicError>; + + /// Clear the proposal queue for the group with the given id. + fn clear_proposal_queue< + GroupId: crate::storage::traits::GroupId, + ProposalRef: crate::storage::traits::ProposalRef, + >( + &self, + group_id: &GroupId, + ) -> Result<(), Self::PublicError>; +} + +impl PublicStorageProvider for T +where + T: StorageProvider, +{ + type PublicError = >::Error; + + fn write_tree< + GroupId: crate::storage::traits::GroupId, + TreeSync: crate::storage::traits::TreeSync, + >( + &self, + group_id: &GroupId, + tree: &TreeSync, + ) -> Result<(), Self::PublicError> { + >::write_tree(self, group_id, tree) + } + + fn write_interim_transcript_hash< + GroupId: crate::storage::traits::GroupId, + InterimTranscriptHash: crate::storage::traits::InterimTranscriptHash, + >( + &self, + group_id: &GroupId, + interim_transcript_hash: &InterimTranscriptHash, + ) -> Result<(), Self::PublicError> { + >::write_interim_transcript_hash( + self, + group_id, + interim_transcript_hash, + ) + } + + fn write_context< + GroupId: crate::storage::traits::GroupId, + GroupContext: crate::storage::traits::GroupContext, + >( + &self, + group_id: &GroupId, + group_context: &GroupContext, + ) -> Result<(), Self::PublicError> { + >::write_context(self, group_id, group_context) + } + + fn write_confirmation_tag< + GroupId: crate::storage::traits::GroupId, + ConfirmationTag: crate::storage::traits::ConfirmationTag, + >( + &self, + group_id: &GroupId, + confirmation_tag: &ConfirmationTag, + ) -> Result<(), Self::PublicError> { + >::write_confirmation_tag(self, group_id, confirmation_tag) + } + + fn queue_proposal< + GroupId: crate::storage::traits::GroupId, + ProposalRef: crate::storage::traits::ProposalRef, + QueuedProposal: crate::storage::traits::QueuedProposal, + >( + &self, + group_id: &GroupId, + proposal_ref: &ProposalRef, + proposal: &QueuedProposal, + ) -> Result<(), Self::PublicError> { + >::queue_proposal(self, group_id, proposal_ref, proposal) + } + + fn queued_proposals< + GroupId: crate::storage::traits::GroupId, + ProposalRef: crate::storage::traits::ProposalRef, + QueuedProposal: crate::storage::traits::QueuedProposal, + >( + &self, + group_id: &GroupId, + ) -> Result, Self::PublicError> { + >::queued_proposals(self, group_id) + } + + fn treesync< + GroupId: crate::storage::traits::GroupId, + TreeSync: crate::storage::traits::TreeSync, + >( + &self, + group_id: &GroupId, + ) -> Result, Self::PublicError> { + >::tree(self, group_id) + } + + fn group_context< + GroupId: crate::storage::traits::GroupId, + GroupContext: crate::storage::traits::GroupContext, + >( + &self, + group_id: &GroupId, + ) -> Result, Self::PublicError> { + >::group_context(self, group_id) + } + + fn interim_transcript_hash< + GroupId: crate::storage::traits::GroupId, + InterimTranscriptHash: crate::storage::traits::InterimTranscriptHash, + >( + &self, + group_id: &GroupId, + ) -> Result, Self::PublicError> { + >::interim_transcript_hash(self, group_id) + } + + fn confirmation_tag< + GroupId: crate::storage::traits::GroupId, + ConfirmationTag: crate::storage::traits::ConfirmationTag, + >( + &self, + group_id: &GroupId, + ) -> Result, Self::PublicError> { + >::confirmation_tag(self, group_id) + } + + fn delete_tree>( + &self, + group_id: &GroupId, + ) -> Result<(), Self::PublicError> { + >::delete_tree(self, group_id) + } + + fn delete_confirmation_tag>( + &self, + group_id: &GroupId, + ) -> Result<(), Self::PublicError> { + >::delete_confirmation_tag(self, group_id) + } + + fn delete_context>( + &self, + group_id: &GroupId, + ) -> Result<(), Self::PublicError> { + >::delete_context(self, group_id) + } + + fn delete_interim_transcript_hash>( + &self, + group_id: &GroupId, + ) -> Result<(), Self::PublicError> { + >::delete_interim_transcript_hash(self, group_id) + } + + fn remove_proposal< + GroupId: crate::storage::traits::GroupId, + ProposalRef: crate::storage::traits::ProposalRef, + >( + &self, + group_id: &GroupId, + proposal_ref: &ProposalRef, + ) -> Result<(), Self::PublicError> { + >::remove_proposal(self, group_id, proposal_ref) + } + + fn clear_proposal_queue< + GroupId: crate::storage::traits::GroupId, + ProposalRef: crate::storage::traits::ProposalRef, + >( + &self, + group_id: &GroupId, + ) -> Result<(), Self::PublicError> { + >::clear_proposal_queue::( + self, group_id, + ) + } +} diff --git a/traits/src/random.rs b/traits/src/random.rs index 424961a497..c6da9851f7 100644 --- a/traits/src/random.rs +++ b/traits/src/random.rs @@ -5,6 +5,7 @@ use std::fmt::Debug; +// ANCHOR: openmls_rand pub trait OpenMlsRand { type Error: std::error::Error + Debug; @@ -14,3 +15,4 @@ pub trait OpenMlsRand { /// Fill a vector of length `len` with bytes. fn random_vec(&self, len: usize) -> Result, Self::Error>; } +// ANCHOR_END: openmls_rand diff --git a/traits/src/storage.rs b/traits/src/storage.rs index 6c14781ade..593474e4a6 100644 --- a/traits/src/storage.rs +++ b/traits/src/storage.rs @@ -49,13 +49,6 @@ pub trait StorageProvider { config: &MlsGroupJoinConfig, ) -> Result<(), Self::Error>; - /// Writes the AAD for the group with given id to storage - fn write_aad>( - &self, - group_id: &GroupId, - aad: &[u8], - ) -> Result<(), Self::Error>; - /// Adds an own leaf node for the group with given id to storage fn append_own_leaf_node< GroupId: traits::GroupId, @@ -158,14 +151,6 @@ pub trait StorageProvider { own_leaf_index: &LeafNodeIndex, ) -> Result<(), Self::Error>; - /// Returns the MlsGroupState for group with given id. - /// Sets whether to use the RatchetTreeExtension for the group with the given id. - fn set_use_ratchet_tree_extension>( - &self, - group_id: &GroupId, - value: bool, - ) -> Result<(), Self::Error>; - /// Writes the GroupEpochSecrets for the group with the given id. fn write_group_epoch_secrets< GroupId: traits::GroupId, @@ -266,18 +251,13 @@ pub trait StorageProvider { group_id: &GroupId, ) -> Result, Self::Error>; + ///ANCHOR: own_leaf_nodes /// Returns the own leaf nodes for the group with given id fn own_leaf_nodes, LeafNode: traits::LeafNode>( &self, group_id: &GroupId, ) -> Result, Self::Error>; - - /// Returns the AAD for the group with given id - /// If the value has not been set, returns an empty vector. - fn aad>( - &self, - group_id: &GroupId, - ) -> Result, Self::Error>; + ///ANCHOR_END: own_leaf_nodes /// Returns references of all queued proposals for the group with group id `group_id`, or an empty vector of none are stored. fn queued_proposal_refs< @@ -299,7 +279,7 @@ pub trait StorageProvider { ) -> Result, Self::Error>; /// Returns the TreeSync tree for the group with group id `group_id`. - fn treesync, TreeSync: traits::TreeSync>( + fn tree, TreeSync: traits::TreeSync>( &self, group_id: &GroupId, ) -> Result, Self::Error>; @@ -367,12 +347,6 @@ pub trait StorageProvider { group_id: &GroupId, ) -> Result, Self::Error>; - /// Returns whether to use the RatchetTreeExtension for the group with the given id. - fn use_ratchet_tree_extension>( - &self, - group_id: &GroupId, - ) -> Result, Self::Error>; - /// Returns the GroupEpochSecrets for the group with the given id. fn group_epoch_secrets< GroupId: traits::GroupId, @@ -453,12 +427,6 @@ pub trait StorageProvider { proposal_ref: &ProposalRef, ) -> Result<(), Self::Error>; - /// Deletes the AAD for the given id from storage - fn delete_aad>( - &self, - group_id: &GroupId, - ) -> Result<(), Self::Error>; - /// Deletes own leaf nodes for the given id from storage fn delete_own_leaf_nodes>( &self, @@ -519,19 +487,13 @@ pub trait StorageProvider { group_id: &GroupId, ) -> Result<(), Self::Error>; - /// Deletes any preference about whether to use the RatchetTreeExtension for the group with the given id. - fn delete_use_ratchet_tree_extension>( - &self, - group_id: &GroupId, - ) -> Result<(), Self::Error>; - /// Deletes the GroupEpochSecrets for the group with the given id. fn delete_group_epoch_secrets>( &self, group_id: &GroupId, ) -> Result<(), Self::Error>; - /// Clear the proposal queue for the grou pwith the given id. + /// Clear the proposal queue for the group with the given id. fn clear_proposal_queue< GroupId: traits::GroupId, ProposalRef: traits::ProposalRef, diff --git a/traits/src/traits.rs b/traits/src/traits.rs index 96514da36c..8f5e7f0e7a 100644 --- a/traits/src/traits.rs +++ b/traits/src/traits.rs @@ -4,6 +4,7 @@ //! API of OpenMLS. pub mod crypto; +pub mod public_storage; pub mod random; pub mod signatures; pub mod storage; @@ -23,6 +24,7 @@ pub mod prelude { /// /// An implementation of this trait must be passed in to the public OpenMLS API /// to perform randomness generation, cryptographic operations, and key storage. +// ANCHOR: openmls_provider pub trait OpenMlsProvider { type CryptoProvider: crypto::OpenMlsCrypto; type RandProvider: random::OpenMlsRand; @@ -37,3 +39,4 @@ pub trait OpenMlsProvider { /// Get the randomness provider. fn rand(&self) -> &Self::RandProvider; } +// ANCHOR_END: openmls_provider