diff --git a/pr/580/docs/help.html b/pr/580/docs/help.html index 99d8cb979..cb140c09e 100644 --- a/pr/580/docs/help.html +++ b/pr/580/docs/help.html @@ -1 +1 @@ -Help

All

Rustdoc help

Back
\ No newline at end of file +Help

All

Rustdoc help

Back
\ No newline at end of file diff --git a/pr/580/docs/noq/enum.ConnectionError.html b/pr/580/docs/noq/enum.ConnectionError.html index 3b8f08c9a..9f9faacff 100644 --- a/pr/580/docs/noq/enum.ConnectionError.html +++ b/pr/580/docs/noq/enum.ConnectionError.html @@ -1,4 +1,4 @@ -ConnectionError in noq - Rust

ConnectionError

Enum ConnectionError 

Source
pub enum ConnectionError {
+ConnectionError in noq - Rust

ConnectionError

Enum ConnectionError 

Source
pub enum ConnectionError {
     VersionMismatch,
     TransportError(Error),
     ConnectionClosed(ConnectionClose),
@@ -20,8 +20,8 @@ and §

LocallyClosed

The local application closed the connection

§

CidsExhausted

The connection could not be created because not enough of the CID space is available

Try using longer connection IDs.

-

Trait Implementations§

Source§

impl Clone for ConnectionError

Source§

fn clone(&self) -> ConnectionError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ConnectionError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Display for ConnectionError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Error for ConnectionError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<Close> for ConnectionError

Source§

fn from(x: Close) -> ConnectionError

Converts to this type from the input type.
Source§

impl From<CloseReason> for ConnectionError

Source§

fn from(value: CloseReason) -> ConnectionError

Converts to this type from the input type.
Source§

impl From<ConnectionError> for ReadError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for ResetError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for SendDatagramError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for StoppedError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for WriteError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for ConnectionError

Source§

fn from(source: Error) -> ConnectionError

Converts to this type from the input type.
Source§

impl PartialEq for ConnectionError

Source§

fn eq(&self, other: &ConnectionError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, -and should not be overridden without very good reason.
Source§

impl Eq for ConnectionError

Source§

impl StructuralPartialEq for ConnectionError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for ConnectionError

Source§

fn clone(&self) -> ConnectionError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ConnectionError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Display for ConnectionError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Error for ConnectionError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<Close> for ConnectionError

Source§

fn from(x: Close) -> ConnectionError

Converts to this type from the input type.
Source§

impl From<CloseReason> for ConnectionError

Source§

fn from(value: CloseReason) -> ConnectionError

Converts to this type from the input type.
Source§

impl From<ConnectionError> for ReadError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for ResetError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for SendDatagramError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for StoppedError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<ConnectionError> for WriteError

Source§

fn from(source: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for ConnectionError

Source§

fn from(source: Error) -> ConnectionError

Converts to this type from the input type.
Source§

impl PartialEq for ConnectionError

Source§

fn eq(&self, other: &ConnectionError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +and should not be overridden without very good reason.
Source§

impl Eq for ConnectionError

Source§

impl StructuralPartialEq for ConnectionError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/580/docs/noq/trait.NetworkChangeHint.html b/pr/580/docs/noq/trait.NetworkChangeHint.html index 3a23ffcd6..950b4b95b 100644 --- a/pr/580/docs/noq/trait.NetworkChangeHint.html +++ b/pr/580/docs/noq/trait.NetworkChangeHint.html @@ -1,4 +1,4 @@ -NetworkChangeHint in noq - Rust

NetworkChangeHint

Trait NetworkChangeHint 

Source
pub trait NetworkChangeHint: Debug + 'static {
+NetworkChangeHint in noq - Rust

NetworkChangeHint

Trait NetworkChangeHint 

Source
pub trait NetworkChangeHint: Debug + 'static {
     // Required method
     fn is_path_recoverable(
         &self,
@@ -6,7 +6,7 @@
         network_path: FourTuple,
     ) -> bool;
 }
Expand description

Hints when the caller identifies a network change.

-

Required Methods§

Source

fn is_path_recoverable(&self, path_id: PathId, network_path: FourTuple) -> bool

Inform the connection if a path may recover after a network change.

+

Required Methods§

Source

fn is_path_recoverable(&self, path_id: PathId, network_path: FourTuple) -> bool

Inform the connection if a path may recover after a network change.

After network changes, paths may not be recoverable. In this case, waiting for the path to become idle may take longer than what is desirable. If Self::is_path_recoverable returns false, a multipath-enabled, client-side connection will establish a new path to diff --git a/pr/580/docs/noq_proto/enum.ClosePathError.html b/pr/580/docs/noq_proto/enum.ClosePathError.html index 98bbb7333..a67f01cc3 100644 --- a/pr/580/docs/noq_proto/enum.ClosePathError.html +++ b/pr/580/docs/noq_proto/enum.ClosePathError.html @@ -1,4 +1,4 @@ -ClosePathError in noq_proto - Rust

ClosePathError

Enum ClosePathError 

Source
pub enum ClosePathError {
+ClosePathError in noq_proto - Rust

ClosePathError

Enum ClosePathError 

Source
pub enum ClosePathError {
     MultipathNotNegotiated,
     ClosedPath,
     LastOpenPath,
@@ -7,8 +7,8 @@
 
§

ClosedPath

The path is already closed or was never opened

§

LastOpenPath

Cannot close the last remaining open path via the local API.

Use Connection::close to end the connection instead.

-

Trait Implementations§

Source§

impl Clone for ClosePathError

Source§

fn clone(&self) -> ClosePathError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ClosePathError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for ClosePathError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for ClosePathError

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl PartialEq for ClosePathError

Source§

fn eq(&self, other: &ClosePathError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, -and should not be overridden without very good reason.
Source§

impl Eq for ClosePathError

Source§

impl StructuralPartialEq for ClosePathError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for ClosePathError

Source§

fn clone(&self) -> ClosePathError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ClosePathError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for ClosePathError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for ClosePathError

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl PartialEq for ClosePathError

Source§

fn eq(&self, other: &ClosePathError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +and should not be overridden without very good reason.
Source§

impl Eq for ClosePathError

Source§

impl StructuralPartialEq for ClosePathError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/580/docs/noq_proto/enum.ConnectionError.html b/pr/580/docs/noq_proto/enum.ConnectionError.html index be3e40450..fd9b3ef44 100644 --- a/pr/580/docs/noq_proto/enum.ConnectionError.html +++ b/pr/580/docs/noq_proto/enum.ConnectionError.html @@ -1,4 +1,4 @@ -ConnectionError in noq_proto - Rust

ConnectionError

Enum ConnectionError 

Source
pub enum ConnectionError {
+ConnectionError in noq_proto - Rust

ConnectionError

Enum ConnectionError 

Source
pub enum ConnectionError {
     VersionMismatch,
     TransportError(TransportError),
     ConnectionClosed(ConnectionClose),
@@ -20,8 +20,8 @@ and §

LocallyClosed

The local application closed the connection

§

CidsExhausted

The connection could not be created because not enough of the CID space is available

Try using longer connection IDs.

-

Trait Implementations§

Source§

impl Clone for ConnectionError

Source§

fn clone(&self) -> ConnectionError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ConnectionError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for ConnectionError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for ConnectionError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<ConnectionError> for Error

Source§

fn from(x: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for ConnectionError

Source§

fn from(source: TransportError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for ConnectionError

Source§

fn eq(&self, other: &ConnectionError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, -and should not be overridden without very good reason.
Source§

impl Eq for ConnectionError

Source§

impl StructuralPartialEq for ConnectionError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for ConnectionError

Source§

fn clone(&self) -> ConnectionError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ConnectionError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for ConnectionError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for ConnectionError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<ConnectionError> for Error

Source§

fn from(x: ConnectionError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for ConnectionError

Source§

fn from(source: TransportError) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for ConnectionError

Source§

fn eq(&self, other: &ConnectionError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +and should not be overridden without very good reason.
Source§

impl Eq for ConnectionError

Source§

impl StructuralPartialEq for ConnectionError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/580/docs/noq_proto/enum.Event.html b/pr/580/docs/noq_proto/enum.Event.html index c3c7cf580..016350d2a 100644 --- a/pr/580/docs/noq_proto/enum.Event.html +++ b/pr/580/docs/noq_proto/enum.Event.html @@ -1,4 +1,4 @@ -Event in noq_proto - Rust

Event

Enum Event 

Source
pub enum Event {
+Event in noq_proto - Rust

Event

Enum Event 

Source
pub enum Event {
     HandshakeDataReady,
     Connected,
     HandshakeConfirmed,
@@ -22,7 +22,7 @@
 
§

DatagramsUnblocked

One or more application datagrams have been sent after blocking

§

Path(PathEvent)

(Multi)Path events

§

NatTraversal(Event)

n0’s nat traversal events

-

Trait Implementations§

Source§

impl Debug for Event

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<PathEvent> for Event

Source§

fn from(source: PathEvent) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl !Freeze for Event

§

impl !RefUnwindSafe for Event

§

impl Send for Event

§

impl Sync for Event

§

impl Unpin for Event

§

impl !UnwindSafe for Event

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Debug for Event

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<PathEvent> for Event

Source§

fn from(source: PathEvent) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl !Freeze for Event

§

impl !RefUnwindSafe for Event

§

impl Send for Event

§

impl Sync for Event

§

impl Unpin for Event

§

impl !UnwindSafe for Event

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

diff --git a/pr/580/docs/noq_proto/enum.PathError.html b/pr/580/docs/noq_proto/enum.PathError.html index 3907a725f..6cfdca62c 100644 --- a/pr/580/docs/noq_proto/enum.PathError.html +++ b/pr/580/docs/noq_proto/enum.PathError.html @@ -1,4 +1,4 @@ -PathError in noq_proto - Rust

PathError

Enum PathError 

Source
pub enum PathError {
+PathError in noq_proto - Rust

PathError

Enum PathError 

Source
pub enum PathError {
     MultipathNotNegotiated,
     ServerSideNotAllowed,
     MaxPathIdReached,
@@ -12,8 +12,8 @@
 
§

RemoteCidsExhausted

No remote CIDs available to open a new path

§

ValidationFailed

Path could not be validated and will be abandoned

§

InvalidRemoteAddress(SocketAddr)

The remote address for the path is not supported by the endpoint

-

Trait Implementations§

Source§

impl Clone for PathError

Source§

fn clone(&self) -> PathError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PathError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for PathError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for PathError

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl PartialEq for PathError

Source§

fn eq(&self, other: &PathError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, -and should not be overridden without very good reason.
Source§

impl Copy for PathError

Source§

impl Eq for PathError

Source§

impl StructuralPartialEq for PathError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Clone for PathError

Source§

fn clone(&self) -> PathError

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PathError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for PathError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for PathError

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl PartialEq for PathError

Source§

fn eq(&self, other: &PathError) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +and should not be overridden without very good reason.
Source§

impl Copy for PathError

Source§

impl Eq for PathError

Source§

impl StructuralPartialEq for PathError

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/580/docs/noq_proto/enum.PathEvent.html b/pr/580/docs/noq_proto/enum.PathEvent.html index e90df682d..d081342ea 100644 --- a/pr/580/docs/noq_proto/enum.PathEvent.html +++ b/pr/580/docs/noq_proto/enum.PathEvent.html @@ -39,7 +39,7 @@ changes the status.

Fields

§id: PathId

Path over which the observed address was reported, PathId::ZERO when multipath is not negotiated

§addr: SocketAddr

The address observed by the remote over this path

-

Trait Implementations§

Source§

impl Clone for PathEvent

Source§

fn clone(&self) -> PathEvent

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PathEvent

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<PathEvent> for Event

Source§

fn from(source: PathEvent) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for PathEvent

Source§

fn eq(&self, other: &PathEvent) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +

Trait Implementations§

Source§

impl Clone for PathEvent

Source§

fn clone(&self) -> PathEvent

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PathEvent

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<PathEvent> for Event

Source§

fn from(source: PathEvent) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for PathEvent

Source§

fn eq(&self, other: &PathEvent) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for PathEvent

Source§

impl StructuralPartialEq for PathEvent

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/580/docs/noq_proto/struct.Connection.html b/pr/580/docs/noq_proto/struct.Connection.html index e2eb3e8d6..971eab63a 100644 --- a/pr/580/docs/noq_proto/struct.Connection.html +++ b/pr/580/docs/noq_proto/struct.Connection.html @@ -33,7 +33,7 @@ increasing time. Specifically, calling Instant may be interleaved in any order with a call to handle_event at that same instant; however events or timeouts with different instants must not be interleaved.

-

Implementations§

Source§

impl Connection

Source

pub fn poll_timeout(&mut self) -> Option<Instant>

Returns the next time at which handle_timeout should be called

+

Implementations§

Source§

impl Connection

Source

pub fn poll_timeout(&mut self) -> Option<Instant>

Returns the next time at which handle_timeout should be called

The value returned may change after:

  • the application performed some I/O on the connection
  • @@ -110,7 +110,7 @@ idle time. Setting None disables the timeout and stops the timer.Result<Option<Duration>, ClosedPath>

Sets the keep_alive_interval for a specific path

See TransportConfig::default_path_keep_alive_interval for details.

Returns the previous value of the setting.

-
Source

pub fn poll_transmit( +

Source

pub fn poll_transmit( &mut self, now: Instant, max_datagrams: NonZeroUsize, @@ -124,62 +124,62 @@ idle time. Setting None disables the timeout and stops the timer.

max_datagrams specifies how many datagrams can be returned inside a single Transmit using GSO. This must be at least 1.

-

Source

pub fn handle_event(&mut self, event: ConnectionEvent)

Process ConnectionEvents generated by the associated Endpoint

+
Source

pub fn handle_event(&mut self, event: ConnectionEvent)

Process ConnectionEvents generated by the associated Endpoint

Will execute protocol logic upon receipt of a connection event, in turn preparing signals (including application Events, EndpointEvents and outgoing datagrams) that should be extracted through the relevant methods.

-
Source

pub fn handle_timeout(&mut self, now: Instant)

Process timer expirations

+
Source

pub fn handle_timeout(&mut self, now: Instant)

Process timer expirations

Executes protocol logic, potentially preparing signals (including application Events, EndpointEvents and outgoing datagrams) that should be extracted through the relevant methods.

It is most efficient to call this immediately after the system clock reaches the latest Instant that was output by poll_timeout; however spurious extra calls will simply no-op and therefore are safe.

-
Source

pub fn close(&mut self, now: Instant, error_code: VarInt, reason: Bytes)

Close a connection immediately

+
Source

pub fn close(&mut self, now: Instant, error_code: VarInt, reason: Bytes)

Close a connection immediately

This does not ensure delivery of outstanding data. It is the application’s responsibility to call this only when all important communications have been completed, e.g. by calling SendStream::finish on outstanding streams and waiting for the corresponding StreamEvent::Finished event.

If Streams::send_streams returns 0, all outstanding stream data has been delivered. There may still be data from the peer that has not been received.

-
Source

pub fn datagrams(&mut self) -> Datagrams<'_>

Control datagrams

-
Source

pub fn stats(&mut self) -> ConnectionStats

Returns connection statistics

-
Source

pub fn path_stats(&mut self, path_id: PathId) -> Option<PathStats>

Returns path statistics

-
Source

pub fn ping(&mut self)

Ping the remote endpoint

+
Source

pub fn datagrams(&mut self) -> Datagrams<'_>

Control datagrams

+
Source

pub fn stats(&mut self) -> ConnectionStats

Returns connection statistics

+
Source

pub fn path_stats(&mut self, path_id: PathId) -> Option<PathStats>

Returns path statistics

+
Source

pub fn ping(&mut self)

Ping the remote endpoint

Causes an ACK-eliciting packet to be transmitted on the connection.

-
Source

pub fn ping_path(&mut self, path: PathId) -> Result<(), ClosedPath>

Ping the remote endpoint over a specific path

+
Source

pub fn ping_path(&mut self, path: PathId) -> Result<(), ClosedPath>

Ping the remote endpoint over a specific path

Causes an ACK-eliciting packet to be transmitted on the path.

-
Source

pub fn force_key_update(&mut self)

Update traffic keys spontaneously

+
Source

pub fn force_key_update(&mut self)

Update traffic keys spontaneously

This can be useful for testing key updates, as they otherwise only happen infrequently.

-
Source

pub fn crypto_session(&self) -> &dyn Session

Get a session reference

-
Source

pub fn is_handshaking(&self) -> bool

Whether the connection is in the process of being established

+
Source

pub fn crypto_session(&self) -> &dyn Session

Get a session reference

+
Source

pub fn is_handshaking(&self) -> bool

Whether the connection is in the process of being established

If this returns false, the connection may be either established or closed, signaled by the emission of a Connected or ConnectionLost message respectively.

For an established connection this essentially means the handshake is completed, but not necessarily yet confirmed.

-
Source

pub fn is_closed(&self) -> bool

Whether the connection is closed

+
Source

pub fn is_closed(&self) -> bool

Whether the connection is closed

Closed connections cannot transport any further data. A connection becomes closed when either peer application intentionally closes it, or when either transport layer detects an error such as a time-out or certificate validation failure.

A ConnectionLost event is emitted with details when the connection becomes closed.

-
Source

pub fn is_drained(&self) -> bool

Whether there is no longer any need to keep the connection around

+
Source

pub fn is_drained(&self) -> bool

Whether there is no longer any need to keep the connection around

Closed connections become drained after a brief timeout to absorb any remaining in-flight packets from the peer. All drained connections have been closed.

-
Source

pub fn accepted_0rtt(&self) -> bool

For clients, if the peer accepted the 0-RTT data packets

+
Source

pub fn accepted_0rtt(&self) -> bool

For clients, if the peer accepted the 0-RTT data packets

The value is meaningless until after the handshake completes.

-
Source

pub fn has_0rtt(&self) -> bool

Whether 0-RTT is/was possible during the handshake

-
Source

pub fn has_pending_retransmits(&self) -> bool

Whether there are any pending retransmits

-
Source

pub fn side(&self) -> Side

Look up whether we’re the client or server of this Connection

-
Source

pub fn path_observed_address( +

Source

pub fn has_0rtt(&self) -> bool

Whether 0-RTT is/was possible during the handshake

+
Source

pub fn has_pending_retransmits(&self) -> bool

Whether there are any pending retransmits

+
Source

pub fn side(&self) -> Side

Look up whether we’re the client or server of this Connection

+
Source

pub fn path_observed_address( &self, path_id: PathId, ) -> Result<Option<SocketAddr>, ClosedPath>

Get the address observed by the remote over the given path

-
Source

pub fn rtt(&self, path_id: PathId) -> Option<Duration>

Current best estimate of this connection’s latency (round-trip-time)

-
Source

pub fn congestion_state(&self, path_id: PathId) -> Option<&dyn Controller>

Current state of this connection’s congestion controller, for debugging purposes

-
Source

pub fn set_max_concurrent_streams(&mut self, dir: Dir, count: VarInt)

Modify the number of remotely initiated streams that may be concurrently open

+
Source

pub fn rtt(&self, path_id: PathId) -> Option<Duration>

Current best estimate of this connection’s latency (round-trip-time)

+
Source

pub fn congestion_state(&self, path_id: PathId) -> Option<&dyn Controller>

Current state of this connection’s congestion controller, for debugging purposes

+
Source

pub fn set_max_concurrent_streams(&mut self, dir: Dir, count: VarInt)

Modify the number of remotely initiated streams that may be concurrently open

No streams may be opened by the peer unless fewer than count are already open. Large counts increase both minimum and worst-case memory consumption.

-
Source

pub fn set_max_concurrent_paths( +

Source

pub fn set_max_concurrent_paths( &mut self, now: Instant, count: NonZeroU32, @@ -190,16 +190,16 @@ actively reduce paths they must be closed using TransportConfig) this can not enable multipath and will fail.

-

Source

pub fn max_concurrent_streams(&self, dir: Dir) -> u64

Current number of remotely initiated streams that may be concurrently open

+
Source

pub fn max_concurrent_streams(&self, dir: Dir) -> u64

Current number of remotely initiated streams that may be concurrently open

If the target for this limit is reduced using set_max_concurrent_streams, it will not change immediately, even if fewer streams are open. Instead, it will decrement by one for each time a remotely initiated stream of matching directionality is closed.

-
Source

pub fn set_send_window(&mut self, send_window: u64)

Source

pub fn set_receive_window(&mut self, receive_window: VarInt)

Source

pub fn is_multipath_negotiated(&self) -> bool

Whether the Multipath for QUIC extension is enabled.

+
Source

pub fn set_send_window(&mut self, send_window: u64)

Source

pub fn set_receive_window(&mut self, receive_window: VarInt)

Source

pub fn is_multipath_negotiated(&self) -> bool

Whether the Multipath for QUIC extension is enabled.

Multipath is only enabled after the handshake is completed and if it was enabled by both peers.

-
Source

pub fn handle_network_change( +

Source

pub fn handle_network_change( &mut self, hint: Option<&dyn NetworkChangeHint>, now: Instant, @@ -214,26 +214,26 @@ paths as non recoverable when necessary accelerates connectivity re-establishmen allow it altogether.

The optional hint allows callers to indicate when paths are non-recoverable and should be migrated to new a PathId.

-

Source

pub fn current_mtu(&self) -> u16

Storage size required for the largest packet that can be transmitted on all currently +

Source

pub fn current_mtu(&self) -> u16

Storage size required for the largest packet that can be transmitted on all currently available paths

Buffers passed to Connection::poll_transmit should be at least this large.

When multipath is enabled, this value is the minimum MTU across all available paths.

-
Source

pub fn add_nat_traversal_address( +

Source

pub fn add_nat_traversal_address( &mut self, address: SocketAddr, ) -> Result<(), Error>

Add addresses the local endpoint considers are reachable for nat traversal.

-
Source

pub fn remove_nat_traversal_address( +

Source

pub fn remove_nat_traversal_address( &mut self, address: SocketAddr, ) -> Result<(), Error>

Removes an address the endpoing no longer considers reachable for nat traversal

Addresses not present in the set will be silently ignored.

-
Source

pub fn get_local_nat_traversal_addresses( +

Source

pub fn get_local_nat_traversal_addresses( &self, ) -> Result<Vec<SocketAddr>, Error>

Get the current local nat traversal addresses

-
Source

pub fn get_remote_nat_traversal_addresses( +

Source

pub fn get_remote_nat_traversal_addresses( &self, ) -> Result<Vec<SocketAddr>, Error>

Get the currently advertised nat traversal addresses by the server

-
Source

pub fn initiate_nat_traversal_round( +

Source

pub fn initiate_nat_traversal_round( &mut self, now: Instant, ) -> Result<Vec<SocketAddr>, Error>

Initiates a new nat traversal round

@@ -243,7 +243,7 @@ initiated, the previous one is cancelled, and paths that have not been opened ar

Returns the server addresses that are now being probed. If addresses fail due to spurious errors, these might succeed later and not be returned in this set.

-

Trait Implementations§

Source§

impl Debug for Connection

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl !Freeze for Connection

§

impl !RefUnwindSafe for Connection

§

impl Send for Connection

§

impl Sync for Connection

§

impl Unpin for Connection

§

impl !UnwindSafe for Connection

Blanket Implementations§

Source§

impl<T> Any for T
where +

Trait Implementations§

Source§

impl Debug for Connection

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl !Freeze for Connection

§

impl !RefUnwindSafe for Connection

§

impl Send for Connection

§

impl Sync for Connection

§

impl Unpin for Connection

§

impl !UnwindSafe for Connection

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

diff --git a/pr/580/docs/noq_proto/struct.MultipathNotNegotiated.html b/pr/580/docs/noq_proto/struct.MultipathNotNegotiated.html index 341d24c17..c4c094137 100644 --- a/pr/580/docs/noq_proto/struct.MultipathNotNegotiated.html +++ b/pr/580/docs/noq_proto/struct.MultipathNotNegotiated.html @@ -1,5 +1,5 @@ -MultipathNotNegotiated in noq_proto - Rust

MultipathNotNegotiated

Struct MultipathNotNegotiated 

Source
pub struct MultipathNotNegotiated { /* private fields */ }
Expand description

Error when the multipath extension was not negotiated, but attempted to be used.

-

Trait Implementations§

Source§

impl Clone for MultipathNotNegotiated

Source§

fn clone(&self) -> MultipathNotNegotiated

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for MultipathNotNegotiated

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for MultipathNotNegotiated

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for MultipathNotNegotiated

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl Copy for MultipathNotNegotiated

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where +MultipathNotNegotiated in noq_proto - Rust

MultipathNotNegotiated

Struct MultipathNotNegotiated 

Source
pub struct MultipathNotNegotiated { /* private fields */ }
Expand description

Error when the multipath extension was not negotiated, but attempted to be used.

+

Trait Implementations§

Source§

impl Clone for MultipathNotNegotiated

Source§

fn clone(&self) -> MultipathNotNegotiated

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for MultipathNotNegotiated

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for MultipathNotNegotiated

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for MultipathNotNegotiated

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl Copy for MultipathNotNegotiated

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where diff --git a/pr/580/docs/noq_proto/struct.TransportError.html b/pr/580/docs/noq_proto/struct.TransportError.html index e140ca2b5..209400548 100644 --- a/pr/580/docs/noq_proto/struct.TransportError.html +++ b/pr/580/docs/noq_proto/struct.TransportError.html @@ -11,7 +11,7 @@
§reason: String

Human-readable explanation of the reason

§crypto: Option<Arc<dyn Error + Send + Sync>>

An underlying crypto (e.g. TLS) layer error

Implementations§

Source§

impl Error

Source

pub fn new(code: Code, reason: String) -> Self

Construct an error with a code and a reason

-

Trait Implementations§

Source§

impl Clone for Error

Source§

fn clone(&self) -> Error

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Error

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for Error

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for Error

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<Error> for ConnectionClose

Source§

fn from(x: TransportError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for ConnectionError

Source§

fn from(source: TransportError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for TransportError

Source§

fn from(e: Error) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for Error

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, +

Trait Implementations§

Source§

impl Clone for Error

Source§

fn clone(&self) -> Error

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Error

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for Error

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for Error

1.30.0 · Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<Error> for ConnectionClose

Source§

fn from(x: TransportError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for ConnectionError

Source§

fn from(source: TransportError) -> Self

Converts to this type from the input type.
Source§

impl From<Error> for TransportError

Source§

fn from(e: Error) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for Error

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for Error

Auto Trait Implementations§

§

impl Freeze for Error

§

impl !RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl !UnwindSafe for Error

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where diff --git a/pr/580/docs/noq_proto/trait.NetworkChangeHint.html b/pr/580/docs/noq_proto/trait.NetworkChangeHint.html index cb615dcdb..93646f23a 100644 --- a/pr/580/docs/noq_proto/trait.NetworkChangeHint.html +++ b/pr/580/docs/noq_proto/trait.NetworkChangeHint.html @@ -1,4 +1,4 @@ -NetworkChangeHint in noq_proto - Rust

NetworkChangeHint

Trait NetworkChangeHint 

Source
pub trait NetworkChangeHint: Debug + 'static {
+NetworkChangeHint in noq_proto - Rust

NetworkChangeHint

Trait NetworkChangeHint 

Source
pub trait NetworkChangeHint: Debug + 'static {
     // Required method
     fn is_path_recoverable(
         &self,
@@ -6,7 +6,7 @@
         network_path: FourTuple,
     ) -> bool;
 }
Expand description

Hints when the caller identifies a network change.

-

Required Methods§

Source

fn is_path_recoverable(&self, path_id: PathId, network_path: FourTuple) -> bool

Inform the connection if a path may recover after a network change.

+

Required Methods§

Source

fn is_path_recoverable(&self, path_id: PathId, network_path: FourTuple) -> bool

Inform the connection if a path may recover after a network change.

After network changes, paths may not be recoverable. In this case, waiting for the path to become idle may take longer than what is desirable. If Self::is_path_recoverable returns false, a multipath-enabled, client-side connection will establish a new path to diff --git a/pr/580/docs/search.index/entry/2bd490e0d429.js b/pr/580/docs/search.index/entry/84ba38a55a91.js similarity index 94% rename from pr/580/docs/search.index/entry/2bd490e0d429.js rename to pr/580/docs/search.index/entry/84ba38a55a91.js index 7f03c27ae..9f5588573 100644 --- a/pr/580/docs/search.index/entry/2bd490e0d429.js +++ b/pr/580/docs/search.index/entry/84ba38a55a91.js @@ -1 +1 @@ -rd_("Af[463,15,464,0,126,0,0]Ak[3096,15,3097,3097,127,0,0]Ag[463,15,464,0,4087,0,0]Al[3096,15,3097,1784,4088,0,0]Al[1985,15,1986,1986,4089,0,0]Al[3096,15,1689,1689,1433,0,0]Ao[1195,13,1196,1196,3930,3037,0]Am[463,13,464,3640,4752,3037,0]Am[463,13,464,4144,1418,3037,0]Al[463,13,464,1094,503,3037,0]Am[463,13,464,1094,4362,3037,0]Am[463,13,464,4036,4355,3037,0]Am[463,13,464,4036,3044,3037,0]Am[463,13,464,4036,3239,3037,0]Am[463,13,464,4036,4354,3037,0]Am[463,13,464,4041,3257,3037,0]Am[463,13,464,4041,4122,3037,0]Aj[463,13,464,0,1443,3037,0]Aj[463,13,464,0,4918,3037,0]Aj[463,13,464,0,1152,3037,0]Aj[463,13,464,0,1426,3037,0]Aj[463,13,464,0,2294,3037,0]Aj[463,13,464,0,3217,3037,0]Aj[463,13,464,0,3041,3037,0]Aj[463,13,464,0,1867,3037,0]Aj[463,13,464,0,4073,3037,0]Aj[463,13,464,0,4447,3037,0]Aj[463,13,464,0,3943,3037,0]Aj[463,13,464,0,3933,3037,0]Aj[463,13,464,0,3025,3037,0]Aj[463,13,464,0,4444,3037,0]Aj[463,13,464,0,4645,3037,0]Aj[463,13,464,0,4079,3037,0]Aj[463,13,464,0,4082,3037,0]Aj[463,13,464,0,4087,3037,0]Aj[463,13,464,0,4811,3037,0]Ai[463,13,464,0,510,3037,0]Ai[463,13,464,0,126,3037,0]Aj[463,13,464,0,2281,3037,0]Ak[463,13,1693,0,5067,3037,0]Ak[463,13,1773,0,1169,3037,0]Ao[3096,13,3097,1810,1444,3037,0]Ao[3096,13,3097,1810,4919,3037,0]Ao[3096,13,3097,3061,1153,3037,0]Ao[3096,13,3097,3070,4753,3037,0]Ao[3096,13,3097,1366,1427,3037,0]Ao[3096,13,3097,1366,3233,3037,0]Ao[3096,13,3097,1366,3040,3037,0]Ao[3096,13,3097,1366,4751,3037,0]Ao[3096,13,3097,1366,4807,3037,0]Ao[3096,13,3097,1366,3207,3037,0]Ao[3096,13,3097,1381,2295,3037,0]Ao[3096,13,3097,1381,3218,3037,0]Ao[3096,13,3097,1381,3042,3037,0]Ao[3096,13,3097,1120,3045,3037,0]Ao[3096,13,3097,1120,4245,3037,0]Ao[3096,13,3097,1125,1868,3037,0]Ao[3096,13,3097,1125,3258,3037,0]Ao[3096,13,3097,1125,3942,3037,0]Ao[3096,13,3097,2002,3961,3037,0]Ao[3096,13,3097,2002,4356,3037,0]Ao[3096,13,3097,2002,4077,3037,0]Ao[3096,13,3097,3641,4448,3037,0]Ao[3096,13,3097,3641,3038,3037,0]Ao[3096,13,3097,3641,4322,3037,0]Ao[3096,13,3097,3194,3944,3037,0]Ao[3096,13,3097,1691,3934,3037,0]Ao[3096,13,3097,1356,3026,3037,0]Ao[3096,13,3097,1356,4337,3037,0]Ao[3096,13,3097,1356,3224,3037,0]Ao[3096,13,3097,1356,3247,3037,0]Ao[3096,13,3097,1356,4084,3037,0]Ao[3096,13,3097,1356,4446,3037,0]Ao[3096,13,3097,1356,4647,3037,0]Ao[3096,13,3097,2305,4651,3037,0]Ao[3096,13,3097,2305,4080,3037,0]Ao[3096,13,3097,1756,2267,3037,0]Ao[3096,13,3097,1756,4749,3037,0]Ao[3096,13,3097,1784,4083,3037,0]Ao[3096,13,3097,1784,4088,3037,0]Al[3096,13,3097,0,4360,3037,0]Al[3096,13,3097,0,4812,3037,0]An[3096,13,3097,3097,511,3037,0]An[3096,13,3097,3097,127,3037,0]Ao[3096,13,3097,3097,2282,3037,0]Ao[3096,13,3097,3097,3024,3037,0]Ao[3096,13,1689,1689,4251,3037,0]Ao[3096,13,4960,4960,4858,3037,0]Ao[3096,13,4960,4960,1171,3037,0]Ao[3096,13,1694,1694,5068,3037,0]Al[3096,13,1774,0,1170,3037,0]Ao[1985,13,1986,1986,4089,3037,0]Ai[463,13,464,1094,503,0,0]Aj[463,13,464,1094,4362,0,0]Aj[463,13,464,4036,3237,0,0]Aj[463,13,464,4036,4859,0,0]Aj[463,13,464,4041,3243,0,0]Ai[3096,14,3039,0,1420,0,0]Ai[3096,14,3039,0,3002,0,0]Ai[3096,14,3039,0,3020,0,0]Ai[3096,14,3039,0,4109,0,0]Ai[3096,14,3039,0,4102,0,0]Ai[3096,14,3960,0,2277,0,0]Ai[3096,14,3960,0,2297,0,0]Ai[3096,14,3960,0,2261,0,0]Ai[3096,14,3960,0,1855,0,0]Ae[1195,7,1196,0,0,0,0]Ah[3096,14,4459,0,499,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Af[463,5,3635,148,0,0,0]Ag[3096,5,3636,148,0,0,0]Al[1095,15,1096,1096,4851,0,0]Ae[2358,5,2359,0,0,0,0]Af[463,6,464,3097,0,0,0]Ae[3096,6,3097,0,0,0,0]Al[3096,15,1689,1689,1433,0,0]Ag[463,19,464,0,1443,0,0]Ag[463,19,464,0,1426,0,0]Al[3096,19,3097,1810,1444,0,0]Al[3096,19,3097,1366,1427,0,0]Ae[1195,5,1196,0,0,0,0]Ae[1095,5,1683,0,0,0,0]Ae[1095,5,1779,0,0,0,0]Af[463,15,464,0,126,0,0]Ak[3096,15,3097,3097,127,0,0]Ai[463,13,464,0,2294,117,0]Ai[463,13,464,0,3217,117,0]Ai[463,13,464,0,4451,117,0]An[3096,13,3097,1381,2295,117,0]An[3096,13,3097,1381,3218,117,0]An[3096,13,3097,1381,4452,117,0]Ai[463,13,464,0,1443,137,0]Ai[463,13,464,0,1426,137,0]Ai[463,13,464,0,3943,137,0]Ai[463,13,464,0,4082,137,0]Ah[463,13,464,0,510,137,0]Ah[463,13,464,0,126,137,0]Ai[463,13,464,0,2281,137,0]An[3096,13,3097,1810,1444,137,0]An[3096,13,3097,3070,4753,137,0]An[3096,13,3097,1366,1427,137,0]An[3096,13,3097,1120,3045,137,0]An[3096,13,3097,1120,4245,137,0]An[3096,13,3097,1125,3258,137,0]An[3096,13,3097,3194,3944,137,0]An[3096,13,3097,2305,4651,137,0]An[3096,13,3097,1756,4749,137,0]An[3096,13,3097,1784,4083,137,0]Am[3096,13,3097,3097,511,137,0]Am[3096,13,3097,3097,127,137,0]An[3096,13,3097,3097,2282,137,0]Ag[463,13,464,0,2281,0,0]Al[3096,13,3097,3097,2282,0,0]Ai[3096,14,3960,0,1421,0,0]Ai[3096,14,3960,0,3009,0,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Al[1985,14,1986,1986,2279,0,0]Al[1985,14,1986,1986,2293,0,0]An[1195,13,1196,1196,134,1159,0]Ao[1195,13,1196,1196,3954,1159,0]Ao[1195,13,1196,1196,3930,1159,0]Ao[1195,13,1380,1380,4357,1159,0]Ao[3968,13,3969,3969,5009,1159,0]Am[463,13,464,4144,4915,1159,0]Am[463,13,464,3640,3209,1159,0]Am[463,13,464,3640,3211,1159,0]Am[463,13,464,3640,4921,1159,0]D`[463,13,464,3640,4752,1159,0,\"impl-Debug-for-SendDatagramError\"]Db[463,13,464,3640,4752,1827,0,\"impl-Display-for-SendDatagramError\"]Am[463,13,464,2304,2259,1159,0]Am[463,13,464,2304,4219,1159,0]Ce[463,13,464,4144,1418,1159,0,\"impl-Debug-for-Lagged\"]Cg[463,13,464,4144,1418,1827,0,\"impl-Display-for-Lagged\"]Am[463,13,464,4144,3231,1159,0]Am[463,13,464,4144,4852,1159,0]Am[463,13,464,2336,2263,1159,0]Ck[463,13,464,2336,3240,1827,0,\"impl-Display-for-RetryError\"]Ci[463,13,464,2336,3240,1159,0,\"impl-Debug-for-RetryError\"]Am[463,13,464,2336,4336,1159,0]Al[463,13,464,1094,503,1159,0]Am[463,13,464,1094,4362,1159,0]Am[463,13,464,4036,3237,1159,0]Am[463,13,464,4036,4859,1159,0]Cm[463,13,464,4036,4355,1159,0,\"impl-Debug-for-ReadToEndError\"]Co[463,13,464,4036,4355,1827,0,\"impl-Display-for-ReadToEndError\"]Ch[463,13,464,4036,3044,1159,0,\"impl-Debug-for-ReadError\"]Cj[463,13,464,4036,3044,1827,0,\"impl-Display-for-ReadError\"]Ci[463,13,464,4036,3239,1159,0,\"impl-Debug-for-ResetError\"]Ck[463,13,464,4036,3239,1827,0,\"impl-Display-for-ResetError\"]Co[463,13,464,4036,4354,1827,0,\"impl-Display-for-ReadExactError\"]Cm[463,13,464,4036,4354,1159,0,\"impl-Debug-for-ReadExactError\"]Am[463,13,464,1393,4123,1159,0]Am[463,13,464,1137,3957,1159,0]Am[463,13,464,4041,3243,1159,0]Ci[463,13,464,4041,3257,1159,0,\"impl-Debug-for-WriteError\"]Ck[463,13,464,4041,3257,1827,0,\"impl-Display-for-WriteError\"]Cm[463,13,464,4041,4122,1827,0,\"impl-Display-for-StoppedError\"]Ck[463,13,464,4041,4122,1159,0,\"impl-Debug-for-StoppedError\"]Am[463,13,464,4041,1857,1159,0]Cd[463,13,464,0,1443,1827,0,\"impl-Display-for-VarInt\"]Cb[463,13,464,0,1443,1159,0,\"impl-Debug-for-VarInt\"]Db[463,13,464,0,4918,1827,0,\"impl-Display-for-VarIntBoundsExceeded\"]D`[463,13,464,0,4918,1159,0,\"impl-Debug-for-VarIntBoundsExceeded\"]Aj[463,13,464,0,1152,1159,0]Cb[463,13,464,0,1426,1159,0,\"impl-Debug-for-PathId\"]Cd[463,13,464,0,1426,1827,0,\"impl-Display-for-PathId\"]Aj[463,13,464,0,2294,1159,0]Aj[463,13,464,0,3217,1159,0]Aj[463,13,464,0,3041,1159,0]Aj[463,13,464,0,4451,1159,0]Aj[463,13,464,0,1867,1159,0]Ch[463,13,464,0,4073,1159,0,\"impl-Debug-for-ClosedStream\"]Cj[463,13,464,0,4073,1827,0,\"impl-Display-for-ClosedStream\"]Cm[463,13,464,0,4447,1827,0,\"impl-Display-for-ConnectionError\"]Ck[463,13,464,0,4447,1159,0,\"impl-Debug-for-ConnectionError\"]Aj[463,13,464,0,4461,1159,0]Aj[463,13,464,0,4470,1159,0]Aj[463,13,464,0,4776,1159,0]Aj[463,13,464,0,4791,1159,0]Aj[463,13,464,0,3943,1159,0]Aj[463,13,464,0,4331,1159,0]Aj[463,13,464,0,4116,1159,0]Aj[463,13,464,0,4975,1159,0]Aj[463,13,464,0,4067,1159,0]Cg[463,13,464,0,3933,1159,0,\"impl-Debug-for-ConfigError\"]Ci[463,13,464,0,3933,1827,0,\"impl-Display-for-ConfigError\"]Ce[463,13,464,0,3025,1159,0,\"impl-Debug-for-FrameType\"]Cg[463,13,464,0,3025,1827,0,\"impl-Display-for-FrameType\"]Cm[463,13,464,0,4444,1827,0,\"impl-Display-for-ConnectionClose\"]Ck[463,13,464,0,4444,1159,0,\"impl-Debug-for-ConnectionClose\"]Cn[463,13,464,0,4645,1827,0,\"impl-Display-for-ApplicationClose\"]Cl[463,13,464,0,4645,1159,0,\"impl-Debug-for-ApplicationClose\"]Ch[463,13,464,0,4079,1159,0,\"impl-Debug-for-ConnectError\"]Cj[463,13,464,0,4079,1827,0,\"impl-Display-for-ConnectError\"]Cj[463,13,464,0,4082,1827,0,\"impl-Display-for-ConnectionId\"]Ch[463,13,464,0,4082,1159,0,\"impl-Debug-for-ConnectionId\"]Aj[463,13,464,0,4087,1159,0]Cn[463,13,464,0,4811,1159,0,\"impl-Debug-for-TransportErrorCode\"]D`[463,13,464,0,4811,1827,0,\"impl-Display-for-TransportErrorCode\"]Aj[463,13,464,0,3220,1159,0]Aj[463,13,464,0,4678,1159,0]Ai[463,13,464,0,510,1159,0]Bn[463,13,464,0,126,1159,0,\"impl-Debug-for-Dir\"]C`[463,13,464,0,126,1827,0,\"impl-Display-for-Dir\"]Cd[463,13,464,0,2281,1159,0,\"impl-Debug-for-StreamId\"]Cf[463,13,464,0,2281,1827,0,\"impl-Display-for-StreamId\"]Aj[463,13,464,0,2291,1159,0]Aj[463,13,3635,0,120,1159,0]Ak[463,13,3635,0,3012,1159,0]Ak[463,13,3635,0,1156,1159,0]Ak[463,13,3635,0,3938,1159,0]Ak[463,13,3635,0,1840,1159,0]Ak[463,13,3635,0,4237,1159,0]Ak[463,13,3635,0,4740,1159,0]Ak[463,13,1693,0,5067,1159,0]Ak[463,13,1693,0,3936,1159,0]Ak[463,13,1693,0,4815,1159,0]Cb[463,13,1773,0,1169,1159,0,\"impl-Debug-for-Error\"]Cd[463,13,1773,0,1169,1827,0,\"impl-Display-for-Error\"]Dc[463,13,1773,0,4913,1827,0,\"impl-Display-for-NoInitialCipherSuite\"]Da[463,13,1773,0,4913,1159,0,\"impl-Debug-for-NoInitialCipherSuite\"]Ao[3096,13,3097,3641,3212,1159,0]Ao[3096,13,3097,2305,2260,1159,0]Ci[3096,13,3097,1810,1444,1827,0,\"impl-Display-for-VarInt\"]Cg[3096,13,3097,1810,1444,1159,0,\"impl-Debug-for-VarInt\"]De[3096,13,3097,1810,4919,1159,0,\"impl-Debug-for-VarIntBoundsExceeded\"]Dg[3096,13,3097,1810,4919,1827,0,\"impl-Display-for-VarIntBoundsExceeded\"]Ao[3096,13,3097,3061,1153,1159,0]Dd[3096,13,3097,3070,4753,1827,0,\"impl-Display-for-SendDatagramError\"]Db[3096,13,3097,3070,4753,1159,0,\"impl-Debug-for-SendDatagramError\"]Ci[3096,13,3097,1366,1427,1827,0,\"impl-Display-for-PathId\"]Cg[3096,13,3097,1366,1427,1159,0,\"impl-Debug-for-PathId\"]Ao[3096,13,3097,1366,4112,1159,0]Ao[3096,13,3097,1366,3233,1159,0]Ao[3096,13,3097,1366,3040,1159,0]Ao[3096,13,3097,1366,4751,1159,0]Dc[3096,13,3097,1366,4807,1159,0,\"impl-Debug-for-SetPathStatusError\"]De[3096,13,3097,1366,4807,1827,0,\"impl-Display-for-SetPathStatusError\"]Ck[3096,13,3097,1366,3207,1159,0,\"impl-Debug-for-ClosedPath\"]Cm[3096,13,3097,1366,3207,1827,0,\"impl-Display-for-ClosedPath\"]Ao[3096,13,3097,1381,2295,1159,0]Ao[3096,13,3097,1381,3218,1159,0]Ao[3096,13,3097,1381,3042,1159,0]Ao[3096,13,3097,1381,4452,1159,0]Cl[3096,13,3097,1120,3045,1827,0,\"impl-Display-for-ReadError\"]Cj[3096,13,3097,1120,3045,1159,0,\"impl-Debug-for-ReadError\"]D`[3096,13,3097,1120,4245,1827,0,\"impl-Display-for-ReadableError\"]Cn[3096,13,3097,1120,4245,1159,0,\"impl-Debug-for-ReadableError\"]Ao[3096,13,3097,1125,1868,1159,0]Ck[3096,13,3097,1125,3258,1159,0,\"impl-Debug-for-WriteError\"]Cm[3096,13,3097,1125,3258,1827,0,\"impl-Display-for-WriteError\"]Cn[3096,13,3097,1125,3942,1827,0,\"impl-Display-for-FinishError\"]Cl[3096,13,3097,1125,3942,1159,0,\"impl-Debug-for-FinishError\"]Ao[3096,13,3097,2002,3961,1159,0]Ao[3096,13,3097,2002,4356,1159,0]Co[3096,13,3097,2002,4077,1827,0,\"impl-Display-for-ClosedStream\"]Cm[3096,13,3097,2002,4077,1159,0,\"impl-Debug-for-ClosedStream\"]Db[3096,13,3097,3641,4448,1827,0,\"impl-Display-for-ConnectionError\"]D`[3096,13,3097,3641,4448,1159,0,\"impl-Debug-for-ConnectionError\"]Cl[3096,13,3097,3641,3038,1827,0,\"impl-Display-for-PathError\"]Cj[3096,13,3097,3641,3038,1159,0,\"impl-Debug-for-PathError\"]Co[3096,13,3097,3641,4322,1159,0,\"impl-Debug-for-ClosePathError\"]Da[3096,13,3097,3641,4322,1827,0,\"impl-Display-for-ClosePathError\"]Dg[3096,13,3097,3641,5004,1159,0,\"impl-Debug-for-MultipathNotNegotiated\"]Di[3096,13,3097,3641,5004,1827,0,\"impl-Display-for-MultipathNotNegotiated\"]Ao[3096,13,3097,3641,1174,1159,0]Ao[3096,13,3097,1116,4462,1159,0]Ao[3096,13,3097,3194,4471,1159,0]Ao[3096,13,3097,3194,4777,1159,0]Ao[3096,13,3097,3194,4792,1159,0]Ao[3096,13,3097,3194,3944,1159,0]Ao[3096,13,3097,1691,4332,1159,0]Ao[3096,13,3097,1691,4118,1159,0]Ao[3096,13,3097,1691,4976,1159,0]Ao[3096,13,3097,1691,4069,1159,0]Cl[3096,13,3097,1691,3934,1159,0,\"impl-Debug-for-ConfigError\"]Cn[3096,13,3097,1691,3934,1827,0,\"impl-Display-for-ConfigError\"]Cj[3096,13,3097,1356,3026,1159,0,\"impl-Debug-for-FrameType\"]Cl[3096,13,3097,1356,3026,1827,0,\"impl-Display-for-FrameType\"]Da[3096,13,3097,1356,4337,1827,0,\"impl-Display-for-InvalidFrameId\"]Co[3096,13,3097,1356,4337,1159,0,\"impl-Debug-for-InvalidFrameId\"]Cm[3096,13,3097,1356,3224,1827,0,\"impl-Display-for-MaybeFrame\"]Ck[3096,13,3097,1356,3224,1159,0,\"impl-Debug-for-MaybeFrame\"]Ck[3096,13,3097,1356,3247,1159,0,\"impl-Debug-for-StreamInfo\"]Cm[3096,13,3097,1356,3247,1827,0,\"impl-Display-for-StreamInfo\"]Cm[3096,13,3097,1356,4084,1159,0,\"impl-Debug-for-DatagramInfo\"]Co[3096,13,3097,1356,4084,1827,0,\"impl-Display-for-DatagramInfo\"]Db[3096,13,3097,1356,4446,1827,0,\"impl-Display-for-ConnectionClose\"]D`[3096,13,3097,1356,4446,1159,0,\"impl-Debug-for-ConnectionClose\"]Dc[3096,13,3097,1356,4647,1827,0,\"impl-Display-for-ApplicationClose\"]Da[3096,13,3097,1356,4647,1159,0,\"impl-Debug-for-ApplicationClose\"]Ci[3096,13,3097,1356,2253,1159,0,\"impl-Debug-for-Datagram\"]Ck[3096,13,3097,1356,2253,1827,0,\"impl-Display-for-Datagram\"]Ao[3096,13,3097,2305,4651,1159,0]Ao[3096,13,3097,2305,2264,1159,0]Cm[3096,13,3097,2305,4080,1159,0,\"impl-Debug-for-ConnectError\"]Co[3096,13,3097,2305,4080,1827,0,\"impl-Display-for-ConnectError\"]Ao[3096,13,3097,2305,3928,1159,0]Ck[3096,13,3097,2305,3241,1159,0,\"impl-Debug-for-RetryError\"]Cm[3096,13,3097,2305,3241,1827,0,\"impl-Display-for-RetryError\"]Ao[3096,13,3097,1756,4240,1159,0]Ao[3096,13,3097,1756,4460,1159,0]Ao[3096,13,3097,1756,5008,1159,0]Ao[3096,13,3097,1756,2267,1159,0]Dd[3096,13,3097,1756,4749,1827,0,\"impl-Display-for-PacketDecodeError\"]Db[3096,13,3097,1756,4749,1159,0,\"impl-Debug-for-PacketDecodeError\"]Ao[3096,13,3097,1784,4450,1159,0]Ao[3096,13,3097,1784,4218,1159,0]Cm[3096,13,3097,1784,4083,1159,0,\"impl-Debug-for-ConnectionId\"]Co[3096,13,3097,1784,4083,1827,0,\"impl-Display-for-ConnectionId\"]Ao[3096,13,3097,1784,4088,1159,0]Ce[3096,13,3097,0,4360,1827,0,\"impl-Display-for-Error\"]Cc[3096,13,3097,0,4360,1159,0,\"impl-Debug-for-Error\"]Cb[3096,13,3097,0,4812,1159,0,\"impl-Debug-for-Code\"]Cd[3096,13,3097,0,4812,1827,0,\"impl-Display-for-Code\"]Ao[3096,13,3097,4258,3221,1159,0]Ao[3096,13,3097,4258,5102,1159,0]Ao[3096,13,3097,4847,4679,1159,0]An[3096,13,3097,3097,511,1159,0]Ce[3096,13,3097,3097,127,1827,0,\"impl-Display-for-Dir\"]Cc[3096,13,3097,3097,127,1159,0,\"impl-Debug-for-Dir\"]Ci[3096,13,3097,3097,2282,1159,0,\"impl-Debug-for-StreamId\"]Ck[3096,13,3097,3097,2282,1827,0,\"impl-Display-for-StreamId\"]Ao[3096,13,3097,3097,2292,1159,0]Cj[3096,13,3097,3097,3024,1159,0,\"impl-Debug-for-FourTuple\"]Cl[3096,13,3097,3097,3024,1827,0,\"impl-Display-for-FourTuple\"]Cn[3096,13,1689,1689,4251,1159,0,\"impl-Debug-for-UnexpectedEnd\"]D`[3096,13,1689,1689,4251,1827,0,\"impl-Display-for-UnexpectedEnd\"]Ao[3096,13,4960,4960,4858,1159,0]Cf[3096,13,4960,4960,1171,1159,0,\"impl-Debug-for-Error\"]Ch[3096,13,4960,4960,1171,1827,0,\"impl-Display-for-Error\"]Ao[3096,13,1694,1694,5068,1159,0]Ao[3096,13,1694,1694,3937,1159,0]Ao[3096,13,1694,1694,4818,1159,0]Ce[3096,13,1774,0,1170,1827,0,\"impl-Display-for-Error\"]Cc[3096,13,1774,0,1170,1159,0,\"impl-Debug-for-Error\"]De[3096,13,1774,1774,4914,1159,0,\"impl-Debug-for-NoInitialCipherSuite\"]Dg[3096,13,1774,1774,4914,1827,0,\"impl-Display-for-NoInitialCipherSuite\"]Am[3096,13,3636,148,121,1159,0]An[3096,13,3636,148,3013,1159,0]Ao[3096,13,3636,1352,1157,1159,0]Ao[3096,13,3636,1352,3939,1159,0]Ao[3096,13,3636,2358,1841,1159,0]Ao[3096,13,3636,2358,4238,1159,0]Ao[3096,13,3636,3636,4741,1159,0]Cf[3096,13,4709,4709,1172,1159,0,\"impl-Debug-for-Error\"]Ch[3096,13,4709,4709,1172,1827,0,\"impl-Display-for-Error\"]Ao[3096,13,4709,4709,1175,1159,0]An[1985,13,1986,416,4361,1159,0]Ao[1985,13,1986,1986,2279,1159,0]Ao[1985,13,1986,1986,2293,1159,0]Ao[1985,13,1986,1986,4089,1159,0]Aj[463,13,464,4144,4915,0,0]Al[3096,13,3097,1366,4112,0,0]Ag[463,14,464,0,2294,0,0]Al[3096,14,3097,1381,2295,0,0]Al[3096,13,3097,1756,4240,0,0]Al[3096,14,3097,1756,5008,0,0]Ah[3096,14,4459,0,499,0,0]Al[1985,14,1986,1986,2279,0,0]Ag[463,13,464,0,4975,0,0]Al[3096,13,3097,1691,4976,0,0]8Al[1195,13,1380,1380,4357,0,0]Al[3968,13,3969,3969,5009,0,0]Ag[463,13,464,0,4210,0,0]Aj[463,13,464,2304,2259,0,0]Ag[463,13,464,0,3234,0,0]Ag[463,13,464,0,4461,0,0]Ag[463,13,464,0,4331,0,0]Ag[463,13,464,0,4116,0,0]Ag[463,13,464,0,4067,0,0]Ag[463,13,464,0,4082,0,0]Ag[463,13,464,0,4678,0,0]Ag[463,13,464,0,2281,0,0]Ag[463,13,3635,0,120,0,0]Ah[463,13,3635,0,1156,0,0]Ah[463,13,3635,0,1840,0,0]Al[3096,13,3097,4480,4211,0,0]Al[3096,13,3097,1116,3235,0,0]Al[3096,13,3097,2305,2260,0,0]Al[3096,13,3097,1756,5127,0,0]Al[3096,13,3097,4258,5097,0,0]Al[3096,13,3097,1116,4462,0,0]Al[3096,13,3097,1691,4332,0,0]Al[3096,13,3097,1691,4118,0,0]Al[3096,13,3097,1691,4069,0,0]Al[3096,13,3097,1756,4240,0,0]Al[3096,13,3097,1784,4083,0,0]Ai[3096,13,3097,0,4360,0,0]Al[3096,13,3097,4258,5102,0,0]Al[3096,13,3097,4847,4679,0,0]Al[3096,13,3097,3097,2282,0,0]Al[3096,13,3097,3097,3024,0,0]Aj[3096,13,3636,148,121,0,0]Al[3096,13,3636,1352,1157,0,0]Al[3096,13,3636,2358,1841,0,0]Ak[1985,13,1986,416,4361,0,0]Al[1095,13,4178,4178,5053,0,0]Al[1095,13,4178,4178,5054,0,0]Aa[463,3,0,0,0,0,0]Ah[463,13,464,0,510,133,0]Am[3096,13,3097,3097,511,133,0]Ag[463,12,464,0,3250,0,0]Aj[463,13,464,1994,1852,0,0]0Am[463,13,464,1393,4123,1852,0]Aj[463,13,464,0,4249,3250,0]Al[3096,12,3097,1691,3251,0,0]Ao[3096,13,3097,1691,4250,3251,0]Aj[463,13,464,3640,3211,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,13,3097,3641,3212,0,0]Al[3096,14,3097,1381,3042,0,0]Ae[1095,7,1683,0,0,0,0]Ae[1095,7,1779,0,0,0,0]Ac[463,4,464,0,0,0,0]Ag[463,15,464,0,4087,0,0]Al[3096,15,3097,1784,4088,0,0]Al[1985,15,1986,1986,4089,0,0]210Ag[463,5,1693,1694,0,0,0]Ae[3096,5,1694,0,0,0,0]Al[3096,15,3097,1756,4460,0,0]Al[3096,15,3097,1356,3224,0,0]Af[463,5,464,1094,0,0,0]Al[3096,15,3097,3641,1174,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Aj[463,15,464,4036,4355,0,0]Af[463,6,464,3097,0,0,0]Ae[3096,6,3097,0,0,0,0]Ag[463,19,464,0,1426,0,0]Al[3096,19,3097,1366,1427,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]Ai[3096,14,3039,0,4102,0,0]Al[1985,14,1986,1986,2279,0,0]Aa[519,3,0,0,0,0,0]Ai[3096,14,3097,0,4360,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1381,3042,0,0]Al[3096,14,3097,1356,2253,0,0]Al[463,13,464,3640,2274,487,0]Al[463,13,464,2336,2263,487,0]Ak[463,13,464,1094,503,487,0]Al[463,13,464,1094,4362,487,0]Al[463,13,464,4036,3237,487,0]Al[463,13,464,4041,3243,487,0]An[3096,13,3097,1120,1407,487,0]Am[1195,13,1196,1196,134,494,0]An[1195,13,1196,1196,3954,494,0]An[1195,13,1196,1196,3930,494,0]An[1195,13,1380,1380,3962,494,0]An[1195,13,1380,1380,1189,494,0]An[1195,13,1380,1380,4357,494,0]Ak[519,13,520,520,3931,494,0]An[3968,13,3969,3969,5009,494,0]Al[463,13,464,3640,4475,494,0]Al[463,13,464,3640,2274,494,0]Ai[463,13,464,0,4210,494,0]Al[463,13,464,4144,4915,494,0]Al[463,13,464,1094,2275,494,0]Al[463,13,464,1094,4643,494,0]Al[463,13,464,3640,3209,494,0]Al[463,13,464,3640,3211,494,0]Al[463,13,464,3640,1843,494,0]Al[463,13,464,3640,1419,494,0]Al[463,13,464,3640,3004,494,0]Al[463,13,464,3640,2247,494,0]Al[463,13,464,3640,4108,494,0]Al[463,13,464,3640,4113,494,0]Al[463,13,464,3640,4921,494,0]Al[463,13,464,3640,4752,494,0]0Al[463,13,464,2304,2259,494,0]Al[463,13,464,2304,4219,494,0]Al[463,13,464,2304,1399,494,0]Al[463,13,464,4144,1418,494,0]Al[463,13,464,4144,3231,494,0]Al[463,13,464,4144,4852,494,0]Al[463,13,464,2336,2263,494,0]Al[463,13,464,2336,3240,494,0]Al[463,13,464,2336,4336,494,0]Ak[463,13,464,1094,503,494,0]Al[463,13,464,1094,4362,494,0]Al[463,13,464,4036,3237,494,0]Al[463,13,464,4036,4859,494,0]Al[463,13,464,4036,4355,494,0]0Al[463,13,464,4036,3044,494,0]Df[463,13,464,4036,3044,494,0,\"impl-From%3CResetError%3E-for-ReadError\"]Dk[463,13,464,4036,3044,494,0,\"impl-From%3CConnectionError%3E-for-ReadError\"]Al[463,13,464,4036,3239,494,0]0Al[463,13,464,4036,4354,494,0]0Al[463,13,464,1393,4123,494,0]Al[463,13,464,1137,3957,494,0]Al[463,13,464,4041,3243,494,0]Al[463,13,464,4041,3257,494,0]Di[463,13,464,4041,3257,494,0,\"impl-From%3CClosedStream%3E-for-WriteError\"]Di[463,13,464,4041,3257,494,0,\"impl-From%3CStoppedError%3E-for-WriteError\"]Dl[463,13,464,4041,3257,494,0,\"impl-From%3CConnectionError%3E-for-WriteError\"]Al[463,13,464,4041,4122,494,0]0Al[463,13,464,4041,1857,494,0]Ai[463,13,464,0,3234,494,0]Ai[463,13,464,0,4249,494,0]Ai[463,13,464,0,4467,494,0]Ai[463,13,464,0,4100,494,0]Ai[463,13,464,0,4345,494,0]Cn[463,13,464,0,1443,494,0,\"impl-From%3CStreamId%3E-for-VarInt\"]Ch[463,13,464,0,1443,494,0,\"impl-From%3Cu8%3E-for-VarInt\"]Ci[463,13,464,0,1443,494,0,\"impl-From%3Cu16%3E-for-VarInt\"]Dh[463,13,464,0,1443,494,0,\"impl-From%3CTransportErrorCode%3E-for-VarInt\"]Ci[463,13,464,0,1443,494,0,\"impl-From%3Cu32%3E-for-VarInt\"]Ai[463,13,464,0,1443,494,0]Ai[463,13,464,0,4918,494,0]Ai[463,13,464,0,1152,494,0]Ai[463,13,464,0,1426,494,0]0Ai[463,13,464,0,2294,494,0]Ai[463,13,464,0,3217,494,0]Ai[463,13,464,0,3041,494,0]Ai[463,13,464,0,4451,494,0]Ai[463,13,464,0,1867,494,0]Ai[463,13,464,0,4073,494,0]Dd[463,13,464,0,4447,494,0,\"impl-From%3CClose%3E-for-ConnectionError\"]Ai[463,13,464,0,4447,494,0]Dm[463,13,464,0,4447,494,0,\"impl-From%3CTransportError%3E-for-ConnectionError\"]Dj[463,13,464,0,4447,494,0,\"impl-From%3CCloseReason%3E-for-ConnectionError\"]Ai[463,13,464,0,4461,494,0]Ai[463,13,464,0,4470,494,0]Ai[463,13,464,0,4776,494,0]Ai[463,13,464,0,4791,494,0]Ai[463,13,464,0,3943,494,0]0Ai[463,13,464,0,4331,494,0]Ai[463,13,464,0,4116,494,0]Ai[463,13,464,0,4975,494,0]Ai[463,13,464,0,4067,494,0]Dj[463,13,464,0,3933,494,0,\"impl-From%3CTryFromIntError%3E-for-ConfigError\"]Ai[463,13,464,0,3933,494,0]Do[463,13,464,0,3933,494,0,\"impl-From%3CVarIntBoundsExceeded%3E-for-ConfigError\"]Ai[463,13,464,0,3025,494,0]Ai[463,13,464,0,4444,494,0]0Ai[463,13,464,0,4645,494,0]Ai[463,13,464,0,4079,494,0]0Ai[463,13,464,0,4082,494,0]Ai[463,13,464,0,4087,494,0]Ai[463,13,464,0,4811,494,0]0Ai[463,13,464,0,3220,494,0]Ai[463,13,464,0,4678,494,0]Ah[463,13,464,0,510,494,0]Ah[463,13,464,0,126,494,0]Ai[463,13,464,0,2281,494,0]0Ai[463,13,464,0,2291,494,0]Ai[463,13,3635,0,120,494,0]Aj[463,13,3635,0,3012,494,0]Aj[463,13,3635,0,1156,494,0]Aj[463,13,3635,0,3938,494,0]Aj[463,13,3635,0,1840,494,0]Aj[463,13,3635,0,4237,494,0]Aj[463,13,3635,0,4740,494,0]Aj[463,13,1693,0,1835,494,0]Ai[463,13,1693,0,497,494,0]Aj[463,13,1693,0,5067,494,0]Aj[463,13,1693,0,3936,494,0]0Aj[463,13,1693,0,4815,494,0]Aj[463,13,1773,0,3252,494,0]Aj[463,13,1773,0,4221,494,0]De[463,13,1773,0,1169,494,0,\"impl-From%3CSystemTimeError%3E-for-Error\"]De[463,13,1773,0,1169,494,0,\"impl-From%3CGetRandomFailed%3E-for-Error\"]Df[463,13,1773,0,1169,494,0,\"impl-From%3CInconsistentKeys%3E-for-Error\"]Dd[463,13,1773,0,1169,494,0,\"impl-From%3CPeerMisbehaved%3E-for-Error\"]Dd[463,13,1773,0,1169,494,0,\"impl-From%3CInvalidMessage%3E-for-Error\"]D`[463,13,1773,0,1169,494,0,\"impl-From%3COtherError%3E-for-Error\"]Aj[463,13,1773,0,1169,494,0]Df[463,13,1773,0,1169,494,0,\"impl-From%3CCertificateError%3E-for-Error\"]Do[463,13,1773,0,1169,494,0,\"impl-From%3CEncryptedClientHelloError%3E-for-Error\"]Df[463,13,1773,0,1169,494,0,\"impl-From%3CPeerIncompatible%3E-for-Error\"]Do[463,13,1773,0,1169,494,0,\"impl-From%3CUnsupportedOperationError%3E-for-Error\"]Dm[463,13,1773,0,1169,494,0,\"impl-From%3CCertRevocationListError%3E-for-Error\"]Aj[463,13,1773,0,4674,494,0]Aj[463,13,1773,0,4913,494,0]Aj[463,13,1773,0,4676,494,0]Am[2358,13,2359,2359,125,494,0]An[2358,13,2359,2359,2250,494,0]An[3096,13,3097,4480,4211,494,0]An[3096,13,3097,3070,3018,494,0]An[3096,13,3097,1120,1407,494,0]An[3096,13,3097,2002,1861,494,0]An[3096,13,3097,2002,3238,494,0]An[3096,13,3097,2002,3244,494,0]An[3096,13,3097,3641,3212,494,0]An[3096,13,3097,1116,3235,494,0]An[3096,13,3097,1691,4250,494,0]An[3096,13,3097,2305,2260,494,0]An[3096,13,3097,2305,4217,494,0]An[3096,13,3097,2305,4654,494,0]An[3096,13,3097,2305,4228,494,0]An[3096,13,3097,1756,5127,494,0]An[3096,13,3097,4258,5097,494,0]An[3096,13,3097,1392,4468,494,0]An[3096,13,3097,1392,4101,494,0]An[3096,13,3097,1392,4346,494,0]An[3096,13,3097,1810,1444,494,0]Cn[3096,13,3097,1810,1444,494,0,\"impl-From%3Cu16%3E-for-VarInt\"]Cn[3096,13,3097,1810,1444,494,0,\"impl-From%3Cu32%3E-for-VarInt\"]Cm[3096,13,3097,1810,1444,494,0,\"impl-From%3Cu8%3E-for-VarInt\"]Dc[3096,13,3097,1810,1444,494,0,\"impl-From%3CStreamId%3E-for-VarInt\"]Co[3096,13,3097,1810,1444,494,0,\"impl-From%3CCode%3E-for-VarInt\"]An[3096,13,3097,1810,4919,494,0]An[3096,13,3097,3061,1153,494,0]An[3096,13,3097,3070,4753,494,0]An[3096,13,3097,1366,1427,494,0]0An[3096,13,3097,1366,4112,494,0]An[3096,13,3097,1366,3233,494,0]An[3096,13,3097,1366,3040,494,0]An[3096,13,3097,1366,4751,494,0]An[3096,13,3097,1366,4807,494,0]An[3096,13,3097,1366,3207,494,0]An[3096,13,3097,1381,2295,494,0]An[3096,13,3097,1381,3218,494,0]An[3096,13,3097,1381,3042,494,0]An[3096,13,3097,1381,4452,494,0]An[3096,13,3097,1120,3045,494,0]An[3096,13,3097,1120,4245,494,0]An[3096,13,3097,1125,1868,494,0]An[3096,13,3097,1125,3258,494,0]An[3096,13,3097,1125,3942,494,0]An[3096,13,3097,2002,3961,494,0]An[3096,13,3097,2002,4356,494,0]An[3096,13,3097,2002,4077,494,0]An[3096,13,3097,3641,4448,494,0]0An[3096,13,3097,3641,3038,494,0]An[3096,13,3097,3641,4322,494,0]An[3096,13,3097,3641,5004,494,0]An[3096,13,3097,3641,1174,494,0]0An[3096,13,3097,1116,4462,494,0]An[3096,13,3097,3194,4471,494,0]An[3096,13,3097,3194,4777,494,0]An[3096,13,3097,3194,4792,494,0]An[3096,13,3097,3194,3944,494,0]0An[3096,13,3097,1691,4332,494,0]An[3096,13,3097,1691,4118,494,0]An[3096,13,3097,1691,4976,494,0]An[3096,13,3097,1691,4069,494,0]Do[3096,13,3097,1691,3934,494,0,\"impl-From%3CTryFromIntError%3E-for-ConfigError\"]Ed[3096,13,3097,1691,3934,494,0,\"impl-From%3CVarIntBoundsExceeded%3E-for-ConfigError\"]An[3096,13,3097,1691,3934,494,0]An[3096,13,3097,1356,3026,494,0]An[3096,13,3097,1356,4337,494,0]An[3096,13,3097,1356,3224,494,0]An[3096,13,3097,1356,3247,494,0]An[3096,13,3097,1356,4084,494,0]An[3096,13,3097,1356,4446,494,0]0An[3096,13,3097,1356,4647,494,0]An[3096,13,3097,1356,2253,494,0]An[3096,13,3097,2305,4651,494,0]An[3096,13,3097,2305,2264,494,0]An[3096,13,3097,2305,4080,494,0]0An[3096,13,3097,2305,3928,494,0]An[3096,13,3097,2305,3241,494,0]An[3096,13,3097,1756,4240,494,0]An[3096,13,3097,1756,4460,494,0]An[3096,13,3097,1756,5008,494,0]An[3096,13,3097,1756,2267,494,0]An[3096,13,3097,1756,4749,494,0]0An[3096,13,3097,1784,4450,494,0]An[3096,13,3097,1784,4218,494,0]An[3096,13,3097,1784,4083,494,0]An[3096,13,3097,1784,4088,494,0]Ak[3096,13,3097,0,4360,494,0]0Ak[3096,13,3097,0,4812,494,0]0An[3096,13,3097,4258,3221,494,0]An[3096,13,3097,4258,5102,494,0]An[3096,13,3097,4847,4679,494,0]Am[3096,13,3097,3097,511,494,0]Am[3096,13,3097,3097,127,494,0]An[3096,13,3097,3097,2282,494,0]0An[3096,13,3097,3097,2292,494,0]An[3096,13,3097,3097,3024,494,0]An[3096,13,1689,1689,4251,494,0]An[3096,13,4960,4960,4858,494,0]An[3096,13,4960,4960,1171,494,0]0An[3096,13,1694,1694,1836,494,0]Am[3096,13,1694,1694,498,494,0]An[3096,13,1694,1694,5068,494,0]An[3096,13,1694,1694,3937,494,0]0An[3096,13,1694,1694,4818,494,0]An[3096,13,1774,1774,3253,494,0]An[3096,13,1774,1774,4222,494,0]Dg[3096,13,1774,0,1170,494,0,\"impl-From%3CCertificateError%3E-for-Error\"]E`[3096,13,1774,0,1170,494,0,\"impl-From%3CEncryptedClientHelloError%3E-for-Error\"]Da[3096,13,1774,0,1170,494,0,\"impl-From%3COtherError%3E-for-Error\"]De[3096,13,1774,0,1170,494,0,\"impl-From%3CInvalidMessage%3E-for-Error\"]Dg[3096,13,1774,0,1170,494,0,\"impl-From%3CInconsistentKeys%3E-for-Error\"]Df[3096,13,1774,0,1170,494,0,\"impl-From%3CGetRandomFailed%3E-for-Error\"]E`[3096,13,1774,0,1170,494,0,\"impl-From%3CUnsupportedOperationError%3E-for-Error\"]De[3096,13,1774,0,1170,494,0,\"impl-From%3CPeerMisbehaved%3E-for-Error\"]Dg[3096,13,1774,0,1170,494,0,\"impl-From%3CPeerIncompatible%3E-for-Error\"]Df[3096,13,1774,0,1170,494,0,\"impl-From%3CSystemTimeError%3E-for-Error\"]Ak[3096,13,1774,0,1170,494,0]Dn[3096,13,1774,0,1170,494,0,\"impl-From%3CCertRevocationListError%3E-for-Error\"]An[3096,13,1774,1774,4675,494,0]An[3096,13,1774,1774,4914,494,0]An[3096,13,1774,1774,4677,494,0]Al[3096,13,3636,148,121,494,0]Am[3096,13,3636,148,3013,494,0]An[3096,13,3636,1352,1157,494,0]An[3096,13,3636,1352,3939,494,0]An[3096,13,3636,2358,1841,494,0]An[3096,13,3636,2358,4238,494,0]An[3096,13,3636,3636,4741,494,0]An[3096,13,4709,4709,1172,494,0]An[3096,13,4709,4709,1175,494,0]An[1985,13,1986,1986,3256,494,0]0Am[1985,13,1986,416,4361,494,0]An[1985,13,1986,1986,2279,494,0]An[1985,13,1986,1986,2293,494,0]An[1985,13,1986,1986,4089,494,0]An[1095,13,1096,1096,3015,494,0]An[1095,13,1096,1096,4851,494,0]Am[1095,13,1683,1683,135,494,0]An[1095,13,1382,1382,1190,494,0]An[1095,13,1382,1382,3963,494,0]An[1095,13,1382,1382,4456,494,0]An[1095,13,4178,4178,5053,494,0]An[1095,13,4178,4178,5054,494,0]Am[1095,13,1779,1779,136,494,0]Ai[463,13,464,0,1443,495,0]Ai[463,13,464,0,1426,495,0]Ai[463,13,464,0,3943,495,0]Ai[463,13,464,0,4082,495,0]Ah[463,13,464,0,510,495,0]Ah[463,13,464,0,126,495,0]Ai[463,13,464,0,2281,495,0]An[3096,13,3097,1810,1444,495,0]An[3096,13,3097,3070,4753,495,0]An[3096,13,3097,1366,1427,495,0]An[3096,13,3097,1120,3045,495,0]An[3096,13,3097,1120,4245,495,0]An[3096,13,3097,1125,3258,495,0]An[3096,13,3097,3194,3944,495,0]An[3096,13,3097,2305,4651,495,0]An[3096,13,3097,1756,4749,495,0]An[3096,13,3097,1784,4083,495,0]Am[3096,13,3097,3097,511,495,0]Am[3096,13,3097,3097,127,495,0]An[3096,13,3097,3097,2282,495,0]An[3096,13,3097,3097,3024,495,0]Am[1195,13,1196,1196,134,496,0]An[1195,13,1196,1196,3954,496,0]An[1195,13,1196,1196,3930,496,0]An[1195,13,1380,1380,3962,496,0]An[1195,13,1380,1380,1189,496,0]An[1195,13,1380,1380,4357,496,0]Ak[519,13,520,520,3931,496,0]An[3968,13,3969,3969,5009,496,0]Al[463,13,464,3640,4475,496,0]Al[463,13,464,3640,2274,496,0]Ai[463,13,464,0,4210,496,0]Al[463,13,464,4144,4915,496,0]Al[463,13,464,1094,2275,496,0]Al[463,13,464,1094,4643,496,0]Al[463,13,464,3640,3209,496,0]Al[463,13,464,3640,3211,496,0]Al[463,13,464,3640,1843,496,0]Al[463,13,464,3640,1419,496,0]Al[463,13,464,3640,3004,496,0]Al[463,13,464,3640,2247,496,0]Al[463,13,464,3640,4108,496,0]Al[463,13,464,3640,4113,496,0]Al[463,13,464,3640,4921,496,0]Al[463,13,464,3640,4752,496,0]Al[463,13,464,2304,2259,496,0]Al[463,13,464,2304,4219,496,0]Al[463,13,464,2304,1399,496,0]Al[463,13,464,4144,1418,496,0]Al[463,13,464,4144,3231,496,0]Al[463,13,464,4144,4852,496,0]Al[463,13,464,2336,2263,496,0]Al[463,13,464,2336,3240,496,0]Al[463,13,464,2336,4336,496,0]Ak[463,13,464,1094,503,496,0]Al[463,13,464,1094,4362,496,0]Al[463,13,464,4036,3237,496,0]Al[463,13,464,4036,4859,496,0]Al[463,13,464,4036,4355,496,0]Al[463,13,464,4036,3044,496,0]Al[463,13,464,4036,3239,496,0]Al[463,13,464,4036,4354,496,0]Al[463,13,464,1393,4123,496,0]Al[463,13,464,1137,3957,496,0]Al[463,13,464,4041,3243,496,0]Al[463,13,464,4041,3257,496,0]Al[463,13,464,4041,4122,496,0]Al[463,13,464,4041,1857,496,0]Ai[463,13,464,0,3234,496,0]Ai[463,13,464,0,4249,496,0]Ai[463,13,464,0,4467,496,0]Ai[463,13,464,0,4100,496,0]Ai[463,13,464,0,4345,496,0]Ai[463,13,464,0,1443,496,0]Ai[463,13,464,0,4918,496,0]Ai[463,13,464,0,1152,496,0]Ai[463,13,464,0,1426,496,0]Ai[463,13,464,0,2294,496,0]Ai[463,13,464,0,3217,496,0]Ai[463,13,464,0,3041,496,0]Ai[463,13,464,0,4451,496,0]Ai[463,13,464,0,1867,496,0]Ai[463,13,464,0,4073,496,0]Ai[463,13,464,0,4447,496,0]Ai[463,13,464,0,4461,496,0]Ai[463,13,464,0,4470,496,0]Ai[463,13,464,0,4776,496,0]Ai[463,13,464,0,4791,496,0]Ai[463,13,464,0,3943,496,0]Ai[463,13,464,0,4331,496,0]Ai[463,13,464,0,4116,496,0]Ai[463,13,464,0,4975,496,0]Ai[463,13,464,0,4067,496,0]Ai[463,13,464,0,3933,496,0]Ai[463,13,464,0,3025,496,0]Ai[463,13,464,0,4444,496,0]Ai[463,13,464,0,4645,496,0]Ai[463,13,464,0,4079,496,0]Ai[463,13,464,0,4082,496,0]Ai[463,13,464,0,4087,496,0]Ai[463,13,464,0,4811,496,0]Ai[463,13,464,0,3220,496,0]Ai[463,13,464,0,4678,496,0]Ah[463,13,464,0,510,496,0]Ah[463,13,464,0,126,496,0]Ai[463,13,464,0,2281,496,0]Ai[463,13,464,0,2291,496,0]Ai[463,13,3635,0,120,496,0]Aj[463,13,3635,0,3012,496,0]Aj[463,13,3635,0,1156,496,0]Aj[463,13,3635,0,3938,496,0]Aj[463,13,3635,0,1840,496,0]Aj[463,13,3635,0,4237,496,0]Aj[463,13,3635,0,4740,496,0]Aj[463,13,1693,0,1835,496,0]Ai[463,13,1693,0,497,496,0]Aj[463,13,1693,0,5067,496,0]Aj[463,13,1693,0,3936,496,0]Aj[463,13,1693,0,4815,496,0]Aj[463,13,1773,0,3252,496,0]Aj[463,13,1773,0,4221,496,0]Aj[463,13,1773,0,1169,496,0]Aj[463,13,1773,0,4674,496,0]Aj[463,13,1773,0,4913,496,0]Aj[463,13,1773,0,4676,496,0]Am[2358,13,2359,2359,125,496,0]An[2358,13,2359,2359,2250,496,0]An[3096,13,3097,4480,4211,496,0]An[3096,13,3097,3070,3018,496,0]An[3096,13,3097,1120,1407,496,0]An[3096,13,3097,2002,1861,496,0]An[3096,13,3097,2002,3238,496,0]An[3096,13,3097,2002,3244,496,0]An[3096,13,3097,3641,3212,496,0]An[3096,13,3097,1116,3235,496,0]An[3096,13,3097,1691,4250,496,0]An[3096,13,3097,2305,2260,496,0]An[3096,13,3097,2305,4217,496,0]An[3096,13,3097,2305,4654,496,0]An[3096,13,3097,2305,4228,496,0]An[3096,13,3097,1756,5127,496,0]An[3096,13,3097,4258,5097,496,0]An[3096,13,3097,1392,4468,496,0]An[3096,13,3097,1392,4101,496,0]An[3096,13,3097,1392,4346,496,0]An[3096,13,3097,1810,1444,496,0]An[3096,13,3097,1810,4919,496,0]An[3096,13,3097,3061,1153,496,0]An[3096,13,3097,3070,4753,496,0]An[3096,13,3097,1366,1427,496,0]An[3096,13,3097,1366,4112,496,0]An[3096,13,3097,1366,3233,496,0]An[3096,13,3097,1366,3040,496,0]An[3096,13,3097,1366,4751,496,0]An[3096,13,3097,1366,4807,496,0]An[3096,13,3097,1366,3207,496,0]An[3096,13,3097,1381,2295,496,0]An[3096,13,3097,1381,3218,496,0]An[3096,13,3097,1381,3042,496,0]An[3096,13,3097,1381,4452,496,0]An[3096,13,3097,1120,3045,496,0]An[3096,13,3097,1120,4245,496,0]An[3096,13,3097,1125,1868,496,0]An[3096,13,3097,1125,3258,496,0]An[3096,13,3097,1125,3942,496,0]An[3096,13,3097,2002,3961,496,0]An[3096,13,3097,2002,4356,496,0]An[3096,13,3097,2002,4077,496,0]An[3096,13,3097,3641,4448,496,0]An[3096,13,3097,3641,3038,496,0]An[3096,13,3097,3641,4322,496,0]An[3096,13,3097,3641,5004,496,0]An[3096,13,3097,3641,1174,496,0]An[3096,13,3097,1116,4462,496,0]An[3096,13,3097,3194,4471,496,0]An[3096,13,3097,3194,4777,496,0]An[3096,13,3097,3194,4792,496,0]An[3096,13,3097,3194,3944,496,0]An[3096,13,3097,1691,4332,496,0]An[3096,13,3097,1691,4118,496,0]An[3096,13,3097,1691,4976,496,0]An[3096,13,3097,1691,4069,496,0]An[3096,13,3097,1691,3934,496,0]An[3096,13,3097,1356,3026,496,0]An[3096,13,3097,1356,4337,496,0]An[3096,13,3097,1356,3224,496,0]An[3096,13,3097,1356,3247,496,0]An[3096,13,3097,1356,4084,496,0]An[3096,13,3097,1356,4446,496,0]An[3096,13,3097,1356,4647,496,0]An[3096,13,3097,1356,2253,496,0]An[3096,13,3097,2305,4651,496,0]An[3096,13,3097,2305,2264,496,0]An[3096,13,3097,2305,4080,496,0]An[3096,13,3097,2305,3928,496,0]An[3096,13,3097,2305,3241,496,0]An[3096,13,3097,1756,4240,496,0]An[3096,13,3097,1756,4460,496,0]An[3096,13,3097,1756,5008,496,0]An[3096,13,3097,1756,2267,496,0]An[3096,13,3097,1756,4749,496,0]An[3096,13,3097,1784,4450,496,0]An[3096,13,3097,1784,4218,496,0]An[3096,13,3097,1784,4083,496,0]An[3096,13,3097,1784,4088,496,0]Ak[3096,13,3097,0,4360,496,0]Ak[3096,13,3097,0,4812,496,0]An[3096,13,3097,4258,3221,496,0]An[3096,13,3097,4258,5102,496,0]An[3096,13,3097,4847,4679,496,0]Am[3096,13,3097,3097,511,496,0]Am[3096,13,3097,3097,127,496,0]An[3096,13,3097,3097,2282,496,0]An[3096,13,3097,3097,2292,496,0]An[3096,13,3097,3097,3024,496,0]An[3096,13,1689,1689,4251,496,0]An[3096,13,4960,4960,4858,496,0]An[3096,13,4960,4960,1171,496,0]An[3096,13,1694,1694,1836,496,0]Am[3096,13,1694,1694,498,496,0]An[3096,13,1694,1694,5068,496,0]An[3096,13,1694,1694,3937,496,0]An[3096,13,1694,1694,4818,496,0]An[3096,13,1774,1774,3253,496,0]An[3096,13,1774,1774,4222,496,0]Ak[3096,13,1774,0,1170,496,0]An[3096,13,1774,1774,4675,496,0]An[3096,13,1774,1774,4914,496,0]An[3096,13,1774,1774,4677,496,0]Al[3096,13,3636,148,121,496,0]Am[3096,13,3636,148,3013,496,0]An[3096,13,3636,1352,1157,496,0]An[3096,13,3636,1352,3939,496,0]An[3096,13,3636,2358,1841,496,0]An[3096,13,3636,2358,4238,496,0]An[3096,13,3636,3636,4741,496,0]An[3096,13,4709,4709,1172,496,0]An[3096,13,4709,4709,1175,496,0]An[1985,13,1986,1986,3256,496,0]Am[1985,13,1986,416,4361,496,0]An[1985,13,1986,1986,2279,496,0]An[1985,13,1986,1986,2293,496,0]An[1985,13,1986,1986,4089,496,0]An[1095,13,1096,1096,3015,496,0]An[1095,13,1096,1096,4851,496,0]Am[1095,13,1683,1683,135,496,0]An[1095,13,1382,1382,1190,496,0]An[1095,13,1382,1382,3963,496,0]An[1095,13,1382,1382,4456,496,0]An[1095,13,4178,4178,5053,496,0]An[1095,13,4178,4178,5054,496,0]Am[1095,13,1779,1779,136,496,0]Ac[519,7,520,0,0,0,0]Ae[3968,7,3969,0,0,0,0]Ae[4261,7,4262,0,0,0,0]Ae[2358,7,2359,0,0,0,0]Ae[4771,7,4772,0,0,0,0]Al[3096,13,3097,1120,1407,0,0]Ao[3096,13,3097,2305,4228,2265,0]Ah[463,12,1693,0,4742,0,0]Al[3096,13,3097,2002,1861,0,0]Al[3096,12,1694,1694,4743,0,0]Aj[463,13,464,3640,3211,0,0]Ab[1095,3,0,0,0,0,0]Ai[463,13,464,1094,503,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,13,3097,3641,3212,0,0]Al[3096,14,3097,1381,3218,0,0]Aj[463,12,464,1994,3200,0,0]Am[463,13,464,3640,4475,1415,0]Am[463,13,464,3640,2274,1415,0]Am[463,13,464,1094,2275,1415,0]Am[463,13,464,3640,3209,1415,0]Am[463,13,464,3640,1843,1415,0]Am[463,13,464,3640,1419,1415,0]Am[463,13,464,3640,3004,1415,0]Am[463,13,464,3640,2247,1415,0]Am[463,13,464,3640,4108,1415,0]Am[463,13,464,3640,4113,1415,0]Am[463,13,464,2304,1399,1415,0]Am[463,13,464,2336,4336,1415,0]Am[463,13,464,4041,1857,1415,0]?Aj[463,13,464,4036,3237,0,0]Al[3096,13,3097,2002,3238,0,0]Al[3096,13,4960,4960,4858,0,0]Al[3096,13,3097,3070,3018,0,0]Ak[1985,13,1986,416,4361,0,0]Ah[463,12,1693,0,4742,0,0]Al[3096,12,1694,1694,4743,0,0]32Ag[463,13,464,0,4975,0,0]Al[3096,13,3097,1691,4976,0,0]Aj[463,13,464,3640,3211,0,0]Al[3096,13,3097,3641,3212,0,0]Ah[463,12,1693,0,1831,0,0]Al[3096,12,1694,1694,1832,0,0]Al[1195,14,1380,1380,4357,0,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Ai[3096,14,4459,0,1186,0,0]Aj[463,13,464,4036,3237,0,0]Aj[463,13,464,4036,4859,0,0]Al[3096,13,3097,2002,3238,0,0]Ag[463,12,464,0,3254,0,0]Aj[463,13,464,0,4345,3254,0]Aj[463,13,464,0,4678,3254,0]Al[3096,12,3097,1392,3255,0,0]Ao[3096,13,3097,1392,4346,3255,0]Ao[3096,13,3097,4847,4679,3255,0]Af[463,5,464,3061,0,0,0]Ah[3096,5,3097,3061,0,0,0]Ag[463,5,3635,1352,0,0,0]Ah[3096,5,3636,1352,0,0,0]Al[1095,15,1096,1096,4851,0,0]Ag[463,6,1773,1355,0,0,0]Ah[3096,6,1774,1355,0,0,0]Ae[3096,6,4960,0,0,0,0]Ae[3096,6,4709,0,0,0,0]Ah[3096,6,3097,3641,0,0,0]1Al[3096,15,3097,1356,3224,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Aj[463,15,464,4036,3044,0,0]Ag[463,15,464,0,4447,0,0]Al[3096,15,3097,1120,3045,0,0]Al[3096,15,3097,3641,4448,0,0]Al[3096,15,3097,1756,4460,0,0]0Ae[1195,5,1380,0,0,0,0]Ae[1095,5,1382,0,0,0,0]Al[1195,15,1196,1196,3954,0,0]Al[3096,13,3097,2305,4654,0,0]Ab[1195,3,0,0,0,0,0]Ah[463,12,3635,0,4738,0,0]Ak[463,13,3635,0,3012,4738,0]Ak[463,13,3635,0,3938,4738,0]Ak[463,13,3635,0,4237,4738,0]Al[3096,12,3636,3636,4739,0,0]An[3096,13,3636,148,3013,4739,0]Ao[3096,13,3636,1352,3939,4739,0]Ao[3096,13,3636,2358,4238,4739,0]Al[1095,13,1096,1096,4851,0,0]Ag[463,14,464,0,1152,0,0]Ag[463,14,464,0,2294,0,0]Ag[463,14,464,0,1867,0,0]Al[3096,14,3097,3061,1153,0,0]Al[3096,14,3097,1381,2295,0,0]Al[3096,14,3097,1125,1868,0,0]Al[3096,14,3097,2305,3928,0,0]An[1195,13,1196,1196,134,1154,0]Ao[1195,13,1196,1196,3954,1154,0]Ao[1195,13,1196,1196,3930,1154,0]Am[463,13,464,3640,3211,1154,0]Am[463,13,464,3640,4921,1154,0]Am[463,13,464,3640,4752,1154,0]Am[463,13,464,2304,2259,1154,0]Am[463,13,464,2304,4219,1154,0]Am[463,13,464,4144,1418,1154,0]Al[463,13,464,1094,503,1154,0]Am[463,13,464,1094,4362,1154,0]Am[463,13,464,4036,4355,1154,0]Am[463,13,464,4036,3044,1154,0]Am[463,13,464,4036,3239,1154,0]Am[463,13,464,4036,4354,1154,0]Am[463,13,464,4041,3257,1154,0]Am[463,13,464,4041,4122,1154,0]Aj[463,13,464,0,1443,1154,0]Aj[463,13,464,0,4918,1154,0]Aj[463,13,464,0,1426,1154,0]Aj[463,13,464,0,2294,1154,0]Aj[463,13,464,0,3217,1154,0]Aj[463,13,464,0,3041,1154,0]Aj[463,13,464,0,4451,1154,0]Aj[463,13,464,0,1867,1154,0]Aj[463,13,464,0,4073,1154,0]Aj[463,13,464,0,4447,1154,0]Aj[463,13,464,0,4470,1154,0]Aj[463,13,464,0,4776,1154,0]Aj[463,13,464,0,4791,1154,0]Aj[463,13,464,0,3943,1154,0]Aj[463,13,464,0,4331,1154,0]Aj[463,13,464,0,4116,1154,0]Aj[463,13,464,0,4975,1154,0]Aj[463,13,464,0,4067,1154,0]Aj[463,13,464,0,3933,1154,0]Aj[463,13,464,0,3025,1154,0]Aj[463,13,464,0,4444,1154,0]Aj[463,13,464,0,4645,1154,0]Aj[463,13,464,0,4079,1154,0]Aj[463,13,464,0,4082,1154,0]Aj[463,13,464,0,4087,1154,0]Aj[463,13,464,0,4811,1154,0]Aj[463,13,464,0,3220,1154,0]Ai[463,13,464,0,510,1154,0]Ai[463,13,464,0,126,1154,0]Aj[463,13,464,0,2281,1154,0]Aj[463,13,3635,0,120,1154,0]Ak[463,13,3635,0,3012,1154,0]Ak[463,13,3635,0,1156,1154,0]Ak[463,13,3635,0,3938,1154,0]Ak[463,13,3635,0,1840,1154,0]Ak[463,13,3635,0,4237,1154,0]Ak[463,13,1773,0,1169,1154,0]Ak[463,13,1773,0,4674,1154,0]Ak[463,13,1773,0,4913,1154,0]Ak[463,13,1773,0,4676,1154,0]Ao[3096,13,3097,1810,1444,1154,0]Ao[3096,13,3097,1810,4919,1154,0]Ao[3096,13,3097,3070,4753,1154,0]Ao[3096,13,3097,1366,1427,1154,0]Ao[3096,13,3097,1366,4112,1154,0]Ao[3096,13,3097,1366,3233,1154,0]Ao[3096,13,3097,1366,3040,1154,0]Ao[3096,13,3097,1366,4751,1154,0]Ao[3096,13,3097,1366,4807,1154,0]Ao[3096,13,3097,1366,3207,1154,0]Ao[3096,13,3097,1381,2295,1154,0]Ao[3096,13,3097,1381,3218,1154,0]Ao[3096,13,3097,1381,3042,1154,0]Ao[3096,13,3097,1381,4452,1154,0]Ao[3096,13,3097,1120,3045,1154,0]Ao[3096,13,3097,1120,4245,1154,0]Ao[3096,13,3097,1125,1868,1154,0]Ao[3096,13,3097,1125,3258,1154,0]Ao[3096,13,3097,1125,3942,1154,0]Ao[3096,13,3097,2002,4356,1154,0]Ao[3096,13,3097,2002,4077,1154,0]Ao[3096,13,3097,3641,4448,1154,0]Ao[3096,13,3097,3641,3038,1154,0]Ao[3096,13,3097,3641,4322,1154,0]Ao[3096,13,3097,3641,5004,1154,0]Ao[3096,13,3097,3194,4471,1154,0]Ao[3096,13,3097,3194,4777,1154,0]Ao[3096,13,3097,3194,4792,1154,0]Ao[3096,13,3097,3194,3944,1154,0]Ao[3096,13,3097,1691,4332,1154,0]Ao[3096,13,3097,1691,4118,1154,0]Ao[3096,13,3097,1691,4976,1154,0]Ao[3096,13,3097,1691,4069,1154,0]Ao[3096,13,3097,1691,3934,1154,0]Ao[3096,13,3097,1356,3026,1154,0]Ao[3096,13,3097,1356,3224,1154,0]Ao[3096,13,3097,1356,3247,1154,0]Ao[3096,13,3097,1356,4084,1154,0]Ao[3096,13,3097,1356,4446,1154,0]Ao[3096,13,3097,1356,4647,1154,0]Ao[3096,13,3097,1356,2253,1154,0]Ao[3096,13,3097,2305,4651,1154,0]Ao[3096,13,3097,2305,4080,1154,0]Ao[3096,13,3097,1756,4460,1154,0]Ao[3096,13,3097,1756,5008,1154,0]Ao[3096,13,3097,1756,2267,1154,0]Ao[3096,13,3097,1756,4749,1154,0]Ao[3096,13,3097,1784,4083,1154,0]Ao[3096,13,3097,1784,4088,1154,0]Al[3096,13,3097,0,4360,1154,0]Al[3096,13,3097,0,4812,1154,0]Ao[3096,13,3097,4258,3221,1154,0]Ao[3096,13,3097,4258,5102,1154,0]An[3096,13,3097,3097,511,1154,0]An[3096,13,3097,3097,127,1154,0]Ao[3096,13,3097,3097,2282,1154,0]Ao[3096,13,3097,3097,3024,1154,0]Ao[3096,13,1689,1689,4251,1154,0]Ao[3096,13,4960,4960,4858,1154,0]Ao[3096,13,4960,4960,1171,1154,0]Al[3096,13,1774,0,1170,1154,0]Ao[3096,13,1774,1774,4675,1154,0]Ao[3096,13,1774,1774,4914,1154,0]Ao[3096,13,1774,1774,4677,1154,0]Am[3096,13,3636,148,121,1154,0]An[3096,13,3636,148,3013,1154,0]Ao[3096,13,3636,1352,1157,1154,0]Ao[3096,13,3636,1352,3939,1154,0]Ao[3096,13,3636,2358,1841,1154,0]Ao[3096,13,3636,2358,4238,1154,0]Ao[3096,13,4709,4709,1175,1154,0]Ao[1985,13,1986,1986,2279,1154,0]Ao[1985,13,1986,1986,2293,1154,0]Ao[1985,13,1986,1986,4089,1154,0]Ao[1095,13,1096,1096,4851,1154,0]Ao[1095,13,1382,1382,4456,1154,0]Ao[1095,13,4178,4178,5053,1154,0]Ao[1095,13,4178,4178,5054,1154,0]Aj[463,13,464,3640,3211,0,0]Aj[463,13,464,2304,2259,0,0]Ai[463,13,464,1094,503,0,0]Al[3096,13,3097,3641,3212,0,0]Aj[463,13,464,0,4082,1160,0]Ao[3096,13,3097,1784,4083,1160,0]Ai[3096,14,3097,0,4360,0,0]Ag[463,13,464,0,2281,0,0]Al[3096,13,3097,3097,2282,0,0]Ag[463,13,464,0,4087,0,0]Al[3096,13,3097,1784,4088,0,0]Ah[463,14,1693,0,1835,0,0]Al[3096,14,1694,1694,1836,0,0]Al[3096,12,3097,1756,4782,0,0]Ao[3096,13,3097,1756,5127,4782,0];Al[1195,13,1380,1380,1189,0,0]Ai[519,13,520,520,3931,0,0]Al[1095,13,1382,1382,1190,0,0]Aj[463,12,464,1994,3200,0,0]Aj[463,13,464,4041,3243,0,0]Al[3096,13,3097,2002,3244,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2260,0,0]Aj[463,12,464,1994,1852,0,0]Am[463,13,464,1393,4123,1852,0]Am[463,13,464,1137,3957,1852,0]Ae[1195,2,1196,0,0,0,0]Ak[1195,14,1196,1196,134,0,0]Aj[463,13,464,3640,3211,0,0]Aj[463,13,464,2304,2259,0,0]Ai[463,13,464,1094,503,0,0]Al[3096,13,3097,3641,3212,0,0]Ae[1095,2,1096,0,0,0,0]Ag[463,13,464,0,3234,0,0]Al[3096,13,3097,1116,3235,0,0]?>Al[3096,13,4960,4960,4858,0,0]Af[463,5,464,2304,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Al[1195,15,1196,1196,3930,0,0]0Al[3096,15,3097,1366,3233,0,0]Ah[3096,5,3097,1120,0,0,0]Af[463,15,464,0,510,0,0]Al[2358,15,2359,2359,2250,0,0]Ak[3096,15,3097,3097,511,0,0]Al[3096,15,4709,4709,1172,0,0]87Af[463,5,464,4144,0,0,0]Af[463,5,464,3640,0,0,0]Al[3096,15,3097,1366,3040,0,0]Al[3096,15,3097,2002,3961,0,0]Af[463,5,464,1366,0,0,0]Ah[3096,5,3097,1366,0,0,0]Ae[3096,8,1689,0,0,0,0]:98?Al[3096,15,3097,3641,1174,0,0]?Af[463,5,464,1810,0,0,0]Ah[3096,5,3097,1810,0,0,0]Aj[463,13,464,2304,2259,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2002,1861,0,0]Al[3096,13,3097,2305,2260,0,0]An[1195,13,1196,1196,134,1405,0]Ao[1195,13,1196,1196,3954,1405,0]Ao[1195,13,1196,1196,3930,1405,0]Ao[1195,13,1380,1380,3962,1405,0]Ao[1195,13,1380,1380,1189,1405,0]Ao[1195,13,1380,1380,4357,1405,0]Al[519,13,520,520,3931,1405,0]Ao[3968,13,3969,3969,5009,1405,0]Am[463,13,464,3640,4475,1405,0]Am[463,13,464,3640,2274,1405,0]Aj[463,13,464,0,4210,1405,0]Am[463,13,464,4144,4915,1405,0]Am[463,13,464,1094,2275,1405,0]Am[463,13,464,1094,4643,1405,0]Am[463,13,464,3640,3209,1405,0]Am[463,13,464,3640,3211,1405,0]Am[463,13,464,3640,1843,1405,0]Am[463,13,464,3640,1419,1405,0]Am[463,13,464,3640,3004,1405,0]Am[463,13,464,3640,2247,1405,0]Am[463,13,464,3640,4108,1405,0]Am[463,13,464,3640,4113,1405,0]Am[463,13,464,3640,4921,1405,0]Am[463,13,464,3640,4752,1405,0]Am[463,13,464,2304,2259,1405,0]Am[463,13,464,2304,4219,1405,0]Am[463,13,464,2304,1399,1405,0]Am[463,13,464,4144,1418,1405,0]Am[463,13,464,4144,3231,1405,0]Am[463,13,464,4144,4852,1405,0]Am[463,13,464,2336,2263,1405,0]Am[463,13,464,2336,3240,1405,0]Am[463,13,464,2336,4336,1405,0]Al[463,13,464,1094,503,1405,0]Am[463,13,464,1094,4362,1405,0]Am[463,13,464,4036,3237,1405,0]Am[463,13,464,4036,4859,1405,0]Am[463,13,464,4036,4355,1405,0]Am[463,13,464,4036,3044,1405,0]Am[463,13,464,4036,3239,1405,0]Am[463,13,464,4036,4354,1405,0]Am[463,13,464,1393,4123,1405,0]Am[463,13,464,1137,3957,1405,0]Am[463,13,464,4041,3243,1405,0]Am[463,13,464,4041,3257,1405,0]Am[463,13,464,4041,4122,1405,0]Am[463,13,464,4041,1857,1405,0]Aj[463,13,464,0,3234,1405,0]Aj[463,13,464,0,4249,1405,0]Aj[463,13,464,0,4467,1405,0]Aj[463,13,464,0,4100,1405,0]Aj[463,13,464,0,4345,1405,0]Aj[463,13,464,0,1443,1405,0]Aj[463,13,464,0,4918,1405,0]Aj[463,13,464,0,1152,1405,0]Aj[463,13,464,0,1426,1405,0]Aj[463,13,464,0,2294,1405,0]Aj[463,13,464,0,3217,1405,0]Aj[463,13,464,0,3041,1405,0]Aj[463,13,464,0,4451,1405,0]Aj[463,13,464,0,1867,1405,0]Aj[463,13,464,0,4073,1405,0]Aj[463,13,464,0,4447,1405,0]Aj[463,13,464,0,4461,1405,0]Aj[463,13,464,0,4470,1405,0]Aj[463,13,464,0,4776,1405,0]Aj[463,13,464,0,4791,1405,0]Aj[463,13,464,0,3943,1405,0]Aj[463,13,464,0,4331,1405,0]Aj[463,13,464,0,4116,1405,0]Aj[463,13,464,0,4975,1405,0]Aj[463,13,464,0,4067,1405,0]Aj[463,13,464,0,3933,1405,0]Aj[463,13,464,0,3025,1405,0]Aj[463,13,464,0,4444,1405,0]Aj[463,13,464,0,4645,1405,0]Aj[463,13,464,0,4079,1405,0]Aj[463,13,464,0,4082,1405,0]Aj[463,13,464,0,4087,1405,0]Aj[463,13,464,0,4811,1405,0]Aj[463,13,464,0,3220,1405,0]Aj[463,13,464,0,4678,1405,0]Ai[463,13,464,0,510,1405,0]Ai[463,13,464,0,126,1405,0]Aj[463,13,464,0,2281,1405,0]Aj[463,13,464,0,2291,1405,0]Aj[463,13,3635,0,120,1405,0]Ak[463,13,3635,0,3012,1405,0]Ak[463,13,3635,0,1156,1405,0]Ak[463,13,3635,0,3938,1405,0]Ak[463,13,3635,0,1840,1405,0]Ak[463,13,3635,0,4237,1405,0]Ak[463,13,3635,0,4740,1405,0]Ak[463,13,1693,0,1835,1405,0]Aj[463,13,1693,0,497,1405,0]Ak[463,13,1693,0,5067,1405,0]Ak[463,13,1693,0,3936,1405,0]Ak[463,13,1693,0,4815,1405,0]Ak[463,13,1773,0,3252,1405,0]Ak[463,13,1773,0,4221,1405,0]Ak[463,13,1773,0,1169,1405,0]Ak[463,13,1773,0,4674,1405,0]Ak[463,13,1773,0,4913,1405,0]Ak[463,13,1773,0,4676,1405,0]An[2358,13,2359,2359,125,1405,0]Ao[2358,13,2359,2359,2250,1405,0]Ao[3096,13,3097,4480,4211,1405,0]Ao[3096,13,3097,3070,3018,1405,0]Ao[3096,13,3097,1120,1407,1405,0]Ao[3096,13,3097,2002,1861,1405,0]Ao[3096,13,3097,2002,3238,1405,0]Ao[3096,13,3097,2002,3244,1405,0]Ao[3096,13,3097,3641,3212,1405,0]Ao[3096,13,3097,1116,3235,1405,0]Ao[3096,13,3097,1691,4250,1405,0]Ao[3096,13,3097,2305,2260,1405,0]Ao[3096,13,3097,2305,4217,1405,0]Ao[3096,13,3097,2305,4654,1405,0]Ao[3096,13,3097,2305,4228,1405,0]Ao[3096,13,3097,1756,5127,1405,0]Ao[3096,13,3097,4258,5097,1405,0]Ao[3096,13,3097,1392,4468,1405,0]Ao[3096,13,3097,1392,4101,1405,0]Ao[3096,13,3097,1392,4346,1405,0]Ao[3096,13,3097,1810,1444,1405,0]Ao[3096,13,3097,1810,4919,1405,0]Ao[3096,13,3097,3061,1153,1405,0]Ao[3096,13,3097,3070,4753,1405,0]Ao[3096,13,3097,1366,1427,1405,0]Ao[3096,13,3097,1366,4112,1405,0]Ao[3096,13,3097,1366,3233,1405,0]Ao[3096,13,3097,1366,3040,1405,0]Ao[3096,13,3097,1366,4751,1405,0]Ao[3096,13,3097,1366,4807,1405,0]Ao[3096,13,3097,1366,3207,1405,0]Ao[3096,13,3097,1381,2295,1405,0]Ao[3096,13,3097,1381,3218,1405,0]Ao[3096,13,3097,1381,3042,1405,0]Ao[3096,13,3097,1381,4452,1405,0]Ao[3096,13,3097,1120,3045,1405,0]Ao[3096,13,3097,1120,4245,1405,0]Ao[3096,13,3097,1125,1868,1405,0]Ao[3096,13,3097,1125,3258,1405,0]Ao[3096,13,3097,1125,3942,1405,0]Ao[3096,13,3097,2002,3961,1405,0]Ao[3096,13,3097,2002,4356,1405,0]Ao[3096,13,3097,2002,4077,1405,0]Ao[3096,13,3097,3641,4448,1405,0]Ao[3096,13,3097,3641,3038,1405,0]Ao[3096,13,3097,3641,4322,1405,0]Ao[3096,13,3097,3641,5004,1405,0]Ao[3096,13,3097,3641,1174,1405,0]Ao[3096,13,3097,1116,4462,1405,0]Ao[3096,13,3097,3194,4471,1405,0]Ao[3096,13,3097,3194,4777,1405,0]Ao[3096,13,3097,3194,4792,1405,0]Ao[3096,13,3097,3194,3944,1405,0]Ao[3096,13,3097,1691,4332,1405,0]Ao[3096,13,3097,1691,4118,1405,0]Ao[3096,13,3097,1691,4976,1405,0]Ao[3096,13,3097,1691,4069,1405,0]Ao[3096,13,3097,1691,3934,1405,0]Ao[3096,13,3097,1356,3026,1405,0]Ao[3096,13,3097,1356,4337,1405,0]Ao[3096,13,3097,1356,3224,1405,0]Ao[3096,13,3097,1356,3247,1405,0]Ao[3096,13,3097,1356,4084,1405,0]Ao[3096,13,3097,1356,4446,1405,0]Ao[3096,13,3097,1356,4647,1405,0]Ao[3096,13,3097,1356,2253,1405,0]Ao[3096,13,3097,2305,4651,1405,0]Ao[3096,13,3097,2305,2264,1405,0]Ao[3096,13,3097,2305,4080,1405,0]Ao[3096,13,3097,2305,3928,1405,0]Ao[3096,13,3097,2305,3241,1405,0]Ao[3096,13,3097,1756,4240,1405,0]Ao[3096,13,3097,1756,4460,1405,0]Ao[3096,13,3097,1756,5008,1405,0]Ao[3096,13,3097,1756,2267,1405,0]Ao[3096,13,3097,1756,4749,1405,0]Ao[3096,13,3097,1784,4450,1405,0]Ao[3096,13,3097,1784,4218,1405,0]Ao[3096,13,3097,1784,4083,1405,0]Ao[3096,13,3097,1784,4088,1405,0]Al[3096,13,3097,0,4360,1405,0]Al[3096,13,3097,0,4812,1405,0]Ao[3096,13,3097,4258,3221,1405,0]Ao[3096,13,3097,4258,5102,1405,0]Ao[3096,13,3097,4847,4679,1405,0]An[3096,13,3097,3097,511,1405,0]An[3096,13,3097,3097,127,1405,0]Ao[3096,13,3097,3097,2282,1405,0]Ao[3096,13,3097,3097,2292,1405,0]Ao[3096,13,3097,3097,3024,1405,0]Ao[3096,13,1689,1689,4251,1405,0]Ao[3096,13,4960,4960,4858,1405,0]Ao[3096,13,4960,4960,1171,1405,0]Ao[3096,13,1694,1694,1836,1405,0]An[3096,13,1694,1694,498,1405,0]Ao[3096,13,1694,1694,5068,1405,0]Ao[3096,13,1694,1694,3937,1405,0]Ao[3096,13,1694,1694,4818,1405,0]Ao[3096,13,1774,1774,3253,1405,0]Ao[3096,13,1774,1774,4222,1405,0]Al[3096,13,1774,0,1170,1405,0]Ao[3096,13,1774,1774,4675,1405,0]Ao[3096,13,1774,1774,4914,1405,0]Ao[3096,13,1774,1774,4677,1405,0]Am[3096,13,3636,148,121,1405,0]An[3096,13,3636,148,3013,1405,0]Ao[3096,13,3636,1352,1157,1405,0]Ao[3096,13,3636,1352,3939,1405,0]Ao[3096,13,3636,2358,1841,1405,0]Ao[3096,13,3636,2358,4238,1405,0]Ao[3096,13,3636,3636,4741,1405,0]Ao[3096,13,4709,4709,1172,1405,0]Ao[3096,13,4709,4709,1175,1405,0]Ao[1985,13,1986,1986,3256,1405,0]An[1985,13,1986,416,4361,1405,0]Ao[1985,13,1986,1986,2279,1405,0]Ao[1985,13,1986,1986,2293,1405,0]Ao[1985,13,1986,1986,4089,1405,0]Ao[1095,13,1096,1096,3015,1405,0]Ao[1095,13,1096,1096,4851,1405,0]An[1095,13,1683,1683,135,1405,0]Ao[1095,13,1382,1382,1190,1405,0]Ao[1095,13,1382,1382,3963,1405,0]Ao[1095,13,1382,1382,4456,1405,0]Ao[1095,13,4178,4178,5053,1405,0]Ao[1095,13,4178,4178,5054,1405,0]An[1095,13,1779,1779,136,1405,0]Ag[463,14,464,0,1867,0,0]Al[3096,14,3097,1125,1868,0,0]Ak[1195,14,1196,1196,134,0,0]Ac[519,7,520,0,0,0,0]Aj[463,13,464,2304,2259,0,0]Ae[1095,2,1096,0,0,0,0]Ae[4771,7,4772,0,0,0,0]Aj[463,13,464,3640,3211,0,0]Ae[3096,2,3097,0,0,0,0]Al[3096,13,3097,2305,2260,0,0]Af[463,2,464,3097,0,0,0]Ag[463,13,464,0,4811,0,0]Ag[463,14,464,0,3217,0,0]Ag[463,14,464,0,4116,0,0]5Ai[3096,13,3097,0,4812,0,0]Al[3096,14,3097,1381,3218,0,0]Al[3096,14,3097,1691,4118,0,0]Ai[3096,14,3097,0,4360,0,0]Aj[463,13,464,0,1443,3019,0]Aj[463,13,464,0,1426,3019,0]Aj[463,13,464,0,3025,3019,0]Aj[463,13,464,0,4811,3019,0]Aj[463,13,464,0,2281,3019,0]Ao[3096,13,3097,1810,1444,3019,0]Ao[3096,13,3097,1366,1427,3019,0]Ao[3096,13,3097,1356,3026,3019,0]Ao[3096,13,3097,1356,3224,3019,0]Al[3096,13,3097,1756,4460,0,0]Al[3096,13,3097,0,4812,3019,0]Ao[3096,13,3097,3097,2282,3019,0]Al[3096,12,1689,1689,3019,0,0]Al[1985,14,1986,1986,2279,0,0]Aj[463,13,464,0,1443,3022,0]Aj[463,13,464,0,1426,3022,0]Aj[463,13,464,0,3025,3022,0]Aj[463,13,464,0,4811,3022,0]Aj[463,13,464,0,2281,3022,0]Ao[3096,13,3097,1810,1444,3022,0]Ao[3096,13,3097,1366,1427,3022,0]Ao[3096,13,3097,1356,3026,3022,0]Ao[3096,13,3097,1356,3224,3022,0]Ao[3096,13,3097,1356,2253,3022,0]Al[3096,13,3097,0,4812,3022,0]Ao[3096,13,3097,3097,2282,3022,0]Al[3096,12,1689,1689,3022,0,0]Aj[463,13,464,4041,3243,0,0]Al[3096,13,3097,2002,3244,0,0]Al[1095,13,1382,1382,3963,0,0]Al[3096,13,3097,2305,2260,0,0]Ag[463,14,1693,0,497,0,0]Ak[3096,14,1694,1694,498,0,0]Aj[463,13,464,2336,2263,0,0]3Ag[463,12,464,0,3254,0,0]Aj[463,13,464,0,4345,3254,0]Aj[463,13,464,0,4678,3254,0]Al[3096,12,3097,1392,3255,0,0]Ao[3096,13,3097,1392,4346,3255,0]Ao[3096,13,3097,4847,4679,3255,0]Al[1095,14,1096,1096,3015,0,0]Ag[463,14,464,0,1152,0,0]Al[3096,14,3097,3061,1153,0,0]Ah[463,13,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,13,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Ag[463,14,1693,0,497,0,0]Ak[3096,14,1694,1694,498,0,0]Ai[3096,14,4459,0,4683,0,0]Ag[463,14,464,0,4444,0,0]Ag[463,14,464,0,4645,0,0]Al[3096,14,3097,1356,4446,0,0]Al[3096,14,3097,1356,4647,0,0]Ai[3096,14,3097,0,4360,0,0]Ai[3096,14,1173,0,4324,0,0]Ai[3096,14,3039,0,3002,0,0]Aj[463,13,464,2304,2259,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2260,0,0]Ah[463,14,1693,0,1835,0,0]Al[3096,13,3097,3097,3024,0,0]Al[3096,14,1694,1694,1836,0,0]Ac[463,4,464,0,0,0,0]Ag[463,2,1693,1694,0,0,0]Ae[3096,4,3097,0,0,0,0]Ae[3096,2,1694,0,0,0,0]Ac[519,7,520,0,0,0,0]:Ae[1095,2,1096,0,0,0,0]Ae[4771,7,4772,0,0,0,0]Am[463,13,464,3640,4752,1162,0]Am[463,13,464,4036,4355,1162,0]Am[463,13,464,4036,3044,1162,0]Am[463,13,464,4036,3239,1162,0]Am[463,13,464,4036,4354,1162,0]Am[463,13,464,4041,3257,1162,0]Am[463,13,464,4041,4122,1162,0]Aj[463,13,464,0,4447,1162,0]Ao[3096,13,3097,3641,4448,1162,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Al[1985,14,1986,1986,2293,0,0]Ai[463,13,464,1094,503,0,0]Ai[3096,14,3039,0,4109,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]Al[1985,14,1986,1986,2279,0,0]Ag[463,14,464,0,3041,0,0]Ag[463,14,464,0,4451,0,0]Al[3096,14,3097,1381,3042,0,0]Al[3096,14,3097,1381,4452,0,0]3210Ah[463,12,1693,0,1831,0,0]Al[3096,12,1694,1694,1832,0,0]Ah[463,12,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,12,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Al[3096,15,3097,3070,4753,0,0]Al[3096,15,3097,1120,3045,0,0]Al[3096,15,3097,1125,3258,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Ah[463,10,1693,1694,0,0,0]Af[3096,10,1694,0,0,0,0]Al[3096,15,3097,1756,4460,0,0]Ag[463,5,1693,1694,0,0,0]Ae[3096,5,1694,0,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Ag[463,5,3635,2358,0,0,0]Ah[3096,5,3636,2358,0,0,0]Al[1095,15,1096,1096,4851,0,0]Af[463,5,464,3640,0,0,0]5454Ag[463,10,464,1994,0,0,0];:Aj[463,15,464,4041,3257,0,0]Af[463,5,464,4041,0,0,0]Al[3096,15,3097,1125,3258,0,0]Al[3096,15,3097,1125,3942,0,0]Al[3096,15,3097,2002,3961,0,0]Ah[3096,5,3097,2002,0,0,0]Aj[463,15,464,4036,4355,0,0]Al[3096,15,3097,1356,3224,0,0]Af[463,5,464,1125,0,0,0]Ah[3096,5,3097,1125,0,0,0]Al[3096,15,3097,1756,2267,0,0]Ag[463,12,464,0,4966,0,0]Al[3096,12,3097,4258,4967,0,0]Ao[3096,13,3097,4258,5097,4967,0]Ao[3096,13,3097,4258,5102,4967,0]Ak[1195,14,1196,1196,134,0,0]An[1195,13,1196,1196,134,4323,0]An[2358,13,2359,2359,125,4323,0]Ak[2358,14,2359,2359,125,0,0]Ao[1095,13,1096,1096,3015,4323,0]An[1095,13,1683,1683,135,4323,0]An[1095,13,1779,1779,136,4323,0]Aj[463,13,464,0,1443,3208,0]Aj[463,13,464,0,1426,3208,0]Aj[463,13,464,0,3943,3208,0]Aj[463,13,464,0,4082,3208,0]Ai[463,13,464,0,510,3208,0]Ai[463,13,464,0,126,3208,0]Aj[463,13,464,0,2281,3208,0]Ao[3096,13,3097,1810,1444,3208,0]Ao[3096,13,3097,3070,4753,3208,0]Ao[3096,13,3097,1366,1427,3208,0]Ao[3096,13,3097,1120,3045,3208,0]Ao[3096,13,3097,1120,4245,3208,0]Ao[3096,13,3097,1125,3258,3208,0]Ao[3096,13,3097,3194,3944,3208,0]Ao[3096,13,3097,2305,4651,3208,0]Ao[3096,13,3097,1756,4749,3208,0]Ao[3096,13,3097,1784,4083,3208,0]An[3096,13,3097,3097,511,3208,0]An[3096,13,3097,3097,127,3208,0]Ao[3096,13,3097,3097,2282,3208,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,2305,2260,0,0]Aj[463,13,464,2336,2263,0,0]Ah[463,12,1693,0,3035,0,0]Ah[463,12,1693,0,3028,0,0]Al[3096,13,3097,2305,2264,0,0]Al[3096,12,1694,1694,3036,0,0]Al[3096,12,1694,1694,3029,0,0]Ao[1195,13,1380,1380,3962,1826,0]Ao[1195,13,1380,1380,1189,1826,0]Al[519,13,520,520,3931,1826,0]Aj[463,13,464,0,4210,1826,0]Am[463,13,464,2304,4219,1826,0]Aj[463,13,464,0,1443,1826,0]Aj[463,13,464,0,1426,1826,0]Aj[463,13,464,0,2294,1826,0]Aj[463,13,464,0,3217,1826,0]Aj[463,13,464,0,3041,1826,0]Aj[463,13,464,0,4451,1826,0]Aj[463,13,464,0,1867,1826,0]Aj[463,13,464,0,4073,1826,0]Aj[463,13,464,0,4470,1826,0]Aj[463,13,464,0,4776,1826,0]Aj[463,13,464,0,4791,1826,0]Aj[463,13,464,0,3943,1826,0]Aj[463,13,464,0,4331,1826,0]Aj[463,13,464,0,4975,1826,0]Aj[463,13,464,0,4678,1826,0]Ak[463,13,3635,0,3012,1826,0]Ak[463,13,3635,0,3938,1826,0]Ak[463,13,3635,0,4237,1826,0]Ak[463,13,3635,0,4740,1826,0]Ao[3096,13,3097,4480,4211,1826,0]Ao[3096,13,3097,4258,5097,1826,0]Ao[3096,13,3097,1810,1444,1826,0]Ao[3096,13,3097,1366,1427,1826,0]Ao[3096,13,3097,1366,3233,1826,0]Ao[3096,13,3097,1366,3207,1826,0]Ao[3096,13,3097,1381,2295,1826,0]Ao[3096,13,3097,1381,3218,1826,0]Ao[3096,13,3097,1381,3042,1826,0]Ao[3096,13,3097,1381,4452,1826,0]Ao[3096,13,3097,1125,1868,1826,0]Ao[3096,13,3097,2002,4356,1826,0]Ao[3096,13,3097,2002,4077,1826,0]Ao[3096,13,3097,3194,4471,1826,0]Ao[3096,13,3097,3194,4777,1826,0]Ao[3096,13,3097,3194,4792,1826,0]Ao[3096,13,3097,3194,3944,1826,0]Ao[3096,13,3097,1691,4332,1826,0]Ao[3096,13,3097,1691,4976,1826,0]Ao[3096,13,3097,4258,5102,1826,0]Ao[3096,13,3097,4847,4679,1826,0]An[3096,13,3636,148,3013,1826,0]Ao[3096,13,3636,1352,3939,1826,0]Ao[3096,13,3636,2358,4238,1826,0]Ao[3096,13,3636,3636,4741,1826,0]Ao[1985,13,1986,1986,2279,1826,0]Ao[1095,13,1382,1382,1190,1826,0]Ao[1095,13,1382,1382,4456,1826,0]Al[3096,13,3097,1784,4218,0,0]Al[3096,13,3097,1756,4240,0,0]Al[3096,13,3097,1756,4460,0,0]Al[3096,14,3097,1756,5008,0,0]Ai[3096,14,4748,0,4813,0,0]Ah[3096,14,4459,0,499,0,0]Ai[3096,14,4459,0,1184,0,0]Ai[3096,14,4459,0,1186,0,0]Ai[3096,14,4459,0,4683,0,0]Ah[463,12,1693,0,3035,0,0]Ah[463,12,1693,0,3028,0,0]Al[3096,12,1694,1694,3036,0,0]Al[3096,12,1694,1694,3029,0,0]Aj[463,13,464,4036,3237,0,0]Aj[463,13,464,4036,4859,0,0]Ah[463,13,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,13,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Ag[463,13,464,0,4470,0,0]Al[3096,13,3097,3194,4471,0,0]Ab[1985,3,0,0,0,0,0]:965Aj[463,13,464,3640,3211,0,0]Aj[463,13,464,1094,2275,0,0]Al[3096,14,3097,1756,5008,0,0]Ai[3096,14,4748,0,4813,0,0]Ah[3096,14,4459,0,499,0,0]Ai[3096,14,4459,0,1184,0,0]Ai[3096,14,4459,0,4683,0,0]Aj[463,13,464,4041,3243,0,0]Al[3096,13,3097,2002,3244,0,0]Ak[1195,14,1196,1196,134,0,0]Al[1195,14,1380,1380,1189,0,0]Al[3096,13,3097,3641,3212,0,0]Ah[463,12,1693,0,3035,0,0]Al[3096,12,1694,1694,3036,0,0]Am[1195,13,1196,1196,134,118,0]An[1195,13,1196,1196,3954,118,0]An[1195,13,1196,1196,3930,118,0]An[1195,13,1380,1380,3962,118,0]An[1195,13,1380,1380,1189,118,0]An[1195,13,1380,1380,4357,118,0]Ak[519,13,520,520,3931,118,0]An[3968,13,3969,3969,5009,118,0]Al[463,13,464,3640,4475,118,0]Al[463,13,464,3640,2274,118,0]Ai[463,13,464,0,4210,118,0]Al[463,13,464,4144,4915,118,0]Al[463,13,464,1094,2275,118,0]Al[463,13,464,1094,4643,118,0]Al[463,13,464,3640,3209,118,0]Al[463,13,464,3640,3211,118,0]Al[463,13,464,3640,1843,118,0]Al[463,13,464,3640,1419,118,0]Al[463,13,464,3640,3004,118,0]Al[463,13,464,3640,2247,118,0]Al[463,13,464,3640,4108,118,0]Al[463,13,464,3640,4113,118,0]Al[463,13,464,3640,4921,118,0]Al[463,13,464,3640,4752,118,0]Al[463,13,464,2304,2259,118,0]Al[463,13,464,2304,4219,118,0]Al[463,13,464,2304,1399,118,0]Al[463,13,464,4144,1418,118,0]Al[463,13,464,4144,3231,118,0]Al[463,13,464,4144,4852,118,0]Al[463,13,464,2336,2263,118,0]Al[463,13,464,2336,3240,118,0]Al[463,13,464,2336,4336,118,0]Ak[463,13,464,1094,503,118,0]Al[463,13,464,1094,4362,118,0]Al[463,13,464,4036,3237,118,0]Al[463,13,464,4036,4859,118,0]Al[463,13,464,4036,4355,118,0]Al[463,13,464,4036,3044,118,0]Al[463,13,464,4036,3239,118,0]Al[463,13,464,4036,4354,118,0]Al[463,13,464,1393,4123,118,0]Al[463,13,464,1137,3957,118,0]Al[463,13,464,4041,3243,118,0]Al[463,13,464,4041,3257,118,0]Al[463,13,464,4041,4122,118,0]Al[463,13,464,4041,1857,118,0]Ai[463,13,464,0,3234,118,0]Ai[463,13,464,0,4249,118,0]Ai[463,13,464,0,4467,118,0]Ai[463,13,464,0,4100,118,0]Ai[463,13,464,0,4345,118,0]Ai[463,13,464,0,1443,118,0]Ai[463,13,464,0,4918,118,0]Ai[463,13,464,0,1152,118,0]Ai[463,13,464,0,1426,118,0]Ai[463,13,464,0,2294,118,0]Ai[463,13,464,0,3217,118,0]Ai[463,13,464,0,3041,118,0]Ai[463,13,464,0,4451,118,0]Ai[463,13,464,0,1867,118,0]Ai[463,13,464,0,4073,118,0]Ai[463,13,464,0,4447,118,0]Ai[463,13,464,0,4461,118,0]Ai[463,13,464,0,4470,118,0]Ai[463,13,464,0,4776,118,0]Ai[463,13,464,0,4791,118,0]Ai[463,13,464,0,3943,118,0]Ai[463,13,464,0,4331,118,0]Ai[463,13,464,0,4116,118,0]Ai[463,13,464,0,4975,118,0]Ai[463,13,464,0,4067,118,0]Ai[463,13,464,0,3933,118,0]Ai[463,13,464,0,3025,118,0]Ai[463,13,464,0,4444,118,0]Ai[463,13,464,0,4645,118,0]Ai[463,13,464,0,4079,118,0]Ai[463,13,464,0,4082,118,0]Ai[463,13,464,0,4087,118,0]Ai[463,13,464,0,4811,118,0]Ai[463,13,464,0,3220,118,0]Ai[463,13,464,0,4678,118,0]Ah[463,13,464,0,510,118,0]Ah[463,13,464,0,126,118,0]Ai[463,13,464,0,2281,118,0]Ai[463,13,464,0,2291,118,0]Ai[463,13,3635,0,120,118,0]Aj[463,13,3635,0,3012,118,0]Aj[463,13,3635,0,1156,118,0]Aj[463,13,3635,0,3938,118,0]Aj[463,13,3635,0,1840,118,0]Aj[463,13,3635,0,4237,118,0]Aj[463,13,3635,0,4740,118,0]Aj[463,13,1693,0,1835,118,0]Ai[463,13,1693,0,497,118,0]Aj[463,13,1693,0,5067,118,0]Aj[463,13,1693,0,3936,118,0]Aj[463,13,1693,0,4815,118,0]Aj[463,13,1773,0,3252,118,0]Aj[463,13,1773,0,4221,118,0]Aj[463,13,1773,0,1169,118,0]Aj[463,13,1773,0,4674,118,0]Aj[463,13,1773,0,4913,118,0]Aj[463,13,1773,0,4676,118,0]Am[2358,13,2359,2359,125,118,0]An[2358,13,2359,2359,2250,118,0]An[3096,13,3097,4480,4211,118,0]An[3096,13,3097,3070,3018,118,0]An[3096,13,3097,1120,1407,118,0]An[3096,13,3097,2002,1861,118,0]An[3096,13,3097,2002,3238,118,0]An[3096,13,3097,2002,3244,118,0]An[3096,13,3097,3641,3212,118,0]An[3096,13,3097,1116,3235,118,0]An[3096,13,3097,1691,4250,118,0]An[3096,13,3097,2305,2260,118,0]An[3096,13,3097,2305,4217,118,0]An[3096,13,3097,2305,4654,118,0]An[3096,13,3097,2305,4228,118,0]An[3096,13,3097,1756,5127,118,0]An[3096,13,3097,4258,5097,118,0]An[3096,13,3097,1392,4468,118,0]An[3096,13,3097,1392,4101,118,0]An[3096,13,3097,1392,4346,118,0]An[3096,13,3097,1810,1444,118,0]An[3096,13,3097,1810,4919,118,0]An[3096,13,3097,3061,1153,118,0]An[3096,13,3097,3070,4753,118,0]An[3096,13,3097,1366,1427,118,0]An[3096,13,3097,1366,4112,118,0]An[3096,13,3097,1366,3233,118,0]An[3096,13,3097,1366,3040,118,0]An[3096,13,3097,1366,4751,118,0]An[3096,13,3097,1366,4807,118,0]An[3096,13,3097,1366,3207,118,0]An[3096,13,3097,1381,2295,118,0]An[3096,13,3097,1381,3218,118,0]An[3096,13,3097,1381,3042,118,0]An[3096,13,3097,1381,4452,118,0]An[3096,13,3097,1120,3045,118,0]An[3096,13,3097,1120,4245,118,0]An[3096,13,3097,1125,1868,118,0]An[3096,13,3097,1125,3258,118,0]An[3096,13,3097,1125,3942,118,0]An[3096,13,3097,2002,3961,118,0]An[3096,13,3097,2002,4356,118,0]An[3096,13,3097,2002,4077,118,0]An[3096,13,3097,3641,4448,118,0]An[3096,13,3097,3641,3038,118,0]An[3096,13,3097,3641,4322,118,0]An[3096,13,3097,3641,5004,118,0]An[3096,13,3097,3641,1174,118,0]An[3096,13,3097,1116,4462,118,0]An[3096,13,3097,3194,4471,118,0]An[3096,13,3097,3194,4777,118,0]An[3096,13,3097,3194,4792,118,0]An[3096,13,3097,3194,3944,118,0]An[3096,13,3097,1691,4332,118,0]An[3096,13,3097,1691,4118,118,0]An[3096,13,3097,1691,4976,118,0]An[3096,13,3097,1691,4069,118,0]An[3096,13,3097,1691,3934,118,0]An[3096,13,3097,1356,3026,118,0]An[3096,13,3097,1356,4337,118,0]An[3096,13,3097,1356,3224,118,0]An[3096,13,3097,1356,3247,118,0]An[3096,13,3097,1356,4084,118,0]An[3096,13,3097,1356,4446,118,0]An[3096,13,3097,1356,4647,118,0]An[3096,13,3097,1356,2253,118,0]An[3096,13,3097,2305,4651,118,0]An[3096,13,3097,2305,2264,118,0]An[3096,13,3097,2305,4080,118,0]An[3096,13,3097,2305,3928,118,0]An[3096,13,3097,2305,3241,118,0]An[3096,13,3097,1756,4240,118,0]An[3096,13,3097,1756,4460,118,0]An[3096,13,3097,1756,5008,118,0]An[3096,13,3097,1756,2267,118,0]An[3096,13,3097,1756,4749,118,0]An[3096,13,3097,1784,4450,118,0]An[3096,13,3097,1784,4218,118,0]An[3096,13,3097,1784,4083,118,0]An[3096,13,3097,1784,4088,118,0]Ak[3096,13,3097,0,4360,118,0]Ak[3096,13,3097,0,4812,118,0]An[3096,13,3097,4258,3221,118,0]An[3096,13,3097,4258,5102,118,0]An[3096,13,3097,4847,4679,118,0]Am[3096,13,3097,3097,511,118,0]Am[3096,13,3097,3097,127,118,0]An[3096,13,3097,3097,2282,118,0]An[3096,13,3097,3097,2292,118,0]An[3096,13,3097,3097,3024,118,0]An[3096,13,1689,1689,4251,118,0]An[3096,13,4960,4960,4858,118,0]An[3096,13,4960,4960,1171,118,0]An[3096,13,1694,1694,1836,118,0]Am[3096,13,1694,1694,498,118,0]An[3096,13,1694,1694,5068,118,0]An[3096,13,1694,1694,3937,118,0]An[3096,13,1694,1694,4818,118,0]An[3096,13,1774,1774,3253,118,0]An[3096,13,1774,1774,4222,118,0]Ak[3096,13,1774,0,1170,118,0]An[3096,13,1774,1774,4675,118,0]An[3096,13,1774,1774,4914,118,0]An[3096,13,1774,1774,4677,118,0]Al[3096,13,3636,148,121,118,0]Am[3096,13,3636,148,3013,118,0]An[3096,13,3636,1352,1157,118,0]An[3096,13,3636,1352,3939,118,0]An[3096,13,3636,2358,1841,118,0]An[3096,13,3636,2358,4238,118,0]An[3096,13,3636,3636,4741,118,0]An[3096,13,4709,4709,1172,118,0]An[3096,13,4709,4709,1175,118,0]An[1985,13,1986,1986,3256,118,0]Am[1985,13,1986,416,4361,118,0]An[1985,13,1986,1986,2279,118,0]An[1985,13,1986,1986,2293,118,0]An[1985,13,1986,1986,4089,118,0]An[1095,13,1096,1096,3015,118,0]An[1095,13,1096,1096,4851,118,0]Am[1095,13,1683,1683,135,118,0]An[1095,13,1382,1382,1190,118,0]An[1095,13,1382,1382,3963,118,0]An[1095,13,1382,1382,4456,118,0]An[1095,13,4178,4178,5053,118,0]An[1095,13,4178,4178,5054,118,0]Am[1095,13,1779,1779,136,118,0]Aj[463,13,464,3640,4921,0,0]Aj[463,13,464,1094,4362,0,0]Ag[463,13,464,0,4067,0,0]Al[3096,13,3097,1691,4069,0,0]Al[3096,14,3097,1756,5008,0,0]Ai[3096,14,4748,0,4813,0,0]Ah[3096,14,4459,0,499,0,0]Ai[3096,14,4459,0,1184,0,0]Af[463,5,464,3640,0,0,0]Al[1195,15,1196,1196,3930,0,0]Ae[2358,6,2359,0,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1356,0,0,0]Aj[463,15,464,3640,4752,0,0]Al[3096,15,3097,3070,4753,0,0]Af[463,5,464,2304,0,0,0]Ah[3096,5,3097,2305,0,0,0]Al[3096,15,3097,2002,3961,0,0]Af[463,5,464,2336,0,0,0]2Ah[3096,6,3097,1756,0,0,0]Ag[463,19,464,0,1443,0,0]Al[3096,19,3097,1810,1444,0,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]=Ah[463,12,1693,0,4117,0,0]>Ak[463,13,1773,0,4676,4117,0]>Al[3096,12,1694,1694,4119,0,0]>Ao[3096,13,1774,1774,4677,4119,0]Ao[1095,13,4178,4178,5054,4119,0]An[2358,13,2359,2359,125,3945,0]Ao[2358,13,2359,2359,2250,3945,0]Ag[463,14,464,0,3041,0,0]Ag[463,14,464,0,4451,0,0]Al[3096,14,3097,1381,3042,0,0]Al[3096,14,3097,1381,4452,0,0]Ag[463,13,464,0,4116,0,0]Al[3096,13,3097,1691,4118,0,0]Aj[463,13,464,1994,4319,0,0]0Ak[1985,13,1986,416,4361,0,0]Al[3096,13,3097,3641,3212,0,0]Al[1095,13,1382,1382,4456,0,0]Ae[1095,2,1096,0,0,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2264,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]6Ag[463,13,464,0,4470,0,0]Al[3096,13,3097,3194,4471,0,0]32Ak[1195,14,1196,1196,134,0,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Al[1985,14,1986,1986,2293,0,0]Al[3096,13,3097,2002,1861,0,0]Al[3096,13,3097,4258,5097,0,0]Al[3096,13,3097,4258,5102,0,0]Aj[463,13,464,4041,3243,0,0]Al[3096,13,3097,2002,3244,0,0]<;Al[1195,14,1380,1380,1189,0,0]Ai[519,14,520,520,3931,0,0]Ah[463,13,1773,0,4674,0,0]Ah[463,13,1773,0,4676,0,0]Al[3096,13,1774,1774,4675,0,0]Al[3096,13,1774,1774,4677,0,0]76Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Af[463,5,464,4480,0,0,0]Ah[3096,5,3097,4480,0,0,0]Ag[463,15,464,0,4447,0,0]Ag[463,15,464,0,4079,0,0]Al[3096,15,3097,3641,4448,0,0]Al[3096,15,3097,2305,4080,0,0]Ah[3096,6,3097,2305,0,0,0]Ah[3096,5,3097,1784,0,0,0]Af[463,5,464,2304,0,0,0]Aj[463,15,464,4036,4354,0,0]Ag[463,5,1773,1774,0,0,0]Ae[3096,5,1774,0,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]Ah[3096,5,3097,2305,0,0,0]Al[3096,15,3097,1756,4749,0,0]?=5454Al[3096,15,3097,2305,4217,0,0]Ag[463,5,3635,2358,0,0,0]Ah[3096,5,3636,2358,0,0,0]Ah[3096,5,3097,1756,0,0,0]98Ah[3096,6,3097,1120,0,0,0]:9Af[463,5,464,1691,0,0,0]Ah[3096,5,3097,1691,0,0,0]Ae[3096,5,1689,0,0,0,0]Al[3096,13,3097,3641,3212,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]Al[1095,14,1096,1096,3015,0,0]Ae[3096,2,3097,0,0,0,0]Ag[463,13,464,0,4331,0,0]Al[3096,13,3097,1691,4332,0,0]Aj[463,12,464,1994,4319,0,0]Ab[4261,3,0,0,0,0,0]Ak[1195,14,1196,1196,134,0,0]Al[1195,14,1380,1380,3962,0,0]98Aj[463,13,464,2336,3240,0,0]Al[3096,13,3097,2305,3241,0,0]Ag[463,13,464,0,4776,0,0]Al[3096,13,3097,3194,4777,0,0];=Al[1195,14,1380,1380,1189,0,0]Ao[1095,13,1096,1096,4851,3050,0]Ag[463,15,464,0,3025,0,0]Af[463,5,464,1356,0,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1356,0,0,0]Af[463,6,464,3641,0,0,0]Ah[3096,6,3097,3641,0,0,0]Al[3096,15,3097,2305,4217,0,0]Ah[3096,5,3097,1784,0,0,0]Af[463,5,464,1381,0,0,0]Ah[3096,5,3097,1381,0,0,0]97Ae[1095,5,1382,0,0,0,0]:8Ah[3096,6,3097,1756,0,0,0]Af[463,5,464,1116,0,0,0]Ah[3096,5,3097,1116,0,0,0]Al[3096,15,3097,1366,4751,0,0]Af[463,5,464,1392,0,0,0]Ah[3096,5,3097,1392,0,0,0]Af[463,5,464,3194,0,0,0]Ah[3096,5,3097,3194,0,0,0]Ag[463,15,464,0,4447,0,0]Al[3096,15,3097,3641,4448,0,0]Af[463,5,464,3640,0,0,0]Aj[463,15,464,4036,3044,0,0]Aj[463,15,464,4036,3239,0,0]Aj[463,15,464,4041,3257,0,0]Aj[463,15,464,4041,4122,0,0]An[1195,13,1196,1196,134,4216,0]Ao[1195,13,1196,1196,3954,4216,0]Ao[1195,13,1196,1196,3930,4216,0]Am[463,13,464,3640,3211,4216,0]Am[463,13,464,3640,4921,4216,0]Am[463,13,464,3640,4752,4216,0]Am[463,13,464,2304,2259,4216,0]Am[463,13,464,2304,4219,4216,0]Am[463,13,464,4144,1418,4216,0]Al[463,13,464,1094,503,4216,0]Am[463,13,464,1094,4362,4216,0]Am[463,13,464,4036,4355,4216,0]Am[463,13,464,4036,3044,4216,0]Am[463,13,464,4036,3239,4216,0]Am[463,13,464,4036,4354,4216,0]Am[463,13,464,4041,3257,4216,0]Am[463,13,464,4041,4122,4216,0]Aj[463,13,464,0,1443,4216,0]Aj[463,13,464,0,4918,4216,0]Aj[463,13,464,0,1426,4216,0]Aj[463,13,464,0,2294,4216,0]Aj[463,13,464,0,3217,4216,0]Aj[463,13,464,0,3041,4216,0]Aj[463,13,464,0,4451,4216,0]Aj[463,13,464,0,1867,4216,0]Aj[463,13,464,0,4073,4216,0]Aj[463,13,464,0,4447,4216,0]Aj[463,13,464,0,4470,4216,0]Aj[463,13,464,0,4776,4216,0]Aj[463,13,464,0,4791,4216,0]Aj[463,13,464,0,3943,4216,0]Aj[463,13,464,0,4331,4216,0]Aj[463,13,464,0,4116,4216,0]Aj[463,13,464,0,4975,4216,0]Aj[463,13,464,0,4067,4216,0]Aj[463,13,464,0,3933,4216,0]Aj[463,13,464,0,3025,4216,0]Aj[463,13,464,0,4444,4216,0]Aj[463,13,464,0,4645,4216,0]Aj[463,13,464,0,4079,4216,0]Aj[463,13,464,0,4082,4216,0]Aj[463,13,464,0,4087,4216,0]Aj[463,13,464,0,4811,4216,0]Aj[463,13,464,0,3220,4216,0]Ai[463,13,464,0,510,4216,0]Ai[463,13,464,0,126,4216,0]Aj[463,13,464,0,2281,4216,0]Aj[463,13,3635,0,120,4216,0]Ak[463,13,3635,0,3012,4216,0]Ak[463,13,3635,0,1156,4216,0]Ak[463,13,3635,0,3938,4216,0]Ak[463,13,3635,0,1840,4216,0]Ak[463,13,3635,0,4237,4216,0]Ak[463,13,1773,0,1169,4216,0]Ak[463,13,1773,0,4674,4216,0]Ak[463,13,1773,0,4913,4216,0]Ak[463,13,1773,0,4676,4216,0]Ao[3096,13,3097,1810,1444,4216,0]Ao[3096,13,3097,1810,4919,4216,0]Ao[3096,13,3097,3070,4753,4216,0]Ao[3096,13,3097,1366,1427,4216,0]Ao[3096,13,3097,1366,4112,4216,0]Ao[3096,13,3097,1366,3233,4216,0]Ao[3096,13,3097,1366,3040,4216,0]Ao[3096,13,3097,1366,4751,4216,0]Ao[3096,13,3097,1366,4807,4216,0]Ao[3096,13,3097,1366,3207,4216,0]Ao[3096,13,3097,1381,2295,4216,0]Ao[3096,13,3097,1381,3218,4216,0]Ao[3096,13,3097,1381,3042,4216,0]Ao[3096,13,3097,1381,4452,4216,0]Ao[3096,13,3097,1120,3045,4216,0]Ao[3096,13,3097,1120,4245,4216,0]Ao[3096,13,3097,1125,1868,4216,0]Ao[3096,13,3097,1125,3258,4216,0]Ao[3096,13,3097,1125,3942,4216,0]Ao[3096,13,3097,2002,4356,4216,0]Ao[3096,13,3097,2002,4077,4216,0]Ao[3096,13,3097,3641,4448,4216,0]Ao[3096,13,3097,3641,3038,4216,0]Ao[3096,13,3097,3641,4322,4216,0]Ao[3096,13,3097,3641,5004,4216,0]Ao[3096,13,3097,3194,4471,4216,0]Ao[3096,13,3097,3194,4777,4216,0]Ao[3096,13,3097,3194,4792,4216,0]Ao[3096,13,3097,3194,3944,4216,0]Ao[3096,13,3097,1691,4332,4216,0]Ao[3096,13,3097,1691,4118,4216,0]Ao[3096,13,3097,1691,4976,4216,0]Ao[3096,13,3097,1691,4069,4216,0]Ao[3096,13,3097,1691,3934,4216,0]Ao[3096,13,3097,1356,3026,4216,0]Ao[3096,13,3097,1356,3224,4216,0]Ao[3096,13,3097,1356,3247,4216,0]Ao[3096,13,3097,1356,4084,4216,0]Ao[3096,13,3097,1356,4446,4216,0]Ao[3096,13,3097,1356,4647,4216,0]Ao[3096,13,3097,1356,2253,4216,0]Ao[3096,13,3097,2305,4651,4216,0]Ao[3096,13,3097,2305,4080,4216,0]Ao[3096,13,3097,1756,4460,4216,0]Ao[3096,13,3097,1756,5008,4216,0]Ao[3096,13,3097,1756,2267,4216,0]Ao[3096,13,3097,1756,4749,4216,0]Ao[3096,13,3097,1784,4083,4216,0]Ao[3096,13,3097,1784,4088,4216,0]Al[3096,13,3097,0,4360,4216,0]Al[3096,13,3097,0,4812,4216,0]Ao[3096,13,3097,4258,3221,4216,0]Ao[3096,13,3097,4258,5102,4216,0]An[3096,13,3097,3097,511,4216,0]An[3096,13,3097,3097,127,4216,0]Ao[3096,13,3097,3097,2282,4216,0]Ao[3096,13,3097,3097,3024,4216,0]Ao[3096,13,1689,1689,4251,4216,0]Ao[3096,13,4960,4960,4858,4216,0]Ao[3096,13,4960,4960,1171,4216,0]Al[3096,13,1774,0,1170,4216,0]Ao[3096,13,1774,1774,4675,4216,0]Ao[3096,13,1774,1774,4914,4216,0]Ao[3096,13,1774,1774,4677,4216,0]Am[3096,13,3636,148,121,4216,0]An[3096,13,3636,148,3013,4216,0]Ao[3096,13,3636,1352,1157,4216,0]Ao[3096,13,3636,1352,3939,4216,0]Ao[3096,13,3636,2358,1841,4216,0]Ao[3096,13,3636,2358,4238,4216,0]Ao[3096,13,4709,4709,1175,4216,0]Ao[1985,13,1986,1986,2279,4216,0]Ao[1985,13,1986,1986,2293,4216,0]Ao[1985,13,1986,1986,4089,4216,0]Ao[1095,13,1096,1096,4851,4216,0]Ao[1095,13,1382,1382,4456,4216,0]Ao[1095,13,4178,4178,5053,4216,0]Ao[1095,13,4178,4178,5054,4216,0]Af[463,7,464,1994,0,0,0]Ag[463,13,464,0,4331,0,0]Al[3096,13,3097,1691,4332,0,0]Ah[463,12,1693,0,3035,0,0]Al[3096,12,1694,1694,3036,0,0]Al[1985,14,1986,1986,2279,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]10Ae[1095,7,1096,0,0,0,0]Aj[463,13,464,2304,2259,0,0]Ae[4261,7,4262,0,0,0,0]Ae[1195,7,1196,0,0,0,0]Al[3096,13,3097,3641,3212,0,0]Aj[463,13,464,3640,3211,0,0]1Al[3096,13,3097,2002,4356,0,0]Al[1195,13,1380,1380,1189,0,0]Al[1195,14,1380,1380,3962,0,0]Aj[463,12,464,1994,1852,0,0]Am[463,13,464,1393,4123,1852,0]Am[463,13,464,1137,3957,1852,0]Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Af[463,5,464,1094,0,0,0]Ag[463,15,464,0,3025,0,0]Af[463,5,464,1356,0,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1356,0,0,0]Ag[463,15,464,0,4447,0,0]Al[3096,15,3097,3641,4448,0,0]Ah[3096,5,3097,2305,0,0,0]Al[3096,15,3097,3641,1174,0,0]1Ag[463,15,464,0,4079,0,0]Al[3096,15,3097,2305,4080,0,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]32Al[3096,15,3097,3641,3038,0,0]><><><21Ag[463,5,1773,1774,0,0,0]Ae[3096,5,1774,0,0,0,0]10Af[463,5,464,4847,0,0,0]Ah[3096,5,3097,4847,0,0,0]Al[3096,15,4709,4709,1172,0,0]Al[3096,15,3097,1366,4751,0,0]6Al[3096,15,3097,1756,4460,0,0]Ag[463,12,464,0,2287,0,0]Aj[463,13,464,0,4210,2287,0]Aj[463,13,464,0,4100,2287,0]Al[3096,12,3097,1392,2288,0,0]Ao[3096,13,3097,4480,4211,2288,0]Ao[3096,13,3097,1392,4101,2288,0]Ae[3968,7,3969,0,0,0,0]Aj[463,13,464,3640,3211,0,0]Al[3096,13,3097,3641,3212,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]32An[1195,13,1196,1196,134,4333,0]An[2358,13,2359,2359,125,4333,0]Ao[2358,13,2359,2359,2250,4333,0]Ao[1095,13,1096,1096,3015,4333,0]An[1095,13,1683,1683,135,4333,0]An[1095,13,1779,1779,136,4333,0]Ak[1985,13,1986,416,4361,0,0]Ag[463,13,464,0,4470,0,0]Al[3096,13,3097,3194,4471,0,0]:9Ae[3096,2,3097,0,0,0,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,2305,2260,0,0]?>43Ae[4261,7,4262,0,0,0,0]6Al[1095,14,1096,1096,3015,0,0]70Ae[1195,7,1196,0,0,0,0]Ag[463,13,464,0,4116,0,0]Ag[463,13,464,0,4067,0,0]Al[3096,13,3097,1691,4118,0,0]Al[3096,13,3097,1691,4069,0,0]Ag[463,14,464,0,4116,0,0]Al[3096,14,3097,1691,4118,0,0]53Aj[463,13,464,4041,3243,0,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]Ag[463,15,464,0,4447,0,0]Al[3096,15,3097,1366,4751,0,0]Al[3096,15,3097,3641,4448,0,0]Ah[463,10,3635,3636,0,0,0]Af[3096,10,3636,0,0,0,0]Ag[463,5,3635,3636,0,0,0]Ae[3096,5,3636,0,0,0,0]Ah[463,10,1693,1694,0,0,0]Af[3096,10,1694,0,0,0,0]Ag[463,15,464,0,4079,0,0]Al[3096,15,3097,2305,4080,0,0]Ag[463,10,464,3641,0,0,0]Ai[3096,10,3097,3641,0,0,0]Ah[3096,6,3097,1756,0,0,0]Ah[3096,6,3097,1366,0,0,0]Af[463,6,464,3640,0,0,0]Ah[3096,6,3097,3070,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]10Aj[463,15,464,3640,4752,0,0]Al[3096,15,3097,3070,4753,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1381,3042,0,0]Ah[463,14,3635,0,4740,0,0]Al[3096,14,3636,3636,4741,0,0]Aj[463,13,464,3640,3211,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]10Al[3096,13,3097,3070,3018,0,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,2305,2260,0,0]Ab[4771,3,0,0,0,0,0]Ao[1095,13,1096,1096,4851,3050,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]Af[463,5,464,3194,0,0,0]Ah[3096,5,3097,3194,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]54Ai[3096,10,3097,1756,0,0,0]Al[3096,15,3097,3641,1174,0,0]7600Al[3096,15,3097,1120,4245,0,0]4365Al[3096,15,4709,4709,1172,0,0]Ae[1095,9,1096,0,0,0,0]:9Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]<;<;Ah[3096,6,3097,1366,0,0,0]21Al[1195,15,1196,1196,3954,0,0]Ac[463,5,464,0,0,0,0]Ae[3096,5,3097,0,0,0,0]Ag[463,15,464,0,4079,0,0]Ag[463,5,1693,1694,0,0,0]Al[3096,15,3097,2305,4080,0,0]Al[3096,15,3097,1756,4749,0,0]Ae[3096,5,1694,0,0,0,0]An[1195,13,1196,1196,134,4323,0]An[2358,13,2359,2359,125,4323,0]Ao[1095,13,1096,1096,3015,4323,0]An[1095,13,1683,1683,135,4323,0]An[1095,13,1779,1779,136,4323,0]Ag[463,13,464,0,4470,0,0]Al[3096,13,3097,3194,4471,0,0]Ag[463,13,464,0,1443,0,0]Al[3096,13,3097,1810,1444,0,0]Aj[463,14,464,2304,4219,0,0]Aj[463,13,464,3640,4921,0,0]Ag[463,13,464,0,4331,0,0]Al[3096,13,3097,1691,4332,0,0]Ag[463,13,464,0,4210,0,0]Al[3096,13,3097,4480,4211,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]7Al[3096,13,3097,3641,3212,0,0]Aj[463,13,464,3640,3211,0,0]Ah[463,13,1773,0,4674,0,0]Ah[463,13,1773,0,4676,0,0]Al[3096,13,1774,1774,4675,0,0]Al[3096,13,1774,1774,4677,0,0]45;:Ao[3968,13,3969,3969,5009,4805,0]Ag[463,13,464,0,4461,0,0]Al[3096,13,3097,1116,4462,0,0]Ae[1095,6,1096,0,0,0,0]Af[463,5,464,4144,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]10Al[3096,15,3097,3641,3038,0,0]Ae[3096,5,4960,0,0,0,0]Af[463,5,464,4036,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Al[3096,15,4709,4709,1172,0,0]Aj[463,14,464,2304,4219,0,0]Ai[463,13,464,0,510,3006,0]Ai[463,13,464,0,126,3006,0]An[3096,13,3097,3097,511,3006,0]An[3096,13,3097,3097,127,3006,0]Ao[2358,13,2359,2359,2250,3248,0]Ag[463,13,464,0,4791,0,0]Al[3096,13,3097,3194,4792,0,0]Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Aj[463,13,464,3640,3211,0,0]Ag[463,12,464,0,4746,0,0]Al[3096,12,3097,3641,4747,0,0]Ag[463,13,464,0,4470,0,0]Al[3096,13,3097,3194,4471,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1381,3042,0,0]Ah[463,12,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,12,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Aj[463,14,464,2304,4219,0,0]Al[3096,13,3097,2002,1861,0,0]Ah[3096,2,4256,4040,0,0,0]Ae[1195,7,1196,0,0,0,0]==Ai[463,13,464,1094,503,0,0]Ak[1985,13,1986,416,4361,0,0]032Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Ae[3096,2,3097,0,0,0,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Ag[463,10,464,4258,0,0,0]Ai[3096,10,3097,4258,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Ag[463,15,464,0,4079,0,0]Al[3096,15,3097,2305,4080,0,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]Af[463,5,464,1691,0,0,0]Ah[3096,5,3097,1691,0,0,0]Ah[463,12,1693,0,3035,0,0]Al[3096,12,1694,1694,3036,0,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,3641,3212,0,0]Al[3096,13,3097,2305,2260,0,0]Al[3096,13,3097,3097,3024,0,0]Ah[463,13,3635,0,4237,0,0]Al[3096,13,3636,2358,4238,0,0]Aj[463,13,464,1994,3048,0,0]0Aj[463,13,464,3640,3211,0,0]6Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]Ag[463,13,464,0,4470,0,0]Al[3096,13,3097,3194,4471,0,0]Al[1095,14,1096,1096,3015,0,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]Al[3096,15,4709,4709,1172,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]10Al[3096,15,3097,1366,4807,0,0]Al[3096,15,3097,3641,3038,0,0]Al[3096,15,3097,3641,4322,0,0]Ah[3096,5,3097,3641,0,0,0]Al[3096,15,3097,1366,4751,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1756,0,0,0]Ae[3968,5,3969,0,0,0,0]Al[1095,13,1096,1096,3015,0,0]Aj[463,13,464,3640,3211,0,0]Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Ah[3096,7,4893,4892,0,0,0]0Al[3096,13,3097,3641,3212,0,0]6Ai[463,13,464,1094,503,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]Ao[3968,13,3969,3969,5009,4805,0]0Ag[463,13,464,0,4067,0,0]Al[3096,13,3097,1691,4069,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]10Ag[463,13,464,0,4776,0,0]Al[3096,13,3097,3194,4777,0,0]Am[1195,13,1196,1196,134,485,0]Am[2358,13,2359,2359,125,485,0]An[1095,13,1096,1096,3015,485,0]Am[1095,13,1683,1683,135,485,0]Am[1095,13,1779,1779,136,485,0]??>An[1195,13,1196,1196,134,4333,0]An[2358,13,2359,2359,125,4333,0]Ao[2358,13,2359,2359,2250,4333,0]Ao[1095,13,1096,1096,3015,4333,0]An[1095,13,1683,1683,135,4333,0]An[1095,13,1779,1779,136,4333,0]Ag[463,13,464,0,4116,0,0]Al[3096,13,3097,1691,4118,0,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]Ae[1095,5,4178,0,0,0,0]0Ag[463,13,464,0,4331,0,0]Al[3096,13,3097,1691,4332,0,0]Ag[463,13,464,0,4067,0,0]Al[3096,13,3097,1691,4069,0,0]Aj[463,13,464,2304,2259,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2264,0,0]Al[3096,13,3097,3641,3212,0,0]Ao[3968,13,3969,3969,5009,4805,0];:Ag[463,5,1693,1694,0,0,0]Ae[3096,5,1694,0,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]?>?>Aj[463,13,464,3640,3211,0,0]6Ag[463,13,464,0,4470,0,0]Al[3096,13,3097,3194,4471,0,0]Ae[3968,7,3969,0,0,0,0]Ae[4261,7,4262,0,0,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1381,3218,0,0]?434343>=>=Al[3096,14,4960,4960,4858,0,0]54Ai[3096,18,3097,3194,0,0,0]") \ No newline at end of file +rd_("Af[463,15,464,0,126,0,0]Ak[3096,15,3097,3097,127,0,0]Ag[463,15,464,0,4087,0,0]Al[3096,15,3097,1784,4088,0,0]Al[1985,15,1986,1986,4089,0,0]Al[3096,15,1689,1689,1433,0,0]Ao[1195,13,1196,1196,3930,3037,0]Am[463,13,464,3640,4752,3037,0]Am[463,13,464,4144,1418,3037,0]Al[463,13,464,1094,503,3037,0]Am[463,13,464,1094,4362,3037,0]Am[463,13,464,4036,4355,3037,0]Am[463,13,464,4036,3044,3037,0]Am[463,13,464,4036,3239,3037,0]Am[463,13,464,4036,4354,3037,0]Am[463,13,464,4041,3257,3037,0]Am[463,13,464,4041,4122,3037,0]Aj[463,13,464,0,1443,3037,0]Aj[463,13,464,0,4918,3037,0]Aj[463,13,464,0,1152,3037,0]Aj[463,13,464,0,1426,3037,0]Aj[463,13,464,0,2294,3037,0]Aj[463,13,464,0,3217,3037,0]Aj[463,13,464,0,3041,3037,0]Aj[463,13,464,0,1867,3037,0]Aj[463,13,464,0,4073,3037,0]Aj[463,13,464,0,4447,3037,0]Aj[463,13,464,0,3943,3037,0]Aj[463,13,464,0,3933,3037,0]Aj[463,13,464,0,3025,3037,0]Aj[463,13,464,0,4444,3037,0]Aj[463,13,464,0,4645,3037,0]Aj[463,13,464,0,4079,3037,0]Aj[463,13,464,0,4082,3037,0]Aj[463,13,464,0,4087,3037,0]Aj[463,13,464,0,4811,3037,0]Ai[463,13,464,0,510,3037,0]Ai[463,13,464,0,126,3037,0]Aj[463,13,464,0,2281,3037,0]Ak[463,13,1693,0,5067,3037,0]Ak[463,13,1773,0,1169,3037,0]Ao[3096,13,3097,1810,1444,3037,0]Ao[3096,13,3097,1810,4919,3037,0]Ao[3096,13,3097,3061,1153,3037,0]Ao[3096,13,3097,3070,4753,3037,0]Ao[3096,13,3097,1366,1427,3037,0]Ao[3096,13,3097,1366,3233,3037,0]Ao[3096,13,3097,1366,3040,3037,0]Ao[3096,13,3097,1366,4751,3037,0]Ao[3096,13,3097,1366,4807,3037,0]Ao[3096,13,3097,1366,3207,3037,0]Ao[3096,13,3097,1382,2295,3037,0]Ao[3096,13,3097,1382,3218,3037,0]Ao[3096,13,3097,1382,3042,3037,0]Ao[3096,13,3097,1120,3045,3037,0]Ao[3096,13,3097,1120,4245,3037,0]Ao[3096,13,3097,1125,1868,3037,0]Ao[3096,13,3097,1125,3258,3037,0]Ao[3096,13,3097,1125,3942,3037,0]Ao[3096,13,3097,2002,3961,3037,0]Ao[3096,13,3097,2002,4356,3037,0]Ao[3096,13,3097,2002,4077,3037,0]Ao[3096,13,3097,3641,4448,3037,0]Ao[3096,13,3097,3641,3038,3037,0]Ao[3096,13,3097,3641,4322,3037,0]Ao[3096,13,3097,3194,3944,3037,0]Ao[3096,13,3097,1691,3934,3037,0]Ao[3096,13,3097,1356,3026,3037,0]Ao[3096,13,3097,1356,4337,3037,0]Ao[3096,13,3097,1356,3224,3037,0]Ao[3096,13,3097,1356,3247,3037,0]Ao[3096,13,3097,1356,4084,3037,0]Ao[3096,13,3097,1356,4446,3037,0]Ao[3096,13,3097,1356,4647,3037,0]Ao[3096,13,3097,2305,4651,3037,0]Ao[3096,13,3097,2305,4080,3037,0]Ao[3096,13,3097,1756,2267,3037,0]Ao[3096,13,3097,1756,4749,3037,0]Ao[3096,13,3097,1784,4083,3037,0]Ao[3096,13,3097,1784,4088,3037,0]Al[3096,13,3097,0,4360,3037,0]Al[3096,13,3097,0,4812,3037,0]An[3096,13,3097,3097,511,3037,0]An[3096,13,3097,3097,127,3037,0]Ao[3096,13,3097,3097,2282,3037,0]Ao[3096,13,3097,3097,3024,3037,0]Ao[3096,13,1689,1689,4251,3037,0]Ao[3096,13,4960,4960,4858,3037,0]Ao[3096,13,4960,4960,1171,3037,0]Ao[3096,13,1694,1694,5068,3037,0]Al[3096,13,1774,0,1170,3037,0]Ao[1985,13,1986,1986,4089,3037,0]Ai[463,13,464,1094,503,0,0]Aj[463,13,464,1094,4362,0,0]Aj[463,13,464,4036,3237,0,0]Aj[463,13,464,4036,4859,0,0]Aj[463,13,464,4041,3243,0,0]Ai[3096,14,3039,0,1420,0,0]Ai[3096,14,3039,0,3002,0,0]Ai[3096,14,3039,0,3020,0,0]Ai[3096,14,3039,0,4109,0,0]Ai[3096,14,3039,0,4102,0,0]Ai[3096,14,3960,0,2277,0,0]Ai[3096,14,3960,0,2297,0,0]Ai[3096,14,3960,0,2261,0,0]Ai[3096,14,3960,0,1855,0,0]Ae[1195,7,1196,0,0,0,0]Ah[3096,14,4459,0,499,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Af[463,5,3635,148,0,0,0]Ag[3096,5,3636,148,0,0,0]Al[1095,15,1096,1096,4851,0,0]Ae[2358,5,2359,0,0,0,0]Af[463,6,464,3097,0,0,0]Ae[3096,6,3097,0,0,0,0]Al[3096,15,1689,1689,1433,0,0]Ag[463,19,464,0,1443,0,0]Ag[463,19,464,0,1426,0,0]Al[3096,19,3097,1810,1444,0,0]Al[3096,19,3097,1366,1427,0,0]Ae[1195,5,1196,0,0,0,0]Ae[1095,5,1683,0,0,0,0]Ae[1095,5,1779,0,0,0,0]Af[463,15,464,0,126,0,0]Ak[3096,15,3097,3097,127,0,0]Ai[463,13,464,0,2294,117,0]Ai[463,13,464,0,3217,117,0]Ai[463,13,464,0,4451,117,0]An[3096,13,3097,1382,2295,117,0]An[3096,13,3097,1382,3218,117,0]An[3096,13,3097,1382,4452,117,0]Ai[463,13,464,0,1443,137,0]Ai[463,13,464,0,1426,137,0]Ai[463,13,464,0,3943,137,0]Ai[463,13,464,0,4082,137,0]Ah[463,13,464,0,510,137,0]Ah[463,13,464,0,126,137,0]Ai[463,13,464,0,2281,137,0]An[3096,13,3097,1810,1444,137,0]An[3096,13,3097,3070,4753,137,0]An[3096,13,3097,1366,1427,137,0]An[3096,13,3097,1120,3045,137,0]An[3096,13,3097,1120,4245,137,0]An[3096,13,3097,1125,3258,137,0]An[3096,13,3097,3194,3944,137,0]An[3096,13,3097,2305,4651,137,0]An[3096,13,3097,1756,4749,137,0]An[3096,13,3097,1784,4083,137,0]Am[3096,13,3097,3097,511,137,0]Am[3096,13,3097,3097,127,137,0]An[3096,13,3097,3097,2282,137,0]Ag[463,13,464,0,2281,0,0]Al[3096,13,3097,3097,2282,0,0]Ai[3096,14,3960,0,1421,0,0]Ai[3096,14,3960,0,3009,0,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Al[1985,14,1986,1986,2279,0,0]Al[1985,14,1986,1986,2293,0,0]An[1195,13,1196,1196,134,1159,0]Ao[1195,13,1196,1196,3954,1159,0]Ao[1195,13,1196,1196,3930,1159,0]Ao[1195,13,1380,1380,4357,1159,0]Ao[3968,13,3969,3969,5009,1159,0]Am[463,13,464,4144,4915,1159,0]Am[463,13,464,3640,3209,1159,0]Am[463,13,464,3640,3211,1159,0]Am[463,13,464,3640,4921,1159,0]D`[463,13,464,3640,4752,1159,0,\"impl-Debug-for-SendDatagramError\"]Db[463,13,464,3640,4752,1827,0,\"impl-Display-for-SendDatagramError\"]Am[463,13,464,2304,2259,1159,0]Am[463,13,464,2304,4219,1159,0]Ce[463,13,464,4144,1418,1159,0,\"impl-Debug-for-Lagged\"]Cg[463,13,464,4144,1418,1827,0,\"impl-Display-for-Lagged\"]Am[463,13,464,4144,3231,1159,0]Am[463,13,464,4144,4852,1159,0]Am[463,13,464,2336,2263,1159,0]Ck[463,13,464,2336,3240,1827,0,\"impl-Display-for-RetryError\"]Ci[463,13,464,2336,3240,1159,0,\"impl-Debug-for-RetryError\"]Am[463,13,464,2336,4336,1159,0]Al[463,13,464,1094,503,1159,0]Am[463,13,464,1094,4362,1159,0]Am[463,13,464,4036,3237,1159,0]Am[463,13,464,4036,4859,1159,0]Cm[463,13,464,4036,4355,1159,0,\"impl-Debug-for-ReadToEndError\"]Co[463,13,464,4036,4355,1827,0,\"impl-Display-for-ReadToEndError\"]Ch[463,13,464,4036,3044,1159,0,\"impl-Debug-for-ReadError\"]Cj[463,13,464,4036,3044,1827,0,\"impl-Display-for-ReadError\"]Ci[463,13,464,4036,3239,1159,0,\"impl-Debug-for-ResetError\"]Ck[463,13,464,4036,3239,1827,0,\"impl-Display-for-ResetError\"]Co[463,13,464,4036,4354,1827,0,\"impl-Display-for-ReadExactError\"]Cm[463,13,464,4036,4354,1159,0,\"impl-Debug-for-ReadExactError\"]Am[463,13,464,1393,4123,1159,0]Am[463,13,464,1137,3957,1159,0]Am[463,13,464,4041,3243,1159,0]Ci[463,13,464,4041,3257,1159,0,\"impl-Debug-for-WriteError\"]Ck[463,13,464,4041,3257,1827,0,\"impl-Display-for-WriteError\"]Cm[463,13,464,4041,4122,1827,0,\"impl-Display-for-StoppedError\"]Ck[463,13,464,4041,4122,1159,0,\"impl-Debug-for-StoppedError\"]Am[463,13,464,4041,1857,1159,0]Cd[463,13,464,0,1443,1827,0,\"impl-Display-for-VarInt\"]Cb[463,13,464,0,1443,1159,0,\"impl-Debug-for-VarInt\"]Db[463,13,464,0,4918,1827,0,\"impl-Display-for-VarIntBoundsExceeded\"]D`[463,13,464,0,4918,1159,0,\"impl-Debug-for-VarIntBoundsExceeded\"]Aj[463,13,464,0,1152,1159,0]Cb[463,13,464,0,1426,1159,0,\"impl-Debug-for-PathId\"]Cd[463,13,464,0,1426,1827,0,\"impl-Display-for-PathId\"]Aj[463,13,464,0,2294,1159,0]Aj[463,13,464,0,3217,1159,0]Aj[463,13,464,0,3041,1159,0]Aj[463,13,464,0,4451,1159,0]Aj[463,13,464,0,1867,1159,0]Ch[463,13,464,0,4073,1159,0,\"impl-Debug-for-ClosedStream\"]Cj[463,13,464,0,4073,1827,0,\"impl-Display-for-ClosedStream\"]Cm[463,13,464,0,4447,1827,0,\"impl-Display-for-ConnectionError\"]Ck[463,13,464,0,4447,1159,0,\"impl-Debug-for-ConnectionError\"]Aj[463,13,464,0,4461,1159,0]Aj[463,13,464,0,4470,1159,0]Aj[463,13,464,0,4776,1159,0]Aj[463,13,464,0,4791,1159,0]Aj[463,13,464,0,3943,1159,0]Aj[463,13,464,0,4331,1159,0]Aj[463,13,464,0,4116,1159,0]Aj[463,13,464,0,4975,1159,0]Aj[463,13,464,0,4067,1159,0]Cg[463,13,464,0,3933,1159,0,\"impl-Debug-for-ConfigError\"]Ci[463,13,464,0,3933,1827,0,\"impl-Display-for-ConfigError\"]Ce[463,13,464,0,3025,1159,0,\"impl-Debug-for-FrameType\"]Cg[463,13,464,0,3025,1827,0,\"impl-Display-for-FrameType\"]Cm[463,13,464,0,4444,1827,0,\"impl-Display-for-ConnectionClose\"]Ck[463,13,464,0,4444,1159,0,\"impl-Debug-for-ConnectionClose\"]Cn[463,13,464,0,4645,1827,0,\"impl-Display-for-ApplicationClose\"]Cl[463,13,464,0,4645,1159,0,\"impl-Debug-for-ApplicationClose\"]Ch[463,13,464,0,4079,1159,0,\"impl-Debug-for-ConnectError\"]Cj[463,13,464,0,4079,1827,0,\"impl-Display-for-ConnectError\"]Cj[463,13,464,0,4082,1827,0,\"impl-Display-for-ConnectionId\"]Ch[463,13,464,0,4082,1159,0,\"impl-Debug-for-ConnectionId\"]Aj[463,13,464,0,4087,1159,0]Cn[463,13,464,0,4811,1159,0,\"impl-Debug-for-TransportErrorCode\"]D`[463,13,464,0,4811,1827,0,\"impl-Display-for-TransportErrorCode\"]Aj[463,13,464,0,3220,1159,0]Aj[463,13,464,0,4678,1159,0]Ai[463,13,464,0,510,1159,0]Bn[463,13,464,0,126,1159,0,\"impl-Debug-for-Dir\"]C`[463,13,464,0,126,1827,0,\"impl-Display-for-Dir\"]Cd[463,13,464,0,2281,1159,0,\"impl-Debug-for-StreamId\"]Cf[463,13,464,0,2281,1827,0,\"impl-Display-for-StreamId\"]Aj[463,13,464,0,2291,1159,0]Aj[463,13,3635,0,120,1159,0]Ak[463,13,3635,0,3012,1159,0]Ak[463,13,3635,0,1156,1159,0]Ak[463,13,3635,0,3938,1159,0]Ak[463,13,3635,0,1840,1159,0]Ak[463,13,3635,0,4237,1159,0]Ak[463,13,3635,0,4740,1159,0]Ak[463,13,1693,0,5067,1159,0]Ak[463,13,1693,0,3936,1159,0]Ak[463,13,1693,0,4815,1159,0]Cb[463,13,1773,0,1169,1159,0,\"impl-Debug-for-Error\"]Cd[463,13,1773,0,1169,1827,0,\"impl-Display-for-Error\"]Dc[463,13,1773,0,4913,1827,0,\"impl-Display-for-NoInitialCipherSuite\"]Da[463,13,1773,0,4913,1159,0,\"impl-Debug-for-NoInitialCipherSuite\"]Ao[3096,13,3097,3641,3212,1159,0]Ao[3096,13,3097,2305,2260,1159,0]Ci[3096,13,3097,1810,1444,1827,0,\"impl-Display-for-VarInt\"]Cg[3096,13,3097,1810,1444,1159,0,\"impl-Debug-for-VarInt\"]De[3096,13,3097,1810,4919,1159,0,\"impl-Debug-for-VarIntBoundsExceeded\"]Dg[3096,13,3097,1810,4919,1827,0,\"impl-Display-for-VarIntBoundsExceeded\"]Ao[3096,13,3097,3061,1153,1159,0]Dd[3096,13,3097,3070,4753,1827,0,\"impl-Display-for-SendDatagramError\"]Db[3096,13,3097,3070,4753,1159,0,\"impl-Debug-for-SendDatagramError\"]Ci[3096,13,3097,1366,1427,1827,0,\"impl-Display-for-PathId\"]Cg[3096,13,3097,1366,1427,1159,0,\"impl-Debug-for-PathId\"]Ao[3096,13,3097,1366,4112,1159,0]Ao[3096,13,3097,1366,3233,1159,0]Ao[3096,13,3097,1366,3040,1159,0]Ao[3096,13,3097,1366,4751,1159,0]Dc[3096,13,3097,1366,4807,1159,0,\"impl-Debug-for-SetPathStatusError\"]De[3096,13,3097,1366,4807,1827,0,\"impl-Display-for-SetPathStatusError\"]Ck[3096,13,3097,1366,3207,1159,0,\"impl-Debug-for-ClosedPath\"]Cm[3096,13,3097,1366,3207,1827,0,\"impl-Display-for-ClosedPath\"]Ao[3096,13,3097,1382,2295,1159,0]Ao[3096,13,3097,1382,3218,1159,0]Ao[3096,13,3097,1382,3042,1159,0]Ao[3096,13,3097,1382,4452,1159,0]Cl[3096,13,3097,1120,3045,1827,0,\"impl-Display-for-ReadError\"]Cj[3096,13,3097,1120,3045,1159,0,\"impl-Debug-for-ReadError\"]D`[3096,13,3097,1120,4245,1827,0,\"impl-Display-for-ReadableError\"]Cn[3096,13,3097,1120,4245,1159,0,\"impl-Debug-for-ReadableError\"]Ao[3096,13,3097,1125,1868,1159,0]Ck[3096,13,3097,1125,3258,1159,0,\"impl-Debug-for-WriteError\"]Cm[3096,13,3097,1125,3258,1827,0,\"impl-Display-for-WriteError\"]Cn[3096,13,3097,1125,3942,1827,0,\"impl-Display-for-FinishError\"]Cl[3096,13,3097,1125,3942,1159,0,\"impl-Debug-for-FinishError\"]Ao[3096,13,3097,2002,3961,1159,0]Ao[3096,13,3097,2002,4356,1159,0]Co[3096,13,3097,2002,4077,1827,0,\"impl-Display-for-ClosedStream\"]Cm[3096,13,3097,2002,4077,1159,0,\"impl-Debug-for-ClosedStream\"]Db[3096,13,3097,3641,4448,1827,0,\"impl-Display-for-ConnectionError\"]D`[3096,13,3097,3641,4448,1159,0,\"impl-Debug-for-ConnectionError\"]Cl[3096,13,3097,3641,3038,1827,0,\"impl-Display-for-PathError\"]Cj[3096,13,3097,3641,3038,1159,0,\"impl-Debug-for-PathError\"]Co[3096,13,3097,3641,4322,1159,0,\"impl-Debug-for-ClosePathError\"]Da[3096,13,3097,3641,4322,1827,0,\"impl-Display-for-ClosePathError\"]Dg[3096,13,3097,3641,5004,1159,0,\"impl-Debug-for-MultipathNotNegotiated\"]Di[3096,13,3097,3641,5004,1827,0,\"impl-Display-for-MultipathNotNegotiated\"]Ao[3096,13,3097,3641,1174,1159,0]Ao[3096,13,3097,1116,4462,1159,0]Ao[3096,13,3097,3194,4471,1159,0]Ao[3096,13,3097,3194,4777,1159,0]Ao[3096,13,3097,3194,4792,1159,0]Ao[3096,13,3097,3194,3944,1159,0]Ao[3096,13,3097,1691,4332,1159,0]Ao[3096,13,3097,1691,4118,1159,0]Ao[3096,13,3097,1691,4976,1159,0]Ao[3096,13,3097,1691,4069,1159,0]Cl[3096,13,3097,1691,3934,1159,0,\"impl-Debug-for-ConfigError\"]Cn[3096,13,3097,1691,3934,1827,0,\"impl-Display-for-ConfigError\"]Cj[3096,13,3097,1356,3026,1159,0,\"impl-Debug-for-FrameType\"]Cl[3096,13,3097,1356,3026,1827,0,\"impl-Display-for-FrameType\"]Da[3096,13,3097,1356,4337,1827,0,\"impl-Display-for-InvalidFrameId\"]Co[3096,13,3097,1356,4337,1159,0,\"impl-Debug-for-InvalidFrameId\"]Cm[3096,13,3097,1356,3224,1827,0,\"impl-Display-for-MaybeFrame\"]Ck[3096,13,3097,1356,3224,1159,0,\"impl-Debug-for-MaybeFrame\"]Ck[3096,13,3097,1356,3247,1159,0,\"impl-Debug-for-StreamInfo\"]Cm[3096,13,3097,1356,3247,1827,0,\"impl-Display-for-StreamInfo\"]Cm[3096,13,3097,1356,4084,1159,0,\"impl-Debug-for-DatagramInfo\"]Co[3096,13,3097,1356,4084,1827,0,\"impl-Display-for-DatagramInfo\"]Db[3096,13,3097,1356,4446,1827,0,\"impl-Display-for-ConnectionClose\"]D`[3096,13,3097,1356,4446,1159,0,\"impl-Debug-for-ConnectionClose\"]Dc[3096,13,3097,1356,4647,1827,0,\"impl-Display-for-ApplicationClose\"]Da[3096,13,3097,1356,4647,1159,0,\"impl-Debug-for-ApplicationClose\"]Ci[3096,13,3097,1356,2253,1159,0,\"impl-Debug-for-Datagram\"]Ck[3096,13,3097,1356,2253,1827,0,\"impl-Display-for-Datagram\"]Ao[3096,13,3097,2305,4651,1159,0]Ao[3096,13,3097,2305,2264,1159,0]Cm[3096,13,3097,2305,4080,1159,0,\"impl-Debug-for-ConnectError\"]Co[3096,13,3097,2305,4080,1827,0,\"impl-Display-for-ConnectError\"]Ao[3096,13,3097,2305,3928,1159,0]Ck[3096,13,3097,2305,3241,1159,0,\"impl-Debug-for-RetryError\"]Cm[3096,13,3097,2305,3241,1827,0,\"impl-Display-for-RetryError\"]Ao[3096,13,3097,1756,4240,1159,0]Ao[3096,13,3097,1756,4460,1159,0]Ao[3096,13,3097,1756,5008,1159,0]Ao[3096,13,3097,1756,2267,1159,0]Dd[3096,13,3097,1756,4749,1827,0,\"impl-Display-for-PacketDecodeError\"]Db[3096,13,3097,1756,4749,1159,0,\"impl-Debug-for-PacketDecodeError\"]Ao[3096,13,3097,1784,4450,1159,0]Ao[3096,13,3097,1784,4218,1159,0]Cm[3096,13,3097,1784,4083,1159,0,\"impl-Debug-for-ConnectionId\"]Co[3096,13,3097,1784,4083,1827,0,\"impl-Display-for-ConnectionId\"]Ao[3096,13,3097,1784,4088,1159,0]Ce[3096,13,3097,0,4360,1827,0,\"impl-Display-for-Error\"]Cc[3096,13,3097,0,4360,1159,0,\"impl-Debug-for-Error\"]Cb[3096,13,3097,0,4812,1159,0,\"impl-Debug-for-Code\"]Cd[3096,13,3097,0,4812,1827,0,\"impl-Display-for-Code\"]Ao[3096,13,3097,4258,3221,1159,0]Ao[3096,13,3097,4258,5102,1159,0]Ao[3096,13,3097,4847,4679,1159,0]An[3096,13,3097,3097,511,1159,0]Ce[3096,13,3097,3097,127,1827,0,\"impl-Display-for-Dir\"]Cc[3096,13,3097,3097,127,1159,0,\"impl-Debug-for-Dir\"]Ci[3096,13,3097,3097,2282,1159,0,\"impl-Debug-for-StreamId\"]Ck[3096,13,3097,3097,2282,1827,0,\"impl-Display-for-StreamId\"]Ao[3096,13,3097,3097,2292,1159,0]Cj[3096,13,3097,3097,3024,1159,0,\"impl-Debug-for-FourTuple\"]Cl[3096,13,3097,3097,3024,1827,0,\"impl-Display-for-FourTuple\"]Cn[3096,13,1689,1689,4251,1159,0,\"impl-Debug-for-UnexpectedEnd\"]D`[3096,13,1689,1689,4251,1827,0,\"impl-Display-for-UnexpectedEnd\"]Ao[3096,13,4960,4960,4858,1159,0]Cf[3096,13,4960,4960,1171,1159,0,\"impl-Debug-for-Error\"]Ch[3096,13,4960,4960,1171,1827,0,\"impl-Display-for-Error\"]Ao[3096,13,1694,1694,5068,1159,0]Ao[3096,13,1694,1694,3937,1159,0]Ao[3096,13,1694,1694,4818,1159,0]Ce[3096,13,1774,0,1170,1827,0,\"impl-Display-for-Error\"]Cc[3096,13,1774,0,1170,1159,0,\"impl-Debug-for-Error\"]De[3096,13,1774,1774,4914,1159,0,\"impl-Debug-for-NoInitialCipherSuite\"]Dg[3096,13,1774,1774,4914,1827,0,\"impl-Display-for-NoInitialCipherSuite\"]Am[3096,13,3636,148,121,1159,0]An[3096,13,3636,148,3013,1159,0]Ao[3096,13,3636,1352,1157,1159,0]Ao[3096,13,3636,1352,3939,1159,0]Ao[3096,13,3636,2358,1841,1159,0]Ao[3096,13,3636,2358,4238,1159,0]Ao[3096,13,3636,3636,4741,1159,0]Cf[3096,13,4709,4709,1172,1159,0,\"impl-Debug-for-Error\"]Ch[3096,13,4709,4709,1172,1827,0,\"impl-Display-for-Error\"]Ao[3096,13,4709,4709,1175,1159,0]An[1985,13,1986,416,4361,1159,0]Ao[1985,13,1986,1986,2279,1159,0]Ao[1985,13,1986,1986,2293,1159,0]Ao[1985,13,1986,1986,4089,1159,0]Aj[463,13,464,4144,4915,0,0]Al[3096,13,3097,1366,4112,0,0]Ag[463,14,464,0,2294,0,0]Al[3096,14,3097,1382,2295,0,0]Al[3096,13,3097,1756,4240,0,0]Al[3096,14,3097,1756,5008,0,0]Ah[3096,14,4459,0,499,0,0]Al[1985,14,1986,1986,2279,0,0]Ag[463,13,464,0,4975,0,0]Al[3096,13,3097,1691,4976,0,0]8Al[1195,13,1380,1380,4357,0,0]Al[3968,13,3969,3969,5009,0,0]Ag[463,13,464,0,4210,0,0]Aj[463,13,464,2304,2259,0,0]Ag[463,13,464,0,3234,0,0]Ag[463,13,464,0,4461,0,0]Ag[463,13,464,0,4331,0,0]Ag[463,13,464,0,4116,0,0]Ag[463,13,464,0,4067,0,0]Ag[463,13,464,0,4082,0,0]Ag[463,13,464,0,4678,0,0]Ag[463,13,464,0,2281,0,0]Ag[463,13,3635,0,120,0,0]Ah[463,13,3635,0,1156,0,0]Ah[463,13,3635,0,1840,0,0]Al[3096,13,3097,4480,4211,0,0]Al[3096,13,3097,1116,3235,0,0]Al[3096,13,3097,2305,2260,0,0]Al[3096,13,3097,1756,5127,0,0]Al[3096,13,3097,4258,5097,0,0]Al[3096,13,3097,1116,4462,0,0]Al[3096,13,3097,1691,4332,0,0]Al[3096,13,3097,1691,4118,0,0]Al[3096,13,3097,1691,4069,0,0]Al[3096,13,3097,1756,4240,0,0]Al[3096,13,3097,1784,4083,0,0]Ai[3096,13,3097,0,4360,0,0]Al[3096,13,3097,4258,5102,0,0]Al[3096,13,3097,4847,4679,0,0]Al[3096,13,3097,3097,2282,0,0]Al[3096,13,3097,3097,3024,0,0]Aj[3096,13,3636,148,121,0,0]Al[3096,13,3636,1352,1157,0,0]Al[3096,13,3636,2358,1841,0,0]Ak[1985,13,1986,416,4361,0,0]Al[1095,13,4178,4178,5053,0,0]Al[1095,13,4178,4178,5054,0,0]Aa[463,3,0,0,0,0,0]Ah[463,13,464,0,510,133,0]Am[3096,13,3097,3097,511,133,0]Ag[463,12,464,0,3250,0,0]Aj[463,13,464,1994,1852,0,0]0Am[463,13,464,1393,4123,1852,0]Aj[463,13,464,0,4249,3250,0]Al[3096,12,3097,1691,3251,0,0]Ao[3096,13,3097,1691,4250,3251,0]Aj[463,13,464,3640,3211,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,13,3097,3641,3212,0,0]Al[3096,14,3097,1382,3042,0,0]Ae[1095,7,1683,0,0,0,0]Ae[1095,7,1779,0,0,0,0]Ac[463,4,464,0,0,0,0]Ag[463,15,464,0,4087,0,0]Al[3096,15,3097,1784,4088,0,0]Al[1985,15,1986,1986,4089,0,0]210Ag[463,5,1693,1694,0,0,0]Ae[3096,5,1694,0,0,0,0]Al[3096,15,3097,1756,4460,0,0]Al[3096,15,3097,1356,3224,0,0]Af[463,5,464,1094,0,0,0]Al[3096,15,3097,3641,1174,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Aj[463,15,464,4036,4355,0,0]Af[463,6,464,3097,0,0,0]Ae[3096,6,3097,0,0,0,0]Ag[463,19,464,0,1426,0,0]Al[3096,19,3097,1366,1427,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]Ai[3096,14,3039,0,4102,0,0]Al[1985,14,1986,1986,2279,0,0]Aa[519,3,0,0,0,0,0]Ai[3096,14,3097,0,4360,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1382,3042,0,0]Al[3096,14,3097,1356,2253,0,0]Al[463,13,464,3640,2274,487,0]Al[463,13,464,2336,2263,487,0]Ak[463,13,464,1094,503,487,0]Al[463,13,464,1094,4362,487,0]Al[463,13,464,4036,3237,487,0]Al[463,13,464,4041,3243,487,0]An[3096,13,3097,1120,1407,487,0]Am[1195,13,1196,1196,134,494,0]An[1195,13,1196,1196,3954,494,0]An[1195,13,1196,1196,3930,494,0]An[1195,13,1380,1380,3962,494,0]An[1195,13,1380,1380,1189,494,0]An[1195,13,1380,1380,4357,494,0]Ak[519,13,520,520,3931,494,0]An[3968,13,3969,3969,5009,494,0]Al[463,13,464,3640,4475,494,0]Al[463,13,464,3640,2274,494,0]Ai[463,13,464,0,4210,494,0]Al[463,13,464,4144,4915,494,0]Al[463,13,464,1094,2275,494,0]Al[463,13,464,1094,4643,494,0]Al[463,13,464,3640,3209,494,0]Al[463,13,464,3640,3211,494,0]Al[463,13,464,3640,1843,494,0]Al[463,13,464,3640,1419,494,0]Al[463,13,464,3640,3004,494,0]Al[463,13,464,3640,2247,494,0]Al[463,13,464,3640,4108,494,0]Al[463,13,464,3640,4113,494,0]Al[463,13,464,3640,4921,494,0]Al[463,13,464,3640,4752,494,0]0Al[463,13,464,2304,2259,494,0]Al[463,13,464,2304,4219,494,0]Al[463,13,464,2304,1399,494,0]Al[463,13,464,4144,1418,494,0]Al[463,13,464,4144,3231,494,0]Al[463,13,464,4144,4852,494,0]Al[463,13,464,2336,2263,494,0]Al[463,13,464,2336,3240,494,0]Al[463,13,464,2336,4336,494,0]Ak[463,13,464,1094,503,494,0]Al[463,13,464,1094,4362,494,0]Al[463,13,464,4036,3237,494,0]Al[463,13,464,4036,4859,494,0]Al[463,13,464,4036,4355,494,0]0Al[463,13,464,4036,3044,494,0]Df[463,13,464,4036,3044,494,0,\"impl-From%3CResetError%3E-for-ReadError\"]Dk[463,13,464,4036,3044,494,0,\"impl-From%3CConnectionError%3E-for-ReadError\"]Al[463,13,464,4036,3239,494,0]0Al[463,13,464,4036,4354,494,0]0Al[463,13,464,1393,4123,494,0]Al[463,13,464,1137,3957,494,0]Al[463,13,464,4041,3243,494,0]Al[463,13,464,4041,3257,494,0]Di[463,13,464,4041,3257,494,0,\"impl-From%3CClosedStream%3E-for-WriteError\"]Di[463,13,464,4041,3257,494,0,\"impl-From%3CStoppedError%3E-for-WriteError\"]Dl[463,13,464,4041,3257,494,0,\"impl-From%3CConnectionError%3E-for-WriteError\"]Al[463,13,464,4041,4122,494,0]0Al[463,13,464,4041,1857,494,0]Ai[463,13,464,0,3234,494,0]Ai[463,13,464,0,4249,494,0]Ai[463,13,464,0,4467,494,0]Ai[463,13,464,0,4100,494,0]Ai[463,13,464,0,4345,494,0]Cn[463,13,464,0,1443,494,0,\"impl-From%3CStreamId%3E-for-VarInt\"]Ch[463,13,464,0,1443,494,0,\"impl-From%3Cu8%3E-for-VarInt\"]Ci[463,13,464,0,1443,494,0,\"impl-From%3Cu16%3E-for-VarInt\"]Dh[463,13,464,0,1443,494,0,\"impl-From%3CTransportErrorCode%3E-for-VarInt\"]Ci[463,13,464,0,1443,494,0,\"impl-From%3Cu32%3E-for-VarInt\"]Ai[463,13,464,0,1443,494,0]Ai[463,13,464,0,4918,494,0]Ai[463,13,464,0,1152,494,0]Ai[463,13,464,0,1426,494,0]0Ai[463,13,464,0,2294,494,0]Ai[463,13,464,0,3217,494,0]Ai[463,13,464,0,3041,494,0]Ai[463,13,464,0,4451,494,0]Ai[463,13,464,0,1867,494,0]Ai[463,13,464,0,4073,494,0]Dd[463,13,464,0,4447,494,0,\"impl-From%3CClose%3E-for-ConnectionError\"]Ai[463,13,464,0,4447,494,0]Dm[463,13,464,0,4447,494,0,\"impl-From%3CTransportError%3E-for-ConnectionError\"]Dj[463,13,464,0,4447,494,0,\"impl-From%3CCloseReason%3E-for-ConnectionError\"]Ai[463,13,464,0,4461,494,0]Ai[463,13,464,0,4470,494,0]Ai[463,13,464,0,4776,494,0]Ai[463,13,464,0,4791,494,0]Ai[463,13,464,0,3943,494,0]0Ai[463,13,464,0,4331,494,0]Ai[463,13,464,0,4116,494,0]Ai[463,13,464,0,4975,494,0]Ai[463,13,464,0,4067,494,0]Dj[463,13,464,0,3933,494,0,\"impl-From%3CTryFromIntError%3E-for-ConfigError\"]Ai[463,13,464,0,3933,494,0]Do[463,13,464,0,3933,494,0,\"impl-From%3CVarIntBoundsExceeded%3E-for-ConfigError\"]Ai[463,13,464,0,3025,494,0]Ai[463,13,464,0,4444,494,0]0Ai[463,13,464,0,4645,494,0]Ai[463,13,464,0,4079,494,0]0Ai[463,13,464,0,4082,494,0]Ai[463,13,464,0,4087,494,0]Ai[463,13,464,0,4811,494,0]0Ai[463,13,464,0,3220,494,0]Ai[463,13,464,0,4678,494,0]Ah[463,13,464,0,510,494,0]Ah[463,13,464,0,126,494,0]Ai[463,13,464,0,2281,494,0]0Ai[463,13,464,0,2291,494,0]Ai[463,13,3635,0,120,494,0]Aj[463,13,3635,0,3012,494,0]Aj[463,13,3635,0,1156,494,0]Aj[463,13,3635,0,3938,494,0]Aj[463,13,3635,0,1840,494,0]Aj[463,13,3635,0,4237,494,0]Aj[463,13,3635,0,4740,494,0]Aj[463,13,1693,0,1835,494,0]Ai[463,13,1693,0,497,494,0]Aj[463,13,1693,0,5067,494,0]Aj[463,13,1693,0,3936,494,0]0Aj[463,13,1693,0,4815,494,0]Aj[463,13,1773,0,3252,494,0]Aj[463,13,1773,0,4221,494,0]De[463,13,1773,0,1169,494,0,\"impl-From%3CSystemTimeError%3E-for-Error\"]De[463,13,1773,0,1169,494,0,\"impl-From%3CGetRandomFailed%3E-for-Error\"]Df[463,13,1773,0,1169,494,0,\"impl-From%3CInconsistentKeys%3E-for-Error\"]Dd[463,13,1773,0,1169,494,0,\"impl-From%3CPeerMisbehaved%3E-for-Error\"]Dd[463,13,1773,0,1169,494,0,\"impl-From%3CInvalidMessage%3E-for-Error\"]D`[463,13,1773,0,1169,494,0,\"impl-From%3COtherError%3E-for-Error\"]Aj[463,13,1773,0,1169,494,0]Df[463,13,1773,0,1169,494,0,\"impl-From%3CCertificateError%3E-for-Error\"]Do[463,13,1773,0,1169,494,0,\"impl-From%3CEncryptedClientHelloError%3E-for-Error\"]Df[463,13,1773,0,1169,494,0,\"impl-From%3CPeerIncompatible%3E-for-Error\"]Do[463,13,1773,0,1169,494,0,\"impl-From%3CUnsupportedOperationError%3E-for-Error\"]Dm[463,13,1773,0,1169,494,0,\"impl-From%3CCertRevocationListError%3E-for-Error\"]Aj[463,13,1773,0,4674,494,0]Aj[463,13,1773,0,4913,494,0]Aj[463,13,1773,0,4676,494,0]Am[2358,13,2359,2359,125,494,0]An[2358,13,2359,2359,2250,494,0]An[3096,13,3097,4480,4211,494,0]An[3096,13,3097,3070,3018,494,0]An[3096,13,3097,1120,1407,494,0]An[3096,13,3097,2002,1861,494,0]An[3096,13,3097,2002,3238,494,0]An[3096,13,3097,2002,3244,494,0]An[3096,13,3097,3641,3212,494,0]An[3096,13,3097,1116,3235,494,0]An[3096,13,3097,1691,4250,494,0]An[3096,13,3097,2305,2260,494,0]An[3096,13,3097,2305,4217,494,0]An[3096,13,3097,2305,4654,494,0]An[3096,13,3097,2305,4228,494,0]An[3096,13,3097,1756,5127,494,0]An[3096,13,3097,4258,5097,494,0]An[3096,13,3097,1392,4468,494,0]An[3096,13,3097,1392,4101,494,0]An[3096,13,3097,1392,4346,494,0]An[3096,13,3097,1810,1444,494,0]Cn[3096,13,3097,1810,1444,494,0,\"impl-From%3Cu16%3E-for-VarInt\"]Cn[3096,13,3097,1810,1444,494,0,\"impl-From%3Cu32%3E-for-VarInt\"]Cm[3096,13,3097,1810,1444,494,0,\"impl-From%3Cu8%3E-for-VarInt\"]Dc[3096,13,3097,1810,1444,494,0,\"impl-From%3CStreamId%3E-for-VarInt\"]Co[3096,13,3097,1810,1444,494,0,\"impl-From%3CCode%3E-for-VarInt\"]An[3096,13,3097,1810,4919,494,0]An[3096,13,3097,3061,1153,494,0]An[3096,13,3097,3070,4753,494,0]An[3096,13,3097,1366,1427,494,0]0An[3096,13,3097,1366,4112,494,0]An[3096,13,3097,1366,3233,494,0]An[3096,13,3097,1366,3040,494,0]An[3096,13,3097,1366,4751,494,0]An[3096,13,3097,1366,4807,494,0]An[3096,13,3097,1366,3207,494,0]An[3096,13,3097,1382,2295,494,0]An[3096,13,3097,1382,3218,494,0]An[3096,13,3097,1382,3042,494,0]An[3096,13,3097,1382,4452,494,0]An[3096,13,3097,1120,3045,494,0]An[3096,13,3097,1120,4245,494,0]An[3096,13,3097,1125,1868,494,0]An[3096,13,3097,1125,3258,494,0]An[3096,13,3097,1125,3942,494,0]An[3096,13,3097,2002,3961,494,0]An[3096,13,3097,2002,4356,494,0]An[3096,13,3097,2002,4077,494,0]An[3096,13,3097,3641,4448,494,0]0An[3096,13,3097,3641,3038,494,0]An[3096,13,3097,3641,4322,494,0]An[3096,13,3097,3641,5004,494,0]An[3096,13,3097,3641,1174,494,0]0An[3096,13,3097,1116,4462,494,0]An[3096,13,3097,3194,4471,494,0]An[3096,13,3097,3194,4777,494,0]An[3096,13,3097,3194,4792,494,0]An[3096,13,3097,3194,3944,494,0]0An[3096,13,3097,1691,4332,494,0]An[3096,13,3097,1691,4118,494,0]An[3096,13,3097,1691,4976,494,0]An[3096,13,3097,1691,4069,494,0]Do[3096,13,3097,1691,3934,494,0,\"impl-From%3CTryFromIntError%3E-for-ConfigError\"]Ed[3096,13,3097,1691,3934,494,0,\"impl-From%3CVarIntBoundsExceeded%3E-for-ConfigError\"]An[3096,13,3097,1691,3934,494,0]An[3096,13,3097,1356,3026,494,0]An[3096,13,3097,1356,4337,494,0]An[3096,13,3097,1356,3224,494,0]An[3096,13,3097,1356,3247,494,0]An[3096,13,3097,1356,4084,494,0]An[3096,13,3097,1356,4446,494,0]0An[3096,13,3097,1356,4647,494,0]An[3096,13,3097,1356,2253,494,0]An[3096,13,3097,2305,4651,494,0]An[3096,13,3097,2305,2264,494,0]An[3096,13,3097,2305,4080,494,0]0An[3096,13,3097,2305,3928,494,0]An[3096,13,3097,2305,3241,494,0]An[3096,13,3097,1756,4240,494,0]An[3096,13,3097,1756,4460,494,0]An[3096,13,3097,1756,5008,494,0]An[3096,13,3097,1756,2267,494,0]An[3096,13,3097,1756,4749,494,0]0An[3096,13,3097,1784,4450,494,0]An[3096,13,3097,1784,4218,494,0]An[3096,13,3097,1784,4083,494,0]An[3096,13,3097,1784,4088,494,0]Ak[3096,13,3097,0,4360,494,0]0Ak[3096,13,3097,0,4812,494,0]0An[3096,13,3097,4258,3221,494,0]An[3096,13,3097,4258,5102,494,0]An[3096,13,3097,4847,4679,494,0]Am[3096,13,3097,3097,511,494,0]Am[3096,13,3097,3097,127,494,0]An[3096,13,3097,3097,2282,494,0]0An[3096,13,3097,3097,2292,494,0]An[3096,13,3097,3097,3024,494,0]An[3096,13,1689,1689,4251,494,0]An[3096,13,4960,4960,4858,494,0]An[3096,13,4960,4960,1171,494,0]0An[3096,13,1694,1694,1836,494,0]Am[3096,13,1694,1694,498,494,0]An[3096,13,1694,1694,5068,494,0]An[3096,13,1694,1694,3937,494,0]0An[3096,13,1694,1694,4818,494,0]An[3096,13,1774,1774,3253,494,0]An[3096,13,1774,1774,4222,494,0]Dg[3096,13,1774,0,1170,494,0,\"impl-From%3CCertificateError%3E-for-Error\"]E`[3096,13,1774,0,1170,494,0,\"impl-From%3CEncryptedClientHelloError%3E-for-Error\"]Da[3096,13,1774,0,1170,494,0,\"impl-From%3COtherError%3E-for-Error\"]De[3096,13,1774,0,1170,494,0,\"impl-From%3CInvalidMessage%3E-for-Error\"]Dg[3096,13,1774,0,1170,494,0,\"impl-From%3CInconsistentKeys%3E-for-Error\"]Df[3096,13,1774,0,1170,494,0,\"impl-From%3CGetRandomFailed%3E-for-Error\"]E`[3096,13,1774,0,1170,494,0,\"impl-From%3CUnsupportedOperationError%3E-for-Error\"]De[3096,13,1774,0,1170,494,0,\"impl-From%3CPeerMisbehaved%3E-for-Error\"]Dg[3096,13,1774,0,1170,494,0,\"impl-From%3CPeerIncompatible%3E-for-Error\"]Df[3096,13,1774,0,1170,494,0,\"impl-From%3CSystemTimeError%3E-for-Error\"]Ak[3096,13,1774,0,1170,494,0]Dn[3096,13,1774,0,1170,494,0,\"impl-From%3CCertRevocationListError%3E-for-Error\"]An[3096,13,1774,1774,4675,494,0]An[3096,13,1774,1774,4914,494,0]An[3096,13,1774,1774,4677,494,0]Al[3096,13,3636,148,121,494,0]Am[3096,13,3636,148,3013,494,0]An[3096,13,3636,1352,1157,494,0]An[3096,13,3636,1352,3939,494,0]An[3096,13,3636,2358,1841,494,0]An[3096,13,3636,2358,4238,494,0]An[3096,13,3636,3636,4741,494,0]An[3096,13,4709,4709,1172,494,0]An[3096,13,4709,4709,1175,494,0]An[1985,13,1986,1986,3256,494,0]0Am[1985,13,1986,416,4361,494,0]An[1985,13,1986,1986,2279,494,0]An[1985,13,1986,1986,2293,494,0]An[1985,13,1986,1986,4089,494,0]An[1095,13,1096,1096,3015,494,0]An[1095,13,1096,1096,4851,494,0]Am[1095,13,1683,1683,135,494,0]An[1095,13,1381,1381,1190,494,0]An[1095,13,1381,1381,3963,494,0]An[1095,13,1381,1381,4456,494,0]An[1095,13,4178,4178,5053,494,0]An[1095,13,4178,4178,5054,494,0]Am[1095,13,1779,1779,136,494,0]Ai[463,13,464,0,1443,495,0]Ai[463,13,464,0,1426,495,0]Ai[463,13,464,0,3943,495,0]Ai[463,13,464,0,4082,495,0]Ah[463,13,464,0,510,495,0]Ah[463,13,464,0,126,495,0]Ai[463,13,464,0,2281,495,0]An[3096,13,3097,1810,1444,495,0]An[3096,13,3097,3070,4753,495,0]An[3096,13,3097,1366,1427,495,0]An[3096,13,3097,1120,3045,495,0]An[3096,13,3097,1120,4245,495,0]An[3096,13,3097,1125,3258,495,0]An[3096,13,3097,3194,3944,495,0]An[3096,13,3097,2305,4651,495,0]An[3096,13,3097,1756,4749,495,0]An[3096,13,3097,1784,4083,495,0]Am[3096,13,3097,3097,511,495,0]Am[3096,13,3097,3097,127,495,0]An[3096,13,3097,3097,2282,495,0]An[3096,13,3097,3097,3024,495,0]Am[1195,13,1196,1196,134,496,0]An[1195,13,1196,1196,3954,496,0]An[1195,13,1196,1196,3930,496,0]An[1195,13,1380,1380,3962,496,0]An[1195,13,1380,1380,1189,496,0]An[1195,13,1380,1380,4357,496,0]Ak[519,13,520,520,3931,496,0]An[3968,13,3969,3969,5009,496,0]Al[463,13,464,3640,4475,496,0]Al[463,13,464,3640,2274,496,0]Ai[463,13,464,0,4210,496,0]Al[463,13,464,4144,4915,496,0]Al[463,13,464,1094,2275,496,0]Al[463,13,464,1094,4643,496,0]Al[463,13,464,3640,3209,496,0]Al[463,13,464,3640,3211,496,0]Al[463,13,464,3640,1843,496,0]Al[463,13,464,3640,1419,496,0]Al[463,13,464,3640,3004,496,0]Al[463,13,464,3640,2247,496,0]Al[463,13,464,3640,4108,496,0]Al[463,13,464,3640,4113,496,0]Al[463,13,464,3640,4921,496,0]Al[463,13,464,3640,4752,496,0]Al[463,13,464,2304,2259,496,0]Al[463,13,464,2304,4219,496,0]Al[463,13,464,2304,1399,496,0]Al[463,13,464,4144,1418,496,0]Al[463,13,464,4144,3231,496,0]Al[463,13,464,4144,4852,496,0]Al[463,13,464,2336,2263,496,0]Al[463,13,464,2336,3240,496,0]Al[463,13,464,2336,4336,496,0]Ak[463,13,464,1094,503,496,0]Al[463,13,464,1094,4362,496,0]Al[463,13,464,4036,3237,496,0]Al[463,13,464,4036,4859,496,0]Al[463,13,464,4036,4355,496,0]Al[463,13,464,4036,3044,496,0]Al[463,13,464,4036,3239,496,0]Al[463,13,464,4036,4354,496,0]Al[463,13,464,1393,4123,496,0]Al[463,13,464,1137,3957,496,0]Al[463,13,464,4041,3243,496,0]Al[463,13,464,4041,3257,496,0]Al[463,13,464,4041,4122,496,0]Al[463,13,464,4041,1857,496,0]Ai[463,13,464,0,3234,496,0]Ai[463,13,464,0,4249,496,0]Ai[463,13,464,0,4467,496,0]Ai[463,13,464,0,4100,496,0]Ai[463,13,464,0,4345,496,0]Ai[463,13,464,0,1443,496,0]Ai[463,13,464,0,4918,496,0]Ai[463,13,464,0,1152,496,0]Ai[463,13,464,0,1426,496,0]Ai[463,13,464,0,2294,496,0]Ai[463,13,464,0,3217,496,0]Ai[463,13,464,0,3041,496,0]Ai[463,13,464,0,4451,496,0]Ai[463,13,464,0,1867,496,0]Ai[463,13,464,0,4073,496,0]Ai[463,13,464,0,4447,496,0]Ai[463,13,464,0,4461,496,0]Ai[463,13,464,0,4470,496,0]Ai[463,13,464,0,4776,496,0]Ai[463,13,464,0,4791,496,0]Ai[463,13,464,0,3943,496,0]Ai[463,13,464,0,4331,496,0]Ai[463,13,464,0,4116,496,0]Ai[463,13,464,0,4975,496,0]Ai[463,13,464,0,4067,496,0]Ai[463,13,464,0,3933,496,0]Ai[463,13,464,0,3025,496,0]Ai[463,13,464,0,4444,496,0]Ai[463,13,464,0,4645,496,0]Ai[463,13,464,0,4079,496,0]Ai[463,13,464,0,4082,496,0]Ai[463,13,464,0,4087,496,0]Ai[463,13,464,0,4811,496,0]Ai[463,13,464,0,3220,496,0]Ai[463,13,464,0,4678,496,0]Ah[463,13,464,0,510,496,0]Ah[463,13,464,0,126,496,0]Ai[463,13,464,0,2281,496,0]Ai[463,13,464,0,2291,496,0]Ai[463,13,3635,0,120,496,0]Aj[463,13,3635,0,3012,496,0]Aj[463,13,3635,0,1156,496,0]Aj[463,13,3635,0,3938,496,0]Aj[463,13,3635,0,1840,496,0]Aj[463,13,3635,0,4237,496,0]Aj[463,13,3635,0,4740,496,0]Aj[463,13,1693,0,1835,496,0]Ai[463,13,1693,0,497,496,0]Aj[463,13,1693,0,5067,496,0]Aj[463,13,1693,0,3936,496,0]Aj[463,13,1693,0,4815,496,0]Aj[463,13,1773,0,3252,496,0]Aj[463,13,1773,0,4221,496,0]Aj[463,13,1773,0,1169,496,0]Aj[463,13,1773,0,4674,496,0]Aj[463,13,1773,0,4913,496,0]Aj[463,13,1773,0,4676,496,0]Am[2358,13,2359,2359,125,496,0]An[2358,13,2359,2359,2250,496,0]An[3096,13,3097,4480,4211,496,0]An[3096,13,3097,3070,3018,496,0]An[3096,13,3097,1120,1407,496,0]An[3096,13,3097,2002,1861,496,0]An[3096,13,3097,2002,3238,496,0]An[3096,13,3097,2002,3244,496,0]An[3096,13,3097,3641,3212,496,0]An[3096,13,3097,1116,3235,496,0]An[3096,13,3097,1691,4250,496,0]An[3096,13,3097,2305,2260,496,0]An[3096,13,3097,2305,4217,496,0]An[3096,13,3097,2305,4654,496,0]An[3096,13,3097,2305,4228,496,0]An[3096,13,3097,1756,5127,496,0]An[3096,13,3097,4258,5097,496,0]An[3096,13,3097,1392,4468,496,0]An[3096,13,3097,1392,4101,496,0]An[3096,13,3097,1392,4346,496,0]An[3096,13,3097,1810,1444,496,0]An[3096,13,3097,1810,4919,496,0]An[3096,13,3097,3061,1153,496,0]An[3096,13,3097,3070,4753,496,0]An[3096,13,3097,1366,1427,496,0]An[3096,13,3097,1366,4112,496,0]An[3096,13,3097,1366,3233,496,0]An[3096,13,3097,1366,3040,496,0]An[3096,13,3097,1366,4751,496,0]An[3096,13,3097,1366,4807,496,0]An[3096,13,3097,1366,3207,496,0]An[3096,13,3097,1382,2295,496,0]An[3096,13,3097,1382,3218,496,0]An[3096,13,3097,1382,3042,496,0]An[3096,13,3097,1382,4452,496,0]An[3096,13,3097,1120,3045,496,0]An[3096,13,3097,1120,4245,496,0]An[3096,13,3097,1125,1868,496,0]An[3096,13,3097,1125,3258,496,0]An[3096,13,3097,1125,3942,496,0]An[3096,13,3097,2002,3961,496,0]An[3096,13,3097,2002,4356,496,0]An[3096,13,3097,2002,4077,496,0]An[3096,13,3097,3641,4448,496,0]An[3096,13,3097,3641,3038,496,0]An[3096,13,3097,3641,4322,496,0]An[3096,13,3097,3641,5004,496,0]An[3096,13,3097,3641,1174,496,0]An[3096,13,3097,1116,4462,496,0]An[3096,13,3097,3194,4471,496,0]An[3096,13,3097,3194,4777,496,0]An[3096,13,3097,3194,4792,496,0]An[3096,13,3097,3194,3944,496,0]An[3096,13,3097,1691,4332,496,0]An[3096,13,3097,1691,4118,496,0]An[3096,13,3097,1691,4976,496,0]An[3096,13,3097,1691,4069,496,0]An[3096,13,3097,1691,3934,496,0]An[3096,13,3097,1356,3026,496,0]An[3096,13,3097,1356,4337,496,0]An[3096,13,3097,1356,3224,496,0]An[3096,13,3097,1356,3247,496,0]An[3096,13,3097,1356,4084,496,0]An[3096,13,3097,1356,4446,496,0]An[3096,13,3097,1356,4647,496,0]An[3096,13,3097,1356,2253,496,0]An[3096,13,3097,2305,4651,496,0]An[3096,13,3097,2305,2264,496,0]An[3096,13,3097,2305,4080,496,0]An[3096,13,3097,2305,3928,496,0]An[3096,13,3097,2305,3241,496,0]An[3096,13,3097,1756,4240,496,0]An[3096,13,3097,1756,4460,496,0]An[3096,13,3097,1756,5008,496,0]An[3096,13,3097,1756,2267,496,0]An[3096,13,3097,1756,4749,496,0]An[3096,13,3097,1784,4450,496,0]An[3096,13,3097,1784,4218,496,0]An[3096,13,3097,1784,4083,496,0]An[3096,13,3097,1784,4088,496,0]Ak[3096,13,3097,0,4360,496,0]Ak[3096,13,3097,0,4812,496,0]An[3096,13,3097,4258,3221,496,0]An[3096,13,3097,4258,5102,496,0]An[3096,13,3097,4847,4679,496,0]Am[3096,13,3097,3097,511,496,0]Am[3096,13,3097,3097,127,496,0]An[3096,13,3097,3097,2282,496,0]An[3096,13,3097,3097,2292,496,0]An[3096,13,3097,3097,3024,496,0]An[3096,13,1689,1689,4251,496,0]An[3096,13,4960,4960,4858,496,0]An[3096,13,4960,4960,1171,496,0]An[3096,13,1694,1694,1836,496,0]Am[3096,13,1694,1694,498,496,0]An[3096,13,1694,1694,5068,496,0]An[3096,13,1694,1694,3937,496,0]An[3096,13,1694,1694,4818,496,0]An[3096,13,1774,1774,3253,496,0]An[3096,13,1774,1774,4222,496,0]Ak[3096,13,1774,0,1170,496,0]An[3096,13,1774,1774,4675,496,0]An[3096,13,1774,1774,4914,496,0]An[3096,13,1774,1774,4677,496,0]Al[3096,13,3636,148,121,496,0]Am[3096,13,3636,148,3013,496,0]An[3096,13,3636,1352,1157,496,0]An[3096,13,3636,1352,3939,496,0]An[3096,13,3636,2358,1841,496,0]An[3096,13,3636,2358,4238,496,0]An[3096,13,3636,3636,4741,496,0]An[3096,13,4709,4709,1172,496,0]An[3096,13,4709,4709,1175,496,0]An[1985,13,1986,1986,3256,496,0]Am[1985,13,1986,416,4361,496,0]An[1985,13,1986,1986,2279,496,0]An[1985,13,1986,1986,2293,496,0]An[1985,13,1986,1986,4089,496,0]An[1095,13,1096,1096,3015,496,0]An[1095,13,1096,1096,4851,496,0]Am[1095,13,1683,1683,135,496,0]An[1095,13,1381,1381,1190,496,0]An[1095,13,1381,1381,3963,496,0]An[1095,13,1381,1381,4456,496,0]An[1095,13,4178,4178,5053,496,0]An[1095,13,4178,4178,5054,496,0]Am[1095,13,1779,1779,136,496,0]Ac[519,7,520,0,0,0,0]Ae[3968,7,3969,0,0,0,0]Ae[4261,7,4262,0,0,0,0]Ae[2358,7,2359,0,0,0,0]Ae[4771,7,4772,0,0,0,0]Al[3096,13,3097,1120,1407,0,0]Ao[3096,13,3097,2305,4228,2265,0]Ah[463,12,1693,0,4742,0,0]Al[3096,13,3097,2002,1861,0,0]Al[3096,12,1694,1694,4743,0,0]Aj[463,13,464,3640,3211,0,0]Ab[1095,3,0,0,0,0,0]Ai[463,13,464,1094,503,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,13,3097,3641,3212,0,0]Al[3096,14,3097,1382,3218,0,0]Aj[463,12,464,1994,3200,0,0]Am[463,13,464,3640,4475,1415,0]Am[463,13,464,3640,2274,1415,0]Am[463,13,464,1094,2275,1415,0]Am[463,13,464,3640,3209,1415,0]Am[463,13,464,3640,1843,1415,0]Am[463,13,464,3640,1419,1415,0]Am[463,13,464,3640,3004,1415,0]Am[463,13,464,3640,2247,1415,0]Am[463,13,464,3640,4108,1415,0]Am[463,13,464,3640,4113,1415,0]Am[463,13,464,2304,1399,1415,0]Am[463,13,464,2336,4336,1415,0]Am[463,13,464,4041,1857,1415,0]?Aj[463,13,464,4036,3237,0,0]Al[3096,13,3097,2002,3238,0,0]Al[3096,13,4960,4960,4858,0,0]Al[3096,13,3097,3070,3018,0,0]Ak[1985,13,1986,416,4361,0,0]Ah[463,12,1693,0,4742,0,0]Al[3096,12,1694,1694,4743,0,0]32Ag[463,13,464,0,4975,0,0]Al[3096,13,3097,1691,4976,0,0]Aj[463,13,464,3640,3211,0,0]Al[3096,13,3097,3641,3212,0,0]Ah[463,12,1693,0,1831,0,0]Al[3096,12,1694,1694,1832,0,0]Al[1195,14,1380,1380,4357,0,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Ai[3096,14,4459,0,1186,0,0]Aj[463,13,464,4036,3237,0,0]Aj[463,13,464,4036,4859,0,0]Al[3096,13,3097,2002,3238,0,0]Ag[463,12,464,0,3254,0,0]Aj[463,13,464,0,4345,3254,0]Aj[463,13,464,0,4678,3254,0]Al[3096,12,3097,1392,3255,0,0]Ao[3096,13,3097,1392,4346,3255,0]Ao[3096,13,3097,4847,4679,3255,0]Af[463,5,464,3061,0,0,0]Ah[3096,5,3097,3061,0,0,0]Ag[463,5,3635,1352,0,0,0]Ah[3096,5,3636,1352,0,0,0]Al[1095,15,1096,1096,4851,0,0]Ag[463,6,1773,1355,0,0,0]Ah[3096,6,1774,1355,0,0,0]Ae[3096,6,4960,0,0,0,0]Ae[3096,6,4709,0,0,0,0]Ah[3096,6,3097,3641,0,0,0]1Al[3096,15,3097,1356,3224,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Aj[463,15,464,4036,3044,0,0]Ag[463,15,464,0,4447,0,0]Al[3096,15,3097,1120,3045,0,0]Al[3096,15,3097,3641,4448,0,0]Al[3096,15,3097,1756,4460,0,0]0Ae[1195,5,1380,0,0,0,0]Ae[1095,5,1381,0,0,0,0]Al[1195,15,1196,1196,3954,0,0]Al[3096,13,3097,2305,4654,0,0]Ab[1195,3,0,0,0,0,0]Ah[463,12,3635,0,4738,0,0]Ak[463,13,3635,0,3012,4738,0]Ak[463,13,3635,0,3938,4738,0]Ak[463,13,3635,0,4237,4738,0]Al[3096,12,3636,3636,4739,0,0]An[3096,13,3636,148,3013,4739,0]Ao[3096,13,3636,1352,3939,4739,0]Ao[3096,13,3636,2358,4238,4739,0]Al[1095,13,1096,1096,4851,0,0]Ag[463,14,464,0,1152,0,0]Ag[463,14,464,0,2294,0,0]Ag[463,14,464,0,1867,0,0]Al[3096,14,3097,3061,1153,0,0]Al[3096,14,3097,1382,2295,0,0]Al[3096,14,3097,1125,1868,0,0]Al[3096,14,3097,2305,3928,0,0]An[1195,13,1196,1196,134,1154,0]Ao[1195,13,1196,1196,3954,1154,0]Ao[1195,13,1196,1196,3930,1154,0]Am[463,13,464,3640,3211,1154,0]Am[463,13,464,3640,4921,1154,0]Am[463,13,464,3640,4752,1154,0]Am[463,13,464,2304,2259,1154,0]Am[463,13,464,2304,4219,1154,0]Am[463,13,464,4144,1418,1154,0]Al[463,13,464,1094,503,1154,0]Am[463,13,464,1094,4362,1154,0]Am[463,13,464,4036,4355,1154,0]Am[463,13,464,4036,3044,1154,0]Am[463,13,464,4036,3239,1154,0]Am[463,13,464,4036,4354,1154,0]Am[463,13,464,4041,3257,1154,0]Am[463,13,464,4041,4122,1154,0]Aj[463,13,464,0,1443,1154,0]Aj[463,13,464,0,4918,1154,0]Aj[463,13,464,0,1426,1154,0]Aj[463,13,464,0,2294,1154,0]Aj[463,13,464,0,3217,1154,0]Aj[463,13,464,0,3041,1154,0]Aj[463,13,464,0,4451,1154,0]Aj[463,13,464,0,1867,1154,0]Aj[463,13,464,0,4073,1154,0]Aj[463,13,464,0,4447,1154,0]Aj[463,13,464,0,4470,1154,0]Aj[463,13,464,0,4776,1154,0]Aj[463,13,464,0,4791,1154,0]Aj[463,13,464,0,3943,1154,0]Aj[463,13,464,0,4331,1154,0]Aj[463,13,464,0,4116,1154,0]Aj[463,13,464,0,4975,1154,0]Aj[463,13,464,0,4067,1154,0]Aj[463,13,464,0,3933,1154,0]Aj[463,13,464,0,3025,1154,0]Aj[463,13,464,0,4444,1154,0]Aj[463,13,464,0,4645,1154,0]Aj[463,13,464,0,4079,1154,0]Aj[463,13,464,0,4082,1154,0]Aj[463,13,464,0,4087,1154,0]Aj[463,13,464,0,4811,1154,0]Aj[463,13,464,0,3220,1154,0]Ai[463,13,464,0,510,1154,0]Ai[463,13,464,0,126,1154,0]Aj[463,13,464,0,2281,1154,0]Aj[463,13,3635,0,120,1154,0]Ak[463,13,3635,0,3012,1154,0]Ak[463,13,3635,0,1156,1154,0]Ak[463,13,3635,0,3938,1154,0]Ak[463,13,3635,0,1840,1154,0]Ak[463,13,3635,0,4237,1154,0]Ak[463,13,1773,0,1169,1154,0]Ak[463,13,1773,0,4674,1154,0]Ak[463,13,1773,0,4913,1154,0]Ak[463,13,1773,0,4676,1154,0]Ao[3096,13,3097,1810,1444,1154,0]Ao[3096,13,3097,1810,4919,1154,0]Ao[3096,13,3097,3070,4753,1154,0]Ao[3096,13,3097,1366,1427,1154,0]Ao[3096,13,3097,1366,4112,1154,0]Ao[3096,13,3097,1366,3233,1154,0]Ao[3096,13,3097,1366,3040,1154,0]Ao[3096,13,3097,1366,4751,1154,0]Ao[3096,13,3097,1366,4807,1154,0]Ao[3096,13,3097,1366,3207,1154,0]Ao[3096,13,3097,1382,2295,1154,0]Ao[3096,13,3097,1382,3218,1154,0]Ao[3096,13,3097,1382,3042,1154,0]Ao[3096,13,3097,1382,4452,1154,0]Ao[3096,13,3097,1120,3045,1154,0]Ao[3096,13,3097,1120,4245,1154,0]Ao[3096,13,3097,1125,1868,1154,0]Ao[3096,13,3097,1125,3258,1154,0]Ao[3096,13,3097,1125,3942,1154,0]Ao[3096,13,3097,2002,4356,1154,0]Ao[3096,13,3097,2002,4077,1154,0]Ao[3096,13,3097,3641,4448,1154,0]Ao[3096,13,3097,3641,3038,1154,0]Ao[3096,13,3097,3641,4322,1154,0]Ao[3096,13,3097,3641,5004,1154,0]Ao[3096,13,3097,3194,4471,1154,0]Ao[3096,13,3097,3194,4777,1154,0]Ao[3096,13,3097,3194,4792,1154,0]Ao[3096,13,3097,3194,3944,1154,0]Ao[3096,13,3097,1691,4332,1154,0]Ao[3096,13,3097,1691,4118,1154,0]Ao[3096,13,3097,1691,4976,1154,0]Ao[3096,13,3097,1691,4069,1154,0]Ao[3096,13,3097,1691,3934,1154,0]Ao[3096,13,3097,1356,3026,1154,0]Ao[3096,13,3097,1356,3224,1154,0]Ao[3096,13,3097,1356,3247,1154,0]Ao[3096,13,3097,1356,4084,1154,0]Ao[3096,13,3097,1356,4446,1154,0]Ao[3096,13,3097,1356,4647,1154,0]Ao[3096,13,3097,1356,2253,1154,0]Ao[3096,13,3097,2305,4651,1154,0]Ao[3096,13,3097,2305,4080,1154,0]Ao[3096,13,3097,1756,4460,1154,0]Ao[3096,13,3097,1756,5008,1154,0]Ao[3096,13,3097,1756,2267,1154,0]Ao[3096,13,3097,1756,4749,1154,0]Ao[3096,13,3097,1784,4083,1154,0]Ao[3096,13,3097,1784,4088,1154,0]Al[3096,13,3097,0,4360,1154,0]Al[3096,13,3097,0,4812,1154,0]Ao[3096,13,3097,4258,3221,1154,0]Ao[3096,13,3097,4258,5102,1154,0]An[3096,13,3097,3097,511,1154,0]An[3096,13,3097,3097,127,1154,0]Ao[3096,13,3097,3097,2282,1154,0]Ao[3096,13,3097,3097,3024,1154,0]Ao[3096,13,1689,1689,4251,1154,0]Ao[3096,13,4960,4960,4858,1154,0]Ao[3096,13,4960,4960,1171,1154,0]Al[3096,13,1774,0,1170,1154,0]Ao[3096,13,1774,1774,4675,1154,0]Ao[3096,13,1774,1774,4914,1154,0]Ao[3096,13,1774,1774,4677,1154,0]Am[3096,13,3636,148,121,1154,0]An[3096,13,3636,148,3013,1154,0]Ao[3096,13,3636,1352,1157,1154,0]Ao[3096,13,3636,1352,3939,1154,0]Ao[3096,13,3636,2358,1841,1154,0]Ao[3096,13,3636,2358,4238,1154,0]Ao[3096,13,4709,4709,1175,1154,0]Ao[1985,13,1986,1986,2279,1154,0]Ao[1985,13,1986,1986,2293,1154,0]Ao[1985,13,1986,1986,4089,1154,0]Ao[1095,13,1096,1096,4851,1154,0]Ao[1095,13,1381,1381,4456,1154,0]Ao[1095,13,4178,4178,5053,1154,0]Ao[1095,13,4178,4178,5054,1154,0]Aj[463,13,464,3640,3211,0,0]Aj[463,13,464,2304,2259,0,0]Ai[463,13,464,1094,503,0,0]Al[3096,13,3097,3641,3212,0,0]Aj[463,13,464,0,4082,1160,0]Ao[3096,13,3097,1784,4083,1160,0]Ai[3096,14,3097,0,4360,0,0]Ag[463,13,464,0,2281,0,0]Al[3096,13,3097,3097,2282,0,0]Ag[463,13,464,0,4087,0,0]Al[3096,13,3097,1784,4088,0,0]Ah[463,14,1693,0,1835,0,0]Al[3096,14,1694,1694,1836,0,0]Al[3096,12,3097,1756,4782,0,0]Ao[3096,13,3097,1756,5127,4782,0];Al[1195,13,1380,1380,1189,0,0]Ai[519,13,520,520,3931,0,0]Al[1095,13,1381,1381,1190,0,0]Aj[463,12,464,1994,3200,0,0]Aj[463,13,464,4041,3243,0,0]Al[3096,13,3097,2002,3244,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2260,0,0]Aj[463,12,464,1994,1852,0,0]Am[463,13,464,1393,4123,1852,0]Am[463,13,464,1137,3957,1852,0]Ae[1195,2,1196,0,0,0,0]Ak[1195,14,1196,1196,134,0,0]Aj[463,13,464,3640,3211,0,0]Aj[463,13,464,2304,2259,0,0]Ai[463,13,464,1094,503,0,0]Al[3096,13,3097,3641,3212,0,0]Ae[1095,2,1096,0,0,0,0]Ag[463,13,464,0,3234,0,0]Al[3096,13,3097,1116,3235,0,0]?>Al[3096,13,4960,4960,4858,0,0]Af[463,5,464,2304,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Al[1195,15,1196,1196,3930,0,0]0Al[3096,15,3097,1366,3233,0,0]Ah[3096,5,3097,1120,0,0,0]Af[463,15,464,0,510,0,0]Al[2358,15,2359,2359,2250,0,0]Ak[3096,15,3097,3097,511,0,0]Al[3096,15,4709,4709,1172,0,0]87Af[463,5,464,4144,0,0,0]Af[463,5,464,3640,0,0,0]Al[3096,15,3097,1366,3040,0,0]Al[3096,15,3097,2002,3961,0,0]Af[463,5,464,1366,0,0,0]Ah[3096,5,3097,1366,0,0,0]Ae[3096,8,1689,0,0,0,0]:98?Al[3096,15,3097,3641,1174,0,0]?Af[463,5,464,1810,0,0,0]Ah[3096,5,3097,1810,0,0,0]Aj[463,13,464,2304,2259,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2002,1861,0,0]Al[3096,13,3097,2305,2260,0,0]An[1195,13,1196,1196,134,1405,0]Ao[1195,13,1196,1196,3954,1405,0]Ao[1195,13,1196,1196,3930,1405,0]Ao[1195,13,1380,1380,3962,1405,0]Ao[1195,13,1380,1380,1189,1405,0]Ao[1195,13,1380,1380,4357,1405,0]Al[519,13,520,520,3931,1405,0]Ao[3968,13,3969,3969,5009,1405,0]Am[463,13,464,3640,4475,1405,0]Am[463,13,464,3640,2274,1405,0]Aj[463,13,464,0,4210,1405,0]Am[463,13,464,4144,4915,1405,0]Am[463,13,464,1094,2275,1405,0]Am[463,13,464,1094,4643,1405,0]Am[463,13,464,3640,3209,1405,0]Am[463,13,464,3640,3211,1405,0]Am[463,13,464,3640,1843,1405,0]Am[463,13,464,3640,1419,1405,0]Am[463,13,464,3640,3004,1405,0]Am[463,13,464,3640,2247,1405,0]Am[463,13,464,3640,4108,1405,0]Am[463,13,464,3640,4113,1405,0]Am[463,13,464,3640,4921,1405,0]Am[463,13,464,3640,4752,1405,0]Am[463,13,464,2304,2259,1405,0]Am[463,13,464,2304,4219,1405,0]Am[463,13,464,2304,1399,1405,0]Am[463,13,464,4144,1418,1405,0]Am[463,13,464,4144,3231,1405,0]Am[463,13,464,4144,4852,1405,0]Am[463,13,464,2336,2263,1405,0]Am[463,13,464,2336,3240,1405,0]Am[463,13,464,2336,4336,1405,0]Al[463,13,464,1094,503,1405,0]Am[463,13,464,1094,4362,1405,0]Am[463,13,464,4036,3237,1405,0]Am[463,13,464,4036,4859,1405,0]Am[463,13,464,4036,4355,1405,0]Am[463,13,464,4036,3044,1405,0]Am[463,13,464,4036,3239,1405,0]Am[463,13,464,4036,4354,1405,0]Am[463,13,464,1393,4123,1405,0]Am[463,13,464,1137,3957,1405,0]Am[463,13,464,4041,3243,1405,0]Am[463,13,464,4041,3257,1405,0]Am[463,13,464,4041,4122,1405,0]Am[463,13,464,4041,1857,1405,0]Aj[463,13,464,0,3234,1405,0]Aj[463,13,464,0,4249,1405,0]Aj[463,13,464,0,4467,1405,0]Aj[463,13,464,0,4100,1405,0]Aj[463,13,464,0,4345,1405,0]Aj[463,13,464,0,1443,1405,0]Aj[463,13,464,0,4918,1405,0]Aj[463,13,464,0,1152,1405,0]Aj[463,13,464,0,1426,1405,0]Aj[463,13,464,0,2294,1405,0]Aj[463,13,464,0,3217,1405,0]Aj[463,13,464,0,3041,1405,0]Aj[463,13,464,0,4451,1405,0]Aj[463,13,464,0,1867,1405,0]Aj[463,13,464,0,4073,1405,0]Aj[463,13,464,0,4447,1405,0]Aj[463,13,464,0,4461,1405,0]Aj[463,13,464,0,4470,1405,0]Aj[463,13,464,0,4776,1405,0]Aj[463,13,464,0,4791,1405,0]Aj[463,13,464,0,3943,1405,0]Aj[463,13,464,0,4331,1405,0]Aj[463,13,464,0,4116,1405,0]Aj[463,13,464,0,4975,1405,0]Aj[463,13,464,0,4067,1405,0]Aj[463,13,464,0,3933,1405,0]Aj[463,13,464,0,3025,1405,0]Aj[463,13,464,0,4444,1405,0]Aj[463,13,464,0,4645,1405,0]Aj[463,13,464,0,4079,1405,0]Aj[463,13,464,0,4082,1405,0]Aj[463,13,464,0,4087,1405,0]Aj[463,13,464,0,4811,1405,0]Aj[463,13,464,0,3220,1405,0]Aj[463,13,464,0,4678,1405,0]Ai[463,13,464,0,510,1405,0]Ai[463,13,464,0,126,1405,0]Aj[463,13,464,0,2281,1405,0]Aj[463,13,464,0,2291,1405,0]Aj[463,13,3635,0,120,1405,0]Ak[463,13,3635,0,3012,1405,0]Ak[463,13,3635,0,1156,1405,0]Ak[463,13,3635,0,3938,1405,0]Ak[463,13,3635,0,1840,1405,0]Ak[463,13,3635,0,4237,1405,0]Ak[463,13,3635,0,4740,1405,0]Ak[463,13,1693,0,1835,1405,0]Aj[463,13,1693,0,497,1405,0]Ak[463,13,1693,0,5067,1405,0]Ak[463,13,1693,0,3936,1405,0]Ak[463,13,1693,0,4815,1405,0]Ak[463,13,1773,0,3252,1405,0]Ak[463,13,1773,0,4221,1405,0]Ak[463,13,1773,0,1169,1405,0]Ak[463,13,1773,0,4674,1405,0]Ak[463,13,1773,0,4913,1405,0]Ak[463,13,1773,0,4676,1405,0]An[2358,13,2359,2359,125,1405,0]Ao[2358,13,2359,2359,2250,1405,0]Ao[3096,13,3097,4480,4211,1405,0]Ao[3096,13,3097,3070,3018,1405,0]Ao[3096,13,3097,1120,1407,1405,0]Ao[3096,13,3097,2002,1861,1405,0]Ao[3096,13,3097,2002,3238,1405,0]Ao[3096,13,3097,2002,3244,1405,0]Ao[3096,13,3097,3641,3212,1405,0]Ao[3096,13,3097,1116,3235,1405,0]Ao[3096,13,3097,1691,4250,1405,0]Ao[3096,13,3097,2305,2260,1405,0]Ao[3096,13,3097,2305,4217,1405,0]Ao[3096,13,3097,2305,4654,1405,0]Ao[3096,13,3097,2305,4228,1405,0]Ao[3096,13,3097,1756,5127,1405,0]Ao[3096,13,3097,4258,5097,1405,0]Ao[3096,13,3097,1392,4468,1405,0]Ao[3096,13,3097,1392,4101,1405,0]Ao[3096,13,3097,1392,4346,1405,0]Ao[3096,13,3097,1810,1444,1405,0]Ao[3096,13,3097,1810,4919,1405,0]Ao[3096,13,3097,3061,1153,1405,0]Ao[3096,13,3097,3070,4753,1405,0]Ao[3096,13,3097,1366,1427,1405,0]Ao[3096,13,3097,1366,4112,1405,0]Ao[3096,13,3097,1366,3233,1405,0]Ao[3096,13,3097,1366,3040,1405,0]Ao[3096,13,3097,1366,4751,1405,0]Ao[3096,13,3097,1366,4807,1405,0]Ao[3096,13,3097,1366,3207,1405,0]Ao[3096,13,3097,1382,2295,1405,0]Ao[3096,13,3097,1382,3218,1405,0]Ao[3096,13,3097,1382,3042,1405,0]Ao[3096,13,3097,1382,4452,1405,0]Ao[3096,13,3097,1120,3045,1405,0]Ao[3096,13,3097,1120,4245,1405,0]Ao[3096,13,3097,1125,1868,1405,0]Ao[3096,13,3097,1125,3258,1405,0]Ao[3096,13,3097,1125,3942,1405,0]Ao[3096,13,3097,2002,3961,1405,0]Ao[3096,13,3097,2002,4356,1405,0]Ao[3096,13,3097,2002,4077,1405,0]Ao[3096,13,3097,3641,4448,1405,0]Ao[3096,13,3097,3641,3038,1405,0]Ao[3096,13,3097,3641,4322,1405,0]Ao[3096,13,3097,3641,5004,1405,0]Ao[3096,13,3097,3641,1174,1405,0]Ao[3096,13,3097,1116,4462,1405,0]Ao[3096,13,3097,3194,4471,1405,0]Ao[3096,13,3097,3194,4777,1405,0]Ao[3096,13,3097,3194,4792,1405,0]Ao[3096,13,3097,3194,3944,1405,0]Ao[3096,13,3097,1691,4332,1405,0]Ao[3096,13,3097,1691,4118,1405,0]Ao[3096,13,3097,1691,4976,1405,0]Ao[3096,13,3097,1691,4069,1405,0]Ao[3096,13,3097,1691,3934,1405,0]Ao[3096,13,3097,1356,3026,1405,0]Ao[3096,13,3097,1356,4337,1405,0]Ao[3096,13,3097,1356,3224,1405,0]Ao[3096,13,3097,1356,3247,1405,0]Ao[3096,13,3097,1356,4084,1405,0]Ao[3096,13,3097,1356,4446,1405,0]Ao[3096,13,3097,1356,4647,1405,0]Ao[3096,13,3097,1356,2253,1405,0]Ao[3096,13,3097,2305,4651,1405,0]Ao[3096,13,3097,2305,2264,1405,0]Ao[3096,13,3097,2305,4080,1405,0]Ao[3096,13,3097,2305,3928,1405,0]Ao[3096,13,3097,2305,3241,1405,0]Ao[3096,13,3097,1756,4240,1405,0]Ao[3096,13,3097,1756,4460,1405,0]Ao[3096,13,3097,1756,5008,1405,0]Ao[3096,13,3097,1756,2267,1405,0]Ao[3096,13,3097,1756,4749,1405,0]Ao[3096,13,3097,1784,4450,1405,0]Ao[3096,13,3097,1784,4218,1405,0]Ao[3096,13,3097,1784,4083,1405,0]Ao[3096,13,3097,1784,4088,1405,0]Al[3096,13,3097,0,4360,1405,0]Al[3096,13,3097,0,4812,1405,0]Ao[3096,13,3097,4258,3221,1405,0]Ao[3096,13,3097,4258,5102,1405,0]Ao[3096,13,3097,4847,4679,1405,0]An[3096,13,3097,3097,511,1405,0]An[3096,13,3097,3097,127,1405,0]Ao[3096,13,3097,3097,2282,1405,0]Ao[3096,13,3097,3097,2292,1405,0]Ao[3096,13,3097,3097,3024,1405,0]Ao[3096,13,1689,1689,4251,1405,0]Ao[3096,13,4960,4960,4858,1405,0]Ao[3096,13,4960,4960,1171,1405,0]Ao[3096,13,1694,1694,1836,1405,0]An[3096,13,1694,1694,498,1405,0]Ao[3096,13,1694,1694,5068,1405,0]Ao[3096,13,1694,1694,3937,1405,0]Ao[3096,13,1694,1694,4818,1405,0]Ao[3096,13,1774,1774,3253,1405,0]Ao[3096,13,1774,1774,4222,1405,0]Al[3096,13,1774,0,1170,1405,0]Ao[3096,13,1774,1774,4675,1405,0]Ao[3096,13,1774,1774,4914,1405,0]Ao[3096,13,1774,1774,4677,1405,0]Am[3096,13,3636,148,121,1405,0]An[3096,13,3636,148,3013,1405,0]Ao[3096,13,3636,1352,1157,1405,0]Ao[3096,13,3636,1352,3939,1405,0]Ao[3096,13,3636,2358,1841,1405,0]Ao[3096,13,3636,2358,4238,1405,0]Ao[3096,13,3636,3636,4741,1405,0]Ao[3096,13,4709,4709,1172,1405,0]Ao[3096,13,4709,4709,1175,1405,0]Ao[1985,13,1986,1986,3256,1405,0]An[1985,13,1986,416,4361,1405,0]Ao[1985,13,1986,1986,2279,1405,0]Ao[1985,13,1986,1986,2293,1405,0]Ao[1985,13,1986,1986,4089,1405,0]Ao[1095,13,1096,1096,3015,1405,0]Ao[1095,13,1096,1096,4851,1405,0]An[1095,13,1683,1683,135,1405,0]Ao[1095,13,1381,1381,1190,1405,0]Ao[1095,13,1381,1381,3963,1405,0]Ao[1095,13,1381,1381,4456,1405,0]Ao[1095,13,4178,4178,5053,1405,0]Ao[1095,13,4178,4178,5054,1405,0]An[1095,13,1779,1779,136,1405,0]Ag[463,14,464,0,1867,0,0]Al[3096,14,3097,1125,1868,0,0]Ak[1195,14,1196,1196,134,0,0]Ac[519,7,520,0,0,0,0]Aj[463,13,464,2304,2259,0,0]Ae[1095,2,1096,0,0,0,0]Ae[4771,7,4772,0,0,0,0]Aj[463,13,464,3640,3211,0,0]Ae[3096,2,3097,0,0,0,0]Al[3096,13,3097,2305,2260,0,0]Af[463,2,464,3097,0,0,0]Ag[463,13,464,0,4811,0,0]Ag[463,14,464,0,3217,0,0]Ag[463,14,464,0,4116,0,0]5Ai[3096,13,3097,0,4812,0,0]Al[3096,14,3097,1382,3218,0,0]Al[3096,14,3097,1691,4118,0,0]Ai[3096,14,3097,0,4360,0,0]Aj[463,13,464,0,1443,3019,0]Aj[463,13,464,0,1426,3019,0]Aj[463,13,464,0,3025,3019,0]Aj[463,13,464,0,4811,3019,0]Aj[463,13,464,0,2281,3019,0]Ao[3096,13,3097,1810,1444,3019,0]Ao[3096,13,3097,1366,1427,3019,0]Ao[3096,13,3097,1356,3026,3019,0]Ao[3096,13,3097,1356,3224,3019,0]Al[3096,13,3097,1756,4460,0,0]Al[3096,13,3097,0,4812,3019,0]Ao[3096,13,3097,3097,2282,3019,0]Al[3096,12,1689,1689,3019,0,0]Al[1985,14,1986,1986,2279,0,0]Aj[463,13,464,0,1443,3022,0]Aj[463,13,464,0,1426,3022,0]Aj[463,13,464,0,3025,3022,0]Aj[463,13,464,0,4811,3022,0]Aj[463,13,464,0,2281,3022,0]Ao[3096,13,3097,1810,1444,3022,0]Ao[3096,13,3097,1366,1427,3022,0]Ao[3096,13,3097,1356,3026,3022,0]Ao[3096,13,3097,1356,3224,3022,0]Ao[3096,13,3097,1356,2253,3022,0]Al[3096,13,3097,0,4812,3022,0]Ao[3096,13,3097,3097,2282,3022,0]Al[3096,12,1689,1689,3022,0,0]Aj[463,13,464,4041,3243,0,0]Al[3096,13,3097,2002,3244,0,0]Al[1095,13,1381,1381,3963,0,0]Al[3096,13,3097,2305,2260,0,0]Ag[463,14,1693,0,497,0,0]Ak[3096,14,1694,1694,498,0,0]Aj[463,13,464,2336,2263,0,0]3Ag[463,12,464,0,3254,0,0]Aj[463,13,464,0,4345,3254,0]Aj[463,13,464,0,4678,3254,0]Al[3096,12,3097,1392,3255,0,0]Ao[3096,13,3097,1392,4346,3255,0]Ao[3096,13,3097,4847,4679,3255,0]Al[1095,14,1096,1096,3015,0,0]Ag[463,14,464,0,1152,0,0]Al[3096,14,3097,3061,1153,0,0]Ah[463,13,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,13,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Ag[463,14,1693,0,497,0,0]Ak[3096,14,1694,1694,498,0,0]Ai[3096,14,4459,0,4683,0,0]Ag[463,14,464,0,4444,0,0]Ag[463,14,464,0,4645,0,0]Al[3096,14,3097,1356,4446,0,0]Al[3096,14,3097,1356,4647,0,0]Ai[3096,14,3097,0,4360,0,0]Ai[3096,14,1173,0,4324,0,0]Ai[3096,14,3039,0,3002,0,0]Aj[463,13,464,2304,2259,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2260,0,0]Ah[463,14,1693,0,1835,0,0]Al[3096,13,3097,3097,3024,0,0]Al[3096,14,1694,1694,1836,0,0]Ac[463,4,464,0,0,0,0]Ag[463,2,1693,1694,0,0,0]Ae[3096,4,3097,0,0,0,0]Ae[3096,2,1694,0,0,0,0]Ac[519,7,520,0,0,0,0]:Ae[1095,2,1096,0,0,0,0]Ae[4771,7,4772,0,0,0,0]Am[463,13,464,3640,4752,1162,0]Am[463,13,464,4036,4355,1162,0]Am[463,13,464,4036,3044,1162,0]Am[463,13,464,4036,3239,1162,0]Am[463,13,464,4036,4354,1162,0]Am[463,13,464,4041,3257,1162,0]Am[463,13,464,4041,4122,1162,0]Aj[463,13,464,0,4447,1162,0]Ao[3096,13,3097,3641,4448,1162,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Al[1985,14,1986,1986,2293,0,0]Ai[463,13,464,1094,503,0,0]Ai[3096,14,3039,0,4109,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]Al[1985,14,1986,1986,2279,0,0]Ag[463,14,464,0,3041,0,0]Ag[463,14,464,0,4451,0,0]Al[3096,14,3097,1382,3042,0,0]Al[3096,14,3097,1382,4452,0,0]3210Ah[463,12,1693,0,1831,0,0]Al[3096,12,1694,1694,1832,0,0]Ah[463,12,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,12,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Al[3096,15,3097,3070,4753,0,0]Al[3096,15,3097,1120,3045,0,0]Al[3096,15,3097,1125,3258,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Ah[463,10,1693,1694,0,0,0]Af[3096,10,1694,0,0,0,0]Al[3096,15,3097,1756,4460,0,0]Ag[463,5,1693,1694,0,0,0]Ae[3096,5,1694,0,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Ag[463,5,3635,2358,0,0,0]Ah[3096,5,3636,2358,0,0,0]Al[1095,15,1096,1096,4851,0,0]Af[463,5,464,3640,0,0,0]5454Ag[463,10,464,1994,0,0,0];:Aj[463,15,464,4041,3257,0,0]Af[463,5,464,4041,0,0,0]Al[3096,15,3097,1125,3258,0,0]Al[3096,15,3097,1125,3942,0,0]Al[3096,15,3097,2002,3961,0,0]Ah[3096,5,3097,2002,0,0,0]Aj[463,15,464,4036,4355,0,0]Al[3096,15,3097,1356,3224,0,0]Af[463,5,464,1125,0,0,0]Ah[3096,5,3097,1125,0,0,0]Al[3096,15,3097,1756,2267,0,0]Ag[463,12,464,0,4966,0,0]Al[3096,12,3097,4258,4967,0,0]Ao[3096,13,3097,4258,5097,4967,0]Ao[3096,13,3097,4258,5102,4967,0]Ak[1195,14,1196,1196,134,0,0]An[1195,13,1196,1196,134,4323,0]An[2358,13,2359,2359,125,4323,0]Ak[2358,14,2359,2359,125,0,0]Ao[1095,13,1096,1096,3015,4323,0]An[1095,13,1683,1683,135,4323,0]An[1095,13,1779,1779,136,4323,0]Aj[463,13,464,0,1443,3208,0]Aj[463,13,464,0,1426,3208,0]Aj[463,13,464,0,3943,3208,0]Aj[463,13,464,0,4082,3208,0]Ai[463,13,464,0,510,3208,0]Ai[463,13,464,0,126,3208,0]Aj[463,13,464,0,2281,3208,0]Ao[3096,13,3097,1810,1444,3208,0]Ao[3096,13,3097,3070,4753,3208,0]Ao[3096,13,3097,1366,1427,3208,0]Ao[3096,13,3097,1120,3045,3208,0]Ao[3096,13,3097,1120,4245,3208,0]Ao[3096,13,3097,1125,3258,3208,0]Ao[3096,13,3097,3194,3944,3208,0]Ao[3096,13,3097,2305,4651,3208,0]Ao[3096,13,3097,1756,4749,3208,0]Ao[3096,13,3097,1784,4083,3208,0]An[3096,13,3097,3097,511,3208,0]An[3096,13,3097,3097,127,3208,0]Ao[3096,13,3097,3097,2282,3208,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,2305,2260,0,0]Aj[463,13,464,2336,2263,0,0]Ah[463,12,1693,0,3035,0,0]Ah[463,12,1693,0,3028,0,0]Al[3096,13,3097,2305,2264,0,0]Al[3096,12,1694,1694,3036,0,0]Al[3096,12,1694,1694,3029,0,0]Ao[1195,13,1380,1380,3962,1826,0]Ao[1195,13,1380,1380,1189,1826,0]Al[519,13,520,520,3931,1826,0]Aj[463,13,464,0,4210,1826,0]Am[463,13,464,2304,4219,1826,0]Aj[463,13,464,0,1443,1826,0]Aj[463,13,464,0,1426,1826,0]Aj[463,13,464,0,2294,1826,0]Aj[463,13,464,0,3217,1826,0]Aj[463,13,464,0,3041,1826,0]Aj[463,13,464,0,4451,1826,0]Aj[463,13,464,0,1867,1826,0]Aj[463,13,464,0,4073,1826,0]Aj[463,13,464,0,4470,1826,0]Aj[463,13,464,0,4776,1826,0]Aj[463,13,464,0,4791,1826,0]Aj[463,13,464,0,3943,1826,0]Aj[463,13,464,0,4331,1826,0]Aj[463,13,464,0,4975,1826,0]Aj[463,13,464,0,4678,1826,0]Ak[463,13,3635,0,3012,1826,0]Ak[463,13,3635,0,3938,1826,0]Ak[463,13,3635,0,4237,1826,0]Ak[463,13,3635,0,4740,1826,0]Ao[3096,13,3097,4480,4211,1826,0]Ao[3096,13,3097,4258,5097,1826,0]Ao[3096,13,3097,1810,1444,1826,0]Ao[3096,13,3097,1366,1427,1826,0]Ao[3096,13,3097,1366,3233,1826,0]Ao[3096,13,3097,1366,3207,1826,0]Ao[3096,13,3097,1382,2295,1826,0]Ao[3096,13,3097,1382,3218,1826,0]Ao[3096,13,3097,1382,3042,1826,0]Ao[3096,13,3097,1382,4452,1826,0]Ao[3096,13,3097,1125,1868,1826,0]Ao[3096,13,3097,2002,4356,1826,0]Ao[3096,13,3097,2002,4077,1826,0]Ao[3096,13,3097,3194,4471,1826,0]Ao[3096,13,3097,3194,4777,1826,0]Ao[3096,13,3097,3194,4792,1826,0]Ao[3096,13,3097,3194,3944,1826,0]Ao[3096,13,3097,1691,4332,1826,0]Ao[3096,13,3097,1691,4976,1826,0]Ao[3096,13,3097,4258,5102,1826,0]Ao[3096,13,3097,4847,4679,1826,0]An[3096,13,3636,148,3013,1826,0]Ao[3096,13,3636,1352,3939,1826,0]Ao[3096,13,3636,2358,4238,1826,0]Ao[3096,13,3636,3636,4741,1826,0]Ao[1985,13,1986,1986,2279,1826,0]Ao[1095,13,1381,1381,1190,1826,0]Ao[1095,13,1381,1381,4456,1826,0]Al[3096,13,3097,1784,4218,0,0]Al[3096,13,3097,1756,4240,0,0]Al[3096,13,3097,1756,4460,0,0]Al[3096,14,3097,1756,5008,0,0]Ai[3096,14,4748,0,4813,0,0]Ah[3096,14,4459,0,499,0,0]Ai[3096,14,4459,0,1184,0,0]Ai[3096,14,4459,0,1186,0,0]Ai[3096,14,4459,0,4683,0,0]Ah[463,12,1693,0,3035,0,0]Ah[463,12,1693,0,3028,0,0]Al[3096,12,1694,1694,3036,0,0]Al[3096,12,1694,1694,3029,0,0]Aj[463,13,464,4036,3237,0,0]Aj[463,13,464,4036,4859,0,0]Ah[463,13,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,13,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Ag[463,13,464,0,4470,0,0]Al[3096,13,3097,3194,4471,0,0]Ab[1985,3,0,0,0,0,0]:965Aj[463,13,464,3640,3211,0,0]Aj[463,13,464,1094,2275,0,0]Al[3096,14,3097,1756,5008,0,0]Ai[3096,14,4748,0,4813,0,0]Ah[3096,14,4459,0,499,0,0]Ai[3096,14,4459,0,1184,0,0]Ai[3096,14,4459,0,4683,0,0]Aj[463,13,464,4041,3243,0,0]Al[3096,13,3097,2002,3244,0,0]Ak[1195,14,1196,1196,134,0,0]Al[1195,14,1380,1380,1189,0,0]Al[3096,13,3097,3641,3212,0,0]Ah[463,12,1693,0,3035,0,0]Al[3096,12,1694,1694,3036,0,0]Am[1195,13,1196,1196,134,118,0]An[1195,13,1196,1196,3954,118,0]An[1195,13,1196,1196,3930,118,0]An[1195,13,1380,1380,3962,118,0]An[1195,13,1380,1380,1189,118,0]An[1195,13,1380,1380,4357,118,0]Ak[519,13,520,520,3931,118,0]An[3968,13,3969,3969,5009,118,0]Al[463,13,464,3640,4475,118,0]Al[463,13,464,3640,2274,118,0]Ai[463,13,464,0,4210,118,0]Al[463,13,464,4144,4915,118,0]Al[463,13,464,1094,2275,118,0]Al[463,13,464,1094,4643,118,0]Al[463,13,464,3640,3209,118,0]Al[463,13,464,3640,3211,118,0]Al[463,13,464,3640,1843,118,0]Al[463,13,464,3640,1419,118,0]Al[463,13,464,3640,3004,118,0]Al[463,13,464,3640,2247,118,0]Al[463,13,464,3640,4108,118,0]Al[463,13,464,3640,4113,118,0]Al[463,13,464,3640,4921,118,0]Al[463,13,464,3640,4752,118,0]Al[463,13,464,2304,2259,118,0]Al[463,13,464,2304,4219,118,0]Al[463,13,464,2304,1399,118,0]Al[463,13,464,4144,1418,118,0]Al[463,13,464,4144,3231,118,0]Al[463,13,464,4144,4852,118,0]Al[463,13,464,2336,2263,118,0]Al[463,13,464,2336,3240,118,0]Al[463,13,464,2336,4336,118,0]Ak[463,13,464,1094,503,118,0]Al[463,13,464,1094,4362,118,0]Al[463,13,464,4036,3237,118,0]Al[463,13,464,4036,4859,118,0]Al[463,13,464,4036,4355,118,0]Al[463,13,464,4036,3044,118,0]Al[463,13,464,4036,3239,118,0]Al[463,13,464,4036,4354,118,0]Al[463,13,464,1393,4123,118,0]Al[463,13,464,1137,3957,118,0]Al[463,13,464,4041,3243,118,0]Al[463,13,464,4041,3257,118,0]Al[463,13,464,4041,4122,118,0]Al[463,13,464,4041,1857,118,0]Ai[463,13,464,0,3234,118,0]Ai[463,13,464,0,4249,118,0]Ai[463,13,464,0,4467,118,0]Ai[463,13,464,0,4100,118,0]Ai[463,13,464,0,4345,118,0]Ai[463,13,464,0,1443,118,0]Ai[463,13,464,0,4918,118,0]Ai[463,13,464,0,1152,118,0]Ai[463,13,464,0,1426,118,0]Ai[463,13,464,0,2294,118,0]Ai[463,13,464,0,3217,118,0]Ai[463,13,464,0,3041,118,0]Ai[463,13,464,0,4451,118,0]Ai[463,13,464,0,1867,118,0]Ai[463,13,464,0,4073,118,0]Ai[463,13,464,0,4447,118,0]Ai[463,13,464,0,4461,118,0]Ai[463,13,464,0,4470,118,0]Ai[463,13,464,0,4776,118,0]Ai[463,13,464,0,4791,118,0]Ai[463,13,464,0,3943,118,0]Ai[463,13,464,0,4331,118,0]Ai[463,13,464,0,4116,118,0]Ai[463,13,464,0,4975,118,0]Ai[463,13,464,0,4067,118,0]Ai[463,13,464,0,3933,118,0]Ai[463,13,464,0,3025,118,0]Ai[463,13,464,0,4444,118,0]Ai[463,13,464,0,4645,118,0]Ai[463,13,464,0,4079,118,0]Ai[463,13,464,0,4082,118,0]Ai[463,13,464,0,4087,118,0]Ai[463,13,464,0,4811,118,0]Ai[463,13,464,0,3220,118,0]Ai[463,13,464,0,4678,118,0]Ah[463,13,464,0,510,118,0]Ah[463,13,464,0,126,118,0]Ai[463,13,464,0,2281,118,0]Ai[463,13,464,0,2291,118,0]Ai[463,13,3635,0,120,118,0]Aj[463,13,3635,0,3012,118,0]Aj[463,13,3635,0,1156,118,0]Aj[463,13,3635,0,3938,118,0]Aj[463,13,3635,0,1840,118,0]Aj[463,13,3635,0,4237,118,0]Aj[463,13,3635,0,4740,118,0]Aj[463,13,1693,0,1835,118,0]Ai[463,13,1693,0,497,118,0]Aj[463,13,1693,0,5067,118,0]Aj[463,13,1693,0,3936,118,0]Aj[463,13,1693,0,4815,118,0]Aj[463,13,1773,0,3252,118,0]Aj[463,13,1773,0,4221,118,0]Aj[463,13,1773,0,1169,118,0]Aj[463,13,1773,0,4674,118,0]Aj[463,13,1773,0,4913,118,0]Aj[463,13,1773,0,4676,118,0]Am[2358,13,2359,2359,125,118,0]An[2358,13,2359,2359,2250,118,0]An[3096,13,3097,4480,4211,118,0]An[3096,13,3097,3070,3018,118,0]An[3096,13,3097,1120,1407,118,0]An[3096,13,3097,2002,1861,118,0]An[3096,13,3097,2002,3238,118,0]An[3096,13,3097,2002,3244,118,0]An[3096,13,3097,3641,3212,118,0]An[3096,13,3097,1116,3235,118,0]An[3096,13,3097,1691,4250,118,0]An[3096,13,3097,2305,2260,118,0]An[3096,13,3097,2305,4217,118,0]An[3096,13,3097,2305,4654,118,0]An[3096,13,3097,2305,4228,118,0]An[3096,13,3097,1756,5127,118,0]An[3096,13,3097,4258,5097,118,0]An[3096,13,3097,1392,4468,118,0]An[3096,13,3097,1392,4101,118,0]An[3096,13,3097,1392,4346,118,0]An[3096,13,3097,1810,1444,118,0]An[3096,13,3097,1810,4919,118,0]An[3096,13,3097,3061,1153,118,0]An[3096,13,3097,3070,4753,118,0]An[3096,13,3097,1366,1427,118,0]An[3096,13,3097,1366,4112,118,0]An[3096,13,3097,1366,3233,118,0]An[3096,13,3097,1366,3040,118,0]An[3096,13,3097,1366,4751,118,0]An[3096,13,3097,1366,4807,118,0]An[3096,13,3097,1366,3207,118,0]An[3096,13,3097,1382,2295,118,0]An[3096,13,3097,1382,3218,118,0]An[3096,13,3097,1382,3042,118,0]An[3096,13,3097,1382,4452,118,0]An[3096,13,3097,1120,3045,118,0]An[3096,13,3097,1120,4245,118,0]An[3096,13,3097,1125,1868,118,0]An[3096,13,3097,1125,3258,118,0]An[3096,13,3097,1125,3942,118,0]An[3096,13,3097,2002,3961,118,0]An[3096,13,3097,2002,4356,118,0]An[3096,13,3097,2002,4077,118,0]An[3096,13,3097,3641,4448,118,0]An[3096,13,3097,3641,3038,118,0]An[3096,13,3097,3641,4322,118,0]An[3096,13,3097,3641,5004,118,0]An[3096,13,3097,3641,1174,118,0]An[3096,13,3097,1116,4462,118,0]An[3096,13,3097,3194,4471,118,0]An[3096,13,3097,3194,4777,118,0]An[3096,13,3097,3194,4792,118,0]An[3096,13,3097,3194,3944,118,0]An[3096,13,3097,1691,4332,118,0]An[3096,13,3097,1691,4118,118,0]An[3096,13,3097,1691,4976,118,0]An[3096,13,3097,1691,4069,118,0]An[3096,13,3097,1691,3934,118,0]An[3096,13,3097,1356,3026,118,0]An[3096,13,3097,1356,4337,118,0]An[3096,13,3097,1356,3224,118,0]An[3096,13,3097,1356,3247,118,0]An[3096,13,3097,1356,4084,118,0]An[3096,13,3097,1356,4446,118,0]An[3096,13,3097,1356,4647,118,0]An[3096,13,3097,1356,2253,118,0]An[3096,13,3097,2305,4651,118,0]An[3096,13,3097,2305,2264,118,0]An[3096,13,3097,2305,4080,118,0]An[3096,13,3097,2305,3928,118,0]An[3096,13,3097,2305,3241,118,0]An[3096,13,3097,1756,4240,118,0]An[3096,13,3097,1756,4460,118,0]An[3096,13,3097,1756,5008,118,0]An[3096,13,3097,1756,2267,118,0]An[3096,13,3097,1756,4749,118,0]An[3096,13,3097,1784,4450,118,0]An[3096,13,3097,1784,4218,118,0]An[3096,13,3097,1784,4083,118,0]An[3096,13,3097,1784,4088,118,0]Ak[3096,13,3097,0,4360,118,0]Ak[3096,13,3097,0,4812,118,0]An[3096,13,3097,4258,3221,118,0]An[3096,13,3097,4258,5102,118,0]An[3096,13,3097,4847,4679,118,0]Am[3096,13,3097,3097,511,118,0]Am[3096,13,3097,3097,127,118,0]An[3096,13,3097,3097,2282,118,0]An[3096,13,3097,3097,2292,118,0]An[3096,13,3097,3097,3024,118,0]An[3096,13,1689,1689,4251,118,0]An[3096,13,4960,4960,4858,118,0]An[3096,13,4960,4960,1171,118,0]An[3096,13,1694,1694,1836,118,0]Am[3096,13,1694,1694,498,118,0]An[3096,13,1694,1694,5068,118,0]An[3096,13,1694,1694,3937,118,0]An[3096,13,1694,1694,4818,118,0]An[3096,13,1774,1774,3253,118,0]An[3096,13,1774,1774,4222,118,0]Ak[3096,13,1774,0,1170,118,0]An[3096,13,1774,1774,4675,118,0]An[3096,13,1774,1774,4914,118,0]An[3096,13,1774,1774,4677,118,0]Al[3096,13,3636,148,121,118,0]Am[3096,13,3636,148,3013,118,0]An[3096,13,3636,1352,1157,118,0]An[3096,13,3636,1352,3939,118,0]An[3096,13,3636,2358,1841,118,0]An[3096,13,3636,2358,4238,118,0]An[3096,13,3636,3636,4741,118,0]An[3096,13,4709,4709,1172,118,0]An[3096,13,4709,4709,1175,118,0]An[1985,13,1986,1986,3256,118,0]Am[1985,13,1986,416,4361,118,0]An[1985,13,1986,1986,2279,118,0]An[1985,13,1986,1986,2293,118,0]An[1985,13,1986,1986,4089,118,0]An[1095,13,1096,1096,3015,118,0]An[1095,13,1096,1096,4851,118,0]Am[1095,13,1683,1683,135,118,0]An[1095,13,1381,1381,1190,118,0]An[1095,13,1381,1381,3963,118,0]An[1095,13,1381,1381,4456,118,0]An[1095,13,4178,4178,5053,118,0]An[1095,13,4178,4178,5054,118,0]Am[1095,13,1779,1779,136,118,0]Aj[463,13,464,3640,4921,0,0]Aj[463,13,464,1094,4362,0,0]Ag[463,13,464,0,4067,0,0]Al[3096,13,3097,1691,4069,0,0]Al[3096,14,3097,1756,5008,0,0]Ai[3096,14,4748,0,4813,0,0]Ah[3096,14,4459,0,499,0,0]Ai[3096,14,4459,0,1184,0,0]Af[463,5,464,3640,0,0,0]Al[1195,15,1196,1196,3930,0,0]Ae[2358,6,2359,0,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1356,0,0,0]Aj[463,15,464,3640,4752,0,0]Al[3096,15,3097,3070,4753,0,0]Af[463,5,464,2304,0,0,0]Ah[3096,5,3097,2305,0,0,0]Al[3096,15,3097,2002,3961,0,0]Af[463,5,464,2336,0,0,0]2Ah[3096,6,3097,1756,0,0,0]Ag[463,19,464,0,1443,0,0]Al[3096,19,3097,1810,1444,0,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]=Ah[463,12,1693,0,4117,0,0]>Ak[463,13,1773,0,4676,4117,0]>Al[3096,12,1694,1694,4119,0,0]>Ao[3096,13,1774,1774,4677,4119,0]Ao[1095,13,4178,4178,5054,4119,0]An[2358,13,2359,2359,125,3945,0]Ao[2358,13,2359,2359,2250,3945,0]Ag[463,14,464,0,3041,0,0]Ag[463,14,464,0,4451,0,0]Al[3096,14,3097,1382,3042,0,0]Al[3096,14,3097,1382,4452,0,0]Ag[463,13,464,0,4116,0,0]Al[3096,13,3097,1691,4118,0,0]Aj[463,13,464,1994,4319,0,0]0Ak[1985,13,1986,416,4361,0,0]Al[3096,13,3097,3641,3212,0,0]Al[1095,13,1381,1381,4456,0,0]Ae[1095,2,1096,0,0,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2264,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]6Ag[463,13,464,0,4470,0,0]Al[3096,13,3097,3194,4471,0,0]32Ak[1195,14,1196,1196,134,0,0]Ag[463,14,464,0,2291,0,0]Al[3096,14,3097,3097,2292,0,0]Al[1985,14,1986,1986,2293,0,0]Al[3096,13,3097,2002,1861,0,0]Al[3096,13,3097,4258,5097,0,0]Al[3096,13,3097,4258,5102,0,0]Aj[463,13,464,4041,3243,0,0]Al[3096,13,3097,2002,3244,0,0]<;Al[1195,14,1380,1380,1189,0,0]Ai[519,14,520,520,3931,0,0]Ah[463,13,1773,0,4674,0,0]Ah[463,13,1773,0,4676,0,0]Al[3096,13,1774,1774,4675,0,0]Al[3096,13,1774,1774,4677,0,0]76Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Af[463,5,464,4480,0,0,0]Ah[3096,5,3097,4480,0,0,0]Ag[463,15,464,0,4447,0,0]Ag[463,15,464,0,4079,0,0]Al[3096,15,3097,3641,4448,0,0]Al[3096,15,3097,2305,4080,0,0]Ah[3096,6,3097,2305,0,0,0]Ah[3096,5,3097,1784,0,0,0]Af[463,5,464,2304,0,0,0]Aj[463,15,464,4036,4354,0,0]Ag[463,5,1773,1774,0,0,0]Ae[3096,5,1774,0,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]Ah[3096,5,3097,2305,0,0,0]Al[3096,15,3097,1756,4749,0,0]?=5454Al[3096,15,3097,2305,4217,0,0]Ag[463,5,3635,2358,0,0,0]Ah[3096,5,3636,2358,0,0,0]Ah[3096,5,3097,1756,0,0,0]98Ah[3096,6,3097,1120,0,0,0]:9Af[463,5,464,1691,0,0,0]Ah[3096,5,3097,1691,0,0,0]Ae[3096,5,1689,0,0,0,0]Al[3096,13,3097,3641,3212,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]Al[1095,14,1096,1096,3015,0,0]Ae[3096,2,3097,0,0,0,0]Ag[463,13,464,0,4331,0,0]Al[3096,13,3097,1691,4332,0,0]Aj[463,12,464,1994,4319,0,0]Ab[4261,3,0,0,0,0,0]Ak[1195,14,1196,1196,134,0,0]Al[1195,14,1380,1380,3962,0,0]98Aj[463,13,464,2336,3240,0,0]Al[3096,13,3097,2305,3241,0,0]Ag[463,13,464,0,4776,0,0]Al[3096,13,3097,3194,4777,0,0];=Al[1195,14,1380,1380,1189,0,0]Ao[1095,13,1096,1096,4851,3050,0]Ag[463,15,464,0,3025,0,0]Af[463,5,464,1356,0,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1356,0,0,0]Af[463,6,464,3641,0,0,0]Ah[3096,6,3097,3641,0,0,0]Al[3096,15,3097,2305,4217,0,0]Ah[3096,5,3097,1784,0,0,0]Af[463,5,464,1382,0,0,0]Ah[3096,5,3097,1382,0,0,0]97Ae[1095,5,1381,0,0,0,0]:8Ah[3096,6,3097,1756,0,0,0]Af[463,5,464,1116,0,0,0]Ah[3096,5,3097,1116,0,0,0]Al[3096,15,3097,1366,4751,0,0]Af[463,5,464,1392,0,0,0]Ah[3096,5,3097,1392,0,0,0]Af[463,5,464,3194,0,0,0]Ah[3096,5,3097,3194,0,0,0]Ag[463,15,464,0,4447,0,0]Al[3096,15,3097,3641,4448,0,0]Af[463,5,464,3640,0,0,0]Aj[463,15,464,4036,3044,0,0]Aj[463,15,464,4036,3239,0,0]Aj[463,15,464,4041,3257,0,0]Aj[463,15,464,4041,4122,0,0]An[1195,13,1196,1196,134,4216,0]Ao[1195,13,1196,1196,3954,4216,0]Ao[1195,13,1196,1196,3930,4216,0]Am[463,13,464,3640,3211,4216,0]Am[463,13,464,3640,4921,4216,0]Am[463,13,464,3640,4752,4216,0]Am[463,13,464,2304,2259,4216,0]Am[463,13,464,2304,4219,4216,0]Am[463,13,464,4144,1418,4216,0]Al[463,13,464,1094,503,4216,0]Am[463,13,464,1094,4362,4216,0]Am[463,13,464,4036,4355,4216,0]Am[463,13,464,4036,3044,4216,0]Am[463,13,464,4036,3239,4216,0]Am[463,13,464,4036,4354,4216,0]Am[463,13,464,4041,3257,4216,0]Am[463,13,464,4041,4122,4216,0]Aj[463,13,464,0,1443,4216,0]Aj[463,13,464,0,4918,4216,0]Aj[463,13,464,0,1426,4216,0]Aj[463,13,464,0,2294,4216,0]Aj[463,13,464,0,3217,4216,0]Aj[463,13,464,0,3041,4216,0]Aj[463,13,464,0,4451,4216,0]Aj[463,13,464,0,1867,4216,0]Aj[463,13,464,0,4073,4216,0]Aj[463,13,464,0,4447,4216,0]Aj[463,13,464,0,4470,4216,0]Aj[463,13,464,0,4776,4216,0]Aj[463,13,464,0,4791,4216,0]Aj[463,13,464,0,3943,4216,0]Aj[463,13,464,0,4331,4216,0]Aj[463,13,464,0,4116,4216,0]Aj[463,13,464,0,4975,4216,0]Aj[463,13,464,0,4067,4216,0]Aj[463,13,464,0,3933,4216,0]Aj[463,13,464,0,3025,4216,0]Aj[463,13,464,0,4444,4216,0]Aj[463,13,464,0,4645,4216,0]Aj[463,13,464,0,4079,4216,0]Aj[463,13,464,0,4082,4216,0]Aj[463,13,464,0,4087,4216,0]Aj[463,13,464,0,4811,4216,0]Aj[463,13,464,0,3220,4216,0]Ai[463,13,464,0,510,4216,0]Ai[463,13,464,0,126,4216,0]Aj[463,13,464,0,2281,4216,0]Aj[463,13,3635,0,120,4216,0]Ak[463,13,3635,0,3012,4216,0]Ak[463,13,3635,0,1156,4216,0]Ak[463,13,3635,0,3938,4216,0]Ak[463,13,3635,0,1840,4216,0]Ak[463,13,3635,0,4237,4216,0]Ak[463,13,1773,0,1169,4216,0]Ak[463,13,1773,0,4674,4216,0]Ak[463,13,1773,0,4913,4216,0]Ak[463,13,1773,0,4676,4216,0]Ao[3096,13,3097,1810,1444,4216,0]Ao[3096,13,3097,1810,4919,4216,0]Ao[3096,13,3097,3070,4753,4216,0]Ao[3096,13,3097,1366,1427,4216,0]Ao[3096,13,3097,1366,4112,4216,0]Ao[3096,13,3097,1366,3233,4216,0]Ao[3096,13,3097,1366,3040,4216,0]Ao[3096,13,3097,1366,4751,4216,0]Ao[3096,13,3097,1366,4807,4216,0]Ao[3096,13,3097,1366,3207,4216,0]Ao[3096,13,3097,1382,2295,4216,0]Ao[3096,13,3097,1382,3218,4216,0]Ao[3096,13,3097,1382,3042,4216,0]Ao[3096,13,3097,1382,4452,4216,0]Ao[3096,13,3097,1120,3045,4216,0]Ao[3096,13,3097,1120,4245,4216,0]Ao[3096,13,3097,1125,1868,4216,0]Ao[3096,13,3097,1125,3258,4216,0]Ao[3096,13,3097,1125,3942,4216,0]Ao[3096,13,3097,2002,4356,4216,0]Ao[3096,13,3097,2002,4077,4216,0]Ao[3096,13,3097,3641,4448,4216,0]Ao[3096,13,3097,3641,3038,4216,0]Ao[3096,13,3097,3641,4322,4216,0]Ao[3096,13,3097,3641,5004,4216,0]Ao[3096,13,3097,3194,4471,4216,0]Ao[3096,13,3097,3194,4777,4216,0]Ao[3096,13,3097,3194,4792,4216,0]Ao[3096,13,3097,3194,3944,4216,0]Ao[3096,13,3097,1691,4332,4216,0]Ao[3096,13,3097,1691,4118,4216,0]Ao[3096,13,3097,1691,4976,4216,0]Ao[3096,13,3097,1691,4069,4216,0]Ao[3096,13,3097,1691,3934,4216,0]Ao[3096,13,3097,1356,3026,4216,0]Ao[3096,13,3097,1356,3224,4216,0]Ao[3096,13,3097,1356,3247,4216,0]Ao[3096,13,3097,1356,4084,4216,0]Ao[3096,13,3097,1356,4446,4216,0]Ao[3096,13,3097,1356,4647,4216,0]Ao[3096,13,3097,1356,2253,4216,0]Ao[3096,13,3097,2305,4651,4216,0]Ao[3096,13,3097,2305,4080,4216,0]Ao[3096,13,3097,1756,4460,4216,0]Ao[3096,13,3097,1756,5008,4216,0]Ao[3096,13,3097,1756,2267,4216,0]Ao[3096,13,3097,1756,4749,4216,0]Ao[3096,13,3097,1784,4083,4216,0]Ao[3096,13,3097,1784,4088,4216,0]Al[3096,13,3097,0,4360,4216,0]Al[3096,13,3097,0,4812,4216,0]Ao[3096,13,3097,4258,3221,4216,0]Ao[3096,13,3097,4258,5102,4216,0]An[3096,13,3097,3097,511,4216,0]An[3096,13,3097,3097,127,4216,0]Ao[3096,13,3097,3097,2282,4216,0]Ao[3096,13,3097,3097,3024,4216,0]Ao[3096,13,1689,1689,4251,4216,0]Ao[3096,13,4960,4960,4858,4216,0]Ao[3096,13,4960,4960,1171,4216,0]Al[3096,13,1774,0,1170,4216,0]Ao[3096,13,1774,1774,4675,4216,0]Ao[3096,13,1774,1774,4914,4216,0]Ao[3096,13,1774,1774,4677,4216,0]Am[3096,13,3636,148,121,4216,0]An[3096,13,3636,148,3013,4216,0]Ao[3096,13,3636,1352,1157,4216,0]Ao[3096,13,3636,1352,3939,4216,0]Ao[3096,13,3636,2358,1841,4216,0]Ao[3096,13,3636,2358,4238,4216,0]Ao[3096,13,4709,4709,1175,4216,0]Ao[1985,13,1986,1986,2279,4216,0]Ao[1985,13,1986,1986,2293,4216,0]Ao[1985,13,1986,1986,4089,4216,0]Ao[1095,13,1096,1096,4851,4216,0]Ao[1095,13,1381,1381,4456,4216,0]Ao[1095,13,4178,4178,5053,4216,0]Ao[1095,13,4178,4178,5054,4216,0]Af[463,7,464,1994,0,0,0]Ag[463,13,464,0,4331,0,0]Al[3096,13,3097,1691,4332,0,0]Ah[463,12,1693,0,3035,0,0]Al[3096,12,1694,1694,3036,0,0]Al[1985,14,1986,1986,2279,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]10Ae[1095,7,1096,0,0,0,0]Aj[463,13,464,2304,2259,0,0]Ae[4261,7,4262,0,0,0,0]Ae[1195,7,1196,0,0,0,0]Al[3096,13,3097,3641,3212,0,0]Aj[463,13,464,3640,3211,0,0]1Al[3096,13,3097,2002,4356,0,0]Al[1195,13,1380,1380,1189,0,0]Al[1195,14,1380,1380,3962,0,0]Aj[463,12,464,1994,1852,0,0]Am[463,13,464,1393,4123,1852,0]Am[463,13,464,1137,3957,1852,0]Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Af[463,5,464,1094,0,0,0]Ag[463,15,464,0,3025,0,0]Af[463,5,464,1356,0,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1356,0,0,0]Ag[463,15,464,0,4447,0,0]Al[3096,15,3097,3641,4448,0,0]Ah[3096,5,3097,2305,0,0,0]Al[3096,15,3097,3641,1174,0,0]1Ag[463,15,464,0,4079,0,0]Al[3096,15,3097,2305,4080,0,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]32Al[3096,15,3097,3641,3038,0,0]><><><21Ag[463,5,1773,1774,0,0,0]Ae[3096,5,1774,0,0,0,0]10Af[463,5,464,4847,0,0,0]Ah[3096,5,3097,4847,0,0,0]Al[3096,15,4709,4709,1172,0,0]Al[3096,15,3097,1366,4751,0,0]6Al[3096,15,3097,1756,4460,0,0]Ag[463,12,464,0,2287,0,0]Aj[463,13,464,0,4210,2287,0]Aj[463,13,464,0,4100,2287,0]Al[3096,12,3097,1392,2288,0,0]Ao[3096,13,3097,4480,4211,2288,0]Ao[3096,13,3097,1392,4101,2288,0]Ae[3968,7,3969,0,0,0,0]Aj[463,13,464,3640,3211,0,0]Al[3096,13,3097,3641,3212,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]32An[1195,13,1196,1196,134,4333,0]An[2358,13,2359,2359,125,4333,0]Ao[2358,13,2359,2359,2250,4333,0]Ao[1095,13,1096,1096,3015,4333,0]An[1095,13,1683,1683,135,4333,0]An[1095,13,1779,1779,136,4333,0]Ak[1985,13,1986,416,4361,0,0]Ag[463,13,464,0,4470,0,0]Al[3096,13,3097,3194,4471,0,0]:9Ae[3096,2,3097,0,0,0,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,2305,2260,0,0]?>43Ae[4261,7,4262,0,0,0,0]6Al[1095,14,1096,1096,3015,0,0]70Ae[1195,7,1196,0,0,0,0]Ag[463,13,464,0,4116,0,0]Ag[463,13,464,0,4067,0,0]Al[3096,13,3097,1691,4118,0,0]Al[3096,13,3097,1691,4069,0,0]Ag[463,14,464,0,4116,0,0]Al[3096,14,3097,1691,4118,0,0]53Aj[463,13,464,4041,3243,0,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]Ag[463,15,464,0,4447,0,0]Al[3096,15,3097,1366,4751,0,0]Al[3096,15,3097,3641,4448,0,0]Ah[463,10,3635,3636,0,0,0]Af[3096,10,3636,0,0,0,0]Ag[463,5,3635,3636,0,0,0]Ae[3096,5,3636,0,0,0,0]Ah[463,10,1693,1694,0,0,0]Af[3096,10,1694,0,0,0,0]Ag[463,15,464,0,4079,0,0]Al[3096,15,3097,2305,4080,0,0]Ag[463,10,464,3641,0,0,0]Ai[3096,10,3097,3641,0,0,0]Ah[3096,6,3097,1756,0,0,0]Ah[3096,6,3097,1366,0,0,0]Af[463,6,464,3640,0,0,0]Ah[3096,6,3097,3070,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]10Aj[463,15,464,3640,4752,0,0]Al[3096,15,3097,3070,4753,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1382,3042,0,0]Ah[463,14,3635,0,4740,0,0]Al[3096,14,3636,3636,4741,0,0]Aj[463,13,464,3640,3211,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]10Al[3096,13,3097,3070,3018,0,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,2305,2260,0,0]Ab[4771,3,0,0,0,0,0]Ao[1095,13,1096,1096,4851,3050,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]Af[463,5,464,3194,0,0,0]Ah[3096,5,3097,3194,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]54Ai[3096,10,3097,1756,0,0,0]Al[3096,15,3097,3641,1174,0,0]7600Al[3096,15,3097,1120,4245,0,0]4365Al[3096,15,4709,4709,1172,0,0]Ae[1095,9,1096,0,0,0,0]:9Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]<;<;Ah[3096,6,3097,1366,0,0,0]21Al[1195,15,1196,1196,3954,0,0]Ac[463,5,464,0,0,0,0]Ae[3096,5,3097,0,0,0,0]Ag[463,15,464,0,4079,0,0]Ag[463,5,1693,1694,0,0,0]Al[3096,15,3097,2305,4080,0,0]Al[3096,15,3097,1756,4749,0,0]Ae[3096,5,1694,0,0,0,0]An[1195,13,1196,1196,134,4323,0]An[2358,13,2359,2359,125,4323,0]Ao[1095,13,1096,1096,3015,4323,0]An[1095,13,1683,1683,135,4323,0]An[1095,13,1779,1779,136,4323,0]Ag[463,13,464,0,4470,0,0]Al[3096,13,3097,3194,4471,0,0]Ag[463,13,464,0,1443,0,0]Al[3096,13,3097,1810,1444,0,0]Aj[463,14,464,2304,4219,0,0]Aj[463,13,464,3640,4921,0,0]Ag[463,13,464,0,4331,0,0]Al[3096,13,3097,1691,4332,0,0]Ag[463,13,464,0,4210,0,0]Al[3096,13,3097,4480,4211,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]7Al[3096,13,3097,3641,3212,0,0]Aj[463,13,464,3640,3211,0,0]Ah[463,13,1773,0,4674,0,0]Ah[463,13,1773,0,4676,0,0]Al[3096,13,1774,1774,4675,0,0]Al[3096,13,1774,1774,4677,0,0]45;:Ao[3968,13,3969,3969,5009,4805,0]Ag[463,13,464,0,4461,0,0]Al[3096,13,3097,1116,4462,0,0]Ae[1095,6,1096,0,0,0,0]Af[463,5,464,4144,0,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]10Al[3096,15,3097,3641,3038,0,0]Ae[3096,5,4960,0,0,0,0]Af[463,5,464,4036,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Al[3096,15,4709,4709,1172,0,0]Aj[463,14,464,2304,4219,0,0]Ai[463,13,464,0,510,3006,0]Ai[463,13,464,0,126,3006,0]An[3096,13,3097,3097,511,3006,0]An[3096,13,3097,3097,127,3006,0]Ao[2358,13,2359,2359,2250,3248,0]Ag[463,13,464,0,4791,0,0]Al[3096,13,3097,3194,4792,0,0]Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Aj[463,13,464,3640,3211,0,0]Ag[463,12,464,0,4746,0,0]Al[3096,12,3097,3641,4747,0,0]Ag[463,13,464,0,4470,0,0]Al[3096,13,3097,3194,4471,0,0]Ag[463,14,464,0,3041,0,0]Al[3096,14,3097,1382,3042,0,0]Ah[463,12,3635,0,3213,0,0]Aj[463,13,3635,0,120,3213,0]Ak[463,13,3635,0,1156,3213,0]Ak[463,13,3635,0,1840,3213,0]Al[3096,12,3636,3636,3214,0,0]Am[3096,13,3636,148,121,3214,0]Ao[3096,13,3636,1352,1157,3214,0]Ao[3096,13,3636,2358,1841,3214,0]Aj[463,14,464,2304,4219,0,0]Al[3096,13,3097,2002,1861,0,0]Ah[3096,2,4256,4040,0,0,0]Ae[1195,7,1196,0,0,0,0]==Ai[463,13,464,1094,503,0,0]Ak[1985,13,1986,416,4361,0,0]032Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Ae[3096,2,3097,0,0,0,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Ag[463,10,464,4258,0,0,0]Ai[3096,10,3097,4258,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]Ag[463,15,464,0,4079,0,0]Al[3096,15,3097,2305,4080,0,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]Af[463,5,464,1691,0,0,0]Ah[3096,5,3097,1691,0,0,0]Ah[463,12,1693,0,3035,0,0]Al[3096,12,1694,1694,3036,0,0]Aj[463,13,464,2304,2259,0,0]Al[3096,13,3097,3641,3212,0,0]Al[3096,13,3097,2305,2260,0,0]Al[3096,13,3097,3097,3024,0,0]Ah[463,13,3635,0,4237,0,0]Al[3096,13,3636,2358,4238,0,0]Aj[463,13,464,1994,3048,0,0]0Aj[463,13,464,3640,3211,0,0]6Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]Ag[463,13,464,0,4470,0,0]Al[3096,13,3097,3194,4471,0,0]Al[1095,14,1096,1096,3015,0,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]Al[3096,15,4709,4709,1172,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]10Al[3096,15,3097,1366,4807,0,0]Al[3096,15,3097,3641,3038,0,0]Al[3096,15,3097,3641,4322,0,0]Ah[3096,5,3097,3641,0,0,0]Al[3096,15,3097,1366,4751,0,0]Ag[463,15,464,0,3025,0,0]Al[3096,15,3097,1356,3026,0,0]Ah[3096,5,3097,1756,0,0,0]Ae[3968,5,3969,0,0,0,0]Al[1095,13,1096,1096,3015,0,0]Aj[463,13,464,3640,3211,0,0]Ah[463,12,1693,0,1853,0,0]Ak[463,13,1773,0,3252,1853,0]Al[3096,12,1694,1694,1854,0,0]Ao[3096,13,1774,1774,3253,1854,0]Ah[3096,7,4893,4892,0,0,0]0Al[3096,13,3097,3641,3212,0,0]6Ai[463,13,464,1094,503,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]Ao[3968,13,3969,3969,5009,4805,0]0Ag[463,13,464,0,4067,0,0]Al[3096,13,3097,1691,4069,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]10Ag[463,13,464,0,4776,0,0]Al[3096,13,3097,3194,4777,0,0]Am[1195,13,1196,1196,134,485,0]Am[2358,13,2359,2359,125,485,0]An[1095,13,1096,1096,3015,485,0]Am[1095,13,1683,1683,135,485,0]Am[1095,13,1779,1779,136,485,0]??>An[1195,13,1196,1196,134,4333,0]An[2358,13,2359,2359,125,4333,0]Ao[2358,13,2359,2359,2250,4333,0]Ao[1095,13,1096,1096,3015,4333,0]An[1095,13,1683,1683,135,4333,0]An[1095,13,1779,1779,136,4333,0]Ag[463,13,464,0,4116,0,0]Al[3096,13,3097,1691,4118,0,0]Ag[463,19,464,0,4811,0,0]Ai[3096,19,3097,0,4812,0,0]Ae[1095,5,4178,0,0,0,0]0Ag[463,13,464,0,4331,0,0]Al[3096,13,3097,1691,4332,0,0]Ag[463,13,464,0,4067,0,0]Al[3096,13,3097,1691,4069,0,0]Aj[463,13,464,2304,2259,0,0]Aj[463,13,464,2336,2263,0,0]Al[3096,13,3097,2305,2264,0,0]Al[3096,13,3097,3641,3212,0,0]Ao[3968,13,3969,3969,5009,4805,0];:Ag[463,5,1693,1694,0,0,0]Ae[3096,5,1694,0,0,0,0]Ah[463,15,1773,0,1169,0,0]Ai[3096,15,1774,0,1170,0,0]?>?>Aj[463,13,464,3640,3211,0,0]6Ag[463,13,464,0,4470,0,0]Al[3096,13,3097,3194,4471,0,0]Ae[3968,7,3969,0,0,0,0]Ae[4261,7,4262,0,0,0,0]Ag[463,14,464,0,3217,0,0]Al[3096,14,3097,1382,3218,0,0]?434343>=>=Al[3096,14,4960,4960,4858,0,0]54Ai[3096,18,3097,3194,0,0,0]") \ No newline at end of file diff --git a/pr/580/docs/search.index/function/dbbcb1ebecee.js b/pr/580/docs/search.index/function/e41ebb0f3113.js similarity index 98% rename from pr/580/docs/search.index/function/dbbcb1ebecee.js rename to pr/580/docs/search.index/function/e41ebb0f3113.js index d35f29dd5..620064619 100644 --- a/pr/580/docs/search.index/function/dbbcb1ebecee.js +++ b/pr/580/docs/search.index/function/e41ebb0f3113.js @@ -1 +1 @@ -rd_("Bf[\"{{{AHEf{ANKd}}{AHEf{ANKd}}}D@n}\",[]]Bf[\"{{{AHEf{BEB`}}{AHEf{BEB`}}}D@n}\",[]]Bd[\"{{{AHEf{KAd}}{AHEf{KAd}}}D@n}\",[]]Bd[\"{{{AHEf{CNn}}{AHEf{CNn}}}D@n}\",[]]Bf[\"{{{AHEf{BBAd}}{AHEf{BBAd}}}D@n}\",[]]Bf[\"{{{AHEf{BB@f}}{AHEf{BB@f}}}D@n}\",[]]Bf[\"{{{AHEf{AGLh}}{AHEf{AGLh}}}D@n}\",[]]Bf[\"{{{AHEf{AIDn}}{AHEf{AIDn}}}D@n}\",[]]Bf[\"{{{AHEf{BB@d}}{AHEf{BB@d}}}D@n}\",[]]Bf[\"{{{AHEf{AIGb}}{AHEf{AIGb}}}D@n}\",[]]Bf[\"{{{AHEf{B@Cd}}{AHEf{B@Cd}}}D@n}\",[]]Bd[\"{{{AHEf{KDf}}{AHEf{KDf}}}D@n}\",[]]Bf[\"{{{AHEf{BFFl}}{AHEf{BFFl}}}D@n}\",[]]Bd[\"{{{AHEf{I@`}}{AHEf{I@`}}}D@n}\",[]]Bd[\"{{{AHEf{KBd}}{AHEf{KBd}}}D@n}\",[]]Bf[\"{{{AHEf{AANl}}{AHEf{AANl}}}D@n}\",[]]Bf[\"{{{AHEf{AIBb}}{AHEf{AIBb}}}D@n}\",[]]Bf[\"{{{AHEf{AGLb}}{AHEf{AGLb}}}D@n}\",[]]Bd[\"{{{AHEf{NIf}}{AHEf{NIf}}}D@n}\",[]]Bf[\"{{{AHEf{AOMb}}{AHEf{AOMb}}}D@n}\",[]]Bf[\"{{{AHEf{BBKn}}{AHEf{BBKn}}}D@n}\",[]]Bf[\"{{{AHEf{ANLn}}{AHEf{ANLn}}}D@n}\",[]]Bf[\"{{{AHEf{ANKj}}{AHEf{ANKj}}}D@n}\",[]]Bf[\"{{{AHEf{AGJb}}{AHEf{AGJb}}}D@n}\",[]]Bf[\"{{{AHEf{BBKh}}{AHEf{BBKh}}}D@n}\",[]]Bf[\"{{{AHEf{BDDj}}{AHEf{BDDj}}}D@n}\",[]]Bf[\"{{{AHEf{AOMn}}{AHEf{AOMn}}}D@n}\",[]]Bf[\"{{{AHEf{AONd}}{AHEf{AONd}}}D@n}\",[]]Bf[\"{{{AHEf{AONn}}{AHEf{AONn}}}D@n}\",[]]Bf[\"{{{AHEf{BEIf}}{AHEf{BEIf}}}D@n}\",[]]Bd[\"{{{AHEf{COl}}{AHEf{COl}}}D@n}\",[]]Bb[\"{{{AHEf{Ol}}{AHEf{Ol}}}D@n}\",[]]Bf[\"{{{AHEf{AAMb}}{AHEf{AAMb}}}D@n}\",[]]Bf[\"{{{AHEf{BGIf}}{AHEf{BGIf}}}D@n}\",[]]Bd[\"{{{AHEf{IBb}}{AHEf{IBb}}}D@n}\",[]]Bd[\"{{{AHEf{KDh}}{AHEf{KDh}}}D@n}\",[]]Bf[\"{{{AHEf{BFFn}}{AHEf{BFFn}}}D@n}\",[]]Bd[\"{{{AHEf{I@b}}{AHEf{I@b}}}D@n}\",[]]Bf[\"{{{AHEf{BEBb}}{AHEf{BEBb}}}D@n}\",[]]Bd[\"{{{AHEf{KBf}}{AHEf{KBf}}}D@n}\",[]]Bf[\"{{{AHEf{AIDb}}{AHEf{AIDb}}}D@n}\",[]]Bf[\"{{{AHEf{AGL`}}{AHEf{AGL`}}}D@n}\",[]]Bf[\"{{{AHEf{BEAn}}{AHEf{BEAn}}}D@n}\",[]]Bf[\"{{{AHEf{BEHn}}{AHEf{BEHn}}}D@n}\",[]]Bf[\"{{{AHEf{AI@n}}{AHEf{AI@n}}}D@n}\",[]]Bf[\"{{{AHEf{AANn}}{AHEf{AANn}}}D@n}\",[]]Bf[\"{{{AHEf{AIBd}}{AHEf{AIBd}}}D@n}\",[]]Bf[\"{{{AHEf{AGLd}}{AHEf{AGLd}}}D@n}\",[]]Bf[\"{{{AHEf{AGLj}}{AHEf{AGLj}}}D@n}\",[]]Bf[\"{{{AHEf{BABj}}{AHEf{BABj}}}D@n}\",[]]Bd[\"{{{AHEf{NIh}}{AHEf{NIh}}}D@n}\",[]]Bf[\"{{{AHEf{AIGd}}{AHEf{AIGd}}}D@n}\",[]]Bf[\"{{{AHEf{ANLl}}{AHEf{ANLl}}}D@n}\",[]]Bf[\"{{{AHEf{ANOb}}{AHEf{ANOb}}}D@n}\",[]]Bf[\"{{{AHEf{BB@h}}{AHEf{BB@h}}}D@n}\",[]]Bf[\"{{{AHEf{AOMj}}{AHEf{AOMj}}}D@n}\",[]]Bf[\"{{{AHEf{BBL`}}{AHEf{BBL`}}}D@n}\",[]]Bf[\"{{{AHEf{AGKl}}{AHEf{AGKl}}}D@n}\",[]]Bf[\"{{{AHEf{BALd}}{AHEf{BALd}}}D@n}\",[]]Bf[\"{{{AHEf{ANM`}}{AHEf{ANM`}}}D@n}\",[]]Bf[\"{{{AHEf{ANKl}}{AHEf{ANKl}}}D@n}\",[]]Bf[\"{{{AHEf{AGJd}}{AHEf{AGJd}}}D@n}\",[]]Bf[\"{{{AHEf{BANb}}{AHEf{BANb}}}D@n}\",[]]Bf[\"{{{AHEf{AIC`}}{AHEf{AIC`}}}D@n}\",[]]Bf[\"{{{AHEf{AIEn}}{AHEf{AIEn}}}D@n}\",[]]Bf[\"{{{AHEf{AONh}}{AHEf{AONh}}}D@n}\",[]]Bf[\"{{{AHEf{BBKl}}{AHEf{BBKl}}}D@n}\",[]]Bf[\"{{{AHEf{BDDn}}{AHEf{BDDn}}}D@n}\",[]]Bf[\"{{{AHEf{BDEf}}{AHEf{BDEf}}}D@n}\",[]]Bf[\"{{{AHEf{AON`}}{AHEf{AON`}}}D@n}\",[]]Bf[\"{{{AHEf{AAKf}}{AHEf{AAKf}}}D@n}\",[]]Bf[\"{{{AHEf{BEAj}}{AHEf{BEAj}}}D@n}\",[]]Bf[\"{{{AHEf{AONf}}{AHEf{AONf}}}D@n}\",[]]Bf[\"{{{AHEf{AOO`}}{AHEf{AOO`}}}D@n}\",[]]Bf[\"{{{AHEf{BBA`}}{AHEf{BBA`}}}D@n}\",[]]Bf[\"{{{AHEf{BEIh}}{AHEf{BEIh}}}D@n}\",[]]Bd[\"{{{AHEf{COn}}{AHEf{COn}}}D@n}\",[]]Bb[\"{{{AHEf{On}}{AHEf{On}}}D@n}\",[]]Bf[\"{{{AHEf{AAMd}}{AHEf{AAMd}}}D@n}\",[]]Bf[\"{{{AHEf{AGJ`}}{AHEf{AGJ`}}}D@n}\",[]]Bf[\"{{{AHEf{BACf}}{AHEf{BACf}}}D@n}\",[]]Bf[\"{{{AHEf{BEOd}}{AHEf{BEOd}}}D@n}\",[]]Bd[\"{{{AHEf{IBf}}{AHEf{IBf}}}D@n}\",[]]Bf[\"{{{AHEf{BGIh}}{AHEf{BGIh}}}D@n}\",[]]Bd[\"{{{AHEf{IBd}}{AHEf{IBd}}}D@n}\",[]]Bf[\"{{{AHEf{AOOb}}{AHEf{AOOb}}}D@n}\",[]]Ai[\"{{{AHEf{CNn}}}KBd}\",[]]Aj[\"{{{AHEf{BBAd}}}KBd}\",[]]Ak[\"{{{AHEf{AIDj}}}AAMb}\",[]]Ak[\"{{{AHEf{BEOf}}}AAMb}\",[]]Ak[\"{{{AHEf{AIEf}}}AAMb}\",[]]o[\"{KAhKBf}\",[]]A`[\"{AGGdKBf}\",[]]A`[\"{AGIhKBf}\",[]]A`[\"{B@AjKBf}\",[]]A`[\"{B@@lKBf}\",[]]Aa[\"{AALjAAMd}\",[]]Aa[\"{AAObAAMd}\",[]]Aa[\"{AAJjAAMd}\",[]]A`[\"{NGnAAMd}\",[]]A`[\"{ANNdNGf}\",[]]A`[\"{CNfAAKf}\",[]]Ac[\"{{AANlAANl}}\",[]]Ac[\"{{AIBbAIBb}}\",[]]Ac[\"{{BBLfAGLb}}\",[]]Bc[\"{{AANnAANn}c{}}\",[\"Add::Output\"]]Bc[\"{{AIBdAIBd}c{}}\",[\"Add::Output\"]]Bc[\"{{BBLhAGLd}c{}}\",[\"Add::Output\"]]Be[\"{{{AHEf{KDf}}{AHEf{KDf}}}AALh}\",[]]Be[\"{{{AHEf{KBd}}{AHEf{KBd}}}AALh}\",[]]Bg[\"{{{AHEf{ANLn}}{AHEf{ANLn}}}AALh}\",[]]Bg[\"{{{AHEf{AONd}}{AHEf{AONd}}}AALh}\",[]]Be[\"{{{AHEf{COl}}{AHEf{COl}}}AALh}\",[]]Bc[\"{{{AHEf{Ol}}{AHEf{Ol}}}AALh}\",[]]Bg[\"{{{AHEf{AAMb}}{AHEf{AAMb}}}AALh}\",[]]Be[\"{{{AHEf{KDh}}{AHEf{KDh}}}AALh}\",[]]Bg[\"{{{AHEf{BEBb}}{AHEf{BEBb}}}AALh}\",[]]Be[\"{{{AHEf{KBf}}{AHEf{KBf}}}AALh}\",[]]Bg[\"{{{AHEf{AGLj}}{AHEf{AGLj}}}AALh}\",[]]Bg[\"{{{AHEf{BABj}}{AHEf{BABj}}}AALh}\",[]]Bg[\"{{{AHEf{AIGd}}{AHEf{AIGd}}}AALh}\",[]]Bg[\"{{{AHEf{ANM`}}{AHEf{ANM`}}}AALh}\",[]]Bg[\"{{{AHEf{BDEf}}{AHEf{BDEf}}}AALh}\",[]]Bg[\"{{{AHEf{BEAj}}{AHEf{BEAj}}}AALh}\",[]]Bg[\"{{{AHEf{AONf}}{AHEf{AONf}}}AALh}\",[]]Be[\"{{{AHEf{COn}}{AHEf{COn}}}AALh}\",[]]Bc[\"{{{AHEf{On}}{AHEf{On}}}AALh}\",[]]Bg[\"{{{AHEf{AAMd}}{AHEf{AAMd}}}AALh}\",[]]o[\"{AAMbOl}\",[]]o[\"{AAMdOn}\",[]]n[\"{KAjOn}\",[]]o[\"{AGHbOn}\",[]]A`[\"{AANfKB`}\",[]]A`[\"{AANhKB`}\",[]]A`[\"{AALnKB`}\",[]]A`[\"{AANjKB`}\",[]]Bh[\"{{{AHEf{A@l}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANNd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANKd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@j}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BGBb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BFFf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIAb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIAf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BFGb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEB`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AAJf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{B@Of}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{KAd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AICn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BENh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAJn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIE`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAN`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{CNn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBAd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIDj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEOf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@f}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AGLh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIDn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BB@d}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{B@Cf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANNj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIEf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIGb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{B@Cd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{NHb}}{AHEf{CEdAGIn}}}KBh}\",[]]Cd[\"{{{AHEf{KDf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BFFl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Cd[\"{{{AHEf{I@`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{KBd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AANl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AIBb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AGLb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BBLf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{NIf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AOMb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BBKn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BBMj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BBNl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEE`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEFn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANLn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BAMf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{B@Bh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BFMn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AOLf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANKj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AGJb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BBKh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BDDj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AOMn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AONd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AONn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEIf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AIBh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BDHl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{COl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cc[\"{{{AHEf{Ol}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AAMb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AANf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cc[\"{{{AHEf{O`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AGHh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{I@h}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANLd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{NF`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BAAj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BE@h}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BGIf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANL`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEIn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{IBb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BFFb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Bi[\"{{{AHEf{AIAh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAJh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{KDh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BFFn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{I@b}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEBb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{KBf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{B@B`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIDb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGL`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEHn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AI@n}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AANn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIBd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGLd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBLh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGLj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BABj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{NIh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIGd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{ANLl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{ANOb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@h}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AOMj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BBL`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AGKl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BALd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BGAh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{IBl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBMl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBNn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEEb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEG`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANM`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BAMh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{B@Bl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BFN`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AOLj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANKl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AGJd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BANb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIC`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIEn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AONh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BBKl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BDDn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AAIj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BDEf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAK`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AON`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{ANK`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIEb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAB`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBMh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BGB`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAKf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BBLd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{B@Od}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AONf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AOO`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBA`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BEIh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIBj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BGMl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BDHn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{COn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bg[\"{{{AHEf{On}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AAMd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AANh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGJ`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BACf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BEOd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{IBf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BGIh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANLb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEJd}}{AHEf{CEdAGIn}}}KBh}\",[]]Cd[\"{{{AHEf{IBd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Bi[\"{{{AHEf{BFFd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bg[\"{{{AHEf{Ob}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGHj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{I@j}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANLf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{NFb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BAAl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BE@j}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{IBh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{IBn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBAb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AALn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AANj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AOOb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bd[\"{{{AHEf{BFFf}}}{{KB`{AIEl}}}}\",[]]Ak[\"{{{AHEf{B@B`}}}AAJb}\",[]]A`[\"{AANlCLf}\",[]]A`[\"{AANnCLf}\",[]]Aj[\"{{{AHEf{BAB`}}}JNf}\",[]]A`[\"{BGB`CLf}\",[]]o[\"{CNfCLf}\",[]]A`[\"{AALnJNf}\",[]]Ce[\"{{{AHEf{CEdBFMn}}{Nn{AAMn}}}{{AHEf{CEdBFMn}}}}\",[]]Ce[\"{{{AHEf{CEdBFN`}}{Nn{AAN`}}}{{AHEf{CEdBFN`}}}}\",[]]8Af[\"{{AAJbCLf}BB@j}\",[]]Ag[\"{{}{{Nn{BGBb}}}}\",[]]Ae[\"{{JNfCLd}B@Nd}\",[]]Cd[\"{{BAMf{KB`{B@Bh}}AGMb{Nn{NGh}}}{{KBl{AAJf}}}}\",[]]Ah[\"{{{Of{IEb}}}AIDd}\",[]]A`[\"{NG`BBMj}\",[]]Ah[\"{{{Nn{NDn}}}BAMf}\",[]]Bc[\"{{{Nn{B@Bj}}{Nn{BE@l}}}B@Bh}\",[]]Ai[\"{{{Nn{AOLh}}}AOLf}\",[]]B`[\"{{{AHEf{{JL`{Nd}}}}}AONd}\",[]]Ae[\"{{CLdJNf}BDHl}\",[]]Ag[\"{{COlOlCLf}AAMb}\",[]]Aj[\"{{{Nn{AGHh}}CLb}O`}\",[]]An[\"{{{Nn{ANLd}}NEdCLb}I@h}\",[]]An[\"{{{Nn{BAAj}}NEdCLb}NF`}\",[]]Ae[\"{{JNfCLd}B@Nf}\",[]]Ah[\"{{{Of{IEb}}}AIDf}\",[]]Bm[\"{{{Nn{BAMh}}{KB`{{Nn{B@Bl}}}}D@n}AAJh}\",[]]A`[\"{JNfBH@n}\",[]]o[\"{{}BGMb}\",[]]A`[\"{NG`BBMl}\",[]]Ah[\"{{{Nn{NE`}}}BAMh}\",[]]Bc[\"{{{Nn{B@Bn}}{Nn{BE@n}}}B@Bl}\",[]]Ai[\"{{{Nn{AOLl}}}AOLj}\",[]]Ek[\"{{AAI`{AHEf{c}}{AHEf{{JL`{CLd}}}}D@n}{{KBj{{JNd{BAB`{KB`{AAI`}}}}BEAj}}}{BEElIDh}}\",[\"\"]]B`[\"{{{AHEf{{JL`{Nd}}}}}AONf}\",[]]Af[\"{{BEIhKDb}BBA`}\",[]]A`[\"{JNfBGMl}\",[]]Ae[\"{{CLdJNf}BDHn}\",[]]Ag[\"{{COnOnCLf}AAMd}\",[]]Am[\"{{AIEl{KB`{KAb}}}AGJ`}\",[]]Aj[\"{{{Nn{AGHj}}CLb}Ob}\",[]]An[\"{{{Nn{ANLf}}NEdCLb}I@j}\",[]]An[\"{{{Nn{BAAl}}NEdCLb}NFb}\",[]]Aj[\"{AIG`{{KBl{BBAb}}}}\",[]]Aa[\"{BDHfBGGj}\",[]]Aa[\"{BDHjBGGl}\",[]]o[\"{COlCOl}\",[]]o[\"{COnCOn}\",[]]Ak[\"{{{AHEf{AIFd}}}AIFb}\",[]]Ai[\"{{{AHEf{NGh}}}NEd}\",[]]0Aj[\"{{{AHEf{B@Cf}}}NEd}\",[]]Ak[\"{{{AHEf{BACb}}}AIFb}\",[]]Ak[\"{{{AHEf{AIFf}}}AIFb}\",[]]Ak[\"{{{AHEf{BACd}}}AIFb}\",[]]Bg[\"{{{AHEf{AIAf}}KBd}{{KB`{AAJb}}}}\",[]]Aa[\"{AGLbAAJb}\",[]]Bg[\"{{{AHEf{AIAh}}KBf}{{KB`{AAJb}}}}\",[]]Aa[\"{AGLdAAJb}\",[]]Ah[\"{A@n{{KBn{HOj}}}}\",[]]Ah[\"{AA`{{KBn{HOj}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Aa[\"{B@@lAIEl}\",[]]Aa[\"{AALnAIEl}\",[]]Aa[\"{BBA`BEIh}\",[]]A`[\"{AGLbCLf}\",[]]A`[\"{AGLdCLf}\",[]]A`[\"{AAIjHOn}\",[]]Am[\"{{{AHEf{CEdAALd}}}HOj}\",[]]Am[\"{{{AHEf{CEdAAJn}}}HOj}\",[]]Al[\"{{{AHEf{CEdCNn}}}HOj}\",[]]Am[\"{{{AHEf{CEdBBAd}}}HOj}\",[]]Am[\"{{{AHEf{CEdAIDj}}}HOj}\",[]]Am[\"{{{AHEf{CEdAIEf}}}HOj}\",[]]Al[\"{{{AHEf{CEdJOn}}}HOj}\",[]]A`[\"{cc{}}\",[\"T\"]]0000000000000000000000Aa[\"{BBKnBEB`}\",[]]111111111111111Aa[\"{AGLhBB@f}\",[]]2Aa[\"{AIDnAGLh}\",[]]Aa[\"{BBKnAGLh}\",[]]Aa[\"{BBKnAIDn}\",[]]55Aa[\"{AGLhBB@d}\",[]]6666Aa[\"{AOMbAIGb}\",[]]Aa[\"{B@CdAIGb}\",[]]Aa[\"{BBKnAIGb}\",[]]9Aa[\"{BBKnB@Cd}\",[]]::::::A`[\"{AAMbKDf}\",[]]n[\"{NdKDf}\",[]]o[\"{CLbKDf}\",[]]A`[\"{BEIfKDf}\",[]]o[\"{CLdKDf}\",[]]???Al[\"{cKBd{{CN`{CLd}}}}\",[\"T\"]]A`[\"{cc{}}\",[\"T\"]]000000A`[\"{I@fBBKn}\",[]]1A`[\"{IAlBBKn}\",[]]Aa[\"{ANKhBBKn}\",[]]33333A`[\"{KDfANLn}\",[]]4444Aa[\"{BBO`ANKj}\",[]]5Aa[\"{BFFlANKj}\",[]]66A`[\"{IAlBBKh}\",[]]7Aa[\"{BEInAOMn}\",[]]8888A`[\"{KDfBEIf}\",[]]99999A`[\"{KDfAAMb}\",[]]:::::::::::Aa[\"{ANOhANL`}\",[]];;;;A`[\"{BBNdIBb}\",[]]A`[\"{BBLjIBb}\",[]]A`[\"{BDFfIBb}\",[]]A`[\"{BAOfIBb}\",[]]A`[\"{BANdIBb}\",[]]A`[\"{AICfIBb}\",[]]A`[\"{cc{}}\",[\"T\"]]A`[\"{BDE`IBb}\",[]]A`[\"{BGIdIBb}\",[]]A`[\"{BDGnIBb}\",[]]A`[\"{BGJfIBb}\",[]]A`[\"{BGDfIBb}\",[]]555555555555555555555555o[\"{CLbKDh}\",[]]o[\"{CLdKDh}\",[]]n[\"{NdKDh}\",[]]A`[\"{AAMdKDh}\",[]]A`[\"{BEIhKDh}\",[]]::::Al[\"{cKBf{{CN`{CLd}}}}\",[\"T\"]];;;;;;;;;;;;;;;;;;;Aa[\"{BBA`BBL`}\",[]]<<<>>>>Aa[\"{BBO`ANKl}\",[]]Aa[\"{BFFnANKl}\",[]]A`[\"{cc{}}\",[\"T\"]]00000Aa[\"{BBA`BBKl}\",[]]11111Aa[\"{BEJdAON`}\",[]]22222222Aa[\"{BACfBEAj}\",[]]3333A`[\"{IBfBBA`}\",[]]4A`[\"{KDhBEIh}\",[]]5555555A`[\"{KDhAAMd}\",[]]6666A`[\"{BACfIBf}\",[]]7777Aa[\"{ANOhANLb}\",[]]8888A`[\"{BDE`IBd}\",[]]A`[\"{BGIdIBd}\",[]]A`[\"{AICfIBd}\",[]]A`[\"{BANdIBd}\",[]]A`[\"{BDFfIBd}\",[]]A`[\"{BBLjIBd}\",[]]A`[\"{BGJfIBd}\",[]]A`[\"{BAOfIBd}\",[]]A`[\"{BDGnIBd}\",[]]A`[\"{BBNdIBd}\",[]]A`[\"{cc{}}\",[\"T\"]]A`[\"{BGDfIBd}\",[]]111111111111An[\"{{{AHEf{c}}}AIG`CLl}\",[\"S\"]]22222222222222Bm[\"{{{AHEf{KDf}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bk[\"{{{AHEf{KBd}}{AHEf{CEdc}}}HOjKA`}\",[\"H\"]]Bn[\"{{{AHEf{ANLn}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AONd}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bm[\"{{{AHEf{COl}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bl[\"{{{AHEf{Ol}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AAMb}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bm[\"{{{AHEf{KDh}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BEBb}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bk[\"{{{AHEf{KBf}}{AHEf{CEdc}}}HOjKA`}\",[\"H\"]]Bn[\"{{{AHEf{AGLj}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BABj}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AIGd}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{ANM`}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BDEf}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BEAj}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AONf}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bm[\"{{{AHEf{COn}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bl[\"{{{AHEf{On}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AAMd}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AGJ`}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Aa[\"{{}c{}}\",[\"U\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n[\"{{}HOj}\",[]]0000Cc[\"{{{AHEf{CEdJOn}}JNf}{{KBj{{KB`{I@b}}AGLj}}}}\",[]]Cf[\"{{{AHEf{CEdBA@h}}}{{KB`{c}}}{}}\",[\"Iterator::Item\"]]Dl[\"{{{AHEf{BE@l}}HOh{AHEf{CEd{JL`{Nd}}}}}{{KBj{{AHEf{{JL`{Nd}}}}ANL`}}}}\",[]]Bh[\"{{{AHEf{CEdNHj}}On}{{KB`{AAMd}}}}\",[]]Dl[\"{{{AHEf{BE@n}}HOh{AHEf{CEd{JL`{Nd}}}}}{{KBj{{AHEf{{JL`{Nd}}}}ANLb}}}}\",[]]Bf[\"{{{AHEf{AIAf}}KBd}{{KB`{CNn}}}}\",[]]Bf[\"{{{AHEf{CNn}}}{{KBj{HOjAI@h}}}}\",[]]A`[\"{AIBbCLf}\",[]]Am[\"{{{AHEf{CEdAIAh}}}HOj}\",[]]A`[\"{AIBdCLf}\",[]]Ck[\"{{{AAd{{AHEf{CEdAI@`}}}}{AHEf{CEdNDb}}}{{COf{HOj}}}}\",[]]Dk[\"{{{AAd{{AHEf{CEdBBOf}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAALd}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAALf}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAIAb}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdNFf}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdKAf}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAGGh}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAAHn}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdB@Ah}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdB@Bb}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdJNn}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdBAN`}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdNHb}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Bf[\"{{{AHEf{CEdAIAh}}}{{KB`{IBl}}}}\",[]]De[\"{{{AHEf{CEdAIDj}}{AHEf{CEd{JL`{Nd}}}}}{{KBj{{KB`{JNf}}AGLh}}}}\",[]]Bm[\"{{{AHEf{CEdAIDl}}D@n}{{KBj{JOnBABj}}}}\",[]]Bo[\"{{COn{AHEf{CEdc}}}{{KBj{BEOdIBf}}}Oh}\",[\"R\"]]Bf[\"{{{AHEf{CEdAGId}}}{{KB`{HOn}}}}\",[]]Ec[\"{{{AHEf{BBAb}}AIG`{AHEf{CEd{JL`{AIBl}}}}{AHEf{CEd{JL`{AALn}}}}}{{KBl{JNf}}}}\",[]]Cn[\"{{{AHEf{BE@l}}HOh{AHEf{CEd{AAj{Nd}}}}}{{KBj{HOjANL`}}}}\",[]]Cn[\"{{{AHEf{BE@n}}HOh{AHEf{CEd{AAj{Nd}}}}}{{KBj{HOjANLb}}}}\",[]]C`[\"{{{AHEf{CEdAGId}}HOnD@n}{{KBj{HOjBEBb}}}}\",[]]Cc[\"{{{AHEf{BBAb}}AIG`{AHEf{AANj}}}{{KBl{HOj}}}}\",[]]Bn[\"{{{AHEf{CEdBFMn}}CLd}{{AHEf{CEdBFMn}}}}\",[]]Bn[\"{{{AHEf{CEdBFN`}}CLd}{{AHEf{CEdBFN`}}}}\",[]]Aj[\"{{{AHEf{AIAf}}}COl}\",[]]Aj[\"{{{AHEf{AIAh}}}COn}\",[]]Cn[\"{{{AHEf{NDn}}{AHEf{{JL`{Nd}}}}{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Cn[\"{{{AHEf{NE`}}{AHEf{{JL`{Nd}}}}{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]A`[\"{BB@jCLf}\",[]]A`[\"{AANfJNf}\",[]]A`[\"{AANhJNf}\",[]]o[\"{IDdD@n}\",[]]Bm[\"{{{AHEf{CEdAIDj}}KDf}{{KBj{HOjAOMb}}}}\",[]]Bm[\"{{{AHEf{CEdBEOf}}KDf}{{KBj{HOjAOMb}}}}\",[]]Bm[\"{{{AHEf{CEdAIDl}}KDh}{{KBj{HOjAOMj}}}}\",[]]Bn[\"{{{AHEf{AIFl}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BAOb}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BDHl}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{AIFn}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BAOd}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BDHn}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bd[\"{{{AHEf{BDEl}}}{{KB`{BA@h}}}}\",[]]Bg[\"{{{Nn{BE@d}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{AGHh}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{ANLd}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{BAAj}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{BE@f}}NEdCLb}{{Of{AIAl}}}}\",[]]Bg[\"{{{Nn{AGHj}}NEdCLb}{{Of{AIAl}}}}\",[]]Bg[\"{{{Nn{ANLf}}NEdCLb}{{Of{AIAl}}}}\",[]]Bg[\"{{{Nn{BAAl}}NEdCLb}{{Of{AIAl}}}}\",[]]Ai[\"{BENf{{Nn{BE@f}}}}\",[]]o[\"{I@`HOn}\",[]]A`[\"{AANlCLf}\",[]]o[\"{NIfJNf}\",[]]o[\"{I@bHOn}\",[]]A`[\"{AANnCLf}\",[]]o[\"{NIhJNf}\",[]]Aa[\"{ANK`BBL`}\",[]]Ai[\"{{{AHEf{A@l}}}A@l}\",[]]Ak[\"{{{AHEf{ANNd}}}ANNd}\",[]]Ak[\"{{{AHEf{ANKd}}}ANKd}\",[]]Ak[\"{{{AHEf{AIAf}}}AIAf}\",[]]Ak[\"{{{AHEf{BFGb}}}BFGb}\",[]]Ak[\"{{{AHEf{BEB`}}}BEB`}\",[]]Ak[\"{{{AHEf{AAJf}}}AAJf}\",[]]Ak[\"{{{AHEf{B@Of}}}B@Of}\",[]]Ai[\"{{{AHEf{KAd}}}KAd}\",[]]Ai[\"{{{AHEf{CNn}}}CNn}\",[]]Ak[\"{{{AHEf{BBAd}}}BBAd}\",[]]Ak[\"{{{AHEf{BB@f}}}BB@f}\",[]]Ak[\"{{{AHEf{AGLh}}}AGLh}\",[]]Ak[\"{{{AHEf{AIDn}}}AIDn}\",[]]Ak[\"{{{AHEf{BB@d}}}BB@d}\",[]]Ak[\"{{{AHEf{AIGb}}}AIGb}\",[]]Ak[\"{{{AHEf{B@Cd}}}B@Cd}\",[]]Ai[\"{{{AHEf{KDf}}}KDf}\",[]]Ak[\"{{{AHEf{BFFl}}}BFFl}\",[]]Ai[\"{{{AHEf{KBd}}}KBd}\",[]]Ak[\"{{{AHEf{AANl}}}AANl}\",[]]Ak[\"{{{AHEf{AIBb}}}AIBb}\",[]]Ak[\"{{{AHEf{AGLb}}}AGLb}\",[]]Ak[\"{{{AHEf{BBLf}}}BBLf}\",[]]Ai[\"{{{AHEf{NIf}}}NIf}\",[]]Ak[\"{{{AHEf{AOMb}}}AOMb}\",[]]Ak[\"{{{AHEf{BBKn}}}BBKn}\",[]]Ak[\"{{{AHEf{BBNl}}}BBNl}\",[]]Ak[\"{{{AHEf{BEE`}}}BEE`}\",[]]Ak[\"{{{AHEf{BEFn}}}BEFn}\",[]]Ak[\"{{{AHEf{ANLn}}}ANLn}\",[]]Ak[\"{{{AHEf{BAMf}}}BAMf}\",[]]Ak[\"{{{AHEf{B@Bh}}}B@Bh}\",[]]Ak[\"{{{AHEf{BFMn}}}BFMn}\",[]]Ak[\"{{{AHEf{AOLf}}}AOLf}\",[]]Ak[\"{{{AHEf{ANKj}}}ANKj}\",[]]Ak[\"{{{AHEf{AGJb}}}AGJb}\",[]]Ak[\"{{{AHEf{BBKh}}}BBKh}\",[]]Ak[\"{{{AHEf{BDDj}}}BDDj}\",[]]Ak[\"{{{AHEf{AOMn}}}AOMn}\",[]]Ak[\"{{{AHEf{AONd}}}AONd}\",[]]Ak[\"{{{AHEf{AONn}}}AONn}\",[]]Ak[\"{{{AHEf{BEIf}}}BEIf}\",[]]Ak[\"{{{AHEf{AIBh}}}AIBh}\",[]]Ai[\"{{{AHEf{COl}}}COl}\",[]]Ag[\"{{{AHEf{Ol}}}Ol}\",[]]Ak[\"{{{AHEf{AAMb}}}AAMb}\",[]]Ag[\"{{{AHEf{O`}}}O`}\",[]]Ak[\"{{{AHEf{AGHh}}}AGHh}\",[]]Ai[\"{{{AHEf{I@h}}}I@h}\",[]]Ak[\"{{{AHEf{ANLd}}}ANLd}\",[]]Ai[\"{{{AHEf{NF`}}}NF`}\",[]]Ak[\"{{{AHEf{BAAj}}}BAAj}\",[]]Ai[\"{{{AHEf{IBb}}}IBb}\",[]]Ak[\"{{{AHEf{BDHd}}}BDHd}\",[]]Ak[\"{{{AHEf{BFFb}}}BFFb}\",[]]Ak[\"{{{AHEf{BDHh}}}BDHh}\",[]]Ai[\"{{{AHEf{KDh}}}KDh}\",[]]Ak[\"{{{AHEf{BFFn}}}BFFn}\",[]]Ak[\"{{{AHEf{BEBb}}}BEBb}\",[]]Ai[\"{{{AHEf{KBf}}}KBf}\",[]]Ak[\"{{{AHEf{B@B`}}}B@B`}\",[]]Ak[\"{{{AHEf{AIDb}}}AIDb}\",[]]Ak[\"{{{AHEf{AGL`}}}AGL`}\",[]]Ak[\"{{{AHEf{BEAn}}}BEAn}\",[]]Ak[\"{{{AHEf{BEHn}}}BEHn}\",[]]Ak[\"{{{AHEf{AI@n}}}AI@n}\",[]]Ak[\"{{{AHEf{AANn}}}AANn}\",[]]Ak[\"{{{AHEf{AIBd}}}AIBd}\",[]]Ak[\"{{{AHEf{AGLd}}}AGLd}\",[]]Ak[\"{{{AHEf{BBLh}}}BBLh}\",[]]Ak[\"{{{AHEf{AGLj}}}AGLj}\",[]]Ak[\"{{{AHEf{BABj}}}BABj}\",[]]Ai[\"{{{AHEf{NIh}}}NIh}\",[]]Ak[\"{{{AHEf{AIGd}}}AIGd}\",[]]Ak[\"{{{AHEf{ANLl}}}ANLl}\",[]]Ak[\"{{{AHEf{BB@h}}}BB@h}\",[]]Ak[\"{{{AHEf{AOMj}}}AOMj}\",[]]Ak[\"{{{AHEf{BBL`}}}BBL`}\",[]]Ak[\"{{{AHEf{AGKl}}}AGKl}\",[]]Ak[\"{{{AHEf{BALd}}}BALd}\",[]]Ak[\"{{{AHEf{BGAh}}}BGAh}\",[]]Ak[\"{{{AHEf{BBNn}}}BBNn}\",[]]Ak[\"{{{AHEf{BEEb}}}BEEb}\",[]]Ak[\"{{{AHEf{BEG`}}}BEG`}\",[]]Ak[\"{{{AHEf{ANM`}}}ANM`}\",[]]Ak[\"{{{AHEf{BAMh}}}BAMh}\",[]]Ak[\"{{{AHEf{B@Bl}}}B@Bl}\",[]]Ak[\"{{{AHEf{BFN`}}}BFN`}\",[]]Ak[\"{{{AHEf{AOLj}}}AOLj}\",[]]Ak[\"{{{AHEf{ANKl}}}ANKl}\",[]]Ak[\"{{{AHEf{AGJd}}}AGJd}\",[]]Ak[\"{{{AHEf{AIC`}}}AIC`}\",[]]Ak[\"{{{AHEf{AIEn}}}AIEn}\",[]]Ak[\"{{{AHEf{AONh}}}AONh}\",[]]Ak[\"{{{AHEf{BBKl}}}BBKl}\",[]]Ak[\"{{{AHEf{BDDn}}}BDDn}\",[]]Ak[\"{{{AHEf{AAIj}}}AAIj}\",[]]Ak[\"{{{AHEf{BDEf}}}BDEf}\",[]]Ak[\"{{{AHEf{AON`}}}AON`}\",[]]Ak[\"{{{AHEf{BBMh}}}BBMh}\",[]]Ak[\"{{{AHEf{BGB`}}}BGB`}\",[]]Ak[\"{{{AHEf{AAKf}}}AAKf}\",[]]Ak[\"{{{AHEf{BEAj}}}BEAj}\",[]]Ak[\"{{{AHEf{AONf}}}AONf}\",[]]Ak[\"{{{AHEf{AOO`}}}AOO`}\",[]]Ak[\"{{{AHEf{BBA`}}}BBA`}\",[]]Ak[\"{{{AHEf{BEIh}}}BEIh}\",[]]Ak[\"{{{AHEf{AIBj}}}AIBj}\",[]]Ak[\"{{{AHEf{BGMl}}}BGMl}\",[]]Ai[\"{{{AHEf{COn}}}COn}\",[]]Ag[\"{{{AHEf{On}}}On}\",[]]Ak[\"{{{AHEf{AAMd}}}AAMd}\",[]]Ak[\"{{{AHEf{AGJ`}}}AGJ`}\",[]]Ak[\"{{{AHEf{BACf}}}BACf}\",[]]Ak[\"{{{AHEf{BEOd}}}BEOd}\",[]]Ai[\"{{{AHEf{IBf}}}IBf}\",[]]Ai[\"{{{AHEf{IBd}}}IBd}\",[]]Ak[\"{{{AHEf{BDHf}}}BDHf}\",[]]Ak[\"{{{AHEf{BFFd}}}BFFd}\",[]]Ak[\"{{{AHEf{BDHj}}}BDHj}\",[]]Ag[\"{{{AHEf{Ob}}}Ob}\",[]]Ak[\"{{{AHEf{AGHj}}}AGHj}\",[]]Ai[\"{{{AHEf{I@j}}}I@j}\",[]]Ak[\"{{{AHEf{ANLf}}}ANLf}\",[]]Ai[\"{{{AHEf{NFb}}}NFb}\",[]]Ak[\"{{{AHEf{BAAl}}}BAAl}\",[]]Ai[\"{{{AHEf{IBn}}}IBn}\",[]]Ak[\"{{{AHEf{AALn}}}AALn}\",[]]Ak[\"{{{AHEf{AANj}}}AANj}\",[]]Ak[\"{{{AHEf{AOOb}}}AOOb}\",[]]Ak[\"{{{AHEf{BENf}}}BENf}\",[]]Ak[\"{{{AHEf{BBM`}}}BBM`}\",[]]Ak[\"{{{AHEf{BGGj}}}BGGj}\",[]]Ak[\"{{{AHEf{BGGl}}}BGGl}\",[]]Bn[\"{{{AHEf{AIAf}}KDf{AHEf{{JL`{Nd}}}}}HOj}\",[]]Bn[\"{{{AHEf{AAJf}}KDf{AHEf{{JL`{Nd}}}}}HOj}\",[]]Bf[\"{{{AHEf{CNn}}}{{KBj{HOjBALb}}}}\",[]]Bf[\"{{{AHEf{CEdAIAh}}NEdKDhHOn}HOj}\",[]]Bj[\"{{{AHEf{AONd}}}{{AHEf{{JL`{Nd}}}}}}\",[]]Bj[\"{{{AHEf{AONf}}}{{AHEf{{JL`{Nd}}}}}}\",[]]Aa[\"{BBA`AIC`}\",[]]A`[\"{AAMbCLf}\",[]]A`[\"{AAMdCLf}\",[]]A`[\"{AONnD@n}\",[]]A`[\"{AOO`D@n}\",[]]l[\"{NEf}\",[]]l[\"{NEh}\",[]]Ce[\"{{{AHEf{BEEl}}{AHEf{CEdOh}}}{{KBj{AONfBEAj}}}}\",[]]Ce[\"{{{AHEf{BH@n}}{AHEf{CEdOh}}}{{KBj{AONfBEAj}}}}\",[]]Bc[\"{{{AHEf{AIAh}}}{{AAj{KBf}}}}\",[]]Bd[\"{{{AHEf{IDj}}{AHEf{CL`}}}HOj}\",[]]Am[\"{{{AHEf{ANKf}}JNf}HOj}\",[]]Ai[\"{{{AHEf{IDl}}}HOj}\",[]]Bg[\"{{{AAd{{AHEf{CEdAI@`}}}}NEd}HOj}\",[]]Bm[\"{{{AHEf{CEdAIEf}}KDf}{{KBj{HOjAOMb}}}}\",[]]Bm[\"{{{AHEf{CEdAIEh}}KDh}{{KBj{HOjAOMj}}}}\",[]]Am[\"{AAJn{{KBj{HOjAIE`}}}}\",[]]Dc[\"{{{AHEf{CEdAAJh}}AAK`{AHEf{CEd{AAj{Nd}}}}}{{KBj{AANhAIEb}}}}\",[]]Bi[\"{{{AHEf{NGh}}{AAd{{Of{K@n}}}}}HOj}\",[]]Bj[\"{{{AHEf{B@Cf}}{AAd{{Of{K@n}}}}}HOj}\",[]]Bj[\"{{{AHEf{ANNj}}{AAd{{Of{K@n}}}}}HOj}\",[]]o[\"{A@lD@n}\",[]]Ak[\"{{{AHEf{AIAf}}}BBLf}\",[]]Ak[\"{{{AHEf{AAJf}}}B@Of}\",[]]Aj[\"{{{AHEf{CNn}}}AGLb}\",[]]An[\"{{{AHEf{CEdAIAh}}}BBLh}\",[]]Ce[\"{{{AHEf{CEdAIDd}}{KB`{KDb}}}{{AHEf{CEdAIDd}}}}\",[]]Ce[\"{{{AHEf{CEdAIDf}}{KB`{KDb}}}{{AHEf{CEdAIDf}}}}\",[]]Ck[\"{{{AHEf{CEdAIEf}}{AHEf{{JL`{Nd}}}}}{{KBj{JNfAIGb}}}}\",[]]Ck[\"{{{AHEf{CEdAIEh}}{AHEf{{JL`{Nd}}}}}{{KBj{JNfAIGd}}}}\",[]]Bl[\"{{{AHEf{BEOd}}{AHEf{CEdc}}}HOjJOl}\",[\"W\"]]Aj[\"{{{AHEf{AAJf}}}JNn}\",[]]An[\"{AAJn{{KBj{AIAbBBKn}}}}\",[]]Bh[\"{{{AHEf{CEdNHj}}On}{{KB`{AAMd}}}}\",[]]Fh[\"{{{AHEf{CEdAAJh}}AAK`NEd{AHEf{CEd{AAj{Nd}}}}{KB`{{Nn{B@Bl}}}}}{{KBj{{JNd{BDEfAIAh}}{Of{ANK`}}}}}}\",[]]Am[\"{AHEf{{AHEf{c}}}{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000o[\"{NIfJNf}\",[]]o[\"{NIhJNf}\",[]]A`[\"{A@lANKd}\",[]]Bc[\"{{AIElBAL`A@l}{{KBn{ANKf}}}}\",[]]Aj[\"{AIEl{{KBl{AAJf}}}}\",[]]B`[\"{{}{{KBj{HOj{Of{IAd}}}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}BBKn}\",[]]Be[\"{{{AHEf{AAJh}}}{{AHEf{BAMh}}}}\",[]]o[\"{NdBEIf}\",[]]A`[\"{AIBbCLf}\",[]]o[\"{B@BhNn}\",[]]o[\"{NdBEIh}\",[]]A`[\"{AIBdCLf}\",[]]o[\"{B@BlNn}\",[]]A`[\"{BBA`KB`}\",[]]Bl[\"{{{AHEf{CEdc}}}{{KBj{KDfBACf}}}Oh}\",[\"B\"]]Bl[\"{{{AHEf{CEdc}}}{{KBj{KBdBACf}}}Oh}\",[\"B\"]]Bm[\"{{{AHEf{CEdc}}}{{KBj{AGJbBACf}}}Oh}\",[\"B\"]]Bm[\"{{{AHEf{CEdc}}}{{KBj{BEIfBACf}}}Oh}\",[\"B\"]]Bm[\"{{{AHEf{CEdc}}}{{KBj{AAMbBACf}}}Oh}\",[\"B\"]]Bh[\"{{{AHEf{CEdc}}}{{KCb{KDh}}}Oh}\",[\"B\"]]Bh[\"{{{AHEf{CEdc}}}{{KCb{KBf}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AGJd}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AIC`}}}Oh}\",[\"B\"]]Ek[\"{{{AHEf{CEd{K@l{AAI`}}}}{AHEf{c}}{AHEf{{JL`{CLd}}}}D@n}{{KBj{BBMhBEAj}}}{BEElIDh}}\",[\"\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{BEIh}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AAMd}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AGIf}}}Oh}\",[\"B\"]]A`[\"{AALnKB`}\",[]]Bk[\"{{{AHEf{KDf}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bk[\"{{{AHEf{KBd}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AGJb}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{BEIf}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AAMb}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bk[\"{{{AHEf{KDh}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bk[\"{{{AHEf{KBf}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AGJd}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AIC`}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AAIj}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{BEIh}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AAMd}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AGIl}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bj[\"{{{AHEf{CEdAIEf}}}{{KBj{HOjAOMb}}}}\",[]]Bj[\"{{{AHEf{CEdAIEh}}}{{KBj{HOjANLl}}}}\",[]]An[\"{{{AHEf{ANOf}}AAJb}HOj}\",[]]Ea[\"{{{AHEf{CEdAAJh}}NEdAGJ`{KB`{AOO`}}AAI`{AHEf{CEd{AAj{Nd}}}}}{{KB`{B@Ob}}}}\",[]]o[\"{CNbNEf}\",[]]o[\"{CNdNEh}\",[]]A`[\"{AAJnHOj}\",[]]Ba[\"{{{AHEf{CEdAAJh}}AAK`}HOj}\",[]]Bh[\"{{{AHEf{AIFl}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BAOb}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BDHl}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{AIFn}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BAOd}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BDHn}}{AHEf{CL`}}HOn}HOj}\",[]]A`[\"{AGHnD@n}\",[]]o[\"{I@`CLf}\",[]]o[\"{I@bCLf}\",[]]Ce[\"{{{AHEf{CEdAIAj}}NEdNEdCLfD@n{AHEf{B@An}}}HOj}\",[]]Cc[\"{{{AHEf{CEdO`}}NEdNEdCLfD@n{AHEf{B@An}}}HOj}\",[]]Cd[\"{{{AHEf{CEdI@h}}NEdNEdCLfD@n{AHEf{B@An}}}HOj}\",[]]Cd[\"{{{AHEf{CEdNF`}}NEdNEdCLfD@n{AHEf{B@An}}}HOj}\",[]]Ce[\"{{{AHEf{CEdAIAl}}NEdNEdCLfD@n{AHEf{B@B`}}}HOj}\",[]]Cc[\"{{{AHEf{CEdOb}}NEdNEdCLfD@n{AHEf{B@B`}}}HOj}\",[]]Cd[\"{{{AHEf{CEdI@j}}NEdNEdCLfD@n{AHEf{B@B`}}}HOj}\",[]]Cd[\"{{{AHEf{CEdNFb}}NEdNEdCLfD@n{AHEf{B@B`}}}HOj}\",[]]o[\"{CNbNEf}\",[]]o[\"{CNdNEh}\",[]]o[\"{BDIfNd}\",[]]A`[\"{BBKhHOn}\",[]]A`[\"{BDDjHOn}\",[]]A`[\"{BBKlHOn}\",[]]A`[\"{BDDnHOn}\",[]]A`[\"{BBA`KDb}\",[]]Aa[\"{BALhBBL`}\",[]]Aa[\"{AGGdBEAn}\",[]]Bg[\"{{{AHEf{AAJf}}AGMb}{{KBl{HOj}}}}\",[]]A`[\"{AAJnHOj}\",[]]Cf[\"{{{AHEf{CEdAAJh}}AAK`{AHEf{CEd{AAj{Nd}}}}}AANh}\",[]]l[\"{NEf}\",[]]Ak[\"{{{AHEf{AGJ`}}}AIEl}\",[]]l[\"{NEh}\",[]]An[\"{{AAJdA@l}{{KBn{HOj}}}}\",[]]B`[\"{{B@BhAIEl}{{KBl{AAJf}}}}\",[]]Bb[\"{B@Bf{{KBj{HOj{Of{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BEB`}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BB@f}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{AGLh}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{AIDn}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BB@d}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{AIGb}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{B@Cd}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BBKn}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BBL`}}}{{KB`{{AHEf{IAd}}}}}}\",[]]A`[\"{AANfKB`}\",[]]A`[\"{AANhKB`}\",[]]A`[\"{AANjKB`}\",[]]Bg[\"{{{AHEf{CNn}}}{{KBj{AID`AI@h}}}}\",[]]Aa[\"{B@AjAIDb}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]A`[\"{AALnJNf}\",[]]Aa[\"{AGLbAANl}\",[]]Aa[\"{BBLfAANl}\",[]]Aa[\"{AGLdAANn}\",[]]Aa[\"{BBLhAANn}\",[]]3210Dh[\"{{{AHEf{NDn}}{AHEf{{JL`{Nd}}}}{AHEf{{JL`{Nd}}}}}{{KBj{HOjANL`}}}}\",[]]Dh[\"{{{AHEf{NE`}}{AHEf{{JL`{Nd}}}}{AHEf{{JL`{Nd}}}}}{{KBj{HOjANLb}}}}\",[]]Aj[\"{{{AHEf{AIAj}}}CLf}\",[]]Ah[\"{{{AHEf{O`}}}CLf}\",[]]Ai[\"{{{AHEf{I@h}}}CLf}\",[]]Ai[\"{{{AHEf{NF`}}}CLf}\",[]]Aj[\"{{{AHEf{AIAl}}}CLf}\",[]]Ah[\"{{{AHEf{Ob}}}CLf}\",[]]Ai[\"{{{AHEf{I@j}}}CLf}\",[]]Ai[\"{{{AHEf{NFb}}}CLf}\",[]]Aj[\"{{{AHEf{BFLl}}}JNf}\",[]]Aj[\"{{{AHEf{BFLn}}}JNf}\",[]]Aj[\"{{{AHEf{BGMb}}}JNf}\",[]]Aj[\"{{{AHEf{BGMl}}}JNf}\",[]]o[\"{A@lJNf}\",[]]n[\"{{}ND`}\",[]]0o[\"{OjAAId}\",[]]111Ba[\"{{AHEf{AHEf{c}}}AALh{}}\",[\"K\"]]0000000000000000000Cg[\"{{{AHEf{AAJf}}AIEl{AHEf{CL`}}}{{KBj{AIAbAOMn}}}}\",[]]Dl[\"{{{AHEf{CEdAAJh}}NEdAOLjAIEl{AHEf{CL`}}}{{KBj{{JNd{BDEfAIAh}}AON`}}}}\",[]]Bd[\"{{{AHEf{AAJn}}}{{KB`{BDEj}}}}\",[]]Dm[\"{{{AHEf{AGKf}}KBdCLf{AHEf{{JL`{Nd}}}}{AHEf{CEdAAI`}}}{{KBj{HOjANL`}}}}\",[]]Ca[\"{{{AHEf{AGJh}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Bd[\"{{{AHEf{AAK`}}}{{KB`{BDEl}}}}\",[]]Dm[\"{{{AHEf{AGKh}}KBfCLf{AHEf{{JL`{Nd}}}}{AHEf{CEdAAI`}}}{{KBj{HOjANLb}}}}\",[]]Ca[\"{{{AHEf{AGJj}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]o[\"{{}ANOd}\",[]]n[\"{{}IDj}\",[]]o[\"{{}ANKf}\",[]]o[\"{{}B@Nd}\",[]]o[\"{{}B@Of}\",[]]n[\"{{}KDf}\",[]]n[\"{{}KBd}\",[]]o[\"{{}AANl}\",[]]o[\"{{}AIBb}\",[]]o[\"{{}AGLb}\",[]]o[\"{{}BBLf}\",[]]n[\"{{}NIf}\",[]]o[\"{{}AOMb}\",[]]o[\"{{}BBNl}\",[]]o[\"{{}BEE`}\",[]]o[\"{{}BEFn}\",[]]o[\"{{}ANLn}\",[]]o[\"{{}BAMf}\",[]]o[\"{{}BFMn}\",[]]o[\"{{}BDHl}\",[]]o[\"{{}AGHh}\",[]]o[\"{{}ANLd}\",[]]o[\"{{}BAAj}\",[]]o[\"{{}BE@h}\",[]]o[\"{{}B@Nf}\",[]]o[\"{{}BGMb}\",[]]n[\"{{}KDh}\",[]]n[\"{{}KBf}\",[]]o[\"{{}AIDb}\",[]]o[\"{{}AI@n}\",[]]o[\"{{}AANn}\",[]]o[\"{{}AIBd}\",[]]o[\"{{}AGLd}\",[]]o[\"{{}BBLh}\",[]]n[\"{{}NIh}\",[]]o[\"{{}BB@h}\",[]]o[\"{{}AOMj}\",[]]o[\"{{}BBNn}\",[]]o[\"{{}BEEb}\",[]]o[\"{{}BEG`}\",[]]o[\"{{}ANM`}\",[]]o[\"{{}BAMh}\",[]]o[\"{{}BFN`}\",[]]o[\"{{}BGMl}\",[]]o[\"{{}BDHn}\",[]]o[\"{{}AGHj}\",[]]o[\"{{}ANLf}\",[]]o[\"{{}BAAl}\",[]]o[\"{{}BE@j}\",[]]o[\"{{}AALn}\",[]]n[\"{{}IDl}\",[]]o[\"{{}BBM`}\",[]]o[\"{{}B@Od}\",[]]Ak[\"{{{AHEf{BAB`}}}AONf}\",[]]Ak[\"{{{AHEf{BBMh}}}AONf}\",[]]Aa[\"{BGB`AONf}\",[]]Aa[\"{BEIjAONf}\",[]]A`[\"{CNfAONf}\",[]]A`[\"{ID`AONf}\",[]]A`[\"{IDdAONf}\",[]]Aa[\"{BDIfAONf}\",[]]Cg[\"{{{AHEf{AGKf}}KBdCLf{AHEf{CEd{JL`{Nd}}}}JNf}HOj}\",[]]Ca[\"{{{AHEf{AGJh}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Cg[\"{{{AHEf{AGKh}}KBfCLf{AHEf{CEd{JL`{Nd}}}}JNf}HOj}\",[]]Ca[\"{{{AHEf{AGJj}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Aj[\"{{{AHEf{AIDj}}}D@n}\",[]]Aj[\"{{{AHEf{BEOf}}}D@n}\",[]]Ak[\"{{{AHEf{AIAj}}}BE@h}\",[]]Ai[\"{{{AHEf{O`}}}BE@h}\",[]]Aj[\"{{{AHEf{I@h}}}BE@h}\",[]]Aj[\"{{{AHEf{NF`}}}BE@h}\",[]]Ak[\"{{{AHEf{AIAl}}}BE@j}\",[]]Ai[\"{{{AHEf{Ob}}}BE@j}\",[]]Aj[\"{{{AHEf{I@j}}}BE@j}\",[]]Aj[\"{{{AHEf{NFb}}}BE@j}\",[]]Bn[\"{{{AHEf{CEdBBNl}}CLb}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}CLb}{{AHEf{CEdBBNn}}}}\",[]]Bf[\"{{{AHEf{CEdAIAj}}NEdCLfCLf}HOj}\",[]]Bd[\"{{{AHEf{CEdO`}}NEdCLfCLf}HOj}\",[]]Bf[\"{{{AHEf{CEdAIAl}}NEdCLfCLf}HOj}\",[]]Bd[\"{{{AHEf{CEdOb}}NEdCLfCLf}HOj}\",[]]Aj[\"{{{AHEf{AIAf}}}KAf}\",[]]Bc[\"{{{AHEf{AALf}}}{{KB`{KBd}}}}\",[]]Aa[\"{BGB`AONf}\",[]]Aa[\"{BEIjAONf}\",[]]A`[\"{CNfAONf}\",[]]A`[\"{ID`AONf}\",[]]Aa[\"{BDIfAONf}\",[]]Aj[\"{{{AHEf{AIEf}}}NHb}\",[]]Bn[\"{{{AHEf{AIEh}}}{{KBj{{KB`{KDh}}AOMj}}}}\",[]]o[\"{A@lJNf}\",[]]o[\"{IDjJNf}\",[]]Am[\"{{{AHEf{CEdAIAh}}}NHj}\",[]]Aj[\"{{{AHEf{AGKf}}}JNf}\",[]]Aj[\"{{{AHEf{AGKh}}}JNf}\",[]]A`[\"{AHEfKDd}\",[]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Bd[\"{{{AHEf{BFGb}}}{{KB`{AIAf}}}}\",[]]Bc[\"{{{AHEf{BBAd}}}{{KB`{CNn}}}}\",[]]Bn[\"{{{AHEf{CEdAOLf}}CLd}{{AHEf{CEdAOLf}}}}\",[]]Bn[\"{{{AHEf{CEdAOLj}}CLd}{{AHEf{CEdAOLj}}}}\",[]]A`[\"{BGB`CLd}\",[]]A`[\"{BEIjCLd}\",[]]o[\"{CNfCLd}\",[]]o[\"{ID`CLd}\",[]]A`[\"{AGHnKB`}\",[]]Aa[\"{AANjAHEf}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Aa[\"{BB@jAAJb}\",[]]A`[\"{JOnBB@h}\",[]]Aa[\"{AGLbAIBb}\",[]]Aa[\"{BBLfAIBb}\",[]]Aa[\"{AGLdAIBd}\",[]]Aa[\"{BBLhAIBd}\",[]]3210Bg[\"{{{AHEf{CEdc}}JNf}AONd{OhIDh}}\",[\"\"]]Bg[\"{{{AHEf{CEdc}}JNf}AONf{OhIDh}}\",[\"\"]]o[\"{{}BBMj}\",[]]o[\"{{}BBMl}\",[]]A`[\"{CLfBGMb}\",[]]Cd[\"{{{AHEf{CL`}}}{{KBn{ANNdc}}}{}}\",[\"FromStr::Err\"]]Cd[\"{{{AHEf{CL`}}}{{KBn{ANKdc}}}{}}\",[\"FromStr::Err\"]]o[\"{CLdKDf}\",[]]o[\"{CLdKDh}\",[]]Al[\"{CLf{{KBj{KDfBFFl}}}}\",[]]Al[\"{CLf{{KBj{KDhBFFn}}}}\",[]]Aa[\"{BFEdANKn}\",[]]Aa[\"{BHA`BA@b}\",[]]Aa[\"{BFEfANKn}\",[]]Aa[\"{BHAbBA@b}\",[]]Af[\"{{}{{KB`{Ab}}}}\",[]]0000Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]Bo[\"{{{AHEf{CEdBEFn}}AAJb}{{AHEf{CEdBEFn}}}}\",[]]Bo[\"{{{AHEf{CEdBEG`}}AAJb}{{AHEf{CEdBEG`}}}}\",[]]Ao[\"{{{Of{AIAj}}}{{Of{Nl}}}}\",[]]Am[\"{{{Of{O`}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{I@h}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{NF`}}}{{Of{Nl}}}}\",[]]Ao[\"{{{Of{AIAl}}}{{Of{Nl}}}}\",[]]Am[\"{{{Of{Ob}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{I@j}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{NFb}}}{{Of{Nl}}}}\",[]]Aj[\"{{{AHEf{BFGb}}}D@n}\",[]]Bo[\"{{{AHEf{CEdBFMn}}AAJb}{{AHEf{CEdBFMn}}}}\",[]]Bo[\"{{{AHEf{CEdBFN`}}AAJb}{{AHEf{CEdBFN`}}}}\",[]]Bc[\"{{{AHEf{AIAb}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AIAf}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AAJn}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AAK`}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AGJ`}}}{{KB`{KAb}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Bc[\"{{{AHEf{AGId}}}{{KB`{JNf}}}}\",[]]Am[\"{{{AHEf{ANOf}}JNf}HOj}\",[]]Aj[\"{{{AHEf{AIAf}}}NFf}\",[]]Bg[\"{{{AHEf{AIEf}}}{{KBj{CCnAOMb}}}}\",[]]Bg[\"{{{AHEf{AIEh}}}{{KBj{CCnAOMj}}}}\",[]]A`[\"{B@OjKB`}\",[]]A`[\"{B@OlKB`}\",[]]A`[\"{AGHnKB`}\",[]]A`[\"{ANK`KB`}\",[]]Ck[\"{{{AHEf{CEdBAMf}}{KB`{{IEf{Nd}}}}}{{AHEf{CEdBAMf}}}}\",[]]Ck[\"{{{AHEf{CEdBAMh}}{KB`{{IEf{Nd}}}}}{{AHEf{CEdBAMh}}}}\",[]]A`[\"{BE@hKB`}\",[]]A`[\"{BE@jKB`}\",[]]Ac[\"{AHEfc{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Ao[\"{c{{KBj{e}}}{}{}}\",[\"U\",\"T\"]]000000000000000000000000000000000000000000000000000Al[\"{JNf{{KBj{KDfBFFl}}}}\",[]]Al[\"{CLf{{KBj{KDfBFFl}}}}\",[]]2Al[\"{HOh{{KBj{KDfBFFl}}}}\",[]]33333333333333Aj[\"{AAJb{{KBj{ANLn}}}}\",[]]4444444Ai[\"{CLf{{KBj{AGJb}}}}\",[]]5555555555555555555555555555Aj[\"{AOLb{{KBj{BDHd}}}}\",[]]Bb[\"{{{Nn{AOLb}}}{{KBj{BDHd}}}}\",[]]7Bb[\"{{{Nn{B@Bd}}}{{KBj{BDHh}}}}\",[]]8Aj[\"{B@Bd{{KBj{BDHh}}}}\",[]]999999999999999999999Al[\"{CLf{{KBj{KDhBFFn}}}}\",[]]Al[\"{HOh{{KBj{KDhBFFn}}}}\",[]]Al[\"{JNf{{KBj{KDhBFFn}}}}\",[]]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Bm[\"{AOLb{{KBj{BDHfc}}}{}}\",[\"TryFrom::Error\"]]Ce[\"{{{Nn{AOLb}}}{{KBj{BDHfc}}}{}}\",[\"TryFrom::Error\"]]Ao[\"{c{{KBj{e}}}{}{}}\",[\"U\",\"T\"]]00Ce[\"{{{Nn{B@Bd}}}{{KBj{BDHjc}}}{}}\",[\"TryFrom::Error\"]]Bm[\"{B@Bd{{KBj{BDHjc}}}{}}\",[\"TryFrom::Error\"]]22222222222222222222222Aj[\"{{}{{KBj{c}}}{}}\",[\"U\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Cd[\"{{{AAd{{AHEf{CEdc}}}}{AHEf{CEdNDb}}}COf{}}\",[\"F\"]]000000000Cc[\"{{{AHEf{BBAb}}AIG`{AHEf{AANj}}}{{KBl{HOj}}}}\",[]]Bk[\"{{{AHEf{BFLl}}AONd}{{KBj{HOjAIBh}}}}\",[]]Bk[\"{{{AHEf{BFLn}}AONf}{{KBj{HOjAIBj}}}}\",[]]0Bk[\"{{{AHEf{BGMb}}AONf}{{KBj{HOjAIBj}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}AAHn}\",[]]Bi[\"{{{AHEf{CEdB@Ch}}}{{KBj{KDfIB`}}}}\",[]]Bi[\"{{{AHEf{CEdB@Ch}}}{{KBj{COlIB`}}}}\",[]]Bh[\"{{{AHEf{CEdB@Ch}}}{{KBj{OlIB`}}}}\",[]]Bj[\"{{{AHEf{CEdB@Ch}}}{{KBj{AAMbIB`}}}}\",[]]Bf[\"{{{AHEf{CEdB@Ch}}}{{KC`{KDh}}}}\",[]]Bf[\"{{{AHEf{CEdB@Ch}}}{{KC`{COn}}}}\",[]]Be[\"{{{AHEf{CEdB@Ch}}}{{KC`{On}}}}\",[]]Bg[\"{{{AHEf{CEdB@Ch}}}{{KC`{AAMd}}}}\",[]]Aa[\"{ANKdBFFj}\",[]]Bc[\"{{{AHEf{AIAj}}}{{Of{AIAj}}}}\",[]]Ba[\"{{{AHEf{O`}}}{{Of{AIAj}}}}\",[]]Bb[\"{{{AHEf{I@h}}}{{Of{AIAj}}}}\",[]]Bb[\"{{{AHEf{NF`}}}{{Of{AIAj}}}}\",[]]Bc[\"{{{AHEf{AIAl}}}{{Of{AIAl}}}}\",[]]Ba[\"{{{AHEf{Ob}}}{{Of{AIAl}}}}\",[]]Bb[\"{{{AHEf{I@j}}}{{Of{AIAl}}}}\",[]]Bb[\"{{{AHEf{NFb}}}{{Of{AIAl}}}}\",[]]A`[\"{AANlCLf}\",[]]An[\"{{{AHEf{CEdAIAh}}}AGId}\",[]]A`[\"{AANnCLf}\",[]]C`[\"{{{AHEf{CEdAONd}}}{{AHEf{CEd{JL`{Nd}}}}}}\",[]]C`[\"{{{AHEf{CEdAONf}}}{{AHEf{CEd{JL`{Nd}}}}}}\",[]]Ah[\"{Nd{{KB`{AONn}}}}\",[]]Ah[\"{Nd{{KB`{AOO`}}}}\",[]]Ah[\"{Nd{{KB`{AOOb}}}}\",[]]A`[\"{AAMbCOl}\",[]]A`[\"{AAMdCOn}\",[]]Bi[\"{AIAb{{KBj{{JNd{AIAfBBOf}}AIAb}}}}\",[]]Aa[\"{{}c{}}\",[\"I\"]]o[\"{COlD@n}\",[]]o[\"{COnD@n}\",[]]Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]21Aj[\"{{{AHEf{AAJn}}}D@n}\",[]]Aj[\"{{{AHEf{AAK`}}}D@n}\",[]]Bn[\"{{{AHEf{CEdB@Bh}}D@n}{{AHEf{CEdB@Bh}}}}\",[]]Bn[\"{{{AHEf{CEdB@Bl}}D@n}{{AHEf{CEdB@Bl}}}}\",[]]Bl[\"{{{AHEf{NGh}}NEd}{{AAd{{Of{AI@`}}}}}}\",[]]Bm[\"{{{AHEf{B@Cf}}NEd}{{AAd{{Of{AI@`}}}}}}\",[]]Bm[\"{{{AHEf{ANNj}}NEd}{{AAd{{Of{AI@`}}}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Ak[\"{{{AHEf{AIAf}}}AALd}\",[]]Bc[\"{{{AHEf{AIAf}}AIElAID`}AALf}\",[]]Ce[\"{{{AHEf{CEdAIAh}}AGJ`AIDbNEd}{{KBj{KBfAGKl}}}}\",[]]43Bm[\"{{{AHEf{CEdAIAh}}KBf}{{KBj{HOjAI@n}}}}\",[]]E`[\"{{{AAd{{AHEf{CEdBFFf}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]E`[\"{{{AAd{{AHEf{CEdBDDf}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]E`[\"{{{AAd{{AHEf{CEdAICn}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]E`[\"{{{AAd{{AHEf{CEdBENh}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]Ef[\"{{{AAd{{AHEf{CEdAIDj}}}}{AHEf{CEdNDb}}{AHEf{CEd{JL`{Nd}}}}}{{COf{{KBl{JNf}}}}}}\",[]]Ec[\"{{{AHEf{CEdAIDj}}{AHEf{CEdNDb}}{AHEf{CEd{JL`{Nd}}}}}{{COf{{KBj{JNfAGLh}}}}}}\",[]]E`[\"{{{AAd{{AHEf{CEdAIDj}}}}{AHEf{CEdNDb}}{AHEf{CEdNGb}}}{{COf{{KBl{HOj}}}}}}\",[]]Fg[\"{{{AHEf{CEdBAKn}}{AHEf{CEdNDb}}{AHEf{CEd{JL`{AIBl}}}}{AHEf{CEd{JL`{AALn}}}}}{{COf{{KBl{JNf}}}}}}\",[]]Dn[\"{{{AAd{{AHEf{CEdAGM`}}}}{AHEf{AANj}}{AHEf{CEdNDb}}}{{COf{{KBl{HOj}}}}}}\",[]]>=Cd[\"{{{AHEf{CEdBAMf}}{Nn{NDn}}}{{AHEf{CEdBAMf}}}}\",[]]Cd[\"{{{AHEf{CEdBAMh}}{Nn{NE`}}}{{AHEf{CEdBAMh}}}}\",[]]Cj[\"{{{AHEf{B@Bj}}CLdAONd{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{BDHh}}CLdAONd{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{B@Bn}}CLdAONf{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{BDHj}}CLdAONf{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{BGGl}}CLdAONb{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Bb[\"{JNf{{JNd{JNf{KB`{JNf}}}}}}\",[]]000Aj[\"{{{AHEf{AIAf}}}JNf}\",[]]A`[\"{AHEfKDb}\",[]]00000000000000000000000000000000000000000000000000000000000000Ce[\"{{{AHEf{CEdB@Bh}}{Nn{BE@l}}}{{AHEf{CEdB@Bh}}}}\",[]]Ce[\"{{{AHEf{CEdB@Bl}}{Nn{BE@n}}}{{AHEf{CEdB@Bl}}}}\",[]]A`[\"{BGB`ICf}\",[]]o[\"{B@BhNn}\",[]]o[\"{B@BlNn}\",[]]Aj[\"{{{AHEf{AAJf}}}HOj}\",[]]Ck[\"{{{AHEf{CEdAIEf}}{AHEf{{JL`{Nd}}}}}{{KBj{HOjAIGb}}}}\",[]]n[\"{{}JNf}\",[]]Ak[\"{{{AHEf{AIAf}}}AGGh}\",[]]Ba[\"{{{AHEf{CEdAANl}}AANl}HOj}\",[]]Ba[\"{{{AHEf{CEdAIBb}}AIBb}HOj}\",[]]Ba[\"{{{AHEf{CEdBBLf}}AGLb}HOj}\",[]]Ba[\"{{{AHEf{CEdAANn}}AANn}HOj}\",[]]Ba[\"{{{AHEf{CEdAIBd}}AIBd}HOj}\",[]]Ba[\"{{{AHEf{CEdBBLh}}AGLd}HOj}\",[]]Bn[\"{{{AHEf{CEdBBNl}}D@n}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}D@n}{{AHEf{CEdBBNn}}}}\",[]]Bi[\"{{{AHEf{CEd}}}{{AHEf{CEdc}}}{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Bc[\"{{AHEf{AHEf{CEdc}}}HOj{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Cc[\"{{{AHEf{CEdAIAh}}NEdKBfKDh}{{KBj{HOjBALd}}}}\",[]]A`[\"{AGHnD@n}\",[]]B`[\"{{AHEf{AHEf{c}}}D@n{}}\",[\"K\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Aa[\"{BBKhBEIf}\",[]]A`[\"{BDDjKDf}\",[]]Aa[\"{BBKlBEIh}\",[]]A`[\"{BDDnKDh}\",[]]A`[\"{BDOlKDh}\",[]]A`[\"{BBMnKDh}\",[]]o[\"{NGnKDh}\",[]]Aa[\"{BBKhAIBn}\",[]]Aa[\"{BBKlAIC`}\",[]]o[\"{KDfCLf}\",[]]o[\"{KDhCLf}\",[]]Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]Aj[\"{{{AHEf{B@Od}}}D@n}\",[]]Bd[\"{{{AHEf{BAKn}}}{{KBl{AIEl}}}}\",[]]Bd[\"{{{AHEf{AAJf}}}{{KBl{AIEl}}}}\",[]]A`[\"{AGLbCLf}\",[]]A`[\"{BBLfCLf}\",[]]A`[\"{AGLdCLf}\",[]]A`[\"{BBLhCLf}\",[]]Cb[\"{{{AHEf{BBM`}}{AHEf{AIEd}}CLf}{{Nn{ANOf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNl}}D@n}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}D@n}{{AHEf{CEdBBNn}}}}\",[]]Bg[\"{{{AHEf{AIAf}}KBd}{{KB`{AGLb}}}}\",[]]Bj[\"{{{AHEf{CEdAIAh}}KBf}{{KB`{AGLd}}}}\",[]]o[\"{AGIhOf}\",[]]Db[\"{{{AAd{{AHEf{CEdAIEf}}}}{AHEf{CEdNDb}}}{{COf{{KBl{HOj}}}}}}\",[]]00Ec[\"{{{AAd{{AHEf{CEdAIEf}}}}{AHEf{CEdNDb}}{AHEf{{JL`{Nd}}}}}{{COf{{KBl{JNf}}}}}}\",[]]Eg[\"{{{AAd{{AHEf{CEdAIEf}}}}{AHEf{CEdNDb}}{AHEf{{JL`{Nd}}}}}{{COf{{KBj{JNfAIGb}}}}}}\",[]]1Bm[\"{{{AHEf{IDl}}{AHEf{CNl}}}{{KBl{HOj}}}}\",[]]Cd[\"{{{AHEf{CEdAIDj}}JNf}{{KBj{{KB`{I@`}}AGLh}}}}\",[]]Cd[\"{{{AHEf{CEdBEOf}}JNf}{{KBj{{KB`{I@`}}AGLh}}}}\",[]]Cn[\"{{{AHEf{CEdAIDj}}{AHEf{CEd{JL`{Nd}}}}}{{KBj{HOjBB@d}}}}\",[]]Bj[\"{{{AHEf{CNn}}AID`}{{KBj{HOjBEHl}}}}\",[]]Bn[\"{{{AHEf{CEdAIDd}}NEd}{{AHEf{CEdAIDd}}}}\",[]]Bn[\"{{{AHEf{CEdAIDf}}NEd}{{AHEf{CEdAIDf}}}}\",[]]A`[\"{BB@jAFd}\",[]]o[\"{IDjCLf}\",[]]o[\"{{}AIEl}\",[]]0o[\"{{}AHEf}\",[]]Bj[\"{{AAJn{Nn{B@Bh}}}{{KBj{AIAbBBKn}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Bh[\"{{{AHEf{AGHn}}AIEl}{{KBn{AGMb}}}}\",[]]A`[\"{AGLbCLb}\",[]]Aj[\"{{{AHEf{AIAh}}}CLb}\",[]]A`[\"{AGLdCLb}\",[]]Ce[\"{{{AHEf{CEdAIDd}}{KB`{KDb}}}{{AHEf{CEdAIDd}}}}\",[]]Ce[\"{{{AHEf{CEdAIDf}}{KB`{KDb}}}{{AHEf{CEdAIDf}}}}\",[]]Aa[\"{AANfAIEl}\",[]]Aa[\"{AANhAIEl}\",[]]Aa[\"{AANjAIEl}\",[]]Aa[\"{AIElAGJ`}\",[]]o[\"{A@lCLb}\",[]]Bn[\"{{{AHEf{CEdBBNl}}CLb}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}CLb}{{AHEf{CEdBBNn}}}}\",[]]A`[\"{AGHnCLb}\",[]]Bo[\"{{{AHEf{CEdBBNl}}AAJb}{{AHEf{CEdBBNl}}}}\",[]]Bo[\"{{{AHEf{CEdBBNn}}AAJb}{{AHEf{CEdBBNn}}}}\",[]]A`[\"{AGHnKB`}\",[]]k[\"{{}}\",[]]0000000000Bh[\"{AAJnc{}}\",[\"IntoFuture::IntoFuture\"]]11A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]o[\"{A@lJNf}\",[]]Ao[\"{{AHEfc}{{NEj{c}}}{}}\",[\"S\"]]0C`[\"{{{AHEf{CEdAIAj}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]Bn[\"{{{AHEf{CEdO`}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]C`[\"{{{AHEf{CEdAIAl}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]Bn[\"{{{AHEf{CEdOb}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]Bk[\"{{{AHEf{CEdIDl}}NEd{AHEf{BBM`}}}HOj}\",[]]A`[\"{BE@hKB`}\",[]]A`[\"{BE@jKB`}\",[]]Bn[\"{{{AHEf{KDf}}{AHEf{KDf}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{KBd}}{AHEf{KBd}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{ANLn}}{AHEf{ANLn}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AONd}}{AHEf{AONd}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{COl}}{AHEf{COl}}}{{KB`{AALh}}}}\",[]]Bl[\"{{{AHEf{Ol}}{AHEf{Ol}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AAMb}}{AHEf{AAMb}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{KDh}}{AHEf{KDh}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BEBb}}{AHEf{BEBb}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{KBf}}{AHEf{KBf}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AGLj}}{AHEf{AGLj}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BABj}}{AHEf{BABj}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AIGd}}{AHEf{AIGd}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{ANM`}}{AHEf{ANM`}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BDEf}}{AHEf{BDEf}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BEAj}}{AHEf{BEAj}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AONf}}{AHEf{AONf}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{COn}}{AHEf{COn}}}{{KB`{AALh}}}}\",[]]Bl[\"{{{AHEf{On}}{AHEf{On}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AAMd}}{AHEf{AAMd}}}{{KB`{AALh}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}AICn}\",[]]Bk[\"{{{AHEf{AIAh}}KBf}{{KBj{AIDbAI@n}}}}\",[]]Df[\"{{{AHEf{CEdAIDj}}{AHEf{CEd{JL`{HOn}}}}}{{KBj{{KB`{JNf}}AGLh}}}}\",[]]Cc[\"{{{AHEf{CEdAIDj}}JNf}{{KBj{{AAj{Nd}}BB@f}}}}\",[]]Bb[\"{{{AHEf{CEdAIAh}}AAMd}AIDl}\",[]]Aj[\"{{{AHEf{AGJh}}}JNf}\",[]]Aj[\"{{{AHEf{AGJj}}}JNf}\",[]]Bb[\"{{{AHEf{CEdAIAh}}AAMd}AIEh}\",[]]Bn[\"{{{AHEf{CEdBBNl}}CLf}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}CLf}{{AHEf{CEdBBNn}}}}\",[]]A`[\"{AGHnKB`}\",[]]A`[\"{B@OjKB`}\",[]]A`[\"{B@OlKB`}\",[]]Ce[\"{{{AHEf{CEdB@Bh}}{Nn{AIFd}}}{{AHEf{CEdB@Bh}}}}\",[]]Ce[\"{{{AHEf{CEdB@Bl}}{Nn{AIFf}}}{{AHEf{CEdB@Bl}}}}\",[]]Ce[\"{{{AHEf{CEdAOLf}}{Nn{AIFl}}}{{AHEf{CEdAOLf}}}}\",[]]Ce[\"{{{AHEf{CEdAOLj}}{Nn{AIFn}}}{{AHEf{CEdAOLj}}}}\",[]]o[\"{A@lCLf}\",[]]Bn[\"{{{AHEf{CEdBEFn}}CLb}{{AHEf{CEdBEFn}}}}\",[]]Bn[\"{{{AHEf{CEdBEG`}}CLb}{{AHEf{CEdBEG`}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}BFGb}\",[]]Aj[\"{{{AHEf{CNn}}}BBAd}\",[]]Ai[\"{{{Nn{B@Bj}}}B@Bh}\",[]]Ai[\"{{{Nn{B@Bn}}}B@Bl}\",[]]Aj[\"{{BBMjc}BBMjAAMl}\",[\"\"]]Aj[\"{{BBMlc}BBMlAAMl}\",[\"\"]]Bm[\"{{{AHEf{CEdAIEf}}HOn}{{KBj{HOjAIGb}}}}\",[]]n[\"{{}KAb}\",[]]o[\"{ND`ND`}\",[]]0000Bd[\"{{{AHEf{BFLl}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{BFLn}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{BGMb}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{BGMl}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{AIAf}}}{{KB`{BBKn}}}}\",[]]Ck[\"{{{AHEf{AAJf}}AOLfAIEl{AHEf{CL`}}}{{KBj{AIAbAOMn}}}}\",[]]Ak[\"{{{AHEf{B@B`}}}AAJb}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]An[\"{{AIDhD@n}{{KBn{JNf}}}}\",[]]Cj[\"{{{AHEf{NGj}}}{{KB`{{JNd{{Of{AGJh}}{Of{AGKf}}}}}}}}\",[]]Ck[\"{{{AHEf{AIFh}}}{{KB`{{JNd{{Of{AGJh}}{Of{AGKf}}}}}}}}\",[]]Cj[\"{{{AHEf{NGl}}}{{KB`{{JNd{{Of{AGJj}}{Of{AGKh}}}}}}}}\",[]]Ck[\"{{{AHEf{AIFj}}}{{KB`{{JNd{{Of{AGJj}}{Of{AGKh}}}}}}}}\",[]]A`[\"{BFEdAAj}\",[]]A`[\"{BHA`AAj}\",[]]A`[\"{BFEfAAj}\",[]]A`[\"{BHAbAAj}\",[]]An[\"{{{AHEf{CEdBFLl}}}AONd}\",[]]An[\"{{{AHEf{CEdBFLn}}}AONf}\",[]]An[\"{{{AHEf{CEdBGMb}}}AONf}\",[]]An[\"{{{AHEf{CEdBGMl}}}AONf}\",[]]Ak[\"{{{AHEf{BBAb}}}B@@f}\",[]]Ba[\"{{{AHEf{CEdAIAh}}BBLd}HOj}\",[]]Bo[\"{{{AHEf{CEdAAJh}}BDEfB@Od}{{KB`{BBLd}}}}\",[]]B`[\"{{{AHEf{NGj}}AONdCOl}CNb}\",[]]Bn[\"{{{AHEf{B@Bj}}CLdAONd}{{KBj{CNbBEIn}}}}\",[]]Ba[\"{{{AHEf{AIFh}}AONdCOl}CNb}\",[]]Bn[\"{{{AHEf{BDHh}}CLdAONd}{{KBj{CNbBEIn}}}}\",[]]B`[\"{{{AHEf{NGl}}AONfCOn}CNd}\",[]]Bn[\"{{{AHEf{B@Bn}}CLdAONf}{{KBj{CNdBEJd}}}}\",[]]Ba[\"{{{AHEf{AIFj}}AONfCOn}CNd}\",[]]Bn[\"{{{AHEf{BDHj}}CLdAONf}{{KBj{CNdBEJd}}}}\",[]]Bn[\"{{{AHEf{BGGl}}CLdAONb}{{KBj{CNdBEJd}}}}\",[]]Aj[\"{{}{{NGd{c}}}{}}\",[\"T\"]]0A`[\"{AGLbCLf}\",[]]A`[\"{BBLfCLf}\",[]]A`[\"{AGLdCLf}\",[]]A`[\"{BBLhCLf}\",[]]Bn[\"{{{AHEf{CEdB@Bh}}JNf}{{AHEf{CEdB@Bh}}}}\",[]]Bn[\"{{{AHEf{CEdB@Bl}}JNf}{{AHEf{CEdB@Bl}}}}\",[]]Aj[\"{{{AHEf{BAKn}}}D@n}\",[]]0Aj[\"{{{AHEf{BBAb}}}D@n}\",[]]Bk[\"{{{AHEf{AIAh}}KBf}{{KBj{AGJ`AI@n}}}}\",[]]Cb[\"{{{AHEf{BBM`}}{AHEf{AIDh}}CLf}{{Nn{ANOf}}}}\",[]]Ak[\"{{{AHEf{AAJn}}}AONd}\",[]]Ak[\"{{{AHEf{AAK`}}}AONf}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Bf[\"{{{AHEf{CEdAIAh}}}{{KB`{NEd}}}}\",[]]Ce[\"{{{AHEf{CEdBBNl}}{Nn{ANMl}}}{{AHEf{CEdBBNl}}}}\",[]]Ce[\"{{{AHEf{CEdBBNn}}{Nn{ANMn}}}{{AHEf{CEdBBNn}}}}\",[]]43A`[\"{A@lANNd}\",[]]A`[\"{AANfKB`}\",[]]A`[\"{AANhKB`}\",[]]A`[\"{AANjKB`}\",[]]Ai[\"{{{AHEf{NHj}}}JNf}\",[]]Bo[\"{{{AHEf{CEdBGMb}}AAJb}{{AHEf{CEdBGMb}}}}\",[]]Bo[\"{{{AHEf{CEdBGMl}}AAJb}{{AHEf{CEdBGMl}}}}\",[]]Bj[\"{{{AHEf{AIEf}}CCn}{{KBj{HOjAOMb}}}}\",[]]Bm[\"{{{AHEf{CEdAIEh}}CCn}{{KBj{HOjAOMj}}}}\",[]]==E`[\"{{{AHEf{BGBb}}{AHEf{{JL`{Nd}}}}{AHEf{BAL`}}{AHEf{BFM`}}}{{KBj{BGDhIAh}}}}\",[]]0Bf[\"{{{Nn{BAC`}}}{{KBj{AOLfBFG`}}}}\",[]]Bf[\"{{{Nn{BAC`}}}{{KBj{AOLjBFG`}}}}\",[]]Bn[\"{{{AHEf{CEdBEE`}}KDf}{{AHEf{CEdBEE`}}}}\",[]]Bn[\"{{{AHEf{CEdBEEb}}KDh}{{AHEf{CEdBEEb}}}}\",[]]o[\"{ND`ND`}\",[]]0000Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]0Ci[\"{{{AHEf{CNn}}{KB`{AAJb}}}{{KBj{{KB`{AAJb}}AI@h}}}}\",[]]Cd[\"{{{AHEf{CEdA@l}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Cc[\"{{{AHEf{CEdOj}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Ce[\"{{{AHEf{CEdAAId}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Ce[\"{{{AHEf{CEdAGHn}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Cd[\"{{{AHEf{CEdA@n}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Cd[\"{{{AHEf{CEdAA`}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Bo[\"{{{AHEf{CEdB@Bh}}BFMn}{{AHEf{CEdB@Bh}}}}\",[]]Bo[\"{{{AHEf{CEdB@Bl}}BFN`}{{AHEf{CEdB@Bl}}}}\",[]]Aj[\"{{{AHEf{BAMf}}}CLf}\",[]]Aj[\"{{{AHEf{BAMh}}}CLf}\",[]]Cc[\"{{{AHEf{CEdAOLf}}{Nn{A`}}}{{AHEf{CEdAOLf}}}}\",[]]Cc[\"{{{AHEf{CEdAOLj}}{Nn{A`}}}{{AHEf{CEdAOLj}}}}\",[]]Cj[\"{{BAMf{KB`{B@Bh}}{Of{BAKn}}{Nn{NGh}}}{{KBl{AAJf}}}}\",[]]Aj[\"{{{AHEf{AAJn}}}D@n}\",[]]Aj[\"{{{AHEf{AAK`}}}D@n}\",[]]Ca[\"{{{AHEf{CEdAIAh}}NEdAICd}{{KBj{HOjBGAh}}}}\",[]]Bd[\"{{{AHEf{BGBb}}}{{AAj{BBNb}}}}\",[]]Bj[\"{{{AHEf{AIAf}}AIEl}{{KBj{HOjIBh}}}}\",[]]Bm[\"{{{AHEf{CEdAIAh}}AIEl}{{KBj{HOjIBh}}}}\",[]]Bn[\"{{{AHEf{CEdBBNl}}JNf}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}JNf}{{AHEf{CEdBBNn}}}}\",[]]Bl[\"{{}{{KBj{{JNd{BAL`BEGj}}{Of{IAd}}}}}}\",[]]Ai[\"{AIAd{{KBn{HOj}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]An[\"{{{AHEf{AAJf}}AOLf}HOj}\",[]]Dc[\"{{{AHEf{CEdAIAh}}NEdKBf{KB`{AAJb}}}{{KBj{{KB`{AAJb}}AI@n}}}}\",[]]o[\"{{}AHEf}\",[]]Aj[\"{{{AHEf{AIAf}}}JNf}\",[]]Bn[\"{{{AHEf{CEdB@Bh}}CLf}{{AHEf{CEdB@Bh}}}}\",[]]Bn[\"{{{AHEf{CEdB@Bl}}CLf}{{AHEf{CEdB@Bl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNl}}KDf}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}KDh}{{AHEf{CEdBBNn}}}}\",[]]:Bb[\"{{{AHEf{CEdAIAh}}OnKDh}HOj}\",[]]Ak[\"{{}{{KBj{AOLfIBb}}}}\",[]]Ak[\"{{}{{KBj{AOLjIBd}}}}\",[]]Bn[\"{{{AHEf{CEdBBNl}}D@n}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}D@n}{{AHEf{CEdBBNn}}}}\",[]]65Cg[\"{{{AHEf{CEdA@l}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Cf[\"{{{AHEf{CEdOj}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Ch[\"{{{AHEf{CEdAAId}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Ch[\"{{{AHEf{CEdAGHn}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Cg[\"{{{AHEf{CEdA@n}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Cg[\"{{{AHEf{CEdAA`}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Bi[\"{{{AHEf{CEdAGJ`}}{AHEf{AGJ`}}}D@n}\",[]]n[\"{{}HOj}\",[]]Ce[\"{{{AHEf{CEdBBNl}}{KB`{JNf}}}{{AHEf{CEdBBNl}}}}\",[]]Ce[\"{{{AHEf{CEdBBNn}}{KB`{JNf}}}{{AHEf{CEdBBNn}}}}\",[]]Bn[\"{{{AHEf{AIAf}}}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]Cd[\"{{{AHEf{CEdAIAh}}NEd}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]Am[\"{{{AHEf{CEdAIAj}}}HOj}\",[]]Al[\"{{{AHEf{CEdI@h}}}HOj}\",[]]Am[\"{{{AHEf{CEdAIAl}}}HOj}\",[]]Al[\"{{{AHEf{CEdI@j}}}HOj}\",[]]Ai[\"{AIAd{{KBn{HOj}}}}\",[]]Bj[\"{{{AHEf{AIAf}}AIEl}{{KBj{HOjIBh}}}}\",[]]Bm[\"{{{AHEf{CEdAIAh}}AIEl}{{KBj{HOjIBh}}}}\",[]]D`[\"{{{AHEf{CEdAIAh}}KBf{KB`{AAJb}}}{{KBj{{KB`{AAJb}}AI@n}}}}\",[]]Ce[\"{{{AHEf{CEdBBNl}}{Nn{BE@d}}}{{AHEf{CEdBBNl}}}}\",[]]Ce[\"{{{AHEf{CEdBBNn}}{Nn{BE@f}}}{{AHEf{CEdBBNn}}}}\",[]]Cf[\"{{{AHEf{CEdBBNl}}{KB`{AAJb}}}{{AHEf{CEdBBNl}}}}\",[]]Cf[\"{{{AHEf{CEdBBNn}}{KB`{AAJb}}}{{AHEf{CEdBBNn}}}}\",[]]Aa[\"{B@OjAICb}\",[]]Aa[\"{B@OlAICb}\",[]]9Bn[\"{{{AHEf{CEdBBNl}}D@n}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}D@n}{{AHEf{CEdBBNn}}}}\",[]]Am[\"{{{AHEf{AIAf}}KDf}HOj}\",[]]o[\"{ND`ND`}\",[]]Bn[\"{{{AHEf{CEdBBNl}}CLd}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}CLd}{{AHEf{CEdBBNn}}}}\",[]]3109854Bn[\"{{{AHEf{AIAf}}}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]Bn[\"{{{AHEf{AIAh}}}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]10A`[\"{BEOdKB`}\",[]]Bm[\"{{{AHEf{CEdBBNl}}Nd}{{AHEf{CEdBBNl}}}}\",[]]Bm[\"{{{AHEf{CEdBBNn}}Nd}{{AHEf{CEdBBNn}}}}\",[]]o[\"{{}AICd}\",[]]") \ No newline at end of file +rd_("Bf[\"{{{AHEf{ANKd}}{AHEf{ANKd}}}D@n}\",[]]Bf[\"{{{AHEf{BEB`}}{AHEf{BEB`}}}D@n}\",[]]Bd[\"{{{AHEf{KAd}}{AHEf{KAd}}}D@n}\",[]]Bd[\"{{{AHEf{CNn}}{AHEf{CNn}}}D@n}\",[]]Bf[\"{{{AHEf{BBAd}}{AHEf{BBAd}}}D@n}\",[]]Bf[\"{{{AHEf{BB@f}}{AHEf{BB@f}}}D@n}\",[]]Bf[\"{{{AHEf{AGLh}}{AHEf{AGLh}}}D@n}\",[]]Bf[\"{{{AHEf{AIDn}}{AHEf{AIDn}}}D@n}\",[]]Bf[\"{{{AHEf{BB@d}}{AHEf{BB@d}}}D@n}\",[]]Bf[\"{{{AHEf{AIGb}}{AHEf{AIGb}}}D@n}\",[]]Bf[\"{{{AHEf{B@Cd}}{AHEf{B@Cd}}}D@n}\",[]]Bd[\"{{{AHEf{KDf}}{AHEf{KDf}}}D@n}\",[]]Bf[\"{{{AHEf{BFFl}}{AHEf{BFFl}}}D@n}\",[]]Bd[\"{{{AHEf{I@`}}{AHEf{I@`}}}D@n}\",[]]Bd[\"{{{AHEf{KBd}}{AHEf{KBd}}}D@n}\",[]]Bf[\"{{{AHEf{AANl}}{AHEf{AANl}}}D@n}\",[]]Bf[\"{{{AHEf{AIBb}}{AHEf{AIBb}}}D@n}\",[]]Bf[\"{{{AHEf{AGLb}}{AHEf{AGLb}}}D@n}\",[]]Bd[\"{{{AHEf{NIf}}{AHEf{NIf}}}D@n}\",[]]Bf[\"{{{AHEf{AOMb}}{AHEf{AOMb}}}D@n}\",[]]Bf[\"{{{AHEf{BBKn}}{AHEf{BBKn}}}D@n}\",[]]Bf[\"{{{AHEf{ANLn}}{AHEf{ANLn}}}D@n}\",[]]Bf[\"{{{AHEf{ANKj}}{AHEf{ANKj}}}D@n}\",[]]Bf[\"{{{AHEf{AGJb}}{AHEf{AGJb}}}D@n}\",[]]Bf[\"{{{AHEf{BBKh}}{AHEf{BBKh}}}D@n}\",[]]Bf[\"{{{AHEf{BDDj}}{AHEf{BDDj}}}D@n}\",[]]Bf[\"{{{AHEf{AOMn}}{AHEf{AOMn}}}D@n}\",[]]Bf[\"{{{AHEf{AONd}}{AHEf{AONd}}}D@n}\",[]]Bf[\"{{{AHEf{AONn}}{AHEf{AONn}}}D@n}\",[]]Bf[\"{{{AHEf{BEIf}}{AHEf{BEIf}}}D@n}\",[]]Bd[\"{{{AHEf{COl}}{AHEf{COl}}}D@n}\",[]]Bb[\"{{{AHEf{Ol}}{AHEf{Ol}}}D@n}\",[]]Bf[\"{{{AHEf{AAMb}}{AHEf{AAMb}}}D@n}\",[]]Bf[\"{{{AHEf{BGIf}}{AHEf{BGIf}}}D@n}\",[]]Bd[\"{{{AHEf{IBb}}{AHEf{IBb}}}D@n}\",[]]Bd[\"{{{AHEf{KDh}}{AHEf{KDh}}}D@n}\",[]]Bf[\"{{{AHEf{BFFn}}{AHEf{BFFn}}}D@n}\",[]]Bd[\"{{{AHEf{I@b}}{AHEf{I@b}}}D@n}\",[]]Bf[\"{{{AHEf{BEBb}}{AHEf{BEBb}}}D@n}\",[]]Bd[\"{{{AHEf{KBf}}{AHEf{KBf}}}D@n}\",[]]Bf[\"{{{AHEf{AIDb}}{AHEf{AIDb}}}D@n}\",[]]Bf[\"{{{AHEf{AGL`}}{AHEf{AGL`}}}D@n}\",[]]Bf[\"{{{AHEf{BEAn}}{AHEf{BEAn}}}D@n}\",[]]Bf[\"{{{AHEf{BEHn}}{AHEf{BEHn}}}D@n}\",[]]Bf[\"{{{AHEf{AI@n}}{AHEf{AI@n}}}D@n}\",[]]Bf[\"{{{AHEf{AANn}}{AHEf{AANn}}}D@n}\",[]]Bf[\"{{{AHEf{AIBd}}{AHEf{AIBd}}}D@n}\",[]]Bf[\"{{{AHEf{AGLd}}{AHEf{AGLd}}}D@n}\",[]]Bf[\"{{{AHEf{AGLj}}{AHEf{AGLj}}}D@n}\",[]]Bf[\"{{{AHEf{BABj}}{AHEf{BABj}}}D@n}\",[]]Bd[\"{{{AHEf{NIh}}{AHEf{NIh}}}D@n}\",[]]Bf[\"{{{AHEf{AIGd}}{AHEf{AIGd}}}D@n}\",[]]Bf[\"{{{AHEf{ANLl}}{AHEf{ANLl}}}D@n}\",[]]Bf[\"{{{AHEf{ANOb}}{AHEf{ANOb}}}D@n}\",[]]Bf[\"{{{AHEf{BB@h}}{AHEf{BB@h}}}D@n}\",[]]Bf[\"{{{AHEf{AOMj}}{AHEf{AOMj}}}D@n}\",[]]Bf[\"{{{AHEf{BBL`}}{AHEf{BBL`}}}D@n}\",[]]Bf[\"{{{AHEf{AGKl}}{AHEf{AGKl}}}D@n}\",[]]Bf[\"{{{AHEf{BALd}}{AHEf{BALd}}}D@n}\",[]]Bf[\"{{{AHEf{ANM`}}{AHEf{ANM`}}}D@n}\",[]]Bf[\"{{{AHEf{ANKl}}{AHEf{ANKl}}}D@n}\",[]]Bf[\"{{{AHEf{AGJd}}{AHEf{AGJd}}}D@n}\",[]]Bf[\"{{{AHEf{BANb}}{AHEf{BANb}}}D@n}\",[]]Bf[\"{{{AHEf{AIC`}}{AHEf{AIC`}}}D@n}\",[]]Bf[\"{{{AHEf{AIEn}}{AHEf{AIEn}}}D@n}\",[]]Bf[\"{{{AHEf{AONh}}{AHEf{AONh}}}D@n}\",[]]Bf[\"{{{AHEf{BBKl}}{AHEf{BBKl}}}D@n}\",[]]Bf[\"{{{AHEf{BDDn}}{AHEf{BDDn}}}D@n}\",[]]Bf[\"{{{AHEf{BDEf}}{AHEf{BDEf}}}D@n}\",[]]Bf[\"{{{AHEf{AON`}}{AHEf{AON`}}}D@n}\",[]]Bf[\"{{{AHEf{AAKf}}{AHEf{AAKf}}}D@n}\",[]]Bf[\"{{{AHEf{BEAj}}{AHEf{BEAj}}}D@n}\",[]]Bf[\"{{{AHEf{AONf}}{AHEf{AONf}}}D@n}\",[]]Bf[\"{{{AHEf{AOO`}}{AHEf{AOO`}}}D@n}\",[]]Bf[\"{{{AHEf{BBA`}}{AHEf{BBA`}}}D@n}\",[]]Bf[\"{{{AHEf{BEIh}}{AHEf{BEIh}}}D@n}\",[]]Bd[\"{{{AHEf{COn}}{AHEf{COn}}}D@n}\",[]]Bb[\"{{{AHEf{On}}{AHEf{On}}}D@n}\",[]]Bf[\"{{{AHEf{AAMd}}{AHEf{AAMd}}}D@n}\",[]]Bf[\"{{{AHEf{AGJ`}}{AHEf{AGJ`}}}D@n}\",[]]Bf[\"{{{AHEf{BACf}}{AHEf{BACf}}}D@n}\",[]]Bf[\"{{{AHEf{BEOd}}{AHEf{BEOd}}}D@n}\",[]]Bd[\"{{{AHEf{IBf}}{AHEf{IBf}}}D@n}\",[]]Bf[\"{{{AHEf{BGIh}}{AHEf{BGIh}}}D@n}\",[]]Bd[\"{{{AHEf{IBd}}{AHEf{IBd}}}D@n}\",[]]Bf[\"{{{AHEf{AOOb}}{AHEf{AOOb}}}D@n}\",[]]Ai[\"{{{AHEf{CNn}}}KBd}\",[]]Aj[\"{{{AHEf{BBAd}}}KBd}\",[]]Ak[\"{{{AHEf{AIDj}}}AAMb}\",[]]Ak[\"{{{AHEf{BEOf}}}AAMb}\",[]]Ak[\"{{{AHEf{AIEf}}}AAMb}\",[]]o[\"{KAhKBf}\",[]]A`[\"{AGGdKBf}\",[]]A`[\"{AGIhKBf}\",[]]A`[\"{B@AjKBf}\",[]]A`[\"{B@@lKBf}\",[]]Aa[\"{AALjAAMd}\",[]]Aa[\"{AAObAAMd}\",[]]Aa[\"{AAJjAAMd}\",[]]A`[\"{NGnAAMd}\",[]]A`[\"{ANNdNGf}\",[]]A`[\"{CNfAAKf}\",[]]Ac[\"{{AANlAANl}}\",[]]Ac[\"{{AIBbAIBb}}\",[]]Ac[\"{{BBLfAGLb}}\",[]]Bc[\"{{AANnAANn}c{}}\",[\"Add::Output\"]]Bc[\"{{AIBdAIBd}c{}}\",[\"Add::Output\"]]Bc[\"{{BBLhAGLd}c{}}\",[\"Add::Output\"]]Be[\"{{{AHEf{KDf}}{AHEf{KDf}}}AALh}\",[]]Be[\"{{{AHEf{KBd}}{AHEf{KBd}}}AALh}\",[]]Bg[\"{{{AHEf{ANLn}}{AHEf{ANLn}}}AALh}\",[]]Bg[\"{{{AHEf{AONd}}{AHEf{AONd}}}AALh}\",[]]Be[\"{{{AHEf{COl}}{AHEf{COl}}}AALh}\",[]]Bc[\"{{{AHEf{Ol}}{AHEf{Ol}}}AALh}\",[]]Bg[\"{{{AHEf{AAMb}}{AHEf{AAMb}}}AALh}\",[]]Be[\"{{{AHEf{KDh}}{AHEf{KDh}}}AALh}\",[]]Bg[\"{{{AHEf{BEBb}}{AHEf{BEBb}}}AALh}\",[]]Be[\"{{{AHEf{KBf}}{AHEf{KBf}}}AALh}\",[]]Bg[\"{{{AHEf{AGLj}}{AHEf{AGLj}}}AALh}\",[]]Bg[\"{{{AHEf{BABj}}{AHEf{BABj}}}AALh}\",[]]Bg[\"{{{AHEf{AIGd}}{AHEf{AIGd}}}AALh}\",[]]Bg[\"{{{AHEf{ANM`}}{AHEf{ANM`}}}AALh}\",[]]Bg[\"{{{AHEf{BDEf}}{AHEf{BDEf}}}AALh}\",[]]Bg[\"{{{AHEf{BEAj}}{AHEf{BEAj}}}AALh}\",[]]Bg[\"{{{AHEf{AONf}}{AHEf{AONf}}}AALh}\",[]]Be[\"{{{AHEf{COn}}{AHEf{COn}}}AALh}\",[]]Bc[\"{{{AHEf{On}}{AHEf{On}}}AALh}\",[]]Bg[\"{{{AHEf{AAMd}}{AHEf{AAMd}}}AALh}\",[]]o[\"{AAMbOl}\",[]]o[\"{AAMdOn}\",[]]n[\"{KAjOn}\",[]]o[\"{AGHbOn}\",[]]A`[\"{AANfKB`}\",[]]A`[\"{AANhKB`}\",[]]A`[\"{AALnKB`}\",[]]A`[\"{AANjKB`}\",[]]Bh[\"{{{AHEf{A@l}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANNd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANKd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@j}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BGBb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BFFf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIAb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIAf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BFGb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEB`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AAJf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{B@Of}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{KAd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AICn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BENh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAJn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIE`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAN`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{CNn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBAd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIDj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEOf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@f}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AGLh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIDn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BB@d}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{B@Cf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANNj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIEf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIGb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{B@Cd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{NHb}}{AHEf{CEdAGIn}}}KBh}\",[]]Cd[\"{{{AHEf{KDf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BFFl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Cd[\"{{{AHEf{I@`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{KBd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AANl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AIBb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AGLb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BBLf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{NIf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AOMb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BBKn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BBMj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BBNl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEE`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEFn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANLn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BAMf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{B@Bh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BFMn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AOLf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANKj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AGJb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BBKh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BDDj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AOMn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AONd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AONn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEIf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AIBh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BDHl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{COl}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cc[\"{{{AHEf{Ol}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AAMb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{AANf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cc[\"{{{AHEf{O`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{AGHh}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{I@h}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANLd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{NF`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BAAj}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BE@h}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BGIf}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{ANL`}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Ce[\"{{{AHEf{BEIn}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]Cd[\"{{{AHEf{IBb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Ce[\"{{{AHEf{BFFb}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Bi[\"{{{AHEf{AIAh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAJh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{KDh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BFFn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{I@b}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEBb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{KBf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{B@B`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIDb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGL`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEHn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AI@n}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AANn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIBd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGLd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBLh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGLj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BABj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{NIh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIGd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{ANLl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{ANOb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BB@h}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AOMj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BBL`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AGKl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BALd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BGAh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{IBl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBMl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBNn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEEb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEG`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANM`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BAMh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{B@Bl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BFN`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AOLj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANKl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AGJd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BANb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIC`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIEn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AONh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BBKl}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BDDn}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AAIj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BDEf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAK`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AON`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{ANK`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AIEb}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BAB`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBMh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BGB`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AAKf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEAj}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BBLd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{B@Od}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AONf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AOO`}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBA`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BEIh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AIBj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BGMl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BDHn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{COn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bg[\"{{{AHEf{On}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AAMd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{AANh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGJ`}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BACf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BEOd}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{IBf}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bi[\"{{{AHEf{BGIh}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANLb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BEJd}}{AHEf{CEdAGIn}}}KBh}\",[]]Cd[\"{{{AHEf{IBd}}{AHEf{CEdAGIn}}}{{KBj{HOjIAb}}}}\",[]]0Bi[\"{{{AHEf{BFFd}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bg[\"{{{AHEf{Ob}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AGHj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{I@j}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{ANLf}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{NFb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BAAl}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BE@j}}{AHEf{CEdAGIn}}}KBh}\",[]]Bh[\"{{{AHEf{IBh}}{AHEf{CEdAGIn}}}KBh}\",[]]0Bh[\"{{{AHEf{IBn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{BBAb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AALn}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AANj}}{AHEf{CEdAGIn}}}KBh}\",[]]Bi[\"{{{AHEf{AOOb}}{AHEf{CEdAGIn}}}KBh}\",[]]Bd[\"{{{AHEf{BFFf}}}{{KB`{AIEl}}}}\",[]]Ak[\"{{{AHEf{B@B`}}}AAJb}\",[]]A`[\"{AANlCLf}\",[]]A`[\"{AANnCLf}\",[]]Aj[\"{{{AHEf{BAB`}}}JNf}\",[]]A`[\"{BGB`CLf}\",[]]o[\"{CNfCLf}\",[]]A`[\"{AALnJNf}\",[]]Ce[\"{{{AHEf{CEdBFMn}}{Nn{AAMn}}}{{AHEf{CEdBFMn}}}}\",[]]Ce[\"{{{AHEf{CEdBFN`}}{Nn{AAN`}}}{{AHEf{CEdBFN`}}}}\",[]]8Af[\"{{AAJbCLf}BB@j}\",[]]Ag[\"{{}{{Nn{BGBb}}}}\",[]]Ae[\"{{JNfCLd}B@Nd}\",[]]Cd[\"{{BAMf{KB`{B@Bh}}AGMb{Nn{NGh}}}{{KBl{AAJf}}}}\",[]]Ah[\"{{{Of{IEb}}}AIDd}\",[]]A`[\"{NG`BBMj}\",[]]Ah[\"{{{Nn{NDn}}}BAMf}\",[]]Bc[\"{{{Nn{B@Bj}}{Nn{BE@l}}}B@Bh}\",[]]Ai[\"{{{Nn{AOLh}}}AOLf}\",[]]B`[\"{{{AHEf{{JL`{Nd}}}}}AONd}\",[]]Ae[\"{{CLdJNf}BDHl}\",[]]Ag[\"{{COlOlCLf}AAMb}\",[]]Aj[\"{{{Nn{AGHh}}CLb}O`}\",[]]An[\"{{{Nn{ANLd}}NEdCLb}I@h}\",[]]An[\"{{{Nn{BAAj}}NEdCLb}NF`}\",[]]Ae[\"{{JNfCLd}B@Nf}\",[]]Ah[\"{{{Of{IEb}}}AIDf}\",[]]Bm[\"{{{Nn{BAMh}}{KB`{{Nn{B@Bl}}}}D@n}AAJh}\",[]]A`[\"{JNfBH@n}\",[]]o[\"{{}BGMb}\",[]]A`[\"{NG`BBMl}\",[]]Ah[\"{{{Nn{NE`}}}BAMh}\",[]]Bc[\"{{{Nn{B@Bn}}{Nn{BE@n}}}B@Bl}\",[]]Ai[\"{{{Nn{AOLl}}}AOLj}\",[]]Ek[\"{{AAI`{AHEf{c}}{AHEf{{JL`{CLd}}}}D@n}{{KBj{{JNd{BAB`{KB`{AAI`}}}}BEAj}}}{BEElIDh}}\",[\"\"]]B`[\"{{{AHEf{{JL`{Nd}}}}}AONf}\",[]]Af[\"{{BEIhKDb}BBA`}\",[]]A`[\"{JNfBGMl}\",[]]Ae[\"{{CLdJNf}BDHn}\",[]]Ag[\"{{COnOnCLf}AAMd}\",[]]Am[\"{{AIEl{KB`{KAb}}}AGJ`}\",[]]Aj[\"{{{Nn{AGHj}}CLb}Ob}\",[]]An[\"{{{Nn{ANLf}}NEdCLb}I@j}\",[]]An[\"{{{Nn{BAAl}}NEdCLb}NFb}\",[]]Aj[\"{AIG`{{KBl{BBAb}}}}\",[]]Aa[\"{BDHfBGGj}\",[]]Aa[\"{BDHjBGGl}\",[]]o[\"{COlCOl}\",[]]o[\"{COnCOn}\",[]]Ak[\"{{{AHEf{AIFd}}}AIFb}\",[]]Ai[\"{{{AHEf{NGh}}}NEd}\",[]]0Aj[\"{{{AHEf{B@Cf}}}NEd}\",[]]Ak[\"{{{AHEf{BACb}}}AIFb}\",[]]Ak[\"{{{AHEf{AIFf}}}AIFb}\",[]]Ak[\"{{{AHEf{BACd}}}AIFb}\",[]]Bg[\"{{{AHEf{AIAf}}KBd}{{KB`{AAJb}}}}\",[]]Aa[\"{AGLbAAJb}\",[]]Bg[\"{{{AHEf{AIAh}}KBf}{{KB`{AAJb}}}}\",[]]Aa[\"{AGLdAAJb}\",[]]Ah[\"{A@n{{KBn{HOj}}}}\",[]]Ah[\"{AA`{{KBn{HOj}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Aa[\"{B@@lAIEl}\",[]]Aa[\"{AALnAIEl}\",[]]Aa[\"{BBA`BEIh}\",[]]A`[\"{AGLbCLf}\",[]]A`[\"{AGLdCLf}\",[]]A`[\"{AAIjHOn}\",[]]Am[\"{{{AHEf{CEdAALd}}}HOj}\",[]]Am[\"{{{AHEf{CEdAAJn}}}HOj}\",[]]Al[\"{{{AHEf{CEdCNn}}}HOj}\",[]]Am[\"{{{AHEf{CEdBBAd}}}HOj}\",[]]Am[\"{{{AHEf{CEdAIDj}}}HOj}\",[]]Am[\"{{{AHEf{CEdAIEf}}}HOj}\",[]]Al[\"{{{AHEf{CEdJOn}}}HOj}\",[]]A`[\"{cc{}}\",[\"T\"]]0000000000000000000000Aa[\"{BBKnBEB`}\",[]]111111111111111Aa[\"{AGLhBB@f}\",[]]2Aa[\"{AIDnAGLh}\",[]]Aa[\"{BBKnAGLh}\",[]]Aa[\"{BBKnAIDn}\",[]]55Aa[\"{AGLhBB@d}\",[]]6666Aa[\"{AOMbAIGb}\",[]]Aa[\"{B@CdAIGb}\",[]]Aa[\"{BBKnAIGb}\",[]]9Aa[\"{BBKnB@Cd}\",[]]::::::A`[\"{AAMbKDf}\",[]]n[\"{NdKDf}\",[]]o[\"{CLbKDf}\",[]]A`[\"{BEIfKDf}\",[]]o[\"{CLdKDf}\",[]]???Al[\"{cKBd{{CN`{CLd}}}}\",[\"T\"]]A`[\"{cc{}}\",[\"T\"]]000000A`[\"{I@fBBKn}\",[]]1A`[\"{IAjBBKn}\",[]]Aa[\"{ANKhBBKn}\",[]]33333A`[\"{KDfANLn}\",[]]4444Aa[\"{BBO`ANKj}\",[]]5Aa[\"{BFFlANKj}\",[]]66A`[\"{IAjBBKh}\",[]]7Aa[\"{BEInAOMn}\",[]]8888A`[\"{KDfBEIf}\",[]]99999A`[\"{KDfAAMb}\",[]]:::::::::::Aa[\"{ANOhANL`}\",[]];;;;A`[\"{BBNdIBb}\",[]]A`[\"{BBLjIBb}\",[]]A`[\"{BDFfIBb}\",[]]A`[\"{BAOfIBb}\",[]]A`[\"{BANdIBb}\",[]]A`[\"{AICfIBb}\",[]]A`[\"{cc{}}\",[\"T\"]]A`[\"{BDE`IBb}\",[]]A`[\"{BGIdIBb}\",[]]A`[\"{BDGnIBb}\",[]]A`[\"{BGJfIBb}\",[]]A`[\"{BGDfIBb}\",[]]555555555555555555555555o[\"{CLbKDh}\",[]]o[\"{CLdKDh}\",[]]n[\"{NdKDh}\",[]]A`[\"{AAMdKDh}\",[]]A`[\"{BEIhKDh}\",[]]::::Al[\"{cKBf{{CN`{CLd}}}}\",[\"T\"]];;;;;;;;;;;;;;;;;;;Aa[\"{BBA`BBL`}\",[]]<<<>>>>Aa[\"{BBO`ANKl}\",[]]Aa[\"{BFFnANKl}\",[]]A`[\"{cc{}}\",[\"T\"]]00000Aa[\"{BBA`BBKl}\",[]]11111Aa[\"{BEJdAON`}\",[]]22222222Aa[\"{BACfBEAj}\",[]]3333A`[\"{IBfBBA`}\",[]]4A`[\"{KDhBEIh}\",[]]5555555A`[\"{KDhAAMd}\",[]]6666A`[\"{BACfIBf}\",[]]7777Aa[\"{ANOhANLb}\",[]]8888A`[\"{BDE`IBd}\",[]]A`[\"{BGIdIBd}\",[]]A`[\"{AICfIBd}\",[]]A`[\"{BANdIBd}\",[]]A`[\"{BDFfIBd}\",[]]A`[\"{BBLjIBd}\",[]]A`[\"{BGJfIBd}\",[]]A`[\"{BAOfIBd}\",[]]A`[\"{BDGnIBd}\",[]]A`[\"{BBNdIBd}\",[]]A`[\"{cc{}}\",[\"T\"]]A`[\"{BGDfIBd}\",[]]111111111111An[\"{{{AHEf{c}}}AIG`CLl}\",[\"S\"]]22222222222222Bm[\"{{{AHEf{KDf}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bk[\"{{{AHEf{KBd}}{AHEf{CEdc}}}HOjKA`}\",[\"H\"]]Bn[\"{{{AHEf{ANLn}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AONd}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bm[\"{{{AHEf{COl}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bl[\"{{{AHEf{Ol}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AAMb}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bm[\"{{{AHEf{KDh}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BEBb}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bk[\"{{{AHEf{KBf}}{AHEf{CEdc}}}HOjKA`}\",[\"H\"]]Bn[\"{{{AHEf{AGLj}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BABj}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AIGd}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{ANM`}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BDEf}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{BEAj}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AONf}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bm[\"{{{AHEf{COn}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bl[\"{{{AHEf{On}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AAMd}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Bn[\"{{{AHEf{AGJ`}}{AHEf{CEdc}}}HOjKA`}\",[\"__H\"]]Aa[\"{{}c{}}\",[\"U\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000n[\"{{}HOj}\",[]]0000Cc[\"{{{AHEf{CEdJOn}}JNf}{{KBj{{KB`{I@b}}AGLj}}}}\",[]]Cf[\"{{{AHEf{CEdBA@h}}}{{KB`{c}}}{}}\",[\"Iterator::Item\"]]Dl[\"{{{AHEf{BE@l}}HOh{AHEf{CEd{JL`{Nd}}}}}{{KBj{{AHEf{{JL`{Nd}}}}ANL`}}}}\",[]]Bh[\"{{{AHEf{CEdNHj}}On}{{KB`{AAMd}}}}\",[]]Dl[\"{{{AHEf{BE@n}}HOh{AHEf{CEd{JL`{Nd}}}}}{{KBj{{AHEf{{JL`{Nd}}}}ANLb}}}}\",[]]Bf[\"{{{AHEf{AIAf}}KBd}{{KB`{CNn}}}}\",[]]Bf[\"{{{AHEf{CNn}}}{{KBj{HOjAI@h}}}}\",[]]A`[\"{AIBbCLf}\",[]]Am[\"{{{AHEf{CEdAIAh}}}HOj}\",[]]A`[\"{AIBdCLf}\",[]]Ck[\"{{{AAd{{AHEf{CEdAI@`}}}}{AHEf{CEdNDb}}}{{COf{HOj}}}}\",[]]Dk[\"{{{AAd{{AHEf{CEdBBOf}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAALd}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAALf}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAIAb}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdNFf}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdKAf}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAGGh}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdAAHn}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdB@Ah}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdB@Bb}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdJNn}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dk[\"{{{AAd{{AHEf{CEdBAN`}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Dj[\"{{{AAd{{AHEf{CEdNHb}}}}{AHEf{CEdNDb}}}{{COf{c}}}{}}\",[\"Future::Output\"]]Bf[\"{{{AHEf{CEdAIAh}}}{{KB`{IBl}}}}\",[]]De[\"{{{AHEf{CEdAIDj}}{AHEf{CEd{JL`{Nd}}}}}{{KBj{{KB`{JNf}}AGLh}}}}\",[]]Bm[\"{{{AHEf{CEdAIDl}}D@n}{{KBj{JOnBABj}}}}\",[]]Bo[\"{{COn{AHEf{CEdc}}}{{KBj{BEOdIBf}}}Oh}\",[\"R\"]]Bf[\"{{{AHEf{CEdAGId}}}{{KB`{HOn}}}}\",[]]Ec[\"{{{AHEf{BBAb}}AIG`{AHEf{CEd{JL`{AIBl}}}}{AHEf{CEd{JL`{AALn}}}}}{{KBl{JNf}}}}\",[]]Cn[\"{{{AHEf{BE@l}}HOh{AHEf{CEd{AAj{Nd}}}}}{{KBj{HOjANL`}}}}\",[]]Cn[\"{{{AHEf{BE@n}}HOh{AHEf{CEd{AAj{Nd}}}}}{{KBj{HOjANLb}}}}\",[]]C`[\"{{{AHEf{CEdAGId}}HOnD@n}{{KBj{HOjBEBb}}}}\",[]]Cc[\"{{{AHEf{BBAb}}AIG`{AHEf{AANj}}}{{KBl{HOj}}}}\",[]]Bn[\"{{{AHEf{CEdBFMn}}CLd}{{AHEf{CEdBFMn}}}}\",[]]Bn[\"{{{AHEf{CEdBFN`}}CLd}{{AHEf{CEdBFN`}}}}\",[]]Aj[\"{{{AHEf{AIAf}}}COl}\",[]]Aj[\"{{{AHEf{AIAh}}}COn}\",[]]Cn[\"{{{AHEf{NDn}}{AHEf{{JL`{Nd}}}}{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Cn[\"{{{AHEf{NE`}}{AHEf{{JL`{Nd}}}}{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]A`[\"{BB@jCLf}\",[]]A`[\"{AANfJNf}\",[]]A`[\"{AANhJNf}\",[]]o[\"{IDdD@n}\",[]]Bm[\"{{{AHEf{CEdAIDj}}KDf}{{KBj{HOjAOMb}}}}\",[]]Bm[\"{{{AHEf{CEdBEOf}}KDf}{{KBj{HOjAOMb}}}}\",[]]Bm[\"{{{AHEf{CEdAIDl}}KDh}{{KBj{HOjAOMj}}}}\",[]]Bn[\"{{{AHEf{AIFl}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BAOb}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BDHl}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{AIFn}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BAOd}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bn[\"{{{AHEf{BDHn}}{AHEf{CL`}}}{{KB`{HOn}}}}\",[]]Bd[\"{{{AHEf{BDEl}}}{{KB`{BA@h}}}}\",[]]Bg[\"{{{Nn{BE@d}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{AGHh}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{ANLd}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{BAAj}}NEdCLb}{{Of{AIAj}}}}\",[]]Bg[\"{{{Nn{BE@f}}NEdCLb}{{Of{AIAl}}}}\",[]]Bg[\"{{{Nn{AGHj}}NEdCLb}{{Of{AIAl}}}}\",[]]Bg[\"{{{Nn{ANLf}}NEdCLb}{{Of{AIAl}}}}\",[]]Bg[\"{{{Nn{BAAl}}NEdCLb}{{Of{AIAl}}}}\",[]]Ai[\"{BENf{{Nn{BE@f}}}}\",[]]o[\"{I@`HOn}\",[]]A`[\"{AANlCLf}\",[]]o[\"{NIfJNf}\",[]]o[\"{I@bHOn}\",[]]A`[\"{AANnCLf}\",[]]o[\"{NIhJNf}\",[]]Aa[\"{ANK`BBL`}\",[]]Ai[\"{{{AHEf{A@l}}}A@l}\",[]]Ak[\"{{{AHEf{ANNd}}}ANNd}\",[]]Ak[\"{{{AHEf{ANKd}}}ANKd}\",[]]Ak[\"{{{AHEf{AIAf}}}AIAf}\",[]]Ak[\"{{{AHEf{BFGb}}}BFGb}\",[]]Ak[\"{{{AHEf{BEB`}}}BEB`}\",[]]Ak[\"{{{AHEf{AAJf}}}AAJf}\",[]]Ak[\"{{{AHEf{B@Of}}}B@Of}\",[]]Ai[\"{{{AHEf{KAd}}}KAd}\",[]]Ai[\"{{{AHEf{CNn}}}CNn}\",[]]Ak[\"{{{AHEf{BBAd}}}BBAd}\",[]]Ak[\"{{{AHEf{BB@f}}}BB@f}\",[]]Ak[\"{{{AHEf{AGLh}}}AGLh}\",[]]Ak[\"{{{AHEf{AIDn}}}AIDn}\",[]]Ak[\"{{{AHEf{BB@d}}}BB@d}\",[]]Ak[\"{{{AHEf{AIGb}}}AIGb}\",[]]Ak[\"{{{AHEf{B@Cd}}}B@Cd}\",[]]Ai[\"{{{AHEf{KDf}}}KDf}\",[]]Ak[\"{{{AHEf{BFFl}}}BFFl}\",[]]Ai[\"{{{AHEf{KBd}}}KBd}\",[]]Ak[\"{{{AHEf{AANl}}}AANl}\",[]]Ak[\"{{{AHEf{AIBb}}}AIBb}\",[]]Ak[\"{{{AHEf{AGLb}}}AGLb}\",[]]Ak[\"{{{AHEf{BBLf}}}BBLf}\",[]]Ai[\"{{{AHEf{NIf}}}NIf}\",[]]Ak[\"{{{AHEf{AOMb}}}AOMb}\",[]]Ak[\"{{{AHEf{BBKn}}}BBKn}\",[]]Ak[\"{{{AHEf{BBNl}}}BBNl}\",[]]Ak[\"{{{AHEf{BEE`}}}BEE`}\",[]]Ak[\"{{{AHEf{BEFn}}}BEFn}\",[]]Ak[\"{{{AHEf{ANLn}}}ANLn}\",[]]Ak[\"{{{AHEf{BAMf}}}BAMf}\",[]]Ak[\"{{{AHEf{B@Bh}}}B@Bh}\",[]]Ak[\"{{{AHEf{BFMn}}}BFMn}\",[]]Ak[\"{{{AHEf{AOLf}}}AOLf}\",[]]Ak[\"{{{AHEf{ANKj}}}ANKj}\",[]]Ak[\"{{{AHEf{AGJb}}}AGJb}\",[]]Ak[\"{{{AHEf{BBKh}}}BBKh}\",[]]Ak[\"{{{AHEf{BDDj}}}BDDj}\",[]]Ak[\"{{{AHEf{AOMn}}}AOMn}\",[]]Ak[\"{{{AHEf{AONd}}}AONd}\",[]]Ak[\"{{{AHEf{AONn}}}AONn}\",[]]Ak[\"{{{AHEf{BEIf}}}BEIf}\",[]]Ak[\"{{{AHEf{AIBh}}}AIBh}\",[]]Ai[\"{{{AHEf{COl}}}COl}\",[]]Ag[\"{{{AHEf{Ol}}}Ol}\",[]]Ak[\"{{{AHEf{AAMb}}}AAMb}\",[]]Ag[\"{{{AHEf{O`}}}O`}\",[]]Ak[\"{{{AHEf{AGHh}}}AGHh}\",[]]Ai[\"{{{AHEf{I@h}}}I@h}\",[]]Ak[\"{{{AHEf{ANLd}}}ANLd}\",[]]Ai[\"{{{AHEf{NF`}}}NF`}\",[]]Ak[\"{{{AHEf{BAAj}}}BAAj}\",[]]Ai[\"{{{AHEf{IBb}}}IBb}\",[]]Ak[\"{{{AHEf{BDHd}}}BDHd}\",[]]Ak[\"{{{AHEf{BFFb}}}BFFb}\",[]]Ak[\"{{{AHEf{BDHh}}}BDHh}\",[]]Ai[\"{{{AHEf{KDh}}}KDh}\",[]]Ak[\"{{{AHEf{BFFn}}}BFFn}\",[]]Ak[\"{{{AHEf{BEBb}}}BEBb}\",[]]Ai[\"{{{AHEf{KBf}}}KBf}\",[]]Ak[\"{{{AHEf{B@B`}}}B@B`}\",[]]Ak[\"{{{AHEf{AIDb}}}AIDb}\",[]]Ak[\"{{{AHEf{AGL`}}}AGL`}\",[]]Ak[\"{{{AHEf{BEAn}}}BEAn}\",[]]Ak[\"{{{AHEf{BEHn}}}BEHn}\",[]]Ak[\"{{{AHEf{AI@n}}}AI@n}\",[]]Ak[\"{{{AHEf{AANn}}}AANn}\",[]]Ak[\"{{{AHEf{AIBd}}}AIBd}\",[]]Ak[\"{{{AHEf{AGLd}}}AGLd}\",[]]Ak[\"{{{AHEf{BBLh}}}BBLh}\",[]]Ak[\"{{{AHEf{AGLj}}}AGLj}\",[]]Ak[\"{{{AHEf{BABj}}}BABj}\",[]]Ai[\"{{{AHEf{NIh}}}NIh}\",[]]Ak[\"{{{AHEf{AIGd}}}AIGd}\",[]]Ak[\"{{{AHEf{ANLl}}}ANLl}\",[]]Ak[\"{{{AHEf{BB@h}}}BB@h}\",[]]Ak[\"{{{AHEf{AOMj}}}AOMj}\",[]]Ak[\"{{{AHEf{BBL`}}}BBL`}\",[]]Ak[\"{{{AHEf{AGKl}}}AGKl}\",[]]Ak[\"{{{AHEf{BALd}}}BALd}\",[]]Ak[\"{{{AHEf{BGAh}}}BGAh}\",[]]Ak[\"{{{AHEf{BBNn}}}BBNn}\",[]]Ak[\"{{{AHEf{BEEb}}}BEEb}\",[]]Ak[\"{{{AHEf{BEG`}}}BEG`}\",[]]Ak[\"{{{AHEf{ANM`}}}ANM`}\",[]]Ak[\"{{{AHEf{BAMh}}}BAMh}\",[]]Ak[\"{{{AHEf{B@Bl}}}B@Bl}\",[]]Ak[\"{{{AHEf{BFN`}}}BFN`}\",[]]Ak[\"{{{AHEf{AOLj}}}AOLj}\",[]]Ak[\"{{{AHEf{ANKl}}}ANKl}\",[]]Ak[\"{{{AHEf{AGJd}}}AGJd}\",[]]Ak[\"{{{AHEf{AIC`}}}AIC`}\",[]]Ak[\"{{{AHEf{AIEn}}}AIEn}\",[]]Ak[\"{{{AHEf{AONh}}}AONh}\",[]]Ak[\"{{{AHEf{BBKl}}}BBKl}\",[]]Ak[\"{{{AHEf{BDDn}}}BDDn}\",[]]Ak[\"{{{AHEf{AAIj}}}AAIj}\",[]]Ak[\"{{{AHEf{BDEf}}}BDEf}\",[]]Ak[\"{{{AHEf{AON`}}}AON`}\",[]]Ak[\"{{{AHEf{BBMh}}}BBMh}\",[]]Ak[\"{{{AHEf{BGB`}}}BGB`}\",[]]Ak[\"{{{AHEf{AAKf}}}AAKf}\",[]]Ak[\"{{{AHEf{BEAj}}}BEAj}\",[]]Ak[\"{{{AHEf{AONf}}}AONf}\",[]]Ak[\"{{{AHEf{AOO`}}}AOO`}\",[]]Ak[\"{{{AHEf{BBA`}}}BBA`}\",[]]Ak[\"{{{AHEf{BEIh}}}BEIh}\",[]]Ak[\"{{{AHEf{AIBj}}}AIBj}\",[]]Ak[\"{{{AHEf{BGMl}}}BGMl}\",[]]Ai[\"{{{AHEf{COn}}}COn}\",[]]Ag[\"{{{AHEf{On}}}On}\",[]]Ak[\"{{{AHEf{AAMd}}}AAMd}\",[]]Ak[\"{{{AHEf{AGJ`}}}AGJ`}\",[]]Ak[\"{{{AHEf{BACf}}}BACf}\",[]]Ak[\"{{{AHEf{BEOd}}}BEOd}\",[]]Ai[\"{{{AHEf{IBf}}}IBf}\",[]]Ai[\"{{{AHEf{IBd}}}IBd}\",[]]Ak[\"{{{AHEf{BDHf}}}BDHf}\",[]]Ak[\"{{{AHEf{BFFd}}}BFFd}\",[]]Ak[\"{{{AHEf{BDHj}}}BDHj}\",[]]Ag[\"{{{AHEf{Ob}}}Ob}\",[]]Ak[\"{{{AHEf{AGHj}}}AGHj}\",[]]Ai[\"{{{AHEf{I@j}}}I@j}\",[]]Ak[\"{{{AHEf{ANLf}}}ANLf}\",[]]Ai[\"{{{AHEf{NFb}}}NFb}\",[]]Ak[\"{{{AHEf{BAAl}}}BAAl}\",[]]Ai[\"{{{AHEf{IBn}}}IBn}\",[]]Ak[\"{{{AHEf{AALn}}}AALn}\",[]]Ak[\"{{{AHEf{AANj}}}AANj}\",[]]Ak[\"{{{AHEf{AOOb}}}AOOb}\",[]]Ak[\"{{{AHEf{BENf}}}BENf}\",[]]Ak[\"{{{AHEf{BBM`}}}BBM`}\",[]]Ak[\"{{{AHEf{BGGj}}}BGGj}\",[]]Ak[\"{{{AHEf{BGGl}}}BGGl}\",[]]Bn[\"{{{AHEf{AIAf}}KDf{AHEf{{JL`{Nd}}}}}HOj}\",[]]Bn[\"{{{AHEf{AAJf}}KDf{AHEf{{JL`{Nd}}}}}HOj}\",[]]Bf[\"{{{AHEf{CNn}}}{{KBj{HOjBALb}}}}\",[]]Bf[\"{{{AHEf{CEdAIAh}}NEdKDhHOn}HOj}\",[]]Bj[\"{{{AHEf{AONd}}}{{AHEf{{JL`{Nd}}}}}}\",[]]Bj[\"{{{AHEf{AONf}}}{{AHEf{{JL`{Nd}}}}}}\",[]]Aa[\"{BBA`AIC`}\",[]]A`[\"{AAMbCLf}\",[]]A`[\"{AAMdCLf}\",[]]A`[\"{AONnD@n}\",[]]A`[\"{AOO`D@n}\",[]]l[\"{NEf}\",[]]l[\"{NEh}\",[]]Ce[\"{{{AHEf{BEEl}}{AHEf{CEdOh}}}{{KBj{AONfBEAj}}}}\",[]]Ce[\"{{{AHEf{BH@n}}{AHEf{CEdOh}}}{{KBj{AONfBEAj}}}}\",[]]Bc[\"{{{AHEf{AIAh}}}{{AAj{KBf}}}}\",[]]Bd[\"{{{AHEf{IDj}}{AHEf{CL`}}}HOj}\",[]]Am[\"{{{AHEf{ANKf}}JNf}HOj}\",[]]Ai[\"{{{AHEf{IDl}}}HOj}\",[]]Bg[\"{{{AAd{{AHEf{CEdAI@`}}}}NEd}HOj}\",[]]Bm[\"{{{AHEf{CEdAIEf}}KDf}{{KBj{HOjAOMb}}}}\",[]]Bm[\"{{{AHEf{CEdAIEh}}KDh}{{KBj{HOjAOMj}}}}\",[]]Am[\"{AAJn{{KBj{HOjAIE`}}}}\",[]]Dc[\"{{{AHEf{CEdAAJh}}AAK`{AHEf{CEd{AAj{Nd}}}}}{{KBj{AANhAIEb}}}}\",[]]Bi[\"{{{AHEf{NGh}}{AAd{{Of{K@n}}}}}HOj}\",[]]Bj[\"{{{AHEf{B@Cf}}{AAd{{Of{K@n}}}}}HOj}\",[]]Bj[\"{{{AHEf{ANNj}}{AAd{{Of{K@n}}}}}HOj}\",[]]o[\"{A@lD@n}\",[]]Ak[\"{{{AHEf{AIAf}}}BBLf}\",[]]Ak[\"{{{AHEf{AAJf}}}B@Of}\",[]]Aj[\"{{{AHEf{CNn}}}AGLb}\",[]]An[\"{{{AHEf{CEdAIAh}}}BBLh}\",[]]Ce[\"{{{AHEf{CEdAIDd}}{KB`{KDb}}}{{AHEf{CEdAIDd}}}}\",[]]Ce[\"{{{AHEf{CEdAIDf}}{KB`{KDb}}}{{AHEf{CEdAIDf}}}}\",[]]Ck[\"{{{AHEf{CEdAIEf}}{AHEf{{JL`{Nd}}}}}{{KBj{JNfAIGb}}}}\",[]]Ck[\"{{{AHEf{CEdAIEh}}{AHEf{{JL`{Nd}}}}}{{KBj{JNfAIGd}}}}\",[]]Bl[\"{{{AHEf{BEOd}}{AHEf{CEdc}}}HOjJOl}\",[\"W\"]]Aj[\"{{{AHEf{AAJf}}}JNn}\",[]]An[\"{AAJn{{KBj{AIAbBBKn}}}}\",[]]Bh[\"{{{AHEf{CEdNHj}}On}{{KB`{AAMd}}}}\",[]]Fh[\"{{{AHEf{CEdAAJh}}AAK`NEd{AHEf{CEd{AAj{Nd}}}}{KB`{{Nn{B@Bl}}}}}{{KBj{{JNd{BDEfAIAh}}{Of{ANK`}}}}}}\",[]]Am[\"{AHEf{{AHEf{c}}}{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000o[\"{NIfJNf}\",[]]o[\"{NIhJNf}\",[]]A`[\"{A@lANKd}\",[]]Bc[\"{{AIElBAL`A@l}{{KBn{ANKf}}}}\",[]]Aj[\"{AIEl{{KBl{AAJf}}}}\",[]]B`[\"{{}{{KBj{HOj{Of{IAd}}}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}BBKn}\",[]]Be[\"{{{AHEf{AAJh}}}{{AHEf{BAMh}}}}\",[]]o[\"{NdBEIf}\",[]]A`[\"{AIBbCLf}\",[]]o[\"{B@BhNn}\",[]]o[\"{NdBEIh}\",[]]A`[\"{AIBdCLf}\",[]]o[\"{B@BlNn}\",[]]A`[\"{BBA`KB`}\",[]]Bl[\"{{{AHEf{CEdc}}}{{KBj{KDfBACf}}}Oh}\",[\"B\"]]Bl[\"{{{AHEf{CEdc}}}{{KBj{KBdBACf}}}Oh}\",[\"B\"]]Bm[\"{{{AHEf{CEdc}}}{{KBj{AGJbBACf}}}Oh}\",[\"B\"]]Bm[\"{{{AHEf{CEdc}}}{{KBj{BEIfBACf}}}Oh}\",[\"B\"]]Bm[\"{{{AHEf{CEdc}}}{{KBj{AAMbBACf}}}Oh}\",[\"B\"]]Bh[\"{{{AHEf{CEdc}}}{{KCb{KDh}}}Oh}\",[\"B\"]]Bh[\"{{{AHEf{CEdc}}}{{KCb{KBf}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AGJd}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AIC`}}}Oh}\",[\"B\"]]Ek[\"{{{AHEf{CEd{K@l{AAI`}}}}{AHEf{c}}{AHEf{{JL`{CLd}}}}D@n}{{KBj{BBMhBEAj}}}{BEElIDh}}\",[\"\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{BEIh}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AAMd}}}Oh}\",[\"B\"]]Bi[\"{{{AHEf{CEdc}}}{{KCb{AGIf}}}Oh}\",[\"B\"]]A`[\"{AALnKB`}\",[]]Bk[\"{{{AHEf{KDf}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bk[\"{{{AHEf{KBd}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AGJb}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{BEIf}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AAMb}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bk[\"{{{AHEf{KDh}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bk[\"{{{AHEf{KBf}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AGJd}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AIC`}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AAIj}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{BEIh}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AAMd}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bl[\"{{{AHEf{AGIl}}{AHEf{CEdc}}}HOjJOl}\",[\"B\"]]Bj[\"{{{AHEf{CEdAIEf}}}{{KBj{HOjAOMb}}}}\",[]]Bj[\"{{{AHEf{CEdAIEh}}}{{KBj{HOjANLl}}}}\",[]]An[\"{{{AHEf{ANOf}}AAJb}HOj}\",[]]Ea[\"{{{AHEf{CEdAAJh}}NEdAGJ`{KB`{AOO`}}AAI`{AHEf{CEd{AAj{Nd}}}}}{{KB`{B@Ob}}}}\",[]]o[\"{CNbNEf}\",[]]o[\"{CNdNEh}\",[]]A`[\"{AAJnHOj}\",[]]Ba[\"{{{AHEf{CEdAAJh}}AAK`}HOj}\",[]]Bh[\"{{{AHEf{AIFl}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BAOb}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BDHl}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{AIFn}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BAOd}}{AHEf{CL`}}HOn}HOj}\",[]]Bh[\"{{{AHEf{BDHn}}{AHEf{CL`}}HOn}HOj}\",[]]A`[\"{AGHnD@n}\",[]]o[\"{I@`CLf}\",[]]o[\"{I@bCLf}\",[]]Ce[\"{{{AHEf{CEdAIAj}}NEdNEdCLfD@n{AHEf{B@An}}}HOj}\",[]]Cc[\"{{{AHEf{CEdO`}}NEdNEdCLfD@n{AHEf{B@An}}}HOj}\",[]]Cd[\"{{{AHEf{CEdI@h}}NEdNEdCLfD@n{AHEf{B@An}}}HOj}\",[]]Cd[\"{{{AHEf{CEdNF`}}NEdNEdCLfD@n{AHEf{B@An}}}HOj}\",[]]Ce[\"{{{AHEf{CEdAIAl}}NEdNEdCLfD@n{AHEf{B@B`}}}HOj}\",[]]Cc[\"{{{AHEf{CEdOb}}NEdNEdCLfD@n{AHEf{B@B`}}}HOj}\",[]]Cd[\"{{{AHEf{CEdI@j}}NEdNEdCLfD@n{AHEf{B@B`}}}HOj}\",[]]Cd[\"{{{AHEf{CEdNFb}}NEdNEdCLfD@n{AHEf{B@B`}}}HOj}\",[]]o[\"{CNbNEf}\",[]]o[\"{CNdNEh}\",[]]o[\"{BDIfNd}\",[]]A`[\"{BBKhHOn}\",[]]A`[\"{BDDjHOn}\",[]]A`[\"{BBKlHOn}\",[]]A`[\"{BDDnHOn}\",[]]A`[\"{BBA`KDb}\",[]]Aa[\"{BALhBBL`}\",[]]Aa[\"{AGGdBEAn}\",[]]Bg[\"{{{AHEf{AAJf}}AGMb}{{KBl{HOj}}}}\",[]]A`[\"{AAJnHOj}\",[]]Cf[\"{{{AHEf{CEdAAJh}}AAK`{AHEf{CEd{AAj{Nd}}}}}AANh}\",[]]l[\"{NEf}\",[]]Ak[\"{{{AHEf{AGJ`}}}AIEl}\",[]]l[\"{NEh}\",[]]An[\"{{AAJdA@l}{{KBn{HOj}}}}\",[]]B`[\"{{B@BhAIEl}{{KBl{AAJf}}}}\",[]]Bb[\"{B@Bd{{KBj{HOj{Of{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BEB`}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BB@f}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{AGLh}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{AIDn}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BB@d}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{AIGb}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{B@Cd}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BBKn}}}{{KB`{{AHEf{IAd}}}}}}\",[]]Bk[\"{{{AHEf{BBL`}}}{{KB`{{AHEf{IAd}}}}}}\",[]]A`[\"{AANfKB`}\",[]]A`[\"{AANhKB`}\",[]]A`[\"{AANjKB`}\",[]]Bg[\"{{{AHEf{CNn}}}{{KBj{AID`AI@h}}}}\",[]]Aa[\"{B@AjAIDb}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]A`[\"{AALnJNf}\",[]]Aa[\"{AGLbAANl}\",[]]Aa[\"{BBLfAANl}\",[]]Aa[\"{AGLdAANn}\",[]]Aa[\"{BBLhAANn}\",[]]3210Dh[\"{{{AHEf{NDn}}{AHEf{{JL`{Nd}}}}{AHEf{{JL`{Nd}}}}}{{KBj{HOjANL`}}}}\",[]]Dh[\"{{{AHEf{NE`}}{AHEf{{JL`{Nd}}}}{AHEf{{JL`{Nd}}}}}{{KBj{HOjANLb}}}}\",[]]Aj[\"{{{AHEf{AIAj}}}CLf}\",[]]Ah[\"{{{AHEf{O`}}}CLf}\",[]]Ai[\"{{{AHEf{I@h}}}CLf}\",[]]Ai[\"{{{AHEf{NF`}}}CLf}\",[]]Aj[\"{{{AHEf{AIAl}}}CLf}\",[]]Ah[\"{{{AHEf{Ob}}}CLf}\",[]]Ai[\"{{{AHEf{I@j}}}CLf}\",[]]Ai[\"{{{AHEf{NFb}}}CLf}\",[]]Aj[\"{{{AHEf{BFLl}}}JNf}\",[]]Aj[\"{{{AHEf{BFLn}}}JNf}\",[]]Aj[\"{{{AHEf{BGMb}}}JNf}\",[]]Aj[\"{{{AHEf{BGMl}}}JNf}\",[]]o[\"{A@lJNf}\",[]]n[\"{{}ND`}\",[]]0o[\"{OjAAId}\",[]]111Ba[\"{{AHEf{AHEf{c}}}AALh{}}\",[\"K\"]]0000000000000000000Cg[\"{{{AHEf{AAJf}}AIEl{AHEf{CL`}}}{{KBj{AIAbAOMn}}}}\",[]]Dl[\"{{{AHEf{CEdAAJh}}NEdAOLjAIEl{AHEf{CL`}}}{{KBj{{JNd{BDEfAIAh}}AON`}}}}\",[]]Bd[\"{{{AHEf{AAJn}}}{{KB`{BDEj}}}}\",[]]Dm[\"{{{AHEf{AGKf}}KBdCLf{AHEf{{JL`{Nd}}}}{AHEf{CEdAAI`}}}{{KBj{HOjANL`}}}}\",[]]Ca[\"{{{AHEf{AGJh}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Bd[\"{{{AHEf{AAK`}}}{{KB`{BDEl}}}}\",[]]Dm[\"{{{AHEf{AGKh}}KBfCLf{AHEf{{JL`{Nd}}}}{AHEf{CEdAAI`}}}{{KBj{HOjANLb}}}}\",[]]Ca[\"{{{AHEf{AGJj}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]o[\"{{}ANOd}\",[]]n[\"{{}IDj}\",[]]o[\"{{}ANKf}\",[]]o[\"{{}B@Nd}\",[]]o[\"{{}B@Of}\",[]]n[\"{{}KDf}\",[]]n[\"{{}KBd}\",[]]o[\"{{}AANl}\",[]]o[\"{{}AIBb}\",[]]o[\"{{}AGLb}\",[]]o[\"{{}BBLf}\",[]]n[\"{{}NIf}\",[]]o[\"{{}AOMb}\",[]]o[\"{{}BBNl}\",[]]o[\"{{}BEE`}\",[]]o[\"{{}BEFn}\",[]]o[\"{{}ANLn}\",[]]o[\"{{}BAMf}\",[]]o[\"{{}BFMn}\",[]]o[\"{{}BDHl}\",[]]o[\"{{}AGHh}\",[]]o[\"{{}ANLd}\",[]]o[\"{{}BAAj}\",[]]o[\"{{}BE@h}\",[]]o[\"{{}B@Nf}\",[]]o[\"{{}BGMb}\",[]]n[\"{{}KDh}\",[]]n[\"{{}KBf}\",[]]o[\"{{}AIDb}\",[]]o[\"{{}AI@n}\",[]]o[\"{{}AANn}\",[]]o[\"{{}AIBd}\",[]]o[\"{{}AGLd}\",[]]o[\"{{}BBLh}\",[]]n[\"{{}NIh}\",[]]o[\"{{}BB@h}\",[]]o[\"{{}AOMj}\",[]]o[\"{{}BBNn}\",[]]o[\"{{}BEEb}\",[]]o[\"{{}BEG`}\",[]]o[\"{{}ANM`}\",[]]o[\"{{}BAMh}\",[]]o[\"{{}BFN`}\",[]]o[\"{{}BGMl}\",[]]o[\"{{}BDHn}\",[]]o[\"{{}AGHj}\",[]]o[\"{{}ANLf}\",[]]o[\"{{}BAAl}\",[]]o[\"{{}BE@j}\",[]]o[\"{{}AALn}\",[]]n[\"{{}IDl}\",[]]o[\"{{}BBM`}\",[]]o[\"{{}B@Od}\",[]]Ak[\"{{{AHEf{BAB`}}}AONf}\",[]]Ak[\"{{{AHEf{BBMh}}}AONf}\",[]]Aa[\"{BGB`AONf}\",[]]Aa[\"{BEIjAONf}\",[]]A`[\"{CNfAONf}\",[]]A`[\"{ID`AONf}\",[]]A`[\"{IDdAONf}\",[]]Aa[\"{BDIfAONf}\",[]]Cg[\"{{{AHEf{AGKf}}KBdCLf{AHEf{CEd{JL`{Nd}}}}JNf}HOj}\",[]]Ca[\"{{{AHEf{AGJh}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Cg[\"{{{AHEf{AGKh}}KBfCLf{AHEf{CEd{JL`{Nd}}}}JNf}HOj}\",[]]Ca[\"{{{AHEf{AGJj}}JNf{AHEf{CEd{JL`{Nd}}}}}HOj}\",[]]Aj[\"{{{AHEf{AIDj}}}D@n}\",[]]Aj[\"{{{AHEf{BEOf}}}D@n}\",[]]Ak[\"{{{AHEf{AIAj}}}BE@h}\",[]]Ai[\"{{{AHEf{O`}}}BE@h}\",[]]Aj[\"{{{AHEf{I@h}}}BE@h}\",[]]Aj[\"{{{AHEf{NF`}}}BE@h}\",[]]Ak[\"{{{AHEf{AIAl}}}BE@j}\",[]]Ai[\"{{{AHEf{Ob}}}BE@j}\",[]]Aj[\"{{{AHEf{I@j}}}BE@j}\",[]]Aj[\"{{{AHEf{NFb}}}BE@j}\",[]]Bn[\"{{{AHEf{CEdBBNl}}CLb}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}CLb}{{AHEf{CEdBBNn}}}}\",[]]Bf[\"{{{AHEf{CEdAIAj}}NEdCLfCLf}HOj}\",[]]Bd[\"{{{AHEf{CEdO`}}NEdCLfCLf}HOj}\",[]]Bf[\"{{{AHEf{CEdAIAl}}NEdCLfCLf}HOj}\",[]]Bd[\"{{{AHEf{CEdOb}}NEdCLfCLf}HOj}\",[]]Aj[\"{{{AHEf{AIAf}}}KAf}\",[]]Bc[\"{{{AHEf{AALf}}}{{KB`{KBd}}}}\",[]]Aa[\"{BGB`AONf}\",[]]Aa[\"{BEIjAONf}\",[]]A`[\"{CNfAONf}\",[]]A`[\"{ID`AONf}\",[]]Aa[\"{BDIfAONf}\",[]]Aj[\"{{{AHEf{AIEf}}}NHb}\",[]]Bn[\"{{{AHEf{AIEh}}}{{KBj{{KB`{KDh}}AOMj}}}}\",[]]o[\"{A@lJNf}\",[]]o[\"{IDjJNf}\",[]]Am[\"{{{AHEf{CEdAIAh}}}NHj}\",[]]Aj[\"{{{AHEf{AGKf}}}JNf}\",[]]Aj[\"{{{AHEf{AGKh}}}JNf}\",[]]A`[\"{AHEfKDd}\",[]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Bd[\"{{{AHEf{BFGb}}}{{KB`{AIAf}}}}\",[]]Bc[\"{{{AHEf{BBAd}}}{{KB`{CNn}}}}\",[]]Bn[\"{{{AHEf{CEdAOLf}}CLd}{{AHEf{CEdAOLf}}}}\",[]]Bn[\"{{{AHEf{CEdAOLj}}CLd}{{AHEf{CEdAOLj}}}}\",[]]A`[\"{BGB`CLd}\",[]]A`[\"{BEIjCLd}\",[]]o[\"{CNfCLd}\",[]]o[\"{ID`CLd}\",[]]A`[\"{AGHnKB`}\",[]]Aa[\"{AANjAHEf}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Aa[\"{BB@jAAJb}\",[]]A`[\"{JOnBB@h}\",[]]Aa[\"{AGLbAIBb}\",[]]Aa[\"{BBLfAIBb}\",[]]Aa[\"{AGLdAIBd}\",[]]Aa[\"{BBLhAIBd}\",[]]3210Bg[\"{{{AHEf{CEdc}}JNf}AONd{OhIDh}}\",[\"\"]]Bg[\"{{{AHEf{CEdc}}JNf}AONf{OhIDh}}\",[\"\"]]o[\"{{}BBMj}\",[]]o[\"{{}BBMl}\",[]]A`[\"{CLfBGMb}\",[]]Cd[\"{{{AHEf{CL`}}}{{KBn{ANNdc}}}{}}\",[\"FromStr::Err\"]]Cd[\"{{{AHEf{CL`}}}{{KBn{ANKdc}}}{}}\",[\"FromStr::Err\"]]o[\"{CLdKDf}\",[]]o[\"{CLdKDh}\",[]]Al[\"{CLf{{KBj{KDfBFFl}}}}\",[]]Al[\"{CLf{{KBj{KDhBFFn}}}}\",[]]Aa[\"{BFEdANKn}\",[]]Aa[\"{BHA`BA@b}\",[]]Aa[\"{BFEfANKn}\",[]]Aa[\"{BHAbBA@b}\",[]]Af[\"{{}{{KB`{Ab}}}}\",[]]0000Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]Bo[\"{{{AHEf{CEdBEFn}}AAJb}{{AHEf{CEdBEFn}}}}\",[]]Bo[\"{{{AHEf{CEdBEG`}}AAJb}{{AHEf{CEdBEG`}}}}\",[]]Ao[\"{{{Of{AIAj}}}{{Of{Nl}}}}\",[]]Am[\"{{{Of{O`}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{I@h}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{NF`}}}{{Of{Nl}}}}\",[]]Ao[\"{{{Of{AIAl}}}{{Of{Nl}}}}\",[]]Am[\"{{{Of{Ob}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{I@j}}}{{Of{Nl}}}}\",[]]An[\"{{{Of{NFb}}}{{Of{Nl}}}}\",[]]Aj[\"{{{AHEf{BFGb}}}D@n}\",[]]Bo[\"{{{AHEf{CEdBFMn}}AAJb}{{AHEf{CEdBFMn}}}}\",[]]Bo[\"{{{AHEf{CEdBFN`}}AAJb}{{AHEf{CEdBFN`}}}}\",[]]Bc[\"{{{AHEf{AIAb}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AIAf}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AAJn}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AAK`}}}{{KB`{KAb}}}}\",[]]Bc[\"{{{AHEf{AGJ`}}}{{KB`{KAb}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Bc[\"{{{AHEf{AGId}}}{{KB`{JNf}}}}\",[]]Am[\"{{{AHEf{ANOf}}JNf}HOj}\",[]]Aj[\"{{{AHEf{AIAf}}}NFf}\",[]]Bg[\"{{{AHEf{AIEf}}}{{KBj{CCnAOMb}}}}\",[]]Bg[\"{{{AHEf{AIEh}}}{{KBj{CCnAOMj}}}}\",[]]A`[\"{B@OjKB`}\",[]]A`[\"{B@OlKB`}\",[]]A`[\"{AGHnKB`}\",[]]A`[\"{ANK`KB`}\",[]]Ck[\"{{{AHEf{CEdBAMf}}{KB`{{IEf{Nd}}}}}{{AHEf{CEdBAMf}}}}\",[]]Ck[\"{{{AHEf{CEdBAMh}}{KB`{{IEf{Nd}}}}}{{AHEf{CEdBAMh}}}}\",[]]A`[\"{BE@hKB`}\",[]]A`[\"{BE@jKB`}\",[]]Ac[\"{AHEfc{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Ao[\"{c{{KBj{e}}}{}{}}\",[\"U\",\"T\"]]000000000000000000000000000000000000000000000000000Al[\"{JNf{{KBj{KDfBFFl}}}}\",[]]Al[\"{CLf{{KBj{KDfBFFl}}}}\",[]]2Al[\"{HOh{{KBj{KDfBFFl}}}}\",[]]33333333333333Aj[\"{AAJb{{KBj{ANLn}}}}\",[]]4444444Ai[\"{CLf{{KBj{AGJb}}}}\",[]]5555555555555555555555555555Aj[\"{AOLd{{KBj{BDHd}}}}\",[]]Bb[\"{{{Nn{AOLd}}}{{KBj{BDHd}}}}\",[]]7Bb[\"{{{Nn{B@Bf}}}{{KBj{BDHh}}}}\",[]]8Aj[\"{B@Bf{{KBj{BDHh}}}}\",[]]999999999999999999999Al[\"{CLf{{KBj{KDhBFFn}}}}\",[]]Al[\"{HOh{{KBj{KDhBFFn}}}}\",[]]Al[\"{JNf{{KBj{KDhBFFn}}}}\",[]]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Bm[\"{AOLd{{KBj{BDHfc}}}{}}\",[\"TryFrom::Error\"]]Ce[\"{{{Nn{AOLd}}}{{KBj{BDHfc}}}{}}\",[\"TryFrom::Error\"]]Ao[\"{c{{KBj{e}}}{}{}}\",[\"U\",\"T\"]]00Ce[\"{{{Nn{B@Bf}}}{{KBj{BDHjc}}}{}}\",[\"TryFrom::Error\"]]Bm[\"{B@Bf{{KBj{BDHjc}}}{}}\",[\"TryFrom::Error\"]]22222222222222222222222Aj[\"{{}{{KBj{c}}}{}}\",[\"U\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Cd[\"{{{AAd{{AHEf{CEdc}}}}{AHEf{CEdNDb}}}COf{}}\",[\"F\"]]000000000Cc[\"{{{AHEf{BBAb}}AIG`{AHEf{AANj}}}{{KBl{HOj}}}}\",[]]Bk[\"{{{AHEf{BFLl}}AONd}{{KBj{HOjAIBh}}}}\",[]]Bk[\"{{{AHEf{BFLn}}AONf}{{KBj{HOjAIBj}}}}\",[]]0Bk[\"{{{AHEf{BGMb}}AONf}{{KBj{HOjAIBj}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}AAHn}\",[]]Bi[\"{{{AHEf{CEdB@Ch}}}{{KBj{KDfIB`}}}}\",[]]Bi[\"{{{AHEf{CEdB@Ch}}}{{KBj{COlIB`}}}}\",[]]Bh[\"{{{AHEf{CEdB@Ch}}}{{KBj{OlIB`}}}}\",[]]Bj[\"{{{AHEf{CEdB@Ch}}}{{KBj{AAMbIB`}}}}\",[]]Bf[\"{{{AHEf{CEdB@Ch}}}{{KC`{KDh}}}}\",[]]Bf[\"{{{AHEf{CEdB@Ch}}}{{KC`{COn}}}}\",[]]Be[\"{{{AHEf{CEdB@Ch}}}{{KC`{On}}}}\",[]]Bg[\"{{{AHEf{CEdB@Ch}}}{{KC`{AAMd}}}}\",[]]Aa[\"{ANKdBFFj}\",[]]Bc[\"{{{AHEf{AIAj}}}{{Of{AIAj}}}}\",[]]Ba[\"{{{AHEf{O`}}}{{Of{AIAj}}}}\",[]]Bb[\"{{{AHEf{I@h}}}{{Of{AIAj}}}}\",[]]Bb[\"{{{AHEf{NF`}}}{{Of{AIAj}}}}\",[]]Bc[\"{{{AHEf{AIAl}}}{{Of{AIAl}}}}\",[]]Ba[\"{{{AHEf{Ob}}}{{Of{AIAl}}}}\",[]]Bb[\"{{{AHEf{I@j}}}{{Of{AIAl}}}}\",[]]Bb[\"{{{AHEf{NFb}}}{{Of{AIAl}}}}\",[]]A`[\"{AANlCLf}\",[]]An[\"{{{AHEf{CEdAIAh}}}AGId}\",[]]A`[\"{AANnCLf}\",[]]C`[\"{{{AHEf{CEdAONd}}}{{AHEf{CEd{JL`{Nd}}}}}}\",[]]C`[\"{{{AHEf{CEdAONf}}}{{AHEf{CEd{JL`{Nd}}}}}}\",[]]Ah[\"{Nd{{KB`{AONn}}}}\",[]]Ah[\"{Nd{{KB`{AOO`}}}}\",[]]Ah[\"{Nd{{KB`{AOOb}}}}\",[]]A`[\"{AAMbCOl}\",[]]A`[\"{AAMdCOn}\",[]]Bi[\"{AIAb{{KBj{{JNd{AIAfBBOf}}AIAb}}}}\",[]]Aa[\"{{}c{}}\",[\"I\"]]o[\"{COlD@n}\",[]]o[\"{COnD@n}\",[]]Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]21Aj[\"{{{AHEf{AAJn}}}D@n}\",[]]Aj[\"{{{AHEf{AAK`}}}D@n}\",[]]Bn[\"{{{AHEf{CEdB@Bh}}D@n}{{AHEf{CEdB@Bh}}}}\",[]]Bn[\"{{{AHEf{CEdB@Bl}}D@n}{{AHEf{CEdB@Bl}}}}\",[]]Bl[\"{{{AHEf{NGh}}NEd}{{AAd{{Of{AI@`}}}}}}\",[]]Bm[\"{{{AHEf{B@Cf}}NEd}{{AAd{{Of{AI@`}}}}}}\",[]]Bm[\"{{{AHEf{ANNj}}NEd}{{AAd{{Of{AI@`}}}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Ak[\"{{{AHEf{AIAf}}}AALd}\",[]]Bc[\"{{{AHEf{AIAf}}AIElAID`}AALf}\",[]]Ce[\"{{{AHEf{CEdAIAh}}AGJ`AIDbNEd}{{KBj{KBfAGKl}}}}\",[]]43Bm[\"{{{AHEf{CEdAIAh}}KBf}{{KBj{HOjAI@n}}}}\",[]]E`[\"{{{AAd{{AHEf{CEdBFFf}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]E`[\"{{{AAd{{AHEf{CEdBDDf}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]E`[\"{{{AAd{{AHEf{CEdAICn}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]E`[\"{{{AAd{{AHEf{CEdBENh}}}}{AHEf{CEdNDb}}}{{COf{{KB`{c}}}}}{}}\",[\"Stream::Item\"]]Ef[\"{{{AAd{{AHEf{CEdAIDj}}}}{AHEf{CEdNDb}}{AHEf{CEd{JL`{Nd}}}}}{{COf{{KBl{JNf}}}}}}\",[]]Ec[\"{{{AHEf{CEdAIDj}}{AHEf{CEdNDb}}{AHEf{CEd{JL`{Nd}}}}}{{COf{{KBj{JNfAGLh}}}}}}\",[]]E`[\"{{{AAd{{AHEf{CEdAIDj}}}}{AHEf{CEdNDb}}{AHEf{CEdNGb}}}{{COf{{KBl{HOj}}}}}}\",[]]Fg[\"{{{AHEf{CEdBAKn}}{AHEf{CEdNDb}}{AHEf{CEd{JL`{AIBl}}}}{AHEf{CEd{JL`{AALn}}}}}{{COf{{KBl{JNf}}}}}}\",[]]Dn[\"{{{AAd{{AHEf{CEdAGM`}}}}{AHEf{AANj}}{AHEf{CEdNDb}}}{{COf{{KBl{HOj}}}}}}\",[]]>=Cd[\"{{{AHEf{CEdBAMf}}{Nn{NDn}}}{{AHEf{CEdBAMf}}}}\",[]]Cd[\"{{{AHEf{CEdBAMh}}{Nn{NE`}}}{{AHEf{CEdBAMh}}}}\",[]]Cj[\"{{{AHEf{B@Bj}}CLdAONd{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{BDHh}}CLdAONd{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{B@Bn}}CLdAONf{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{BDHj}}CLdAONf{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Cj[\"{{{AHEf{BGGl}}CLdAONb{AHEf{{JL`{Nd}}}}}{{IEf{Nd}}}}\",[]]Bb[\"{JNf{{JNd{JNf{KB`{JNf}}}}}}\",[]]000Aj[\"{{{AHEf{AIAf}}}JNf}\",[]]A`[\"{AHEfKDb}\",[]]00000000000000000000000000000000000000000000000000000000000000Ce[\"{{{AHEf{CEdB@Bh}}{Nn{BE@l}}}{{AHEf{CEdB@Bh}}}}\",[]]Ce[\"{{{AHEf{CEdB@Bl}}{Nn{BE@n}}}{{AHEf{CEdB@Bl}}}}\",[]]A`[\"{BGB`ICf}\",[]]o[\"{B@BhNn}\",[]]o[\"{B@BlNn}\",[]]Aj[\"{{{AHEf{AAJf}}}HOj}\",[]]Ck[\"{{{AHEf{CEdAIEf}}{AHEf{{JL`{Nd}}}}}{{KBj{HOjAIGb}}}}\",[]]n[\"{{}JNf}\",[]]Ak[\"{{{AHEf{AIAf}}}AGGh}\",[]]Ba[\"{{{AHEf{CEdAANl}}AANl}HOj}\",[]]Ba[\"{{{AHEf{CEdAIBb}}AIBb}HOj}\",[]]Ba[\"{{{AHEf{CEdBBLf}}AGLb}HOj}\",[]]Ba[\"{{{AHEf{CEdAANn}}AANn}HOj}\",[]]Ba[\"{{{AHEf{CEdAIBd}}AIBd}HOj}\",[]]Ba[\"{{{AHEf{CEdBBLh}}AGLd}HOj}\",[]]Bn[\"{{{AHEf{CEdBBNl}}D@n}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}D@n}{{AHEf{CEdBBNn}}}}\",[]]Bi[\"{{{AHEf{CEd}}}{{AHEf{CEdc}}}{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Bc[\"{{AHEf{AHEf{CEdc}}}HOj{}}\",[\"T\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Cc[\"{{{AHEf{CEdAIAh}}NEdKBfKDh}{{KBj{HOjBALd}}}}\",[]]A`[\"{AGHnD@n}\",[]]B`[\"{{AHEf{AHEf{c}}}D@n{}}\",[\"K\"]]00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Aa[\"{BBKhBEIf}\",[]]A`[\"{BDDjKDf}\",[]]Aa[\"{BBKlBEIh}\",[]]A`[\"{BDDnKDh}\",[]]A`[\"{BDOlKDh}\",[]]A`[\"{BBMnKDh}\",[]]o[\"{NGnKDh}\",[]]Aa[\"{BBKhAIBn}\",[]]Aa[\"{BBKlAIC`}\",[]]o[\"{KDfCLf}\",[]]o[\"{KDhCLf}\",[]]Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]Aj[\"{{{AHEf{B@Od}}}D@n}\",[]]Bd[\"{{{AHEf{BAKn}}}{{KBl{AIEl}}}}\",[]]Bd[\"{{{AHEf{AAJf}}}{{KBl{AIEl}}}}\",[]]A`[\"{AGLbCLf}\",[]]A`[\"{BBLfCLf}\",[]]A`[\"{AGLdCLf}\",[]]A`[\"{BBLhCLf}\",[]]Cb[\"{{{AHEf{BBM`}}{AHEf{AIEd}}CLf}{{Nn{ANOf}}}}\",[]]Bn[\"{{{AHEf{CEdBBNl}}D@n}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}D@n}{{AHEf{CEdBBNn}}}}\",[]]Bg[\"{{{AHEf{AIAf}}KBd}{{KB`{AGLb}}}}\",[]]Bj[\"{{{AHEf{CEdAIAh}}KBf}{{KB`{AGLd}}}}\",[]]o[\"{AGIhOf}\",[]]Db[\"{{{AAd{{AHEf{CEdAIEf}}}}{AHEf{CEdNDb}}}{{COf{{KBl{HOj}}}}}}\",[]]00Ec[\"{{{AAd{{AHEf{CEdAIEf}}}}{AHEf{CEdNDb}}{AHEf{{JL`{Nd}}}}}{{COf{{KBl{JNf}}}}}}\",[]]Eg[\"{{{AAd{{AHEf{CEdAIEf}}}}{AHEf{CEdNDb}}{AHEf{{JL`{Nd}}}}}{{COf{{KBj{JNfAIGb}}}}}}\",[]]1Bm[\"{{{AHEf{IDl}}{AHEf{CNl}}}{{KBl{HOj}}}}\",[]]Cd[\"{{{AHEf{CEdAIDj}}JNf}{{KBj{{KB`{I@`}}AGLh}}}}\",[]]Cd[\"{{{AHEf{CEdBEOf}}JNf}{{KBj{{KB`{I@`}}AGLh}}}}\",[]]Cn[\"{{{AHEf{CEdAIDj}}{AHEf{CEd{JL`{Nd}}}}}{{KBj{HOjBB@d}}}}\",[]]Bj[\"{{{AHEf{CNn}}AID`}{{KBj{HOjBEHl}}}}\",[]]Bn[\"{{{AHEf{CEdAIDd}}NEd}{{AHEf{CEdAIDd}}}}\",[]]Bn[\"{{{AHEf{CEdAIDf}}NEd}{{AHEf{CEdAIDf}}}}\",[]]A`[\"{BB@jAFd}\",[]]o[\"{IDjCLf}\",[]]o[\"{{}AIEl}\",[]]0o[\"{{}AHEf}\",[]]Bj[\"{{AAJn{Nn{B@Bh}}}{{KBj{AIAbBBKn}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Bh[\"{{{AHEf{AGHn}}AIEl}{{KBn{AGMb}}}}\",[]]A`[\"{AGLbCLb}\",[]]Aj[\"{{{AHEf{AIAh}}}CLb}\",[]]A`[\"{AGLdCLb}\",[]]Ce[\"{{{AHEf{CEdAIDd}}{KB`{KDb}}}{{AHEf{CEdAIDd}}}}\",[]]Ce[\"{{{AHEf{CEdAIDf}}{KB`{KDb}}}{{AHEf{CEdAIDf}}}}\",[]]Aa[\"{AANfAIEl}\",[]]Aa[\"{AANhAIEl}\",[]]Aa[\"{AANjAIEl}\",[]]Aa[\"{AIElAGJ`}\",[]]o[\"{A@lCLb}\",[]]Bn[\"{{{AHEf{CEdBBNl}}CLb}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}CLb}{{AHEf{CEdBBNn}}}}\",[]]A`[\"{AGHnCLb}\",[]]Bo[\"{{{AHEf{CEdBBNl}}AAJb}{{AHEf{CEdBBNl}}}}\",[]]Bo[\"{{{AHEf{CEdBBNn}}AAJb}{{AHEf{CEdBBNn}}}}\",[]]A`[\"{AGHnKB`}\",[]]k[\"{{}}\",[]]0000000000Bh[\"{AAJnc{}}\",[\"IntoFuture::IntoFuture\"]]11A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]o[\"{A@lJNf}\",[]]Ao[\"{{AHEfc}{{NEj{c}}}{}}\",[\"S\"]]0C`[\"{{{AHEf{CEdAIAj}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]Bn[\"{{{AHEf{CEdO`}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]C`[\"{{{AHEf{CEdAIAl}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]Bn[\"{{{AHEf{CEdOb}}NEdCLfD@n{KB`{CLf}}}HOj}\",[]]Bk[\"{{{AHEf{CEdIDl}}NEd{AHEf{BBM`}}}HOj}\",[]]A`[\"{BE@hKB`}\",[]]A`[\"{BE@jKB`}\",[]]Bn[\"{{{AHEf{KDf}}{AHEf{KDf}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{KBd}}{AHEf{KBd}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{ANLn}}{AHEf{ANLn}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AONd}}{AHEf{AONd}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{COl}}{AHEf{COl}}}{{KB`{AALh}}}}\",[]]Bl[\"{{{AHEf{Ol}}{AHEf{Ol}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AAMb}}{AHEf{AAMb}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{KDh}}{AHEf{KDh}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BEBb}}{AHEf{BEBb}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{KBf}}{AHEf{KBf}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AGLj}}{AHEf{AGLj}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BABj}}{AHEf{BABj}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AIGd}}{AHEf{AIGd}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{ANM`}}{AHEf{ANM`}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BDEf}}{AHEf{BDEf}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{BEAj}}{AHEf{BEAj}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AONf}}{AHEf{AONf}}}{{KB`{AALh}}}}\",[]]Bn[\"{{{AHEf{COn}}{AHEf{COn}}}{{KB`{AALh}}}}\",[]]Bl[\"{{{AHEf{On}}{AHEf{On}}}{{KB`{AALh}}}}\",[]]C`[\"{{{AHEf{AAMd}}{AHEf{AAMd}}}{{KB`{AALh}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}AICn}\",[]]Bk[\"{{{AHEf{AIAh}}KBf}{{KBj{AIDbAI@n}}}}\",[]]Df[\"{{{AHEf{CEdAIDj}}{AHEf{CEd{JL`{HOn}}}}}{{KBj{{KB`{JNf}}AGLh}}}}\",[]]Cc[\"{{{AHEf{CEdAIDj}}JNf}{{KBj{{AAj{Nd}}BB@f}}}}\",[]]Bb[\"{{{AHEf{CEdAIAh}}AAMd}AIDl}\",[]]Aj[\"{{{AHEf{AGJh}}}JNf}\",[]]Aj[\"{{{AHEf{AGJj}}}JNf}\",[]]Bb[\"{{{AHEf{CEdAIAh}}AAMd}AIEh}\",[]]Bn[\"{{{AHEf{CEdBBNl}}CLf}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}CLf}{{AHEf{CEdBBNn}}}}\",[]]A`[\"{AGHnKB`}\",[]]A`[\"{B@OjKB`}\",[]]A`[\"{B@OlKB`}\",[]]Ce[\"{{{AHEf{CEdB@Bh}}{Nn{AIFd}}}{{AHEf{CEdB@Bh}}}}\",[]]Ce[\"{{{AHEf{CEdB@Bl}}{Nn{AIFf}}}{{AHEf{CEdB@Bl}}}}\",[]]Ce[\"{{{AHEf{CEdAOLf}}{Nn{AIFl}}}{{AHEf{CEdAOLf}}}}\",[]]Ce[\"{{{AHEf{CEdAOLj}}{Nn{AIFn}}}{{AHEf{CEdAOLj}}}}\",[]]o[\"{A@lCLf}\",[]]Bn[\"{{{AHEf{CEdBEFn}}CLb}{{AHEf{CEdBEFn}}}}\",[]]Bn[\"{{{AHEf{CEdBEG`}}CLb}{{AHEf{CEdBEG`}}}}\",[]]Ak[\"{{{AHEf{AIAf}}}BFGb}\",[]]Aj[\"{{{AHEf{CNn}}}BBAd}\",[]]Ai[\"{{{Nn{B@Bj}}}B@Bh}\",[]]Ai[\"{{{Nn{B@Bn}}}B@Bl}\",[]]Aj[\"{{BBMjc}BBMjAAMl}\",[\"\"]]Aj[\"{{BBMlc}BBMlAAMl}\",[\"\"]]Bm[\"{{{AHEf{CEdAIEf}}HOn}{{KBj{HOjAIGb}}}}\",[]]n[\"{{}KAb}\",[]]o[\"{ND`ND`}\",[]]0000Bd[\"{{{AHEf{BFLl}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{BFLn}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{BGMb}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{BGMl}}}{{KB`{AAJb}}}}\",[]]Bd[\"{{{AHEf{AIAf}}}{{KB`{BBKn}}}}\",[]]Ck[\"{{{AHEf{AAJf}}AOLfAIEl{AHEf{CL`}}}{{KBj{AIAbAOMn}}}}\",[]]Ak[\"{{{AHEf{B@B`}}}AAJb}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]An[\"{{AIDhD@n}{{KBn{JNf}}}}\",[]]Cj[\"{{{AHEf{NGj}}}{{KB`{{JNd{{Of{AGJh}}{Of{AGKf}}}}}}}}\",[]]Ck[\"{{{AHEf{AIFh}}}{{KB`{{JNd{{Of{AGJh}}{Of{AGKf}}}}}}}}\",[]]Cj[\"{{{AHEf{NGl}}}{{KB`{{JNd{{Of{AGJj}}{Of{AGKh}}}}}}}}\",[]]Ck[\"{{{AHEf{AIFj}}}{{KB`{{JNd{{Of{AGJj}}{Of{AGKh}}}}}}}}\",[]]A`[\"{BFEdAAj}\",[]]A`[\"{BHA`AAj}\",[]]A`[\"{BFEfAAj}\",[]]A`[\"{BHAbAAj}\",[]]An[\"{{{AHEf{CEdBFLl}}}AONd}\",[]]An[\"{{{AHEf{CEdBFLn}}}AONf}\",[]]An[\"{{{AHEf{CEdBGMb}}}AONf}\",[]]An[\"{{{AHEf{CEdBGMl}}}AONf}\",[]]Ak[\"{{{AHEf{BBAb}}}B@@f}\",[]]Ba[\"{{{AHEf{CEdAIAh}}BBLd}HOj}\",[]]Bo[\"{{{AHEf{CEdAAJh}}BDEfB@Od}{{KB`{BBLd}}}}\",[]]B`[\"{{{AHEf{NGj}}AONdCOl}CNb}\",[]]Bn[\"{{{AHEf{B@Bj}}CLdAONd}{{KBj{CNbBEIn}}}}\",[]]Ba[\"{{{AHEf{AIFh}}AONdCOl}CNb}\",[]]Bn[\"{{{AHEf{BDHh}}CLdAONd}{{KBj{CNbBEIn}}}}\",[]]B`[\"{{{AHEf{NGl}}AONfCOn}CNd}\",[]]Bn[\"{{{AHEf{B@Bn}}CLdAONf}{{KBj{CNdBEJd}}}}\",[]]Ba[\"{{{AHEf{AIFj}}AONfCOn}CNd}\",[]]Bn[\"{{{AHEf{BDHj}}CLdAONf}{{KBj{CNdBEJd}}}}\",[]]Bn[\"{{{AHEf{BGGl}}CLdAONb}{{KBj{CNdBEJd}}}}\",[]]Aj[\"{{}{{NGd{c}}}{}}\",[\"T\"]]0A`[\"{AGLbCLf}\",[]]A`[\"{BBLfCLf}\",[]]A`[\"{AGLdCLf}\",[]]A`[\"{BBLhCLf}\",[]]Bn[\"{{{AHEf{CEdB@Bh}}JNf}{{AHEf{CEdB@Bh}}}}\",[]]Bn[\"{{{AHEf{CEdB@Bl}}JNf}{{AHEf{CEdB@Bl}}}}\",[]]Aj[\"{{{AHEf{BAKn}}}D@n}\",[]]0Aj[\"{{{AHEf{BBAb}}}D@n}\",[]]Bk[\"{{{AHEf{AIAh}}KBf}{{KBj{AGJ`AI@n}}}}\",[]]Cb[\"{{{AHEf{BBM`}}{AHEf{AIDh}}CLf}{{Nn{ANOf}}}}\",[]]Ak[\"{{{AHEf{AAJn}}}AONd}\",[]]Ak[\"{{{AHEf{AAK`}}}AONf}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]Bf[\"{{{AHEf{CEdAIAh}}}{{KB`{NEd}}}}\",[]]Ce[\"{{{AHEf{CEdBBNl}}{Nn{ANMl}}}{{AHEf{CEdBBNl}}}}\",[]]Ce[\"{{{AHEf{CEdBBNn}}{Nn{ANMn}}}{{AHEf{CEdBBNn}}}}\",[]]43A`[\"{A@lANNd}\",[]]A`[\"{AANfKB`}\",[]]A`[\"{AANhKB`}\",[]]A`[\"{AANjKB`}\",[]]Ai[\"{{{AHEf{NHj}}}JNf}\",[]]Bo[\"{{{AHEf{CEdBGMb}}AAJb}{{AHEf{CEdBGMb}}}}\",[]]Bo[\"{{{AHEf{CEdBGMl}}AAJb}{{AHEf{CEdBGMl}}}}\",[]]Bj[\"{{{AHEf{AIEf}}CCn}{{KBj{HOjAOMb}}}}\",[]]Bm[\"{{{AHEf{CEdAIEh}}CCn}{{KBj{HOjAOMj}}}}\",[]]==E`[\"{{{AHEf{BGBb}}{AHEf{{JL`{Nd}}}}{AHEf{BAL`}}{AHEf{BFM`}}}{{KBj{BGDhIAl}}}}\",[]]0Bf[\"{{{Nn{BAC`}}}{{KBj{AOLfBFG`}}}}\",[]]Bf[\"{{{Nn{BAC`}}}{{KBj{AOLjBFG`}}}}\",[]]Bn[\"{{{AHEf{CEdBEE`}}KDf}{{AHEf{CEdBEE`}}}}\",[]]Bn[\"{{{AHEf{CEdBEEb}}KDh}{{AHEf{CEdBEEb}}}}\",[]]o[\"{ND`ND`}\",[]]0000Aj[\"{{{AHEf{AIAh}}}D@n}\",[]]0Ci[\"{{{AHEf{CNn}}{KB`{AAJb}}}{{KBj{{KB`{AAJb}}AI@h}}}}\",[]]Cd[\"{{{AHEf{CEdA@l}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Cc[\"{{{AHEf{CEdOj}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Ce[\"{{{AHEf{CEdAAId}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Ce[\"{{{AHEf{CEdAGHn}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Cd[\"{{{AHEf{CEdA@n}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Cd[\"{{{AHEf{CEdAA`}}{AHEf{AHOn}}}{{KBj{HOjIAn}}}}\",[]]Bo[\"{{{AHEf{CEdB@Bh}}BFMn}{{AHEf{CEdB@Bh}}}}\",[]]Bo[\"{{{AHEf{CEdB@Bl}}BFN`}{{AHEf{CEdB@Bl}}}}\",[]]Aj[\"{{{AHEf{BAMf}}}CLf}\",[]]Aj[\"{{{AHEf{BAMh}}}CLf}\",[]]Cc[\"{{{AHEf{CEdAOLf}}{Nn{A`}}}{{AHEf{CEdAOLf}}}}\",[]]Cc[\"{{{AHEf{CEdAOLj}}{Nn{A`}}}{{AHEf{CEdAOLj}}}}\",[]]Cj[\"{{BAMf{KB`{B@Bh}}{Of{BAKn}}{Nn{NGh}}}{{KBl{AAJf}}}}\",[]]Aj[\"{{{AHEf{AAJn}}}D@n}\",[]]Aj[\"{{{AHEf{AAK`}}}D@n}\",[]]Ca[\"{{{AHEf{CEdAIAh}}NEdAICd}{{KBj{HOjBGAh}}}}\",[]]Bd[\"{{{AHEf{BGBb}}}{{AAj{BBNb}}}}\",[]]Bj[\"{{{AHEf{AIAf}}AIEl}{{KBj{HOjIBh}}}}\",[]]Bm[\"{{{AHEf{CEdAIAh}}AIEl}{{KBj{HOjIBh}}}}\",[]]Bn[\"{{{AHEf{CEdBBNl}}JNf}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}JNf}{{AHEf{CEdBBNn}}}}\",[]]Bl[\"{{}{{KBj{{JNd{BAL`BEGj}}{Of{IAd}}}}}}\",[]]Ai[\"{AIAd{{KBn{HOj}}}}\",[]]A`[\"{AIBbCLf}\",[]]A`[\"{AIBdCLf}\",[]]An[\"{{{AHEf{AAJf}}AOLf}HOj}\",[]]Dc[\"{{{AHEf{CEdAIAh}}NEdKBf{KB`{AAJb}}}{{KBj{{KB`{AAJb}}AI@n}}}}\",[]]o[\"{{}AHEf}\",[]]Aj[\"{{{AHEf{AIAf}}}JNf}\",[]]Bn[\"{{{AHEf{CEdB@Bh}}CLf}{{AHEf{CEdB@Bh}}}}\",[]]Bn[\"{{{AHEf{CEdB@Bl}}CLf}{{AHEf{CEdB@Bl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNl}}KDf}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}KDh}{{AHEf{CEdBBNn}}}}\",[]]:Bb[\"{{{AHEf{CEdAIAh}}OnKDh}HOj}\",[]]Ak[\"{{}{{KBj{AOLfIBb}}}}\",[]]Ak[\"{{}{{KBj{AOLjIBd}}}}\",[]]Bn[\"{{{AHEf{CEdBBNl}}D@n}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}D@n}{{AHEf{CEdBBNn}}}}\",[]]65Cg[\"{{{AHEf{CEdA@l}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Cf[\"{{{AHEf{CEdOj}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Ch[\"{{{AHEf{CEdAAId}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Ch[\"{{{AHEf{CEdAGHn}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Cg[\"{{{AHEf{CEdA@n}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Cg[\"{{{AHEf{CEdAA`}}{AHEf{CEdAHOn}}}{{KBj{HOjIAn}}}}\",[]]Bi[\"{{{AHEf{CEdAGJ`}}{AHEf{AGJ`}}}D@n}\",[]]n[\"{{}HOj}\",[]]Ce[\"{{{AHEf{CEdBBNl}}{KB`{JNf}}}{{AHEf{CEdBBNl}}}}\",[]]Ce[\"{{{AHEf{CEdBBNn}}{KB`{JNf}}}{{AHEf{CEdBBNn}}}}\",[]]Bn[\"{{{AHEf{AIAf}}}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]Cd[\"{{{AHEf{CEdAIAh}}NEd}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]Am[\"{{{AHEf{CEdAIAj}}}HOj}\",[]]Al[\"{{{AHEf{CEdI@h}}}HOj}\",[]]Am[\"{{{AHEf{CEdAIAl}}}HOj}\",[]]Al[\"{{{AHEf{CEdI@j}}}HOj}\",[]]Ai[\"{AIAd{{KBn{HOj}}}}\",[]]Bj[\"{{{AHEf{AIAf}}AIEl}{{KBj{HOjIBh}}}}\",[]]Bm[\"{{{AHEf{CEdAIAh}}AIEl}{{KBj{HOjIBh}}}}\",[]]D`[\"{{{AHEf{CEdAIAh}}KBf{KB`{AAJb}}}{{KBj{{KB`{AAJb}}AI@n}}}}\",[]]Ce[\"{{{AHEf{CEdBBNl}}{Nn{BE@d}}}{{AHEf{CEdBBNl}}}}\",[]]Ce[\"{{{AHEf{CEdBBNn}}{Nn{BE@f}}}{{AHEf{CEdBBNn}}}}\",[]]Cf[\"{{{AHEf{CEdBBNl}}{KB`{AAJb}}}{{AHEf{CEdBBNl}}}}\",[]]Cf[\"{{{AHEf{CEdBBNn}}{KB`{AAJb}}}{{AHEf{CEdBBNn}}}}\",[]]Aa[\"{B@OjAICb}\",[]]Aa[\"{B@OlAICb}\",[]]9Bn[\"{{{AHEf{CEdBBNl}}D@n}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}D@n}{{AHEf{CEdBBNn}}}}\",[]]Am[\"{{{AHEf{AIAf}}KDf}HOj}\",[]]o[\"{ND`ND`}\",[]]Bn[\"{{{AHEf{CEdBBNl}}CLd}{{AHEf{CEdBBNl}}}}\",[]]Bn[\"{{{AHEf{CEdBBNn}}CLd}{{AHEf{CEdBBNn}}}}\",[]]3109854Bn[\"{{{AHEf{AIAf}}}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]Bn[\"{{{AHEf{AIAh}}}{{KBj{{AAj{AIEl}}IBh}}}}\",[]]10A`[\"{BEOdKB`}\",[]]Bm[\"{{{AHEf{CEdBBNl}}Nd}{{AHEf{CEdBBNl}}}}\",[]]Bm[\"{{{AHEf{CEdBBNn}}Nd}{{AHEf{CEdBBNn}}}}\",[]]o[\"{{}AICd}\",[]]") \ No newline at end of file diff --git a/pr/580/docs/search.index/path/b5fe16f07d66.js b/pr/580/docs/search.index/path/0c408f7dccc7.js similarity index 96% rename from pr/580/docs/search.index/path/b5fe16f07d66.js rename to pr/580/docs/search.index/path/0c408f7dccc7.js index 9f8bcc580..5ad799bfc 100644 --- a/pr/580/docs/search.index/path/b5fe16f07d66.js +++ b/pr/580/docs/search.index/path/0c408f7dccc7.js @@ -1 +1 @@ -rd_("f[1,\"\"]0Al[10,\"core::ops\",\"core::ops\"]Ce[5,\"clap_builder::util::id\",\"clap_builder::util::id\"]22Ag[10,\"core::ops::arith\"]A`[10,\"core::any\"]Ao[5,\"alloc::sync\",\"alloc::sync\"]Ae[5,\"noq::congestion\"]Ch[5,\"noq_proto::congestion\",\"noq_proto::congestion::bbr\"]Ba[5,\"alloc::boxed\",\"alloc::boxed\"]Cb[10,\"bytes::buf::buf_impl\",\"bytes::buf::buf_impl\"]Ai[5,\"noq_perf\",\"noq_perf\"]i[6,\"noq\"]Ak[6,\"noq_proto\",\"noq_proto\"]Ae[10,\"core::ops::bit\"]Ac[5,\"bench\",\"bench\"]Ba[5,\"perf::client\",\"perf::client\"]Ba[5,\"perf::server\",\"perf::server\"]A`[10,\"core::cmp\"]Ak[5,\"core::pin\",\"core::pin\"]Am[5,\"alloc::vec\",\"alloc::vec\"]Ak[2,\"noq_proto::congestion\"]f[1,\"\"]00m[2,\"noq_udp\"]f[0,\"\"]f[3,\"\"]3333Ak[10,\"clap_builder::derive\"]Bn[10,\"std::os::fd::owned\",\"std::os::fd::owned\"]Af[10,\"core::ops::drop\"]Ad[10,\"core::convert\"]Aa[10,\"core::hash\"]1Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ba[15,\"noq_proto::ProtectedHeader\"]Ak[5,\"std::path\",\"std::path\"]Ae[5,\"noq\",\"noq::path\"]Bi[6,\"core::task::poll\",\"core::task::poll\"]Bb[10,\"core::marker\",\"core::marker\"]i[6,\"noq\"]Ak[6,\"noq_proto\",\"noq_proto\"]2f[1,\"\"]?i[2,\"noq\"]f[3,\"\"]Ag[2,\"noq_proto::config\"]Bd[2,\"noq_proto::connection::streams\"]0Ab[2,\"noq::runtime\"]55Bd[10,\"core::convert\",\"core::convert\"]Ba[5,\"bytes::bytes\",\"bytes::bytes\"]i[5,\"noq\"]Cb[5,\"noq_proto\",\"noq_proto::connection::assembler\"]Ab[10,\"core::clone\"]Bi[6,\"noq_proto::frame\",\"noq_proto::frame\"]Ae[5,\"noq::congestion\"]Cj[5,\"noq_proto::congestion\",\"noq_proto::congestion::cubic\"]A`[10,\"core::fmt\"]Ag[10,\"core::ops::deref\"]Ak[5,\"core::fmt\",\"core::fmt\"]Ab[10,\"core::error\"]Ai[2,\"noq::crypto::rustls\"]Bc[6,\"rustls::error\",\"rustls::error\"]Ao[2,\"noq_proto::crypto::rustls\"]Cm[5,\"noq_proto::transport_error\",\"noq_proto::transport_error\"]Ba[8,\"clap_builder\",\"clap_builder\"]Bi[6,\"arbitrary::error\",\"arbitrary::error\"]Ai[6,\"noq::crypto::rustls\"]Ao[6,\"noq_proto::crypto::rustls\"]Dg[6,\"noq_proto::transport_parameters\",\"noq_proto::transport_parameters\"]Co[6,\"noq_proto::n0_nat_traversal\",\"noq_proto::n0_nat_traversal\"]o[2,\"noq_proto\"]Bg[6,\"noq_proto\",\"noq_proto::connection\"]2Bi[5,\"core::ops::range\",\"core::ops::range\"]Ba[15,\"noq_proto::ProtectedHeader\"]0Bb[10,\"core::marker\",\"core::marker\"]Ba[5,\"bench::stats\",\"bench::stats\"]Ao[5,\"perf::stats\",\"perf::stats\"]Ba[5,\"rustls::quic\",\"rustls::quic\"]Ah[10,\"std::io\",\"std::io\"]f[1,\"\"]f[3,\"\"]Ak[2,\"noq_proto::congestion\"]l[2,\"rustls\"]i[2,\"noq\"]o[2,\"noq_proto\"]1Ak[2,\"noq_proto::congestion\"]f[3,\"\"]Ak[15,\"noq_proto::PathEvent\"]Ak[5,\"noq\",\"noq::connection\"]Ag[10,\"core::ops::arith\"]A`[10,\"arbitrary\"]Al[10,\"tokio::io::async_read\"]Ai[10,\"futures_io::if_std\"]Am[15,\"noq_proto::StreamEvent\"]Ae[5,\"noq::congestion\"]Ch[5,\"noq_proto::congestion\",\"noq_proto::congestion::bbr\"]Ac[10,\"core::borrow\"]Aa[5,\"perf\",\"perf\"]Ak[5,\"criterion\",\"criterion\"]Cb[5,\"noq_proto\",\"noq_proto::connection::datagrams\"]Bl[10,\"noq_proto::coding\",\"noq_proto::coding\"]=0Ak[5,\"core::fmt\",\"core::fmt\"]Ak[5,\"noq_proto\",\"noq_proto\"]i[6,\"noq\"]Bb[6,\"noq_proto\",\"noq_proto::frame\"]Ab[10,\"noq::crypto\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ba[5,\"hdrhistogram\",\"hdrhistogram\"]21A`[10,\"core::cmp\"]Bg[6,\"noq_proto\",\"noq_proto::connection\"]o[2,\"noq_proto\"]Bn[6,\"noq_proto\",\"noq_proto::connection::paths\"]i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::connection::stats\"]Al[6,\"noq\",\"noq::recv_stream\"]Cf[6,\"noq_proto\",\"noq_proto::connection::streams::recv\"]Ak[10,\"futures_core::future\"]Ak[10,\"futures_core::stream\"]Ai[10,\"noq\",\"noq::runtime\"]Bc[5,\"std::net::udp\",\"std::net::udp\"]Ak[10,\"clap_builder::derive\"]Ak[2,\"noq_proto::connection\"]0f[3,\"\"]f[1,\"\"]Ag[2,\"noq_proto::config\"]Em[5,\"clap_builder::parser::matches::arg_matches\",\"clap_builder::parser::matches::arg_matches\"]7Am[10,\"tokio::io::async_write\"]Ai[10,\"futures_io::if_std\"]Da[5,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]Bn[5,\"noq_proto\",\"noq_proto::connection::paths\"]Aa[10,\"equivalent\"]Ak[5,\"noq\",\"noq::connection\"]Bg[5,\"noq::connection\",\"noq::connection\"]1Bg[5,\"noq_proto\",\"noq_proto::connection\"]Af[10,\"noq::congestion\"]Cd[10,\"noq_proto::congestion\",\"noq_proto::congestion\"]A`[10,\"hashbrown\"]6i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::connection::stats\"]B`[10,\"core::future::into_future\"]2Bj[5,\"noq_proto\",\"noq_proto::cid_generator\"]Ag[5,\"std::io\",\"std::io\"]Bi[6,\"noq_proto::frame\",\"noq_proto::frame\"]Bb[6,\"noq_proto\",\"noq_proto::frame\"]Bo[6,\"rustls::msgs::enums\",\"rustls::msgs::enums\"]Bm[8,\"core::num::nonzero\",\"core::num::nonzero\"]Cm[5,\"rustls::error::other_error\",\"rustls::error::other_error\"]A`[10,\"core::cmp\"]Am[5,\"noq\",\"noq::event_stream\"]Da[6,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]Bn[6,\"noq_proto\",\"noq_proto::connection::paths\"]=Bi[5,\"noq_proto\",\"noq_proto::config::qlog\"]Bi[5,\"noq::recv_stream\",\"noq::recv_stream\"]Al[5,\"noq\",\"noq::recv_stream\"]C`[5,\"noq_proto\",\"noq_proto::connection::streams\"]Al[6,\"noq\",\"noq::recv_stream\"]Ai[5,\"noq\",\"noq::incoming\"]Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Bi[5,\"noq::send_stream\",\"noq::send_stream\"]Al[5,\"noq\",\"noq::send_stream\"]5Dc[6,\"rustls_pki_types::server_name\",\"rustls_pki_types::server_name\"]Ce[6,\"core::net::socket_addr\",\"core::net::socket_addr\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]Ak[10,\"clap_builder::derive\"]Ak[5,\"std::time\",\"std::time\"]j[10,\"noq\"]Bd[10,\"noq_proto\",\"noq_proto::config\"]Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]3Bc[10,\"noq_proto\",\"noq_proto::token\"]Ag[5,\"noq_udp\",\"noq_udp\"]Al[6,\"noq\",\"noq::send_stream\"]Cf[6,\"noq_proto\",\"noq_proto::connection::streams::send\"]i[2,\"noq\"]o[2,\"noq_proto\"]10Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Ac[6,\"bench\",\"bench\"]Aa[5,\"bulk\",\"bulk\"]Da[6,\"noq_proto::connection::state\",\"noq_proto::connection::state\"]i[6,\"noq\"]Bc[6,\"noq_proto\",\"noq_proto::config\"]Bc[6,\"rustls::enums\",\"rustls::enums\"]Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ae[5,\"noq::congestion\"]Cj[5,\"noq_proto::congestion\",\"noq_proto::congestion::cubic\"]=i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::config::transport\"]Ae[10,\"tonic::request\"]j[10,\"noq\"]Bj[10,\"noq_proto\",\"noq_proto::config::qlog\"]>An[5,\"noq\",\"noq::runtime::smol\"]o[2,\"noq_proto\"]C`[6,\"noq_proto\",\"noq_proto::connection::streams\"]Ba[5,\"bench::stats\",\"bench::stats\"]Ao[5,\"perf::stats\",\"perf::stats\"]Ci[5,\"ring::error::unspecified\",\"ring::error::unspecified\"]f[3,\"\"]i[2,\"noq\"]Ak[2,\"noq_proto::connection\"]1Co[5,\"rustls::client::client_conn\",\"rustls::client::client_conn\"]Bk[5,\"noq_proto::config\",\"noq_proto::config\"]?Ab[10,\"noq::crypto\"]Bc[5,\"noq_proto\",\"noq_proto::config\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]i[5,\"noq\"]C`[5,\"noq_proto\",\"noq_proto::connection::streams\"]Bo[6,\"noq_proto::endpoint\",\"noq_proto::endpoint\"]i[6,\"noq\"]Be[6,\"noq_proto\",\"noq_proto::endpoint\"]Bk[5,\"noq_proto::shared\",\"noq_proto::shared\"]5Bc[5,\"noq_proto\",\"noq_proto::shared\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]4Bc[6,\"noq_proto\",\"noq_proto::shared\"]Ag[6,\"noq_udp\",\"noq_udp\"]Bb[10,\"core::iter::traits::collect\"]Bm[8,\"core::num::nonzero\",\"core::num::nonzero\"];Bb[5,\"noq_proto\",\"noq_proto::token\"]Ak[15,\"noq_proto::PathEvent\"]Ak[5,\"noq\",\"noq::connection\"]1Da[5,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]Bn[5,\"noq_proto\",\"noq_proto::connection::paths\"]2Co[5,\"rustls::server::server_conn\",\"rustls::server::server_conn\"]Bk[5,\"noq_proto::config\",\"noq_proto::config\"]i[5,\"noq\"]Ab[10,\"noq::crypto\"]Bc[5,\"noq_proto\",\"noq_proto::config\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ce[5,\"core::net::socket_addr\",\"core::net::socket_addr\"]0Al[6,\"noq\",\"noq::send_stream\"]Ao[5,\"noq\",\"noq::runtime::tokio\"]Cg[5,\"arbitrary::unstructured\",\"arbitrary::unstructured\"]i[2,\"noq\"]j[2,\"perf\"]9Bl[5,\"noq_proto\",\"noq_proto::bloom_token_log\"]Ab[10,\"core::clone\"]Be[6,\"noq_proto\",\"noq_proto::endpoint\"]Bc[5,\"noq_proto\",\"noq_proto::shared\"]Ai[5,\"noq\",\"noq::endpoint\"]Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]Bc[6,\"rustls::enums\",\"rustls::enums\"]Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Ae[5,\"noq::congestion\"]Cm[5,\"noq_proto::congestion\",\"noq_proto::congestion::new_reno\"]Bi[5,\"core::num::error\",\"core::num::error\"]Bc[5,\"noq_proto\",\"noq_proto::packet\"]Ec[5,\"clap_builder::builder::possible_value\",\"clap_builder::builder::possible_value\"]Bi[6,\"rustls_pki_types\",\"rustls_pki_types\"]Cf[6,\"noq_proto\",\"noq_proto::connection::streams::recv\"]Cg[5,\"rustls::webpki::anchors\",\"rustls::webpki::anchors\"]i[5,\"noq\"]Bc[5,\"noq_proto\",\"noq_proto::config\"]Bk[5,\"noq_proto::coding\",\"noq_proto::coding\"]o[2,\"noq_proto\"]0f[3,\"\"]Ai[10,\"noq\",\"noq::runtime\"]Bi[5,\"rustls_pki_types\",\"rustls_pki_types\"]Cc[6,\"noq_proto::connection\",\"noq_proto::connection\"]Bg[6,\"noq_proto\",\"noq_proto::connection\"]Ak[10,\"clap_builder::derive\"]Ag[15,\"noq_proto::Event\"]:91Ai[5,\"noq\",\"noq::incoming\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]Bc[6,\"rustls::error\",\"rustls::error\"]=Bb[5,\"noq_proto\",\"noq_proto::token\"]1Al[6,\"noq\",\"noq::recv_stream\"]0C`[5,\"noq_proto\",\"noq_proto::connection::streams\"]Ba[5,\"bench::stats\",\"bench::stats\"]o[5,\"noq_proto\"]Al[5,\"noq_udp\",\"noq_udp::imp\"]Ae[5,\"noq\",\"noq::path\"]i[5,\"noq\"]9i[6,\"noq\"]>Bc[5,\"noq_proto\",\"noq_proto::shared\"]2Bn[5,\"noq_proto\",\"noq_proto::connection::stats\"]Ba[5,\"rustls::rand\",\"rustls::rand\"]Ao[5,\"perf::stats\",\"perf::stats\"]o[2,\"noq_proto\"]Bc[6,\"noq_proto\",\"noq_proto::packet\"]7Bi[5,\"noq_proto\",\"noq_proto::config::qlog\"]Bc[15,\"noq_proto::PathAbandonReason\"]Bc[6,\"rustls::enums\",\"rustls::enums\"]Ak[5,\"std::time\",\"std::time\"];Bb[5,\"noq_proto\",\"noq_proto::token\"]Da[5,\"noq_proto::config::transport\",\"noq_proto::config::transport\"]=Bn[5,\"noq_proto\",\"noq_proto::config::transport\"]Bi[5,\"core::num::error\",\"core::num::error\"]Ak[5,\"noq\",\"noq::connection\"]:Ae[5,\"noq\",\"noq::path\"]i[5,\"noq\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]Bc[6,\"rustls::error\",\"rustls::error\"]Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Bo[5,\"noq_proto::endpoint\",\"noq_proto::endpoint\"]122Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]106Bo[5,\"noq_proto\",\"noq_proto::token_memory_cache\"]Ba[15,\"noq_proto::ProtectedHeader\"]o[2,\"noq_proto\"]Bc[15,\"noq_proto::PathAbandonReason\"]Af[10,\"noq::congestion\"]Cd[10,\"noq_proto::congestion\",\"noq_proto::congestion\"]Ae[5,\"noq::congestion\"]Cc[5,\"noq_proto::congestion\",\"noq_proto::congestion\"]Ab[10,\"noq::crypto\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]j[10,\"noq\"]Bh[10,\"noq_proto\",\"noq_proto::connection\"]9Bc[6,\"noq_proto\",\"noq_proto::packet\"]:Bn[6,\"noq_proto\",\"noq_proto::connection::paths\"]Ak[6,\"noq\",\"noq::connection\"]Cb[6,\"noq_proto\",\"noq_proto::connection::datagrams\"]f[3,\"\"]i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::config::transport\"]Bd[10,\"noq_proto\",\"noq_proto::packet\"]21Bi[5,\"rustls_pki_types\",\"rustls_pki_types\"]Be[5,\"rustls::verify\",\"rustls::verify\"]Ae[10,\"rustls::verify\"]Da[6,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]:6o[5,\"noq_proto\"]Bc[15,\"noq_proto::PacketDecodeError\"]Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]o[2,\"noq_proto\"]Aa[6,\"perf\",\"perf\"]Am[5,\"noq\",\"noq::event_stream\"]Dg[5,\"noq_proto::transport_parameters\",\"noq_proto::transport_parameters\"]Al[5,\"noq\",\"noq::recv_stream\"]Bh[2,\"noq_proto::connection::send_buffer\"]An[2,\"noq_proto::bench_exports\"]Ba[15,\"noq::crypto::rustls::Error\"]Bg[15,\"noq_proto::crypto::rustls::Error\"]Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]8Be[6,\"rustls::suites\",\"rustls::suites\"]i[5,\"noq\"]Bc[5,\"noq_proto\",\"noq_proto::varint\"]Be[6,\"rustls::webpki\",\"rustls::webpki\"]Ak[5,\"noq\",\"noq::connection\"]?j[10,\"noq\"]Bk[10,\"noq_proto\",\"noq_proto::cid_generator\"]Be[5,\"rustls::verify\",\"rustls::verify\"]6Bc[5,\"noq_proto\",\"noq_proto::config\"]Bg[5,\"noq_proto\",\"noq_proto::connection\"]Bc[5,\"noq_proto\",\"noq_proto::packet\"]Ao[5,\"certificate\",\"certificate\"]Bc[6,\"rustls::error\",\"rustls::error\"]5Bm[5,\"perf::noprotection\",\"perf::noprotection\"]01Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ce[5,\"rustls::crypto::cipher\",\"rustls::crypto::cipher\"]Bj[5,\"noq_proto\",\"noq_proto::cid_generator\"]07Ba[15,\"noq::crypto::rustls::Error\"]Bg[15,\"noq_proto::crypto::rustls::Error\"]") \ No newline at end of file +rd_("f[1,\"\"]0Al[10,\"core::ops\",\"core::ops\"]Ce[5,\"clap_builder::util::id\",\"clap_builder::util::id\"]22Ag[10,\"core::ops::arith\"]A`[10,\"core::any\"]Ao[5,\"alloc::sync\",\"alloc::sync\"]Ae[5,\"noq::congestion\"]Ch[5,\"noq_proto::congestion\",\"noq_proto::congestion::bbr\"]Ba[5,\"alloc::boxed\",\"alloc::boxed\"]Cb[10,\"bytes::buf::buf_impl\",\"bytes::buf::buf_impl\"]Ai[5,\"noq_perf\",\"noq_perf\"]i[6,\"noq\"]Ak[6,\"noq_proto\",\"noq_proto\"]Ae[10,\"core::ops::bit\"]Ac[5,\"bench\",\"bench\"]Ba[5,\"perf::client\",\"perf::client\"]Ba[5,\"perf::server\",\"perf::server\"]A`[10,\"core::cmp\"]Ak[5,\"core::pin\",\"core::pin\"]Am[5,\"alloc::vec\",\"alloc::vec\"]Ak[2,\"noq_proto::congestion\"]f[1,\"\"]00m[2,\"noq_udp\"]f[0,\"\"]f[3,\"\"]3333Ak[10,\"clap_builder::derive\"]Bn[10,\"std::os::fd::owned\",\"std::os::fd::owned\"]Af[10,\"core::ops::drop\"]Ad[10,\"core::convert\"]Aa[10,\"core::hash\"]1Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ba[15,\"noq_proto::ProtectedHeader\"]Ak[5,\"std::path\",\"std::path\"]Ae[5,\"noq\",\"noq::path\"]Bi[6,\"core::task::poll\",\"core::task::poll\"]Bb[10,\"core::marker\",\"core::marker\"]i[6,\"noq\"]Ak[6,\"noq_proto\",\"noq_proto\"]2f[1,\"\"]?i[2,\"noq\"]f[3,\"\"]Ag[2,\"noq_proto::config\"]Bd[2,\"noq_proto::connection::streams\"]0Ab[2,\"noq::runtime\"]55Bd[10,\"core::convert\",\"core::convert\"]Ba[5,\"bytes::bytes\",\"bytes::bytes\"]i[5,\"noq\"]Cb[5,\"noq_proto\",\"noq_proto::connection::assembler\"]Ab[10,\"core::clone\"]Bi[6,\"noq_proto::frame\",\"noq_proto::frame\"]Ae[5,\"noq::congestion\"]Cj[5,\"noq_proto::congestion\",\"noq_proto::congestion::cubic\"]A`[10,\"core::fmt\"]Ag[10,\"core::ops::deref\"]Ak[5,\"core::fmt\",\"core::fmt\"]Ab[10,\"core::error\"]Ai[2,\"noq::crypto::rustls\"]Ao[2,\"noq_proto::crypto::rustls\"]Cm[5,\"noq_proto::transport_error\",\"noq_proto::transport_error\"]Bc[6,\"rustls::error\",\"rustls::error\"]Ba[8,\"clap_builder\",\"clap_builder\"]Bi[6,\"arbitrary::error\",\"arbitrary::error\"]Ai[6,\"noq::crypto::rustls\"]Ao[6,\"noq_proto::crypto::rustls\"]Dg[6,\"noq_proto::transport_parameters\",\"noq_proto::transport_parameters\"]Co[6,\"noq_proto::n0_nat_traversal\",\"noq_proto::n0_nat_traversal\"]o[2,\"noq_proto\"]Bg[6,\"noq_proto\",\"noq_proto::connection\"]2Bi[5,\"core::ops::range\",\"core::ops::range\"]Ba[15,\"noq_proto::ProtectedHeader\"]0Bb[10,\"core::marker\",\"core::marker\"]Ba[5,\"bench::stats\",\"bench::stats\"]Ao[5,\"perf::stats\",\"perf::stats\"]Ba[5,\"rustls::quic\",\"rustls::quic\"]Ah[10,\"std::io\",\"std::io\"]f[1,\"\"]f[3,\"\"]Ak[2,\"noq_proto::congestion\"]l[2,\"rustls\"]i[2,\"noq\"]o[2,\"noq_proto\"]1Ak[2,\"noq_proto::congestion\"]f[3,\"\"]Ak[15,\"noq_proto::PathEvent\"]Ak[5,\"noq\",\"noq::connection\"]Ag[10,\"core::ops::arith\"]A`[10,\"arbitrary\"]Al[10,\"tokio::io::async_read\"]Ai[10,\"futures_io::if_std\"]Am[15,\"noq_proto::StreamEvent\"]Ae[5,\"noq::congestion\"]Ch[5,\"noq_proto::congestion\",\"noq_proto::congestion::bbr\"]Ac[10,\"core::borrow\"]Aa[5,\"perf\",\"perf\"]Ak[5,\"criterion\",\"criterion\"]Cb[5,\"noq_proto\",\"noq_proto::connection::datagrams\"]Bl[10,\"noq_proto::coding\",\"noq_proto::coding\"]=0Ak[5,\"core::fmt\",\"core::fmt\"]Ak[5,\"noq_proto\",\"noq_proto\"]i[6,\"noq\"]Bb[6,\"noq_proto\",\"noq_proto::frame\"]Ab[10,\"noq::crypto\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ba[5,\"hdrhistogram\",\"hdrhistogram\"]21A`[10,\"core::cmp\"]Bg[6,\"noq_proto\",\"noq_proto::connection\"]o[2,\"noq_proto\"]Bn[6,\"noq_proto\",\"noq_proto::connection::paths\"]i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::connection::stats\"]Al[6,\"noq\",\"noq::recv_stream\"]Cf[6,\"noq_proto\",\"noq_proto::connection::streams::recv\"]Ak[10,\"futures_core::future\"]Ak[10,\"futures_core::stream\"]Ai[10,\"noq\",\"noq::runtime\"]Bc[5,\"std::net::udp\",\"std::net::udp\"]Ak[10,\"clap_builder::derive\"]Ak[2,\"noq_proto::connection\"]0f[3,\"\"]f[1,\"\"]Ag[2,\"noq_proto::config\"]Em[5,\"clap_builder::parser::matches::arg_matches\",\"clap_builder::parser::matches::arg_matches\"]7Am[10,\"tokio::io::async_write\"]Ai[10,\"futures_io::if_std\"]Da[5,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]Bn[5,\"noq_proto\",\"noq_proto::connection::paths\"]Aa[10,\"equivalent\"]Ak[5,\"noq\",\"noq::connection\"]Bg[5,\"noq::connection\",\"noq::connection\"]1Bg[5,\"noq_proto\",\"noq_proto::connection\"]Af[10,\"noq::congestion\"]Cd[10,\"noq_proto::congestion\",\"noq_proto::congestion\"]A`[10,\"hashbrown\"]6i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::connection::stats\"]B`[10,\"core::future::into_future\"]2Bj[5,\"noq_proto\",\"noq_proto::cid_generator\"]Ag[5,\"std::io\",\"std::io\"]Bi[6,\"noq_proto::frame\",\"noq_proto::frame\"]Bb[6,\"noq_proto\",\"noq_proto::frame\"]Bo[6,\"rustls::msgs::enums\",\"rustls::msgs::enums\"]Bm[8,\"core::num::nonzero\",\"core::num::nonzero\"]Cm[5,\"rustls::error::other_error\",\"rustls::error::other_error\"]A`[10,\"core::cmp\"]Am[5,\"noq\",\"noq::event_stream\"]Da[6,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]Bn[6,\"noq_proto\",\"noq_proto::connection::paths\"]=Bi[5,\"noq_proto\",\"noq_proto::config::qlog\"]Bi[5,\"noq::recv_stream\",\"noq::recv_stream\"]Al[5,\"noq\",\"noq::recv_stream\"]C`[5,\"noq_proto\",\"noq_proto::connection::streams\"]Al[6,\"noq\",\"noq::recv_stream\"]Ai[5,\"noq\",\"noq::incoming\"]Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Bi[5,\"noq::send_stream\",\"noq::send_stream\"]Al[5,\"noq\",\"noq::send_stream\"]5Dc[6,\"rustls_pki_types::server_name\",\"rustls_pki_types::server_name\"]Ce[6,\"core::net::socket_addr\",\"core::net::socket_addr\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]Ak[10,\"clap_builder::derive\"]Ak[5,\"std::time\",\"std::time\"]j[10,\"noq\"]Bd[10,\"noq_proto\",\"noq_proto::config\"]Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]3Bc[10,\"noq_proto\",\"noq_proto::token\"]Ag[5,\"noq_udp\",\"noq_udp\"]Al[6,\"noq\",\"noq::send_stream\"]Cf[6,\"noq_proto\",\"noq_proto::connection::streams::send\"]i[2,\"noq\"]o[2,\"noq_proto\"]10Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Ac[6,\"bench\",\"bench\"]Aa[5,\"bulk\",\"bulk\"]Da[6,\"noq_proto::connection::state\",\"noq_proto::connection::state\"]i[6,\"noq\"]Bc[6,\"noq_proto\",\"noq_proto::config\"]Bc[6,\"rustls::enums\",\"rustls::enums\"]Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ae[5,\"noq::congestion\"]Cj[5,\"noq_proto::congestion\",\"noq_proto::congestion::cubic\"]=i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::config::transport\"]Ae[10,\"tonic::request\"]j[10,\"noq\"]Bj[10,\"noq_proto\",\"noq_proto::config::qlog\"]>An[5,\"noq\",\"noq::runtime::smol\"]o[2,\"noq_proto\"]C`[6,\"noq_proto\",\"noq_proto::connection::streams\"]Ba[5,\"bench::stats\",\"bench::stats\"]Ao[5,\"perf::stats\",\"perf::stats\"]Ci[5,\"ring::error::unspecified\",\"ring::error::unspecified\"]f[3,\"\"]i[2,\"noq\"]Ak[2,\"noq_proto::connection\"]1Bk[5,\"noq_proto::config\",\"noq_proto::config\"]Co[5,\"rustls::client::client_conn\",\"rustls::client::client_conn\"]?Ab[10,\"noq::crypto\"]Bc[5,\"noq_proto\",\"noq_proto::config\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]i[5,\"noq\"]C`[5,\"noq_proto\",\"noq_proto::connection::streams\"]Bo[6,\"noq_proto::endpoint\",\"noq_proto::endpoint\"]i[6,\"noq\"]Be[6,\"noq_proto\",\"noq_proto::endpoint\"]Bk[5,\"noq_proto::shared\",\"noq_proto::shared\"]5Bc[5,\"noq_proto\",\"noq_proto::shared\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]4Bc[6,\"noq_proto\",\"noq_proto::shared\"]Ag[6,\"noq_udp\",\"noq_udp\"]Bb[10,\"core::iter::traits::collect\"]Bm[8,\"core::num::nonzero\",\"core::num::nonzero\"];Bb[5,\"noq_proto\",\"noq_proto::token\"]Ak[15,\"noq_proto::PathEvent\"]Ak[5,\"noq\",\"noq::connection\"]1Da[5,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]Bn[5,\"noq_proto\",\"noq_proto::connection::paths\"]2Bk[5,\"noq_proto::config\",\"noq_proto::config\"]Co[5,\"rustls::server::server_conn\",\"rustls::server::server_conn\"]i[5,\"noq\"]Ab[10,\"noq::crypto\"]Bc[5,\"noq_proto\",\"noq_proto::config\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ce[5,\"core::net::socket_addr\",\"core::net::socket_addr\"]0Al[6,\"noq\",\"noq::send_stream\"]Ao[5,\"noq\",\"noq::runtime::tokio\"]Cg[5,\"arbitrary::unstructured\",\"arbitrary::unstructured\"]i[2,\"noq\"]j[2,\"perf\"]9Bl[5,\"noq_proto\",\"noq_proto::bloom_token_log\"]Ab[10,\"core::clone\"]Be[6,\"noq_proto\",\"noq_proto::endpoint\"]Bc[5,\"noq_proto\",\"noq_proto::shared\"]Ai[5,\"noq\",\"noq::endpoint\"]Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]Bc[6,\"rustls::enums\",\"rustls::enums\"]Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Ae[5,\"noq::congestion\"]Cm[5,\"noq_proto::congestion\",\"noq_proto::congestion::new_reno\"]Bi[5,\"core::num::error\",\"core::num::error\"]Bc[5,\"noq_proto\",\"noq_proto::packet\"]Ec[5,\"clap_builder::builder::possible_value\",\"clap_builder::builder::possible_value\"]Bi[6,\"rustls_pki_types\",\"rustls_pki_types\"]Cf[6,\"noq_proto\",\"noq_proto::connection::streams::recv\"]Cg[5,\"rustls::webpki::anchors\",\"rustls::webpki::anchors\"]i[5,\"noq\"]Bc[5,\"noq_proto\",\"noq_proto::config\"]Bk[5,\"noq_proto::coding\",\"noq_proto::coding\"]o[2,\"noq_proto\"]0f[3,\"\"]Ai[10,\"noq\",\"noq::runtime\"]Bi[5,\"rustls_pki_types\",\"rustls_pki_types\"]Cc[6,\"noq_proto::connection\",\"noq_proto::connection\"]Bg[6,\"noq_proto\",\"noq_proto::connection\"]Ak[10,\"clap_builder::derive\"]Ag[15,\"noq_proto::Event\"]:91Ai[5,\"noq\",\"noq::incoming\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]Bc[6,\"rustls::error\",\"rustls::error\"]=Bb[5,\"noq_proto\",\"noq_proto::token\"]1Al[6,\"noq\",\"noq::recv_stream\"]0C`[5,\"noq_proto\",\"noq_proto::connection::streams\"]Ba[5,\"bench::stats\",\"bench::stats\"]o[5,\"noq_proto\"]Al[5,\"noq_udp\",\"noq_udp::imp\"]Ae[5,\"noq\",\"noq::path\"]i[5,\"noq\"]9i[6,\"noq\"]>Bc[5,\"noq_proto\",\"noq_proto::shared\"]2Bn[5,\"noq_proto\",\"noq_proto::connection::stats\"]Ba[5,\"rustls::rand\",\"rustls::rand\"]Ao[5,\"perf::stats\",\"perf::stats\"]o[2,\"noq_proto\"]Bc[6,\"noq_proto\",\"noq_proto::packet\"]7Bi[5,\"noq_proto\",\"noq_proto::config::qlog\"]Bc[15,\"noq_proto::PathAbandonReason\"]Bc[6,\"rustls::enums\",\"rustls::enums\"]Ak[5,\"std::time\",\"std::time\"];Bb[5,\"noq_proto\",\"noq_proto::token\"]Da[5,\"noq_proto::config::transport\",\"noq_proto::config::transport\"]=Bn[5,\"noq_proto\",\"noq_proto::config::transport\"]Bi[5,\"core::num::error\",\"core::num::error\"]Ak[5,\"noq\",\"noq::connection\"]:Ae[5,\"noq\",\"noq::path\"]i[5,\"noq\"]Bb[5,\"noq_proto\",\"noq_proto::frame\"]Bc[6,\"rustls::error\",\"rustls::error\"]Be[5,\"noq_proto\",\"noq_proto::endpoint\"]Bo[5,\"noq_proto::endpoint\",\"noq_proto::endpoint\"]122Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]106Bo[5,\"noq_proto\",\"noq_proto::token_memory_cache\"]Ba[15,\"noq_proto::ProtectedHeader\"]o[2,\"noq_proto\"]Bc[15,\"noq_proto::PathAbandonReason\"]Af[10,\"noq::congestion\"]Cd[10,\"noq_proto::congestion\",\"noq_proto::congestion\"]Ae[5,\"noq::congestion\"]Cc[5,\"noq_proto::congestion\",\"noq_proto::congestion\"]Ab[10,\"noq::crypto\"]Bl[10,\"noq_proto::crypto\",\"noq_proto::crypto\"]j[10,\"noq\"]Bh[10,\"noq_proto\",\"noq_proto::connection\"]9Bc[6,\"noq_proto\",\"noq_proto::packet\"]:Bn[6,\"noq_proto\",\"noq_proto::connection::paths\"]Ak[6,\"noq\",\"noq::connection\"]Cb[6,\"noq_proto\",\"noq_proto::connection::datagrams\"]f[3,\"\"]i[5,\"noq\"]Bn[5,\"noq_proto\",\"noq_proto::config::transport\"]Bd[10,\"noq_proto\",\"noq_proto::packet\"]21Bi[5,\"rustls_pki_types\",\"rustls_pki_types\"]Be[5,\"rustls::verify\",\"rustls::verify\"]Ae[10,\"rustls::verify\"]Da[6,\"noq_proto::connection::paths\",\"noq_proto::connection::paths\"]:6o[5,\"noq_proto\"]Bc[15,\"noq_proto::PacketDecodeError\"]Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]o[2,\"noq_proto\"]Aa[6,\"perf\",\"perf\"]Am[5,\"noq\",\"noq::event_stream\"]Dg[5,\"noq_proto::transport_parameters\",\"noq_proto::transport_parameters\"]Al[5,\"noq\",\"noq::recv_stream\"]Bh[2,\"noq_proto::connection::send_buffer\"]An[2,\"noq_proto::bench_exports\"]Ba[15,\"noq::crypto::rustls::Error\"]Bg[15,\"noq_proto::crypto::rustls::Error\"]Ai[5,\"noq::crypto::rustls\"]Ck[5,\"noq_proto::crypto::rustls\",\"noq_proto::crypto::rustls\"]8Be[6,\"rustls::suites\",\"rustls::suites\"]i[5,\"noq\"]Bc[5,\"noq_proto\",\"noq_proto::varint\"]Be[6,\"rustls::webpki\",\"rustls::webpki\"]Ak[5,\"noq\",\"noq::connection\"]?j[10,\"noq\"]Bk[10,\"noq_proto\",\"noq_proto::cid_generator\"]Be[5,\"rustls::verify\",\"rustls::verify\"]6Bc[5,\"noq_proto\",\"noq_proto::config\"]Bg[5,\"noq_proto\",\"noq_proto::connection\"]Bc[5,\"noq_proto\",\"noq_proto::packet\"]Ao[5,\"certificate\",\"certificate\"]Bc[6,\"rustls::error\",\"rustls::error\"]5Bm[5,\"perf::noprotection\",\"perf::noprotection\"]01Aa[5,\"noq::crypto\"]Bk[5,\"noq_proto::crypto\",\"noq_proto::crypto\"]Ce[5,\"rustls::crypto::cipher\",\"rustls::crypto::cipher\"]Bj[5,\"noq_proto\",\"noq_proto::cid_generator\"]07Ba[15,\"noq::crypto::rustls::Error\"]Bg[15,\"noq_proto::crypto::rustls::Error\"]") \ No newline at end of file diff --git a/pr/580/docs/search.index/root.js b/pr/580/docs/search.index/root.js index 973d62e46..7d3da02b8 100644 --- a/pr/580/docs/search.index/root.js +++ b/pr/580/docs/search.index/root.js @@ -1 +1 @@ -rr_('{"normalizedName":{"I":"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","N":"ADBg","E":"OjAAAAAAAAA=","H":"EsWEWAg0"},"crateNames":{"N":"j","E":"OjAAAAAAAAA=","H":"JFDJy0NX"},"name":{"N":"ADBg","E":"OjAAAAAAAAA=","H":"+RVafadn"},"path":{"N":"BAo","E":"OzAAAAEAAAcSugACAAQACQAAAAsAZQByAAEAeQAAAH8ABACKAAEAjQAFAJQAGwCyAOsAoAEIAKoBJADQAQ4A4wEAAOcBBQDzAQEA9wECAPsBAAAAAgUACAI8AkYEAABIBBIAXAQCAGAEAwBlBAoAcQQJAIUEAACXBAIAmwQDAKAEAACiBAAApwQAAKkEAACsBJoASAUBAEwFCABWBQgAYAUCAGYFCABzBQIAdwUEAH8FBQCNBQEAmQUCAJ0FAgCkBe0AkwYEAJkGAACbBgAAngY8ANwGDwDuBgMA8wYDAPgGGAASBwwAJAcBACgHAAAtBwEAMQcAADMHAwA/BwAAQQcCAEYHAABJBwAATAd0AMIHBQDKBwYA0gfzAMgIAADKCAEAzggBANUIAADbCAUA5QgAAOcIAADqCAIA8AgBAPkIBQABCR0AIAkUADcJgQK6CwAAwQsBAMcLAADMCwAA0gsAANYLAwDiCwAA6gsJAPULBwD+CxkAGQwQACsMTQB6DAMAggwAAIQMAQCcDAEAugx3ATQOAgA5Dh0BWA8AAGMPAQBpDwMAbw8BAHIPAQB1DwEAfA8DAIEPQQDEDwIAyQ8WAOYPAQDpDwIA9A8BAPkPBAD/DwIABhAEAA0QAAAcEBIAMBAgAFIQHgBzEAMAexAAAH4QAQCBEAEAhBAHAJAQAQCVEAEAmxADAKAQAACiEAIAphA3AOQQBQDtEAEA8hAFAPsQBQAFEQEAChFQAFwRAABgEQAAZREBAGgRAQBvEQAAeBEBAHsRAwCAEaEAIxIAACUSAAAoEgEAKxIAAC4SAwAzEgoAPxIBAEcSAgBLEhgAZRIXAH4SAgCHEgEAkRIRAKQSAgCpEgMArhIHALgSAwC9EgUAxxICAM0SAADPEgEA0hIbAO8SAgD0EgQA+xIfAB0TCwArEwQAMxMAADkTJQBgEwQAaBMFAHATGgCMEwIAkRMQAKQTFwC+EwoAzBMFANMTFADpEwMA7hMXAAkUHQA=","H":"tf4W8H1m"},"entry":{"N":"ACAo","E":"OjAAAAEAAAAAAAcBEAAAAAAAAQAHAAgACgBxAHQAdQB2AHoAewCEAIgAiQCMAJMAsACxAJ4BnwGpAd8B4AHhAeIB5AHlAeYB7QHuAe8B8gH1AfoB/AH/AQYCRQRbBF8EZARwBHsEfAR9BH4EgQSCBIYEhwSIBIkEigSLBIwEjQSOBI8ElASaBJ8EoQSjBKYEqASqBEcFSgVLBVUFXwVjBWQFZQVvBXAFcQVyBXwFfQWFBYYFhwWIBYsFjAWPBZAFkwWUBZUFlgWXBZwFoAWhBZIGmAaaBpwGnQbbBuwG7QbyBvcGEQcfByAHIQciByMHKQcsBzcHOAc5BzoHPgdFB0cHSAfIB8kH0QfHCM0I0AjRCNQI2AjZCOMI5AjtCPcI+Aj/CAAJHwk1CbkLvAu9C74LvwvAC8ULyAvLC84L1QvcC94L5QvmC+gL6Qv0C/0LKgx5DH4MgAyBDIMMhwyJDI4MjwySDJUMlgyYDJkMmgybDJ8MowypDKwMrQyvDLAMMg4zDjcOOA5bD14PaA93D3sPww/HD8gP4A/hD+0P8A/+DwIQBRAMEA4QERASEBcQGBAbEC8QURB3EIAQjhCSEJMQlxCfEKEQ3xDgEOIQ4xDsEPEQ+hBkEWoRbhFwEXERdBF3EX8RJxIsEjISPhJKEmQSfRKLEo0SvBLDEsQSxRLMEu4SGxMcEykTKhM0EzcTXxNnE6IToxPJE9ITBxQIFA==","H":"K9SQ4NQp"},"desc":{"N":"FNl","E":"OzAAAAEAADoNhgEAAAEABwABAAoAVgBvAAAAcQAFAHkAAwCEAAEAhwACAIwAGwCwAOsAngEBAKkBAgDMAQIA0AEBANUBAQDYAQAA3QEJAO0BAgDyAQAA9QEAAPgBAgD8AQAA/wEAAAICAQAGAgEADAIGACoCAAA6AgAAPAICAEECAABGAgIASgIAAFECBABZAgAAYQIAAGMCAQBqAgAAbwIAAHECAAB0AgAAdgIAAHsCAACBAgAAjQIAAJICBQCZAgQAtgIEAL8CAADTAgAA2AIAAN0CAADjAgEA6wIAAPECAAD6AgAA/wIAAAEDAAAJAwAADgMAABMDAAAYAwkAIwMAADADAAA/AxQAOwQEAEEEAABFBAAARwQAAEkEAABLBAAATQQMAFsEAABfBAAAYQQAAGQEAABtBAAAcAQAAHYEAQB5BAUAgQQBAIUECgCUBAAAmgQAAJ8EAAChBAAAowQFAKoEAQCtBAIAsQQDALwEhgBHBQQAVAUBAFcFAgBfBQAAYQUFAGwFAABvBQMAdwUDAHwFAQCDBQUAiwUBAI8FAQCTBQQAnAUBAJ8FAgCoBeYAkgYBAJUGAQCYBgAAmgYAAJwGAQCgBgAApAYAAKcGCACxBgEAtQYLAMQGAADLBgEAzgYBANQGAgDYBgMA7AYCAPAGAADyBgEA9QYLAAYHAQARBwAAFQcCABkHAgAfBwQAKQcAACwHAgAxBwAAMwcHAD4HAABFBwAARwcBAE8HAABSBxkAdAcwAKYHAQC4BwIAvAcCAMMHAADFBwAAyAcBANEHAADTBwAA1wfmAMcIBADNCAAA0AgBANQIAADYCAEA3wgBAOMIAQDtCAAA9wgBAPwIBAAPCQEAGQkEAB8JAAAjCQIAJwkCADIJAQA1CQIAQwm6AAAKAAACCk0AUwpgAbgLAQC8CwQAxQsBAMgLAADLCwAAzgsAANALAQDVCwAA1wsBANwLAADeCwAA5QsBAOgLAQDrCwkA9gsCAPoLAwABDAEACQwAABQMAwAcDAEAHwwEACUMAAAoDAIALgwAADAMBQA3DD4AeQwAAH4MAACADAEAgwwAAIcMAACJDAAAjgwBAJIMAACVDAEAmAwFAJ8MAACjDAAAqQwAAKwMBAC7DAUAwwxtATIOAQA3DvcAQg8AAEgPAwBNDwEAVQ8BAFgPAwBeDwAAYw8BAGgPAABrDwEAbw8EAHUPAgB5DwIAfQ8DAJEPDwCiDwEApQ8AAKcPAQCrDxMAww8AAMcPAQDdDwEA4A8BAO0PAADwDwAA8w8AAPwPAwACEAAABRAAAAcQAwAMEAAADhAAABEQAQAXEAEAGxAFACMQAQAoEAIALBAAAC4QAQA2EAEAPRABAEEQBABQEAIAVRABAFoQAQBlEAMAdxAAAH4QAgCHEAMAjhAAAJAQAwCVEAIAnBABAJ8QAAChEAAApRAAAKcQAgCvEAIAsxACALcQBgDDEAAAzxABANMQCQDfEAEA4hABAOwQAADxEAAA9BABAPoQAAD9EAMABBEAAAwRAAAOEQAAEBEAABURAAAXEQMAHBEAAB4RAAAgEQAAIxEAACURAAAnEQAAKxEAAC4RAAAwEQAAMhEAADYRAAA4EQIAPhEAAEARAABNEQEAVREAAFgRAgBcEQAAZBECAGgRAgBuEQAAcBEBAHQRAAB3EQAAfxGHAA0SBAATEgAAGRIBABwSAQAfEgAAIRIAACMSAAAlEgAAJxIAACwSAAAyEgAAOBIGAEoSAABNEgEAUBICAFUSAQBZEgUAYhICAGwSAABxEgAAfRIAAIsSAACNEgAAkRIDAJwSAwCjEgEAuRIAALwSAgDDEgIAxxICAMwSAADSEgQA4RIBAO4SAQDyEgAA9BIDAP8SBAAHEwAACRMAABITAgAWEwIAGxMBAB4TAAAhEwMAKRMBADQTAAA3EwAAPRMGAFMTAABWEwEAXRMCAGETAABkEwAAZxMAAHwTAQCNEwEAkBMBAJQTAACWEwAAnBMDAKITAQCqEwQAshMFALwTAQDGEwAAyRMAANITAADXEwMA5BMAAPITBQD5EwAA/xMAAAEUAQAHFAEAERQAABUUAAA=","H":"qFWkrVd+"},"function":{"N":"A@Jc","E":"OzAAAAEAAIMDWAAAAAoAcQAbAJMAAACwAAEAngEBAKkBAADPAQAA3wEiAAYCAQBFBAAARwQAAFsEAABfBAAAZAQAAHAEAAB7BC0AqgQBAEcFAABKBQEAVQUAAF8FAABjBQMAbAUAAG8FAwB2BS0AkgYAAJUGAACYBgIAnAYCAKIGAADbBgAA7AYGAPUGAAD3BgAAEQcAABwHMADBBwAAyAcBANEHAADGCDMA/wgBAB8JAAA1CQEAuQswAPQLAAD9CwAAGAwAACoMAAB5DAAAfgwDAIMMNgAyDgMANw4BAFcPAABZDxgAdA8HAIAPAADDDwAAxw8BAN0PIQAAEBsALxAAAFEQAQBvECsAnxACAKUQAADZEDAAWhElACISKQBkEgEAexIbAKMSAAClEhMAuhIXAO4SAADyEgsAGxMCACUTEwBfEwAAYhMAAGUTCgCBEw8AohMFALoTAwDHEwsA3hMAAOgTBQAGFAQA","H":"27yx6+zu"},"type":{"N":"AJl","E":"OzAAAAEAAHoSnAACAAQACQAAAAsAZQByAAIAeQAAAH8ABQCIAAAAigABAI0AIgCyAOsAnwEJAKoBNADjAQEA5gEIAPMBAQD3AQIA+wEAAAACBQAHAnMCgQQAAIUEAgCKBAAAjAQAAJQEAACXBAIAmwQDAKAEAACiBAAApwQAAKkEAACrBLMAYAUQAHMFAgB3BQUAfwUFAI0FAQCZBQYApAV6ASEHBAAoBwAALQcBADEHAAAzBwMAPwcAAEEHAgBFBwQATAd7AMkH/ADICAAAyggBAM0IAgDVCAAA2AgBANsIBQDlCAAA5wgAAOoIAgDwCAEA+Qi/AroLAAC8CwMAwQsBAMULAADHCwAAzAsAANILAADWCwMA3AsAAN4LAADiCwAA5QsBAOkLQAArDFIAgAwCAIQMAQCHDAAAjgwBAJIMAACbDAIArwwAALoMnAJYDwAAYw8BAGgPBABvDwEAcg8BAHUPAgB8D2MA5g8BAOkPAgD0DwEA+Q8IAAYQBAANEAAAHBBUAHMQBAB7EAAAfhABAIEQAQCEEAcAkBABAJUQAQCbEEIA4hAAAOQQBQDsEAIA8hAFAPsQBQAFEQEAChFQAFwRAABgEQAAZREBAGgRAgBvEQAAeBEBAHsRpgAjEgAAJRIAACgSAQArEgAALhIDADMSCgA/EgEARxICAEsSMQB+EgIAhxIBAIsSAACNEgAAkRIVAKkSAwCuEgcAuBIDAL0SBQDEEgAAxxICAM0SAADPEgEA0hIfAPQSBAD7Ei0AKxMEADMTAAA5EysAaBMFAHATGgCMEwIAkRMQAKQTFwC+EwoAzBMFANMTFADpEwMA7hMXAAkUHQA=","H":"PmtGE8B2"},"alias":{"N":"`","E":"OzAAAAEAACYUAQAAACYU","H":"p2IVDFMs"},"generic_inverted_index":{"N":"b","E":"OjAAAAAAAAA=","H":"9aRB+vFv"}}') \ No newline at end of file +rr_('{"normalizedName":{"I":"AQQA9HsRAAABAAEAAQATgAKgIAAAD05lcwEAAaBQAAASvGvzcQAAAAoE/gABAwGwIBDbAAFl8joSAAABAAEAAbCAEtkAAXX0sQAAADEBMQcBAPMAAjRh9+ABAACaA54K5wABAFECAQABAwGwIBDZAAFl8jgSAAABABMAArCAEtkAAWF1OjAAAAEAAAAAAAkAEAAAALEA4gETCRQJ/w8XEP0Q/hBPE1ATAQAA9rAAAADuAEMAMAcBAIcDE4ACoIAAABOfMnMBAASgAAAACMigEAAABXqwAAR7AP6ggAAAE54wNThz9rAAAADuAEMAMAcBAIcDAQYA9DURAAABAAEAAQABgAKwAAR7AP6ggAAAE544c5MABKCQAAATn6AAAAAB4DIzNnLz6gEAAAEAAQABAgD1tQcAAAEAaAHqApMEIwACsLASZAABbnL05wEAAAEAAQDfBgEDAPQyDAAAAQABAAEAAQABsFATpgABcgGjBAAAAYACoBAAAAyZoDAAABACM3MAB2VqZWN0ZWQAAPR7EQAAAQABAAEAAAAHY2NlcHRlZAAAAXoRAAAA8gJ0dAIAYXIBTAcAAADyAW8BAXJ18gACAAABAAC2AAABZQEEsEASMAABsEAT4AABcmRlaHQAOjAAAAEAAAAAACgAEAAAAG0EbgRvBHIF2wjcCAEJNAmCDFYPxQ/GD9MPAhBdEF4QXxCmEBESbRJuEm8ScBKbEqkSqhLXEtgSRBNFE0kTShNLE1sTXBO+E78T1RPWE/oT+xMBAwD03wgAAAEANgMBAAEDAPMTDAAAAQABAPOAAmlvAYACoEAAAA9CsCAMwQABZXABBQGwMBKJAAFo83ITAAABAGsAE4ICoDAAABBPY3ABAgA7MAAAAQAA5wACAMULAADDDOYAAQEAOjAAAAEAAAAAAAcAEAAAAGURZhGcEp0S9BL1EpwTnRPzBgFpAYsQAAATggKwgBKvAAFudAEBAbBQEIwAAWP0LwcAAAEAAQAEAiOAAqBQAAAQUGNuABBuZ2Nvbm5lY3Rpb25zaWRlAAAB/RIAAAAAAmVuAADySgcAAAEAAAAIYW5kc2hha2UAAPQeEgAAAQABAAEAAAAEcnJvcgAA8rgMAAABAAAABGh1bmsBANAAEG0AAXMB3A8AAAAABWh1bmtzAAABehIAAADyAmxsAQBjAX0MAAAA8gCEgJUAAPSoBAAAywABAAEA9YAMAAABAMoCAQABAAADYmxlAADy+AgAAAEAAPKBdAMAYWV0AApwdWRwc29ja2V0AADzGxIAAAEAAQAA8oADAWFpb2UACmFydGluc3RhbnQAAPLwEgAAAQAAAAhuZ2xlY2VydAAA8ngSAAABAADygAIAaXQAD29vdGNlcnRpZmljYXRlcwAA8qATAAABAAAABGVmaXgAAPLaDwAAAQAAEoABAbDgE+YAAXJsAAZuaXRpYWwAAPRpEAAAAQABAAEAAAAFcnlwdG8AAPLYDwAAAQAA9gEAAWgFAaDQAAATwmNpcHJzYQDyfA8AAKoAAANkb3cAADswAAABAAAHAAEAFAcHADswAAABAAAcAAcAyg8CABsRDQBCEQIAFhIBAJkSAQDqEgEAfhMCAPKAAgBudAAJYXRoaGFuZGxlAAABCREAAAAABWFuZGxlAADy1g8AAAEAAAAPb25uZWN0aW9uaGFuZGxlAAABOBMAAADygWsDAGNocBKAAQKgAAAAEzOwsBLfAAFhZHgAA2RsZQAAAXwMAAAA8gJpdAEAaQAB5RIAAPZ1AACEiKCQAAAUJiowTso3U6EQAAATwhEBAYRwFgA7MAAAAQAAOAEMAKoBJADSAQYAfAUAAKgF5gAUBwcAyg8CABsRDQBCEQIAFhIBAJkSAQDqEgEAfhMCAAEFAPajDAAAAQABAB4DAQA2AwEKAaBAAAATomXyzBMAAAEAAYADsHAQ9gABsCATwAABsGASugABYWRvAQkA820SAAABAO0A8QABQ2H1GBAAAOcAAQBRAgEA8QABQWH2/w8AABgA5gABAFECAQABBQA7MAAAAQAABwADAEIRAgDqEgEAfhMCAAEHAPYNEwAAAQCjAFQAFgABAAGAAqEQAAAUArCAE/oAAWl1AQYA9JUQAAABALcAAQABBQD0thIAAAEAlQABAPMAAWMBIhIAAAEDAPasDAAAxwJaAAEAuQIBAAEEADswAAABAAAKAAQAERAFAEMSAQChEgEAvRMAAAGGAqAAAAASw6AAAAASxGRy8wIBdgHvEgAA84ACZW8BgAKwIBMLAAGgIAAAD3JiZAAIZWdvdGlhdGUAAPJKEgAAAQAAAAdpc21hdGNoAADyeBEAAAEAADIBbgIBgBLsABDwbW5zOzAAAAEAAAUAAQDACAUAOzAAAAEAAAUAAQDMEgUAEoABAqCwAAATM7CAE6YAAW9kehKAAQEF5oH0AANpYQAJc2lnbmF0dXJlAAABnxMAAAAIAAAAAZ4TAAAA8oNsczECADIzAAhydmVyY2VydAAAAe8SAAAAEoABAaBQAAATxmVj8gACAHN08hIHAAABAAAAC3VpbGRlcmVycm9yAAABNxMAAADyAAEAYgDzxBIAACIBAQASgAEBoAAAABLDcmQSgAEBoFAAABOQZWPygWYCAGl59goAAAIGoHAAABIUoLAAABOQaXNhY2VudnkAOzAAAAEAAAoABACZBQIA8gYEAA0MAQBQEAAA5kIAAIKJwAAAAACMJs8cOB5MW5c6kvPasVAUHQABsHATRwABoTAAABQRBAABC2EaAPIqCQAA/QYBgAKgUAAAEJOgoAAAErxrcBOAAqAgAAAQJ2VpAQUBsGATzgABZjswAAABAAAGAAMAwAsCAPYSAQB8EwEAAA1vdW5kc2V4Y2VlZGVkAADyNRMAAAEAAPoZAQBi86IFAAABAG4BABKBaQEBoDAAABFZbmEBAgA7MAAAAQAA9wACAI4MAQA5DvUAAAdhcmlhbnRzAAABWREAAAAAA251bQAAAekLAAAA+iYCAGV2APP7DwAAlwASAgECAPQvEQAAAQABAAEAAQoA8y0TAAABAAEA84ECbXQBBgDz8RAAAAEAAQABggKwYBK0AAGw0BPMAAFpchOAArAQDJMAAWVpAAVvbmZpZwAA9G4TAAABAEkAAQAA8gRva2VuAQBj8nYSAAABAAAABWFpbGVkAADySBIAAAEAAPKCb24CAGZ0AAAAAbAAE8MAAWT0tQsAAAEAAQABAAD6iAIAZWk2BgABZIGIsTAT6QABoGAAABDwoFAAABCEsJAShwABsEAQgQABAQAAtBAHAAGjEwAA8gACAWl1ZQA6MAAAAQAAAAAACgAQAAAAIAkhCagP3RLeEg0TDhOxEwUUGxQcFPKAAgJscml09hsAAMLHoDAAAAjmQAQAAKhAFAEAOjAAAAEAAAAAAAcAEAAAAF8EYARhBAwJDQkmDMUQxhABBQA7MAAAAQAABwABALIQBwABAAGwUBEzAAFjAekLAAABAQKwgBN2AAGgMAAAEBtpdQFnEwAAAQEAOzAAAAEAAAYAAgDsBgUA8wsAAAEBAPVzEAAAAQABAAEAggLzgAJlbAEAAaCQAAAS42jyqxIAAAEAEwADsEARcgABsDASxQABZGVy87sEAAAsAgEAAQ4A9P4TAAABAAEAAQABBQD0PBIAAAEApAABAAEHAPT2EgAAAQCFAAEAI4ACoUAAABPeYnYAAnplAAABcgUAAAECEAAA9gUAAIGGsAAPSQABAAEAlwAEADowAAABAAAAAAAJABAAAAAEBwUHnwygDFIPwA8MEA0QFRLkEgEBAPUZCQAAAQABAAEAAQAABnJib3VuZAAA8tQPAAABAAASgAEBdPODqeqQZW8AA2F0cwAAAWgQAAAACAIAAAHTDwAAAPKDYWRzAgBpdBKAAQGwAAVxBl5vZQAEcmFkZQAA8r4IAAABAAAAEG9jYWxpZnNhbWVyZW1vdGUAAAH4EwAAAAACdXQAADswAAABAAAFAAEA8hMFAADyDXJvbWFyZ21hdGNoZXMBAG07MAAAAQAABQABALITBQAAMgNhdGUCArBAEjUAAbAAEvMAh2ZsZXMAOzAAAAEAABQABQCyEAcAVxIBANISBACqEwQAFRQAAPYCAAAEAqCQAAASo2RnbHBjaQA6MAAAAQAAAAAABwAQAAAAewWYDDwSPRLhEuISDxQQFAEDAbAwD3EA63T2OgcAAAEAjgCrB6YA7QEBAAGwcBM1AAFl8mkPAAABACMAAqBAAAATjGVz9NQPAAABACcEAQAAF3NhYmxlYWZ0ZXJuZXR3b3JrY2hhbmdlAAAB3hMAAAAABmVyc2lvbgAAOzAAAAEAAAUAAQDMEgUAAAANcGVyYXRpb25lcnJvcgAAAdITAAAAAAdhbWV0eXBlAADy+xIAAAEAAAAFeXBlZXIAAPKVEgAAAQAA8odwcG9ydGVkBABibm92AAd1Y3R1cmVkAAABGxAAAAASgAEBsJATbAABcmEAB2VjaWZpZWQAAAF7DwAAAPKAAwBwdHUACWVjdnN0cmVhbQAAAfoSAAAA8gZyZGVyZWQBAHIA8ikRAAAYAAEAAPd+BQAAEQEBADEJrAABAAwCAANvd24AAAFJBwAAAPIAAQFucwD1fwQAAAEAzwoBAIwAAQYA8+ITAAABADUAAQIAOzAAAAEAAIcAAgB3EAAAgBGGAAAEdGltZQAAAfcIAAAApgEAAAIDwAAAAAR8sQAT5AAtdHhkbnPyigAAAAEAOjAAAAEAAAAAAAsAEAAAADIHOAm7C7oMiRCKEA8SEBKTEpQSIxMkEwAKeHBlY3RlZGVuZAAAAZoQAAAA9lMAAIaFoGAAABKusGAS2QABoHAAABITEEUKDgAFAPLdAQAAAQABDQD0thIAAAEAlQABAAEKAPVJEwAAAQABAHMAAQAAAXgAAPQNBwAAAQABAAEAAAgVAADy9QgAAAEAAAACZWYAAAG3DAAAAAAEdGF0ZQAAAQgRAAAA+hwBAHMB6AsAAPTeEAAAPQEBAAEA8oJjawIAZXIABG5kZXIAAAHnCwAAAPKAAwBlb3QBAwD0DxMAAAEADwABAAAAAAD0CQcAAAEAAQABAADygAEBeG/yAAMBcnN0cAHjAQAAAcEHAADygAEBcGkAATQAAbCAEtkAAXUB4gEAAPITCQAAAQAAATIAAAHhAQAA8xEJAAABAIcDAIACAOOAAAAEe8AAAAAB4DI2di9IAAgLwAAAAABxP8ovJY8rLSM3JQpKf+DSxsKRZ2gNUhNXLsJ9Sn/oYdDb+GyLVatS5OPlUD0PI/mpMTM2OGRucHNiY2VmZ2lsbXJ0dQA7MAAAAQAACgAEAL8HAQBDDwEAgQ8CAIoPAwABAAA7MAAAAQAABwACAA0HAwAGCQMAIYACsCAPfACqqmlvAYUCoAAAABLDoAAAABLEZHIjgAKgAAAAD/80ZQEJAPWDEwAABQABAAEAAQABgAKwgBKLAAGhAAAAE9tjZhOAA6AgAAAQw7CQEJgAAWVvc/EAAcJy8+oBAAABAAEAAQQA9AoSAAABAGUBAQABAAD0MBAAAAEAAQABAAggAAA7MAAAAQAA5wACAKEFAADXB+YAAPonAQFpcwA6MAAAAQAAAAAADgAQAAAA2ggVCRYJFwkYCdAL0Qs2DzcPXg9xD1wQgBD7EvwS8gABAXBsAXAAAAA7MAAAAQAACAADADkJAQBjEAEAvhAEAPEBASVz8rsLAAD/AAEFAPQPEwAAAQAPAAEA8YACIQBpcAgAAAABcQUAAAHPCwAAEoABAaCQAAASo2xjdAIAAAEFAAIEANV5WNsKLVhRNKTbV3BkbnJzdQA7MAAAAQAACgAEAL8HAQBDDwEAgQ8CAIoPAwABAQGgMAAAEBt1AWcTAAATgAKgQAAAEgdjbgEGAPSBEgAAAQCJAQEAEwICsGASgwABZm3yjAwAAAEAI4ECsEASrwABZWwBAQA7MAAAAQAAQAADAKAFAADtCAAANww+AAEBADswAAABAAAJAAIAtwcHAIMSAQBTgAOgEAAABwhjZG4BAQD1LQwAAAEAAQABAAEAE4ACsLATWAABYW8AE2l0aHBsYXRmb3JtdmVyaWZpZXIAAPLmEwAAAQAAAARyZWFtAAAB5gsAAAAAAm5kAAABtAsAAADygAIAZXQAA2V4dAAA8tcQAAABAADyA29sbAEAbjswAAABAAAJAAEAqgsJAAAAA250bwAAOzAAAAEAAOcAAgBIBwAAwwrmAAAABHR1cmUAAAHlCwAAAAAHbnRlcnJvcgAAAXcRAAAA8gJvbQEAaTswAAABAAD5AAIARwcAAMoJ+AAA8oACAHJ19gUAAIWCsEAMpwABIIESEAAEADswAAABAAAJAAQAnwQBAF0FAQAPDAEALxEDAAEHAPT/EgAAAQABAAEA8wEBdDswAAABAAAIAAIAvQsAAOsLBwABAAGgUAAAE8JzARISAAAjgAKgwAAAE/lpdAGCArBAE4YAAaBQAAARZGJmAAAAADswAAABAAAGAAIA+RIAAF8TBQAACFUAAPLQEwAAAQAA8ohhcmFtZXRlcgIAZXMAA29kZQAA8soSAAABAAD6AgEAY/MFEQAAAQABAAAINQAAOzAAAAEAAAcAAgB0EQIAcRIEAAGREwAA8gNvcnQDAGNlcPN5DAAAAQABAAABAAGwYBN4AAFlAa8TAAD6RwABc/PyCAAAAQABAPPEEAAAPwAVAQAFZXN1bHQAAAEEEQAAAPICZXIBAHIAAaUQAADygAMAZm1w8oABAXNkcoABAx94I1nSim5jcna2AwAAAgRxn/P1tglheWVpb3UA9N8BAABEBewBAQABAwA7MAAAAQAAhwACAHcQAACAEYYAE4ECoGAAABEpaW8BgAKgoAAAE5ewEA9DAAFhdAECAaAwAAAP/mEBCQwAAAGAArBQEKoAAbAgDzgAAWNu84ACbnQBgQKwoBOEAAGwoBOGAAFjchOAAqAgAAAL1WVyAQQAOzAAAAEAAA4AAgCSDAAAkQ8NACOAArBQD2kAAWJ1AQEBoEAAABECZQHCDwAAE4ACsDAPXwABbnIBAAD05hIAAAEAAQABABMCArCAEroAAXN29DsJAAABACwKAQABhQKwcBOBAAGwMBLXAAFlcwECADswAAABAAAHAAEAIgkHAAADaXplAAABVg8AAAAAB3VyYXRpb24AAAFYEQAAAPICYWwCAGRzAPLgEwAAAQAABHJpbmcAADswAAABAAA/AAIA7QgAADcMPgAAEoABAaBQAAARC3RlAQYA9HUPAAABAO8AAQABAQGgQAAAEBllOzAAAAEAAAcAAgA+BwUAzwcBABOAArAgEi4AAWVpAAtzc2libGV2YWx1ZQAAAaQSAAAA0gABA6BQAAAQAG9lcHMA83IEAAABAAEAAANuZWQAADswAAABAACHAAIARQcAAEMJhgAAAAxhbnlhZGRyZXNzZXMAAAFHEgAAAAACbmcAAAFGBwAAAAADcmdlAADy8AgAAAEAAPKAAgBhb/KAAwBsbXcABnVudGltZQAAARoQAAAAAAx1cnJlbnR0aHJlYWQAAAHJEgAAAPpuAgBjcvKnBAAAyQAAAQUA9G4TAAABAEkAAQAABHRvcmUAAPS1DAAAAQAbAwEA8vgQAAABAAAJZXVzZWVycm9yAADychEAAAEAAAACb3MAAAF4DAAAAAAKZW1vcnljYWNoZQAA80USAAABAKgAAAABZwAA8u4IAAABAPUDEAAAAQBtAAEADQESgAEBsGATWAABb2kAAmV5AADydgwAAAEA8oUSAAABAPpZhoEAnAMEAAABbwUAADowAAABAAAAAAAHABAAAADfCOAIFgwXDIEQghB2EncS8oACAGVp9v0LAAUMoDAAAAwIVy4QJcYgsNATpgABa29wc3QwYWJjZWZnaW1ydXYAOzAAAAEAAGoCCgDvAQAAVAPmAIMFAQCcBgoASAcAAMMK5gAYDAAAqg2GANgPAQArEAMAAYACsXAUHwABoNAAABOYY28BgAKgkAAAE56gkAAAE58yMwAGZXNzaW9uAADyswwAAAEAAPIAAQFzMQA7MAAAAQAABgACAOwGBQDzCwAAkoABA7AABW0AAbBgEGEAAXNlaW8BDQA6MAAAAQAAAAAABwAQAAAAvRK+ElYTVxONE44T2RPaEwGAATiY2EbwKG4BAAGwgBOkAAFw8qATAAABAEMFA6AgAAAQ36BAAAASJ2Rlc/OADwAANAMBAAECAPM+EgAAAQABAAEAAPW+EAAAAQABAAEAAQAigAEB9lAFbQABbHkBAAD0EwwAAAEAAQBqAAECADowAAABAAAAAAAJABAAAABmD2cPVxAREWASYRJaE9wTDRQOFAAHcmVzaG9sZAAA8lYRAAABAAASgAEBsCAPcQDraHkABW91cmNlAAD0sQwAAAEAHQMBAAAAA291dAAA8+oIAAABAAEAAHYDAACDg6BAAAARcQgABhBAAQA6MAAAAQAAAAAAFwAQAAAAOgc7B8kH9wgrCSwJsAxTD1QPdA8aECEQIhAjECQQYRBiEJgQmRAHElgTWROEE4UTEoABAbAwEA4AAWVhtioAgMLJAP8ttqHwoCAAAAx8GdFyhnuLIbkkBMuPoBAAABAnAAAEAsAKuAgBAwGgoAAAFCZ38hYUAAABABOAA7DgE+YAAbBAD9oAAWFscgELAPSIEwAAAQABAAEAAQwA9PQSAAABAKcAAQAjgAKgcAAAE7Bnd/OAAmVvAQwA89wTAAAxAAEA8wABYQHyEgAAARAA8wUUAAAWAAEAAQUA9GkQAAABAAEAAQABAAGgYAAAEjdy95EFAAABADUCEAQBAMcDAQAzgAOgEAAAEhpkbnMBCQD0aBEAAAEANQEBAAEHAPSQEAAAAQCoAAEAM4CEoQAAABQGsEAP2AABgEEBAQECsCAMnAABsAAMHAABZXPyNQcAAAEAAQQBsFASjQABcvRrDwAAAQDpAAEAE4ACoLAAABPCYXPzgAJiYwADaXN0AAABGhIAAAAAAnBzAAABVREAAADyBWdocHV0AgBiaAFVDwAAABKAAQGw0BOgAAF1bxKAAQFwRqSKnypvZba8AACBjaAgAAAHN3PFo2o9X6BQAAARCaDgAAATew6JxnKARrDQE2wAAQAAAZf1CgA6MAAAAQAAAAAAGwAQAAAA9QH2AfcBRQRGBOII2QsaDBsMHgyDDIQMhQyGDDEOfA8AECYQTxD2EPcQOxE8EXUTuhO7E84TzxMBAQDzKQcAAMcLAQABCgD05hIAAAEAAQABAAGAAqAwAAATM6DAAAATZ295YwCEoHAAABFYoDAAAA9WCIgC8uATAAABAAGAAqAAAAAQF6AAAAAQGDQ28wIBdvKtDAAAqwIBBAA6MAAAAQAAAAAABwAQAAAAYw9kDygQKRCREpISIRMiEwEAAqAQAAAMNrBQE2wAAWlv8vgIAAABAPOBAmVvAQcA9AYTAAABAAEAAQABAwD0/xIAAAEAAQABAPosAAFyOzAAAAEAAAUAAQB1BAUAAAGBAVOrScaCzG0IewAA8tUHAAABAADyAAEBbHIA9S0MAAABAAEAAQABAPYOAACCiaBgAAAReqBwAAATHjhbhwLmFy0nDYYbqUAEAA9oBQA7MAAAAQAAEQAIAAsCAAAtBwEA5ggAADIJAQB8EAEAhxABABIRBQANEgEAAAAIEibeeewYAlFU9GM7YzCi0J3TmDaEWyAr73AyJa2+xBRhWHklzi3F/VOgD1BuqehN5IAB5wAQASPZBKvs3GRl53HzcioRhmW/Uzgr+otunmX6m9fVMrCwE+YAAaDgAAATGaAwAAAPTi6ZUIEtwhOc7Ipp6T9JWHw4qh7YlDEyZHWiBY7QRBDS59J61R+3AG2uEhrLAkxpKQ5VNZdoXWFoaWxvcnV5MDFiY2RlZmdqa21ucHN0dnd4ADswAAABAAB4BGUAbwAAAIQAAwCyAOsAqQEAANABAQDZAQMAQAQBAGcEAQB8BAAAlAQCAJsEAwChBAEAVwUFAHYFAAB9BQAAfwUCAJAFAACTBQUAogUFAJIGBADKBgUA0QYBANsGAgARBwAAIAcBACkHAAA5BwAATAcAAGwHOwCxBwUAwgcDAMcIAADNCAAA0QgCANkIAADqCAIA8ggCAP8IAQAeCQAAxQsBAN4LAQDoCwAAAQwBAAgMAAAKDAEAHwwDACgMAQAyDAMAeQwCAI4MAQCVDAAAwwzmADkO9QBRDwAAVQ8AAGYPAgB3DwEAfw8AAI4PAgD2DwIAORABAEQQAQBMEAIAVxAAAHcQAgCbEAAApxAAAMQQAADXEAEA3hAAAOMQBgADEQEAChEAABERAABFEQIAYBEBAIARhgAIEgMAEhIAABQSAAAYEgAAGhIDAEwSBgBgEgEAeBIBAIkSAQDlEgAA7xICAP8SAwAREwcAPRMFAFoTAABnEwAAcBMBAMITAADMEwEA1xMAANwTAADyEwUA/hMDAA0UAQABBAD0LxEAAAEAAQABACODArAwE8MAAWFyQ4ADsAATTwABsAATUQABNDZhAQcAOzAAAAEAAAUAAgCqEwQAFRQAAAEBAaBQAAARBHIBpRAAAGOAhKAAAAAB5aBgAAATUxhAAQGAA7BgEzsAAaBwAAASIrBQDzoAAWVpcgGAAqAAAAAFeaCAAAATnjhzE4ACoJAAABOfMjMBAwDztQcAAAEAaAEIIQAAAXERAAAA8gd0ZW10aW1lAQBlAbAMAADymBAAAAEAAAFjgISwMAu+AAGgQAAADH+ggAAAEN6wQAyAAAEAAB0B/wEAAADygAIAbnMBAAD0iRAAAAEAhQEBACOAAqBgAAASrmJpAQEAOzAAAAEAAAYAAgCTBQUABBEAAAAAAADy7BIAAAEAAd0TAADyA2lvbgEAcwA7MAAAAQAABQABAMwSBQAACWZ5c2NoZW1lcwAAAcYTAAAA+qECAGlzAAppcGhlcnN1aXRlAAABNBMAAAA2AACGcG9ydGVkAgOwUBKVAAGwcBL7AAGg0AAAE9JjdmJubwACdGUAAaAAAAASuXMBpgQAAPRZDwAA1wMBAAMAAQABoIAAABQVZgEDEwAA8gZvbW1hbmQAAXMBrwwAAAEaEQAAEgABAaBgAAAT+WNzAPJTEQAAAQD2AQCAg4OwEBJoAAECgQAAKAEBBQD0RhAAAAEAAQABABOAArCwEw8AAWFsAQIBsHATwAABcDswAAABAAAJAAIAqQcHAFMQAQABAAD0Pg8AAAEAAQABAPMDAXMBsRAAAAECAaAwAAAQG3UBZxMAAAECAaBQAAATwnMBEhIAAAgVAAABoAUAADswAAABAAA/AAIA7QgAADcMPgAigAIA5lAAAAcIZG4BAgD0iRAAAAEAhQEBAAAAAADzeQ8AAAEA7QABZxEAAAAFZXJyb3IAAPLBEgAAAQAA8oJhdAIAZXMBAgD09BAAAAEAbQEBAAACbmkAAPSTEgAAAQCPAAEAAAADaWRpAAD0xxIAAAEAlQABAADyhW9ja2VkAgBidfKAAQFsafIAAgFidHX1RAcAAI0AAQABAAEAOjAAAAEAAAAAAAoAEAAAAKEPYBAaE5kT4hPjE+UT8BPxExQUGBQADGVjZWl2ZXdpbmRvdwAA834TAAABAAEAAAAJaW1pdGVycm9yAADyvxIAAAEAAAACZm8AAAGuDAAAACKAAgDQAAjoAAFkbgAHaW5pc2hlZAAAARkSAAAAAAR2ZW50AADydw8AAAEAAAAGbG9ja2VkAAD0kRIAAAEAjwABAADyA2F0YQEAYgD0hxAAAAEAhQEBAPICYW2HgDgJAzswAAABAAAFAAIAnAUDAAYHAQA6MAAAAQAAAAAAHgAQAAAA5gujDKQMpQypDKoMqwxvD3APww/ED8gPyQ/mD+cP6A/pD+oP6w/sDyoQLxBaEFsQ+hIeE0MT2BPkEwIUERTyAAICZWlhdQHfAQAA8yMHAADsAQEAAQEA97UMAAABABsDAQDFAGEAAQAABmVuZGluZwAA9HUPAAABAO8AAQAACBgAAAEZEAAAAPpKAQBlOzAAAAEAAAcAAgA+BwUAzwcBAAASgAEBsCASLgABZWkyAAIBoFAAABAAcHNl83IEAAABAAEAAFKAAQKgMAAAC9VwZ3IACnN5c3RlbXRpbWUAAPKYEAAAAQAAAQABsEASwQABZfMIEQAASwEBAAEIAPT2EgAAAQCFAAEAEgFzAAMGVeWMqOqwQBLFAAFhYmXyBAcAAAEAOjAAAAEAAAAAAAcAEAAAAJ8MoAxSD8APDBANEBUS5BIAAAAAOzAAAAEAAAsAAgCkBAEAYwUJADowAAABAAAAAAATABAAAAD1CPYI4AvhC5AMkQw2DkUPRg9HD1oPeQ96D2cQaBB6EAwRYhFjEWcR8oACAXN1ZQADaW1lAADyUw8AAAEAAAgmAAA7MAAAAQAACQABAM0QCQAAOtQCAbBgEvAAAXN0aQCCbGUBAeZAAAAMNrBQE2wAAWlv8IADAQABBFpicnRu9kMAAMTIXr+cliBysEAJQQABSLIInQrpcDmysHP0oBAAAA//QAKQAIBlIggAOzAAAAEAABIACAA5BwAAaA8AAEQQAQCnEAAA4xAGABoSAAD/EgMAzBMBAAGAA7AAE08AAbAAE1EAAbBwE8MAATQ2YQEEAPQSFAAAAQAKAAEAQ4EDsMATdgABoEAAABDdZG1wAQEAOzAAAAEAAA4ABAA8BwEAswwBAM0QCQALEQAAAQEAOzAAAAEAAAYAAgC8CwAAuwwFAGOAA7BwEJICEmJnbwEAAbAwDLMAAXM7MAAAAQAACAADAEcSAAC4EgAAHxQGAEOAA6BAAAAL9LAwDA0AAW1ycwEBADswAAABAAAKAAMA8RACACkTAwAHFAMAI4ADoDAAAA/foLAAABLcZGdtAAVocmVzaAAA8kEJAAABAAC2CwAAAQeggAAAEiKggAAAERp0YWRlaXJ1dgA7MAAAAQAAGAAJAH0PAQCVEAEAyRABANkQAwBIEQYALRMCAHsTAADTEwEAAxQBAIGAhLDAE3YAAaAAAAAEfaBAAAAQ3QookAAAAXAAAPMBBwAAAQABAAAAAmlkAAD1ygcAAAEAAQABAAEAAPKAAgBjaTKAAQKgQAAAC/NjZXUBFAD0/hMAAAEAAQABAAGAArBgE6QAAaDQAAATdWVvAYACoFAAAA97oPAAABOvY24ILQAAAXEEAADywQwAAAEACAAAAPNgBQAAAQABAAASgAECsBASoAE/sMATCwABd2N0dgYAgIKFoCAAAAciKa0AAYo6AQEAEEgJAQAAOzAAAAEAAAsABQDfBgYATg8AAFsPAAAlEAAAjRIBAAADcmNlAAGwsBPrAAFsOzAAAAEAAAgAAQD4BggA9LEMAAABAB0DAQAAgAIAwAAAABAXwAAAABAYNDbyA2RkcgEAdgGtDAAAABoIAQGgQAAAEQhhcwD36AsAAJcDXwE9AQEAAQClARKBawEBoCAAAAy3ZXJ2AACAAgOgAAAABYWgcAAAEl9jdW5ycwEAADswAAABAAAMAAMAxwgAAD0TBQDyEwUAAYYCoGAAABNGoJAAABOwZW7zgAJsdPEBAeJz9vIIAAABAAEA0Ac/ABUBCDwAAAF0DwAAAPIBbAEAcgFwBAAAANKAAQOwMBF4AAFvYWl1AANpY2UAAaAgAAAMlW0BXwUAAAAAFGlwc2VydmVydmVyaWZpY2F0aW9uAAABkBMAAAABAwDzMhIAAAEAAQAjhAKxIBQZAAFjawADaW50AAD0MgwAAAEAAQABAAAAAAABsFATpgABcgGjBAAAADowAgKwQBIwAAGwQBPgAAFkaGV0820EAAABAAEAOjAAAAEAAAAAACQAEAAAAHIF2wjcCDQJggxWD8UPxg/TDwIQXRBeEF8QphAREm0SbhJvEnASmxKpEqoS1xLYEkQTRRNJE0oTSxNbE1wTvhO/E9UT1hP6E/sTAYECoDAAABPXoFAAABNnY3MABWNoZW1lAAABcBEAAAAIMQAA8ssQAAABAAA6WQIBoEAAABOjbHN2APKeEwAAAQD6DQEBYWXyawQAAAEAOzAAAAEAAAYAAgC8CwAAuwwFAAgEAAGgkAAAEzNu9P0BAAABAGsCAQAB/RIAAHYEAICDhLBwEJICErBwEngAATTxWE6tPkgAgAJgAgEAAaAgAAAPZXIBhwUAAAEAAqFAAAAT6KBAAAAQe2Nl89QIAAABAEQJ84ACZHIBAQA6MAAAAQAAAAAACQAQAAAAVhFXEWoSaxJUE1UTqBOpExkUGhQACmxkdHJhbnNtaXQAAPIDEQAAFQEAYoACAfdABKEAAXJ1bAEIAPUqEQAAAQABAAEAAQAAAmVkAAAB9wYAAABSgAECP8biHW/McmtucgACAqBQAAAQw2FvZXUAOzAAAAEAABwABQDuAQAAPwMUAMIGAgBBCQEASQ8BAAEGAPVzEAAAAQABAAEAggIjgAKwUBM1AAFjaAEDAbBAEOAAAWUBMQ4AAAGAArAACT8AAbAwEXIAAWRyAAtwY29ubmVjdGlvbgAAAaMSAAAAAQMA9G8PAAABAOoAAQAAA3R1cwAAAVIPAAAA8oABAWFyAAl2ZXJjb25maWcAAPKhEgAAAQAAAAVpbmRvdwAA8hYSAAABAAAACXVmZmVyc2l6ZQAAAVwTAAAA+qECAGJ38oACAG5y8oACAGV0AApidWZmZXJzaXplAAABWxMAAAAACWl2ZXdpbmRvdwAA8uoSAAABAADygmVjAgBldgAGaW9yaXR5AADyYxAAAAEAAAgnAADyxRIAAAEAAPIFdGF0dXMBAGUBFRIAAAAADWF4aWRsZXRpbWVvdXQAAAHcEwAAAAAQZWVwYWxpdmVpbnRlcnZhbAAAAQUUAAAA8oJ0aAMAa21z8oACAGFyABplbW90ZW5hdHRyYXZlcnNhbGFkZHJlc3NlcwAA8iQUAAABAAAACmRsZXRpbWVvdXQAAAFaEwAAAAAJbmlzdHJlYW1zAAABGBQAAAAABnRyZWFtcwAAAeUTAAAAAARhdGhzAAABxRMAAAAACGlzdHJlYW1zAAABFBQAAADyiW9uY3VycmVudISAAoAK8oJheAMAY2lyAAdpZmV0aW1lAADyYRAAAAEAAAAOcGFsaXZlaW50ZXJ2YWwAAAGxEwAAABqbAQGwAAwrAAFleQASZWZhdWx0Y2xpZW50Y29uZmlnAAAB2xMAAAAADGxwbnByb3RvY29scwAA9OYSAAABAAEAAQAA9h8AAImCoEAAAAymsHAS3QABCZwLEAEAADswAAABAAALAAQAmwQDAFoFAgDRBgEARRECAAhPAADyPAcAAAEAOzAAAAEAAAwAAwCzDAEAzRAJAAsRAADyAAEAcwA7MAAAAQAACAADAEcSAAC4EgAAHxQGAAEAADswAAABAAALAAIAygYFAEwSBQAADWlkZW5vdGFsbG93ZWQAAAEzEwAAAAADYW1lAAD0rAwAAMcCWgABAPKHEgAAAQAAB25kcG9pbnQAAAEUEgAAAAAEbmZpZwAAOzAAAAEAAAUAAQAREAUA9UMSAAABAF0AAQAbAQCGZXJpZmllAgDAAAAAEsPAAAAAEsRkcvICcnQBAHYAAe8SAADygAIAZW8IMgAAAXIPAAAA9gEAAAUBoLAAABOQYWNlbnN2OzAAAAEAAAcAAgCZBQIA8gYEAPINDAAAAQASgAEBG5rs9v+McmQSgAEBoEAAABAnZWGSAAEDsEAPWwDKsCASxQABdmVydADyrRIAAFkBAAxscG10dWRwcm9iZXMAAPIfEwAAAQAAEgABArAQE6QAAbDgE6YAAXBlb/JnBAAAAQD0wgcAAAEAAQABAAECAPR1DwAAAQDvAAEAAQEA8+cLAABbA2IBCCEAAPPKDwAAAQABAPIWEgAAAQAACW5yZWxpYWJsZQAAARMSAAAAAAV0cmVhbQEAwAAAABBgc/WpDAAAAQABAB0DAQAAABVic2VydmVkYWRkcmVzc3JlcG9ydHMAAPISFAAAAQAAAAdhaXJuZXNzAADyyRAAAAEAAAAHbnN0cmVhbQAAAR4TAAAAAANhaXQAAAHlEgAAAAghAADyjxIAAAEAAPIDcmFtAgBld/IQEAAAuAAA+s4CAGdvAANhY2UAAAGgEgAAAd8TAAAAAnplAADybxIAAAEA81wTAAB5AAEA8oACAGlwAAZlbmNoZXMAAPMbEwAAAQABAADyBXVmZmVyAgBicwHHDwAAAPIAh4IqQBoQAQD0/AEAAGgCAQABAPK0CwAAcwDygAIAZHQIAgAA810QAAABAAEAAPIAAQBpADowAAABAAAAAAAHABAAAAA4EF8SRxNIE3gTeROXE5gTEoRtZW50AQGwsBPuAAFzYeYTBQDGyfbABGIAAaBwAAASEXdaPxrOdaBwAAAQjqCwAAAT16BAAAAL9LBgEggAAUAQiAOARmYgADswAAABAAAaAA0AggQAALsEAABDBQMAUwUBAOcGAQDnCAAAPgkAAEgPAAAHEAEAuhABAFoRAwAjEgMAVRIBAAGCAqEQAAAT3rAACM4AAWFkAAJ1YgAA8lMRAAABAAAAAmRkAAD0TxEAAAEAAQABAADyh3VyYXRpbmcCAGFzAYADoJAAABLcoDAAABN1oFAAABP4Y3ByAAZsZXNpemUAAPLFDwAAAQAA8oABAXBldAEAgAIFAAMGoDAAAA/finbjGr2fQFfG0ir3a210YmRnbHYAAA4KFjseX8o3LhjcCMMne1ziMyGNHagTfd/vH2pxANkyFMFV3QpsKObWgXGUU2nnClbLcUjlAH00LgStcWnZMuYxE3XyJpZevwCrGr3ucleefU0LMFFrJBctVYJycs83HbIkoCAAAAV6oGAAABK8dei9vOwBW2/FfX52btY53qVwFRWa4goVObtKLN1BoKAAABQmYWVoaWtsbW9wcnN0dXkwMTI4YmNkZnZ3ADswAAABAAAJAWwAoAEBAOQBAADwAQEAAgIBAH4EAACkBAEAqQQAALUEBQBVBQEAYwUJAH4FAACPBgEA7AYFAAQHAQBEBwAAUQcAALcHBwDRBwMAyQgAAPUIAQD7CAAANwkAAMkLAADgCwEA8wsAAP0LAwADDAIAHAwBAHgMAAB+DAAAkAwBAJ4MAgA2DgAAPg8DAEUPAgBSDwAAWg8AAGkPAQB5DwEAfQ8BAKEPAACkDwMAvw8CAAwQAQAcEAQAMBADADgQAAA7EAgARhADAGAQAABnEAEAbRABAHoQAACDEAAAlRABAJ8QAQDJEAEA2RADAOwQAAAMEQAANREDAEgRBgBVEQAAWREAAGIRAQBnEQAAFRIAADISAgBHEgAAWRIGAGYSAQB6EgAAgxIBAJcSAQC4EgEA2xIAAN8SAQDjEgEA5hIDAOwSAQDzEgAA+RIAAP4SAAADEwAADxMBABkTBAAfEwEALRMCAEcTAQBOEwAAXxMFAHQTAAB4EwMAhhMBAJcTAgCgEwEArxMAALITBQDFEwEA0xMBAN0TAADiEwEA5RMAAPATAQADFAEAEhQCABYUAgAdFAgAAQAAOzAAAAEAAAcAAgAJBwMAAgkDAAGAArAgE84AAbAgE2wAAWFvAQgA8/oQAAABAAEAAYACgAvWbbBZsEASgwABZHRjgASgQAAAC86wcBPmAAFhZWl2AQsA9AYTAAABAAEAAQABBQD0KxAAAAEAAQABAPMBAmNkAXsQAAABgAN+SnXUjGGwEAvTAAGgMAAAEE9jZXABAwD0gRIAAAEAiQEBACOBAqBQAAASDGV0EwACoLAAABK5YWPyRwQAAO8EAQQAOzAAAAEAAAoAAwDSEgQAqhMEABUUAAAAA3RscwAAOzAAAAEAAAUAAQDsBgUAAfMLAAAAA3lwZQAA8nEPAADrAAD6VAEAdPM6BwAAAQCOAPN0DwAApgDtAfIAAQB08t0BAAABAACygAICDsfPJ4QDbnNjcAEFADswAAABAAAJAAEAzRAJABMAA6BwAAATU6AwAAAQl2VmdPafEAAAAQByAwEACgABAAELAaBAAAATomXyzBMAAAEAI4ECsFAQbwABY3YBAAA7MAAAAQAABgACAPkSAABfEwUAI4gCsEAT0AABZXMBDQGwQBPKAAFl9ZITAAABAAEAAQABAAEFADswAAABAAAIAAMAdBECAHESBACREwAAAQcA9HsRAAABAAEAAQABAwD0NREAAAEAAQABAAAIc3RpbWF0b3IAAPIOEAAAAQAAlgEAAAEEoHAAABF6sCAPUwABZWFpa3L02QEAAAEAAQABADowAAABAAAAAAAIABAAAABMB7UHtgceCQgMjg+PD5APmxA2DwAAwclGrDLpHPxiFnl4GRKgMAAAC89H8Iw2NXsAAAACAEWhDQFvAAAAOzAAAAEAABQABwChBAEAygYFAHkMAgBMEgUAeBIBAO8SAADXEwAAAQABK+pnYX6mbTswAAABAADnAAIAfAUAAKgF5gABBgD0KRMAAAEAAQABAAEPAPQHFAAAAQABAAEA84QCaG3zAAFyOzAAAAEAAAcAAgDmAQAADAIGAAGAArBAEq8AAST9pdRmPWVsAQEA9A8TAAABAA8AAQAjgAKgsAAAE3VhZQAEdG9yZQAAAZcQAAAAEoV0Y2VydAEBsHAToAABc2l2ggAAwcsjX9BQrRSg8AAAEv1NkMCKxIagcAAAEDhojtxqTp8T7ZEkTgSwQBPAAAEAABAAgACuHwDyAAIAAAEAAYACsBAQyQABoKAAABPec3QBAQD2rAwAAMcCWgABALkCAQABAwDzMhMAAGgAAQATgAKwQBDtAAFhZfOAAmxtAARzZWVkAADyPwkAAAEAAPKAAQJnYWUBgAKwUBOBAAGgAAAACNljdAGAAqAwAAATo3cLCX0P/2FvAQMA9JoMAACdBpkAAQABgAKwEBDLAAGgQAAAEhNlaQEFAPR7EQAAAQABAAEAAYACoNAAABP5oFAAABOvY24AC2tlbmxpZmV0aW1lAADyWBMAAAEAAAhtAAD1LQwAAAEAAQABAAEAAPKAAgBhbwgVAADypwwAAAEAAPIAAgBldPSfBAAAAQC9AAEAOzAAAAEAAAUAAgAPDAEALxEDAPKAAQF5YQAOcmVjb25uZWN0aW9uaWQAAPS9EgAAAQCYAAEA9I0TAAABAEsAAQDygAIAaXIBAAD0/xIAAAEAAQABAAECADowAAABAAAAAAAJABAAAABWEVcRahJrElQTVROoE6kTGRQaFPMAAW/yQQkAAAEAAAJsdAAAOzAAAAEAAAUAAQCTBQUAAQQRAAAABG9uc2UAAPLnCAAAVwD0BxAAAAEAsgABAAgeAAD0bw8AAAEA6gABAAAAAmV5AADyKwwAAAEAAAgFAAABpgwAAAByAAMBsHAS3QABZWtzaTswAAABAAAGAAIAmwQDAFoFAgDzRREAAAEAAQASgAEBsDATpAABdG52CQCAg4WgQAAAEXCxABPrAAEQZPR+ICoQgAiEQAYBBQD0pxIAAAEAkQABAPMCAWP13Q8AAAEAvgABAAEACFcAAAE5BwAA82gPAADcAAEA8oJ1ZQEBc24AEHJkZXJpbmd0aHJlc2hvbGQAAPJUEwAAAQAAABJhdHRyYXZlcnNhbGFkZHJlc3MAAPIDFAAAAQAAAAZkZHJlc3MAAPSVEAAAAQC3AAEAADq0AgGgAAAAEN1hbmQBFAD1IRQAAAEAAQABAAEACEMAAPIMEAAAAQAAAAlhdGhzdGF0dXMAAAHkEgAAAAAKcGVuc3RyZWFtcwAAARoTAAAAAAxpZHNleGhhdXN0ZWQAAAH4EgAAAAAIYWxpZGF0ZWQAAPLDEwAAAQAA8gVkcmVzcwEAdvVIEQAAAQABAAEAAQDzLRMAAAEAAQAAB2FuZG9uZWQAAPJuEQAAAQAA8oACAGJk+gcFAWFjb3BzbvPpBgAAAQABAPKJDwAAbwTygW8CAHR2AQIA880IAAA0AwEAAAlhbmRzaGFrZXMAAAHjEgAAAPIAAQBoAPKrEgAAAQDyAnNlAQBk8ucGAAABAAABigKwABNPAAGwABNRAAE0NgADbmNlAAABKgwAAADygXIBAWVysgACArAQD9oAAWV1aW0A9X0EAAAKAMEAAQBuBwELAPTYEwAADAAeAA8AAQkAOjAAAAEAAAAAAAcAEAAAAL0SvhJWE1cTjROOE9kT2hMTgAOwEBOmAAGwYBMLAAFucnYIFQAA9aMMAAABAAEAHgMBAAH6EgAAAANldGEAAAHmCAAAAAhZAADybRIAAAEAAVsTAADyAAMAYm1z818EAAABAAEAASYMAAAIOQAA80IRAAABAAEA9eoSAAABAJMAAQABAAATbmlkaXJlY3Rpb25hbHN0cmVhbQAAAREUAAAACDgAAPIdFAAAAQAAAARlc2V0AADzRREAAAEAAQAAAAZ0YWdyYW0AAAFsEgAAAPIAAgBhcgDzbxAAAAEAuwEAEWRpcmVjdGlvbmFsc3RyZWFtAAABAhQAAAASgAEBsIAT+gABaXX2AQCDaXZlhYKgAAAAEFCwcBNHAAEKQBgAAAO2AQCAAgOgQAAAElJldmxvdAAHYnN0cmFjdAAAARISAAAA8gNpbmQBAGEB5gYAAAAIawAAOzAAAAEAAAYAAQDfBgYA9FsPAADKAGgCAQASgAEBsHASCAABb2UACG5vcmRlcmVkAAABQREAAAAIIQAAAQIRAAAA8gRvZW5kAQBlAcIPAAAAAAhhbmRzaGFrZQAA9D0RAAABAAEAAQAACAIAAAEBEQAAAPIDYWN0AQBlAVEPAAAAAANyb3IAAPPiCwAAAQABAADygAIAcngAB2F0YWdyYW0AAPILEAAAvAAAAAN1bmsBAMAAAAAPwXPyTw8AAAEAAAALcnRzZnJvbWZpbGUAAAFTEwAAAPKAAgBlaAACdWYAAAE4BwAAAAgGAAABlBAAAADyA2JsZQEAZfLkCAAAAQAA9g8AAIiBoAAAABKynwAMAABA9PsBAABhAgEAAQD3vgsAAAEAZAABAAEAjgYWAAEBAPU3EgAAbgABAEUBAQAAhHRpcHYCANAAEP0AAdAAEP8AATQ28gJ1dAEAYfIoDAAAAQAA8oFoAQFvZXYAAIADAhku9f2J+qBwAAAQpGNkc2109t80AMnJFEJuxde8W/rE0c3hOZF6OQbTsHARcgABwAlUAwCCqiwAOzAAAAEAADIADQCGBQAAyAYBAFgHEwDlCwAAkgwAALUMAQCRDw0A0Q8BAJcQAADvEAAA+BABAGgSAQCeEwEAAQkA8xsSAAABAAEAAQEA86gHAACSBwEAE4ECoFAAABAqZXMBBAGwMBKpAAFz80wQAAABAAEAAYACoBAAAA9ysAAIvgABZGUBAgDzhwwAAIQGAQAAFG9ubmVjdGlvbmlkZ2VuZXJhdG9yAAAB7RMAAAASAm9tAQKwQBOGAAGgUAAAEWRjYmYB3gYAAAASgAIB5lAAAASaGt4PWos5ZGdzthMAgMHMbuLrIFcgsAAHJAABEyWq7r8GUJEKGUzdYP/iYbovH3gjWdKKoAAAAASqAAAIAIBTpkoAAMbPAYAS1nbtWE4l5kwIHmGIwxVRDyX58RudcJOZiQ/zCUUTvYSkdRSqsc2WX4dvZzINYxdAMsBqDAC4whKJBhqQTFzaDVqfX3YIV09xUo3JOzMS73PhRNKltvVIVkHoSJQZIsSAIxVFUljxQdYaTTiXEAWodMse6f8kfyMGbzYAQAQYBoBbp2kAOzAAAAEAAMIAYQB3AAIAfQACAJMAAACoAAMA3wEAAAQCAQCIBAsAmAQBAEoFAACFBQAAhwUBAJkFAgCRBgAAxgYBAPIGBAAjBwAAKgcBAMgHAADYCAAA3QgBAA8JAQA9CQAAzgsAAN0LAADiCwIA5wsAAPQLAAAGDAEACQwAAA0MAQATDAIAfwwAAIwMAQCaDAAApgwCAK0MAAC4DAEAOA8BADwPAQBCDwAAVw8BAFwPAQBfDwEAZQ8AAHIPAACiDwEAxw8AAO0PAgD0DwEA+Q8BAP4PAAAFEAEADhABABkQAABQEAAAhBAAAI4QAACTEAEAoRAEAK8QAQDfEAIA7RABAAERAQAFEQIAXhEBAGoRAQBxEQIAdxEAACcSAAAwEgEANRIBADgSAwB7EgEAixIBAI8SAQCVEgEArRIAAK8SAQC8EgAAvxIDAMQSAgAlEwEAMhMAADcTAABlEwEAbBMBAHYTAQCPEwAAmhMBAKITAADAEwEAxxMEANATAgDmEwIA7RMAAPkTAAAGFAAAAYACoCAAAAk2oDAAAAwYZXIBAQD0OQcAAC8I3AABAPGAAlEAbnMBBQA7MAAAAQAA9wACAI4MAQA5DvUAAAtlcnZlcmNvbmZpZwAA8kMSAAABAAAAC2xpZW50Y29uZmlnAADyQRIAAAEAADKAAgGwIBIIAAFjc2LygAEBY3ZSgAECoBAAAAfBaWRlAANhdGgAAPI7EQAAAQAAAAJudgAA8sUQAAABAAD6hAIAZXAACWxlZmFjdG9yeQAA8mwRAAABAAAABWN0b3J5AAD0bQ8AAAEA6gABAADygAMAYWlyAAJpcgAAAT0JAAAAAAVvbmZpZwAA8qEMAAABAADyAm9nAwBjZGYBWwQAAADyAAIBbHVwADswAAABAABXAAMACwBVAM8BAADcCwAAAQABdOKuFiurYfL/EAAAAQABAAE3xo7aF/Rh8v0QAAABAPOAAjQ2AQACoCAAABFVoDAAABIaYmjykAUAAMUJARMA9P4TAAABAAEAAQABBwDzGxIAAAEAAQDzgANkcnQBCAD05hIAAAEAAQABABOAArAABKkL2nBzAQgA9A8TAAABAA8AAQAjgAKgoAAAE5hhdAEEAaAAAAASuXP0WQ8AANcDAQADAPMCAXMBkQYAAAEAAPQJBwAAAQABAAEA8YUCmptobQAIaW9sYXRpb24AAPK6EgAAAQAAEgJvbAEBBwDUVq4xdnPyOwkAAAEA8mgTAAABAPIAAQBjAAEYDAAAAQICoLAAABO8oLAAABO9Y3PzURAAAAEAXAAADG5pdGlhbGhlYWRlcgAAAY8TAAAAAAVlYWRlcgAA8moRAAABAADygWQCAGhp8oJjdAEBZWnygAIAZW9wgAEDAJ8JsEATwAABdGJwdvGCAqWmaG0ACmtjczhrZXlkZXIAAAG8EgAAAAAFZXlkZXIAAAGTEAAAAPKDYXRlAgBrcAAEcml0eQAA8jkJAAABAPJjEAAAAQAAA3NvbgAAAU4PAAAA+kYBAGrzVwUAAAEAAQAA8oADAW5vdmEAjHJyZWRhZGRyZXNzdgIA0AATTwAB0AATUQABNDYSgAEBsBAP2gABZWkSgAEBsFATpAABZnPygAMBZWlveAGAAXq/1i8SvHQBAgD25wgAAFcAyQYBALIAAQAACWlibGV2YWx1ZQAAAZIQAAABpBIAAPIAAQBzAAF4DAAAAARyaXRlAADzSw8AAAEAAQAAAAZhbnNtaXQAAAHEEAAAAAAFbWVvdXQAAAFXEAAAAPKAAgBpcgAGdXRkb3duAAABwxAAAAAAAm5kAAABJwwAAADygAIAZWgIDgAA8yMMAAABAAEAABrCAgDnYAAADCZhYwADZXh0AAD0HwwAAAEAAQABAPLXEAAAAQAABGx1c2gAAPJJDwAAAQAAAA1uZHBvaW50ZXZlbnRzAAABThMAAAAABGxvc2UAAAFIDwAAAPIBbIiANCAXOzAAAAEAAA8AAgD6AQAATAQOADswAAABAAAJAAEAqgsJAAGBAqAgAAAQerBQEi4AAWFvAQMBoAAAABNOcwF5EAAAIoABAcAAAAAHyHJ2UgJudAECsFAQ6gABZWNzADswAAABAAAIAAQA0QgCAP8IAQD2DwIAFBIAAPYCAICDg7AQE2wAAQAJAgBgAQEAAPUZCQAAAQABAAEAAQAIIgAAAR4MAAAA8gABAHA7MAAAAQAABQACAPgBAQBIBAMA8i4SAAABAPIAAQBnAYkAAADzcQQAAFAIAQDygAEBbmQBAQA7MAAAAQAA5wACAKEFAADXB+YAAQABoEAAABAZZTswAAABAAAHAAIAPgcFAM8HAQABBAD0MBAAAAEAAQABAAGBAqAgAAAQmrBAEt8AAWVp84ACZXQjgAKgQAAAD3tpdAAZaXN0ZW50Y29uZ2VzdGlvbnRocmVzaG9sZAAA8hkUAAABAAAAC2lwaGVyc3VpdGVzAAABuRIAAADyAAEAYwFHBAAAATYJAAAygAICoJAAABPSsEAP1AABZnNhYgASZW50b3ZlcnNpemVkcmVjb3JkAADyphMAAAEAAAAJaXNiZWhhdmVkAADz+hAAAAEAAQAAAApjb21wYXRpYmxlAADzPhIAAAEAAQAAAAZlbnRpdHkAAPW+EAAAAQABAAEAAQAA8oACAGRu+ksDAGltcwDylRIAAAEA9gEAAIKFLr2YuKB3c6ws8IlBEAABDCECADowAAABAAAAAAAOABAAAADaCBUJFgkXCRgJ0AvRCzYPNw9eD3EPXBCAEPsS/BIBCAD1SRMAAAEAAQBzAAEAAQEA82AFAAABAAEAAQsA9g0TAAABAKMAVAAWAAEAAQMA8z4SAAABAAEAAQQBoKAAABQmd/IWFAAAAQABDQDz3BMAADEAAQAADW5zdGFibGVvcnBvb3IAAPJsEwAAAQAAAAVhY2t1cAAA9DwSAAABAKQAAQAAAAh2YWlsYWJsZQAA9PYSAAABAIUAAQAAMgFzAgGwQBLFAAFhYmXznwwAAAEAIAPyFRIAAM8AAAAAAPXgCwAAAQBkAwEAAQAA8oJhdAIAc3UABmxvY2tlZAAA9AkQAAABALIAAQAAMgACAaCgAAAUJmJ0d/JVBQAAAQDzxRMAAFEAAQAAD2lyZWNvbm5lY3Rpb25pZAAA9I0TAAABAEsAAQAACGkAAPQHEAAAAQCyAAEAAAAQdXJjZWxpbWl0cmVhY2hlZAAA8usTAAABAADygAIAb3A6lwIBsIATCwABc3RjAA5ic2VydmVkYWRkcmVzcwAAAXsTAAAAAAxjb25uZWN0aW9uaWQAAPT0EgAAAQCnAAEAABKAAQGgcAAAE7B3ZxKAAQFZHC2qfcllbwgbAAGgYAAAEjdy85EFAAABADUC9NcLAAABAMcDAQABgAKgQAAAE0awMBJoAAFhcwADZW50AQDQAAyeAyFz8t4LAAABAAAIRgAAAd0LAADy4BAAAAEA8oACAXJ2bgAJZHNibG9ja2VkAAD0aBEAAAEANQEBAAAAB2FsbGVuZ2UAAPSQEAAAAQCoAAEAAPKAAgBoaQhFAAABNwcAAAAAAmNuAADynAwAAAEAABIBawIA0AAMHAABZXPyNQcAAAEAAAAFZWFzb24AAPKNEgAAAQAA8gVhbmRvbgEAcvRrDwAAAQDpAAEAAPKAAgBiY/Y/AwCKhKBQAAARCT5NrLbJ4RdhC4CUAPX1AQAAAQABAE4CAQA6MAAAAQAAAAAAFAAQAAAA4gjZCxoMGwweDIMMhAyFDIYMMQ4AEE8Q9hD3EDsRPBF1E7oTuxPOE88T8oABAWhpAQAAOzAAAAEAABMAAQBYBxMAAYQCsEAT0AABIs46YmvaZXMjgAKgIAAADIdibQACcmQAAAGbDAAAAAAFZWNvZGUAAAGPEAAAAAACbXAAADswAAABAAATAAEAqw8TAACyg2lhbISA5xAAAAvcHEAAAAdudGVycm9yAAABjhAAAAAAB3l0ZXNpemUAAAEREgAAADoSAgGwABKtAVliaXLyUwUAAAEAAPKAAgJzdGFlAARvbXR1AADyQw8AAAEAAAACbmcAAPIzBwAAAQAAEoABAaAAAAAFiGly8oACAGR0AQAA9EYQAAABAAEAAQAACGhyZXNob2xkAADyahIAAAEAAAACZXkAAPLaCwAAAQAAAAplY29kZWVycm9yAADyixIAAAEAAPICZXQDAWRrdHPz2wYAAAEAAQAAAAZuZ3JhdGUAAPKpDwAAAQAAMoACAbAAEqABP2lrZfYOAICEhLAQByoAAQwABQAJUPaRMQDFzaCQAAASo3knfXcnBbBACL4AAaCQAAASvDds9FFEwCzspJE6Py1e6VCTKkiXmWZUT0BEkAAAMy8PADswAAABAABGABAAlAATAJ8BAADjAQAA5gEAAAwCBgByBAIAewUAALQGAAABBwIAwQcAAC0JBACYDAAAqw8TADwSAQDhEgEADxQBAAEAADswAAABAAAIAAIAegAAAPULBwARAAKkoCAAAAfBcHUBzwEAAAEDAPXdCAAAAQCBBgEAaQQjgAIh5QGsl99ucgGAAmOFAFaSfaAgAAAQAmNpAQEBsLAT6wABbDswAAABAAAMAAMA+AYIALEMAQDPDwEAE4ACoEAAAAvPY3QBAAEG6LbFTuxp85gMAAB3BwEAAQICoCAAABFVoDAAABIaYmgBVQ8AACOBAqCAAAASuGFwAYQCsAAQ/QABsAAQ/wABNDYIVAAAAZAFAAAAAAdmYm91bmRzAADyaQ8AAAEAAAAOb2luZ2hhbmRzaGFrZXMAAAEZEwAAAPIAAwFnb3BhADowAAABAAAAAAAOABAAAADqCOsI7AgoDCkMZg9nD1cQERFgEmESWhPcEw0UDhRWDgCAAQegEAAADJmwkBEDARUARVrPEAl0M2dsbnBycwEDAPQVCQAAAQABAAEAAQABStaGewQ3YwEYDAAAAQABsPAUDwABa/aDEwAABQABAAEAAQAlAPMDAWTyShIAAAEAAYICsHAToAABoEAAABCXaXMTgAKwYBMnAAFlbwEBA6BwAAARWKBAAAATM6AwAAAPVmRsc/LgEwAAAQAIWgAAAZoMAAAA8gJlcgEAZfKYBAAAAQAAdg0AAIGHcp/CavKEP0lYfDiqgAAAFWEEAPOEAAAATAEBAAEEAPNFEgAAAQCoAPMAAWM6MAAAAQAAAAAACgAQAAAAbQ9uD1gQWRDiEGwRbRGBEoISCxQMFAGAAqBAAAAQGiSu+B6GF25wAQIBK+pnYX6mbTswAAABAADnAAIAfAUAAKgF5gABgAOgQAAAC86gEAAAC9awcBPmAAFhZXYBgAJ+SnXUjGGgMAAAEE9jcAEEAPNoDwAA3AABACMAAqCgAAAS22RxOjAAAAEAAAAAAAgAEAAAAMgGyQa1DLYM0Q/SD5cQ+BD5EAEHAPQNEQAAAQABAAEAAQEAOzAAAAEAAAgAAgAvDwYAyhIBAPOAAmRuI4ACsJASVwABZW8BAAD0OQkAAAEAKQcBACOAAqAQAAAS8mh5AAZkc3RjaWQAAPJTEAAAAQAA8oABAWd0AYECoBAAABKzoHAAABL6YWPzAQFy8ikRAAAYAAgLAAGwgBNUAAF0AeMIAAAA+qsBAWll8gABAGUBiAAAAPObDAAACwcBAPZrAACCiVZB6EiUGWVIIAKhLggBABSUTQA7MAAAAQAAaAAyAIgECwBKBQAAhQUAANgIAADdCAEA3QsAAOILAgAGDAEAmgwAAKYMAgC4DAEAVw8AAFwPAQBfDwEAZQ8AAO0PAgD0DwEA+Q8BAP4PAAAOEAEAGRAAAI4QAACUEAAAoRACAOAQAQDtEAEAAREBAAURAgBeEQEAcRECAHcRAAAnEgAAMBIBADUSAQB7EgEAixIBAI8SAQCvEgEAvxIDAMUSAQAlEwEANxMAAGUTAQBsEwEAdhMBAKITAADHEwQA0BMCAOgTAADtEwAAAQcCoLAAABO8oLAAABO9Y3PzURAAAAEAXAABgwJ2va6ffudUf0kcFmVobfOAAmlvAAJvbgAAAY8FAAAA8gABAGnzhQAAAAEAAQABxgsAAAAQaXJlY3Rpb25hbHN0cmVhbQAAAeQTAAAA8gJuaQEAZPIyBwAABgIAAANhdHMAAAFnEQAAAPIGdHJlYW1zAQB0AAEaEwAAAAVuc3VyZQAA8mgSAAABAAD6OQEAZfPiCAAAOAMBAAEAEAAACCYAAPSLBQAAAQABAAEAAAAKb25uZWN0aW9ucwAA8mYSAAABAAAIBwAAAdgTAAAA8gFpAQBk8ooFAAA8AgDyAIaAFoAK80IEAAABAAEAABKAAQGgoAAAE9JucjYCAACChaCwAAATmKCwAAASpGxkHGRCM0s60gK+7hAABADQAwA7MAAAAQAACgADAOYBAAAMAgYAcgQCAAGEAqAQAAAMmaAwAAAQAjNzAYECsDASjQABsEASqwABYWYBgAKwIBO6AAGwYBNoAAFhcgGAArBQE+4AAaAQAAALxmZwAQIAOzAAAAEAAAYAAQDjEAYAAQIBoEAAABOiZfLMEwAAAQDzgAJpbwGAArBAEioBDqAgAAAQp2FpAYECsAASUwABsAARYgABZXMTgAKgMAAAEx5hcgEIAPMyEgAAAQABACOAAqAQAAAS/WRzABV1cmlvdXNjb25nZXN0aW9uZXZlbnQAAPT+EwAAAQABAAEAAAGBAqBAAAAQJ6BwAAATvWFlCE8AAPTCBwAAAQABAAEAAPIAAQFucgD25wgAAFcAyQYBALIAAQDyAAICZXBpdAD1ZhIAAAEAhQABAPAAAAd1dXBkYXRlAAA7MAAAAQAABwABALIQBwAAEoABAbBgEXgAAXRpAAZ0ZXJ2YWwAAAGoDwAAABKAAQEQADslZJpuZAGAArAwE3YAAbAwEkgAAWNpAAV0Ynl0ZQAAAbEQAAAAEoABAbAgErEAWXNtEoABArDgE3AAAVyPw1ijrHJkZ/KAAQFpYQEDAbAAEpcAAXM7MAAAAQAADQADAGARAQAREwcA/hMDAAEFADswAAABAACHAAIAdxAAAIARhgABggKwIBADAAGwQBD4AAFsc/OBAmt1AQMA9V4RAAABABwBAQBWAQEDADswAAABAACGAAEAqg2GAAEAAPS5CwAAAQC0BQEAAQIAOzAAAAEAAAcAAQD1CwcAAAVkYWNrcwAA9KQPAAABAAEAAQAA8gABBm5iZGlydHYAOzAAAAEAAIwABQD0AQAAgQQAALwEhgB+EAEAGBEBAAALZXN0aW9uZXZlbnQAADswAAABAAAHAAEAERMHAAAa/QEBsNAUCwABZ3QAAAAA8uEIAAA4AzswAAABAAAFAAIAKBIBAH0SAwDyAnNlAQBkADswAAABAAAJAAMAWhEDACMSAwBVEgEAEoABAaCQAAATvG9pMoACAQqkyrRQRGxvdQAEeXRlcwAAATcJAAAAAQUA9NgTAAAMAB4ADwAjgAKgYAAAEvJncwgtAAA7MAAAAQAABwABANMGBwAAUoABArCQE7oAAWNibPZvJwCIilJ2dWauHCzcPXeO80YNElCgNLBQEpkAATcRAsDolQA7MAAAAQAATAAfAI8FAADfBgYAPAcBAMAIBQDQCAAA/ggAAMgLAAARDAEAiQwCALMMAQAyDgMANw4BAE4PAABbDwAAaw8BAIQPBAAlEAAAURABAFUQAQCLEAAArhAAAM0QCQALEQAADREDAFgRAACNEgEAoxIAALoSAQDMEgUA3BIAAJATAAABAQKgwAAAEsmgYAAAEBpjcvKnBAAAyQABgAEu8l5jtuRu8gAAAmVpAQkAAAAACB8AAPLRBgAAAQAAEoABAbAwE+4AAXNsEoABArBQD2kAAVi8b5HbDWZidQGEArBwE4EAAbAwEtcAAWVzAARhZGRyAADyOhIAAAEAAAgAAADyOBIAAAEAAPKCcHYCADQ2AAt4dGVybmFsYWRkcgAA8zITAABoAAEAAAEGAPQSFAAAAQAKAAEA8wIBcgF7EwAA8gNkZHIAAWX0BRAAAAEAqQABAADyhWVydmVkAwBhZWmSgAEDoLAAABN1fk9UJKcpc2FldQAACA97AjzY94M4hnQyGdU4Feb5mAQdbd9yJ0YizzRTNOgQ7XXSp2on+MOKqCppbMXP7vKgMAAADAgt0OMbDlVNLEYxe/9iCuXWFydcu8egPANPCzAE1RZldOPVbkJf1Ng/lJVJllaJOG4fOqLfABBP9PfunjNmQul2vDw8btMrqTxyHSamGpdPe63rcHZiZmtucHJ0dTBhY2RlZ2lsbW9xc3Z3eAA7MAAAAQAAdgISAO8BAAAAAgEAVAPmAKcEAABwBQAAgwUBAJwGCgAvBwIASAcAADUJAADDCuYAGAwAAK4MAACqDYYA2A8BAPMPAAArEAMA6RMBAAEAAqCAAAASR7BwE5cAAWFzOzAAAAEAAAgAAgB1AAAAIgkHAAEBAaEAAAAT5GTyMgcAAAYCI4ADoAAAAAvpoWAAABPebW5zAYGFsDASjQABsEASqwABoFAAABITsKAS3QABsHARcgABIQgKAQYBBwDUVq4xc/JoEwAAAQABAgGwUBJoAAFl9uIIAAA4AwEA5QO6AwEAU4ADoBAAAAx4YW9yAQEBN+wyfWX9dfK/BwAAAQABCQDzRRIAAAEAqABTgAOwYBF4AAFlaXQBAQD0dgwAAAEADgYBABMAA6AwAAAHSTa078memmVuc/V/BAAAAQDPCgEAjAABgAKwIBKxAFmgUAAAELFtc0OAA7DgE3AAAVyPw1ijrGRncjGAAzkAsAAMrgNFYWlvAQABoQAAABPYZPKKBQAAPAITgAOgUAAAEq6gMAAACTdpbHkBAAGgoAAAEttk8sgGAAABAAEEAaCQAAAS+nLyKREAABgA84ACZGUAAAABsAAElwKybjswAAABAAAGAAEA0gEGAAAACWlhYmxlcGF0aAAA8vYQAAABAAAADm5vdWdoYWRkcmVzc2VzAAABuBIAAAASAAEDoGAAABMzsHATJwABP0lYfDiqZWFjbvOEAAAATAEBAAAAAmRwAAABwQcAAAAAA290bwAAARgMAAAAAAJyZgAAATYJAAAA8oACAGVy8gACAHB1Ac8BAAAACHoAAAG9EwAAAAh6AAABvBMAAADyCG90ZWN0aW9uAgBjc/NREAAAAQBcAAASgAEBoAAAAAvGcnQAA2l6ZQAAAQIQAAAAIoRlcm91AgDjIAAADJkzcwAEdG9yZQAA8vgQAAABAAAIdwAA8gMQAAABAADyhG9rZW4CAGxz8gABAHQB9AEAAADygAIAZXoAEW5pdGlhbGNpcGhlcnN1aXRlAADyMBMAAAEAAAgvAADy3QgAAAEAAAASZWZhdWx0Y2xpZW50Y29uZmlnAADyahMAAAEAAAARZGF2YWlsYWJsZWZvcnBhdGgAAPLOEwAAAQAAABNydGlmaWNhdGVzcHJlc2VudGVkAADypBMAAAEAADKAAgGwQBCMAAFlaW8AEnBwbGljYXRpb25wcm90b2NvbAAA8mgTAAABAAD2fwEAy8OwUBPuAAGgsAAAErhAR2gaAAiABAD0LwcAAAEAAQAEAgEEAPSkDwAAAQABAAEAI4ACoEAAABQmYWQBAAKgMAAAE9egUAAAE2djczswAAABAACSAAcAiwUDAEUHAACoBwAAQwmGALkLAQA6DwEAbhEBAAGAAXX5o2HidXQAB3J0dGtleXMAAPQ1EQAAAQABAAEAAPIAAQAx8kAEAAABADswAAABAAAFAAIAHwwDANcQAQASgAEBoIAAABCadHAAEWl0aGFic3RyYWN0c29ja2V0AAABwhMAAAAAA2tlbgAA9N8IAAABADYDAQAAAANtZXIAAPMTDAAAAQABAADygAIAaW8ABWVuZGVyAAABQg8AAAAABW9uZmlnAADyjBAAAAEAAPIBbwEAY/QvBwAAAQABAAQCAAAFZWl2ZXIAAAFQEAAAAPrHAgBjbgAMeHBlY3RlZGl0ZW1zAADy3xIAAAEAAAgyAAD0ZREAAAEANgEBAPT0EgAAAQCnAAEA8glvbm5lY3Rpb24BAGkBixAAAADyAIaAFAAXOzAAAAEAACQAAQCqASQAAPGAAmhpa3UINQAAAU8QAAAAAANpbnQAAPKJEgAAAQAA8gVoYW5nZQEAaADzchMAAAEAawDyg29yawIAY3DygAEBd28AD2V5ZXhjaGFuZ2Vncm91cAAA8g8UAAABAADyAAEAawD2gxMAAAUAAQABAAEAJQDyBm90aWF0ZQEAZADyShIAAAEA9J8AAMTIAAMJFmwZGm4bH3yLaD1zsBAQyQABcwAQADKAQ4gJADswAAABAACMAAUA9AEAAIEEAAC8BIYAfhABABgRAQABiQJ2va6ffudUf0kcFmVobQEEAPTYEwAADAAeAA8AI4ACsHASMAABaXQHAQCAhUqwEt6SQbBAEO0AAaBgAAAS8qAgAAAJAVEBAgEBADswAAABAAAHAAEA0wYHAAGBArAAE0YA4LEgE+4AAWRzI4ACsIATugABYWwBAgOwIBDLAAGgUAAAEXCgQAAAE6Nsc3bynhMAAAEAAQIA84YPAAABAAEAAQEAOzAAAAEAAAYAAQAfFAYA8wYBZfTTEwAAAQAvAAEAAAZwZGF0ZXMAAPLzEgAAhwAAAARuZGVkAAABjBMAAADyBG91bmQBAGUA8vwTAAABAPIIcmF2ZXJzYWwCAXJ1YQEBEAAA8mQSAAABAPKAAQJ0aXUABGF5ZXIAAPKiDwAAAQAAAARyb3VwAAABmAwAAADygAIAZ2waDwEBsDAS+wABZHQA9qwMAADHAloAAQC5AgEA8oACBG10YmNscAAMbmF0dHJhdmVyc2FsAADyZBIAAAEAAAAABBRUkAWBAOcypoEpUeht6nGOOEhQOXkSq+FLX2iNiDBvMUg4lttGTT22p4IxXaafJLZWbpl+WVIBqDTl2CJIcRdS6Gl1hS0ZKHc9TaqTGi04+Cw/9KRJfWofugdqoBBxD74HB56eKzMd4bVHOg4S/C1PaFYLb8O5YTg0bra+blGwUBKZAAE5nBvQsHMegMsKKTkwYWVvYmNkZmdoaWtsbW5wcnN0dXZ3eXoAOzAAAAEAAIwAOQAHAAAAiQAAAKwAAwCiAQMAqAEAAN0BAQA7BAQAQgQCAGsEAQBxBAAAlwQAAGAFAgBvBQAAdwUBAI8FAADfBgYAPAcBAEkHAgBNBwMA1QcBAMAIBQDQCAAA3wgBAP4IAAC8CwAAyAsAABEMAQAWDAEAiQwCAJwMAQCzDAEAuwwHADIOAwA3DgEATg8AAFsPAABrDwEAhA8EACUQAABREAEAVRABAIEQAQCLEAAArhAAAMMQAADLEAsACxEAAA0RAwBYEQAAdhIBAI0SAQCjEgAAuhIBAMwSBQDcEgAABBMBAJATAAABBQDzfhMAAAEAAQBDhAOwkBP6AAGgAAAAEitiZHcTgQKgMAAAD4ljbQGAAqAQAAATU6BQAAASGWxuI4ACoEAAABFkYWkBBgD0kRIAAAEAjwABAPMDAWL0hxAAAAEAhQEBAAGAArBAETMAAaEwAAAT7WhvAQIA8wMMAAABAAEAE4CEoCAAAAv0sBAJCgABsDAThgABAAlIAQEBsIAS2QABdfITCQAAAQAAAAAAAakBAAA7MAAAAQAA+QAJAH0FAADHCAAAzQgAAMULAAABDAEAlQwAAMMM5gA9EwUA8hMFAAALdG5lZ290aWF0ZWQAAPSIEwAAAQABAAEAABKAAQGggAAAE7BvZRIGdGlwYXRoAQKgYAAAE0Zztxn4D+xuZXAB2QsAAAC2AACAAgOwEAkRAAGwYBEzAAFsdDM2bQEGAPNxEAAAAQANAQECAaBAAAARcWXzsAwAAOgDAQAADXNjb3Zlcnljb25maWcAAPS2EgAAAQCVAAEAABKAAQE+BT0+oSVpcBIAAQE37DJ9Zf1kdQA7MAAAAQAACgAEAL8HAQBDDwEAgQ8CAIoPAwDyAAECdWlvADswAAABAADpAAEAsgDpAAEGAPP6EAAAAQABABOAArBAEXgAAWJtAQMBsEAT4AABdPJEEwAAAQAjhQKgQAAAE3RicyMAA6BAAAAQg6BQAAAQ72FiZvfWCAAAAQBIACsHAQBfAAEAAAxlc2V0aW50ZXJ2YWwAAPLdEgAAAQAAAAJ0dQAA8r8HAAABAAAACW11bWNoYW5nZQAA8jMRAAABAAB2AQAAg4OwEAyuA0WgUAAAEXcAEQFgAAQBqAEAAAAABnJhdGlvbgAA8hEMAAABAAC2AACAAgOwAAjoAAFM2aWCl2RnbmRzdAEDAPN3DwAAAQAAAQEDADswAAABAAAKAAMA8RACACkTAwAHFAMAAQQA9LEMAAABAB0DAQAzAAOwMAyQAAFvc3QBxhMAAAEAAPQCCQAAAQABAAEAQwADoEAAABP4sCASjwABZXJ49BMMAAABAAEAagABCADzRRIAAAEAqAABgAKwsBMlAAGgMAAAEXFucgECAPPqCAAAAQABAAEGAPT8DwAAAQCrAAEAowCEoEAAAAyYsEAPogABQEkA89YLAADbBlkAAQIAOjAAAAEAAAAAAAcAEAAAANAL0Qs2DzcPcQ9cEPsS/BIBAAD0BgkAAAEAAQABAAGBArBAE9AAASLOOmJr2mVzAANpY3MAADswAAABAAAHAAEAtwcHAPKDEgAAAQBWAwCAAQWgAAAACOawcBFWAAFyYWVoeHnW4gAAwcugkAAAEtygEAAAEPBJnheBTqohKbEn4lygMAAAE3UAAAACAEe8CQA6MAAAAQAAAAAAIgAQAAAASwVMBToHOwfJB/cIKwksCZYMlwysDLAMUw9UD3MPdA/ND84PGhAhECIQIxAkEGEQYhCYEJkQcBEHEocSiBJYE1kThBOFEwECADswAAABAAALAAIAPRMFAPITBQDzCAFtOzAAAAEAAAwAAwDsEAAAWRIFALITBQAABGV0cnkAAPIPDAAAAQAAAAdyYWdtZW50AADzTBAAAAEAAQAAAAZlZnJhbWUAAPKWDAAAAQAA8oADAGJmcgANZHBwYXlsb2Fkc2l6ZQAA80kTAAABAAEA8r4TAAABAAAPcmFuc21pdHNlZ21lbnRzAADyeBMAAAEAAAhUAAD0iRAAAAEAhQEBAAAAA2lkaQAA9PQQAAABAG0BAQAA8gACAGJ1AaEPAAAAAANhdGEAAPSHEAAAAQCFAQEAAPKEcmVhbQIAZHMAAnplAADz2wgAAAEAWAAA8oACAGl0ABhvdGVuYXR0cmF2ZXJzYWxhZGRyZXNzZXMAAAEjFAAA8iQUAAABAAAMZWl2ZXNlZ21lbnRzAADyRxMAAAEAAPqVAgBjbQAGZWFjaGVkAAABNxIAAADyBWF0aGlkAQBy9NcLAAABAMcDAQAAAAZjb21pbmcAAPJKEAAAAQAAAAlsZXRpbWVvdXQAAPJgEgAAAQD0WhMAAIIAMQABAPKAAgBkbgAKc29zZWdtZW50cwAAAV8SAAAAAAdyYW1zaXplAAABmxIAAAD6CwEAZ/QtBwAAAQAEAgEAAAAJbmlzdHJlYW1zAADy4hMAAAEAARgUAAAIYgAAAZkTAAAB5RMAAAANdWx0aXBhdGhwYXRocwAA8hYUAAABAAAACGlzdHJlYW1zAADy8BMAAAEAABrfAQGgYAAAFBRkc/YAAIlvbmN1cnJlbnQEAaBAAAATxWJtc3VwAAdja2RlbGF5AADyrBAAAAEAAPY/AACKgbCwEqkAAU2BDyAAAPSAAAAAAQABAAEAAAAGZm9ybWVkAAAB1gsAAAAIWwAA9TsEAAABAAEAAQABAAD2BACAhISwMAcmAAFxLLnZ7Pobgt1N9wkACWAEIAX2HwQAxc2gIAAACQ6wkBK/AAF6xN3uoJBI7NgwpMEdq7HF1HVKvhJJTW+wcBPmAAGgMAAAEuVARAAGgAu3GQA7MAAAAQAAWQIhAO0BAAATAisBnAUDAN4GAAAGBwEARwcAAMoIAgD8CAEAygn4ANULAADmCwAA6QsAAKMMAgCpDAIAbw8BAMMPAQDIDwEA5g8GAAsQAAAQEAAAKhAAAC8QAABaEAEAxxABAGwSAADyEgAA+hIAAB4TAABDEwAA2BMAAOQTAAACFAAAERQAAAEDAPNLDwAAAQABAAEEADswAAABAAANAAEAGxENAPOAAmlyAYACoDAAAA/7sHASugABYWkBAAKgMAAAC+mgcAAAEVlldvP7DwAAlwASAhOAA7BQEvMAh7AQD0kAAWVwcwEBAPOODwAAAQABAAEDAaBAAAATjGXy/BMAAAEAAQEA8yMMAAABAAEAE4ACoBAAAAwmYWNzgISgUAAAD3QQQAwBCQD0DxMAAAEADwABABOAAlCjoaF2YW1uAQIAOzAAAAEAAAUAAgAfDAMA1xABACOAArEwFB8AAWFlAQIA9IoPAAABAAEAAQABAgA7MAAAAQAACAABADsQCADzAAFlAQcCAAABgAKgQAAAE4+gQAAAD/9lbwEAAaBQAAAS8m8B+ggAAAGAA7AwD0kAAaBAAAAL1qCQAAAT12xvcwEBADswAAABAAATAAEAqw8TAIOAhKBAAAASerCQEzAAAaAwAAAPSIAZAAGAA7CwEq8AAaAQAAATM7AwDMEAAWNlcwEBAaBwAAASs2UBmwwAAAEIAPNxEAAAAQANAROAAqDAAAATmG1wAQIA99MPAADTAKMCAQABAHMAAQATgAKwMBBoAKRpdPMBAXPy7hMAAAEAAAtwbXR1ZHByb2JlcwAA8g8TAAABAAAABWNrZXRzAAD0RhAAAAEAAQABAADygAIAYWwIXAAA9D4PAAABAAEAAQAA8gACAGJwADswAAABAAAGAAEA4xAGAAAPcmVkdWN0aW9uZmFjdG9yAADydhMAAAEAADKAAgF5K/67QLRzdGUAA3lwZQAAAdoIAAAA8gABAHTy8gEAAAEAAUYHAAASgAEBAFhuWCZYZ2UBggKwIBDFAAGwMBE7AAFlcAEFAPRtDwAAAQDqAAEAU4ADsJARbAABYWlyQgAAA7BQDKEAAaAgAAAJPWNkZvKmAQAAAQA6MAAAAQAAAAAACAAQAAAAWwTQBu4I7wgDEAQQcRByEH8RAAd5Y2xvc2VkAADyhRAAAAEAAAAAAAD1LQkAAAEAAQABAAEAABKAAQGgoAAAE/hwZgAFb3N0djQAAAH/DwAAAAhaAADyPA8AAAEAAPYAAAFsBAGxQBQfAAFhaGlsbvJRBQAAAQAAEoABAQraiGNAPmFr9h0AAISFoEAAABPJRCACEUARAPLpEwAAAQABAQEfTi+2Z1JpASoJAAABAQGgQAAAE6Jl8swTAAABAAEAAPUtCQAAAQABAAEAAQABBgD0pRIAAAEARQEBAAEEAPS/EgAAAQAHAQEA8wICZXL0ChIAAAEAZQEBAAGBARSQyunS/XQABHRpbWUAAPIrCQAAAQA7MAAAAQAABwADACEQAwBhEAEAWBMBABKAAQGgkAAAE/hlcxYvAADByqAwAAASEyjI2XDPPS91Ey220rBgE3AAAaAQAAAJAQAIAABABySLAAF8AAAAAQUAOjAAAAEAAAAAAAgAEAAAAGYPZw8REWASYRJaE9wTDRQOFCOAArAAEycAAWVpAYADsHATOwABsRAT7gABsCAPxQABZGVpAQIA9u0QAAABAMEBAQAaAQEAQwCEdfK215J3sGASgwABsIAQbwABIBAF8/QLAACYAAEAAYICoKAAABKzoEAAAA/7b3YBgAKwUBFsAAGwUBPOAAFhbwGAAqAwAAAQlLAwEDkAAXJ2AYQCsKAThAABsKAThgABY3LzAAF0984IAAABAJUI5AABAP0A4AABgAOwIBJ4AAGgoAAAE0OwYBMEAAFlbG8BAAA7MAAAAQAA9wACAI4MAQA5DvUAAQAA9JAQAAABAKgAAQATgAKhMAAAFAZldMIAgISgsAAAE06wsBNyAAFYAAT0ogEAAAEAAQABADswAAABAAAHAAMATQcDANUHAQDLEAEA1ocDAMHOoRAAABPeoBAAAAw2sFATbAABsDAQ9gABoAAAAAvcsEAQkgISAAAIAEBf8AsAOjAAAAEAAAAAAB8AEAAAAG0FbgVxBcUG5AjlCPgI+QjAC8ELwgvKC80Lzwt8DIcM1g/XDwkRExIqEj4SPxJAEvYS9xILEwwTOBNTE3wTfRMBgAKwsBPmAAGwIBK6AAFmafECAbRl9NMTAAABAC8AAQDzAgFl9TwPAAABAPUDaAABAAGFArBwEwQAAbCAEzsAAWNzAQIBsGATzgABZjswAAABAAAGAAMAwAsCAPYSAQB8EwEAAIACAMAAAAAHLOdAAAAI2WR4+nkBAGUA8qIPAAABAPIAAQBlAPMiBwAAigkBAAAJdG9wZW5wYXRoAAABABAAAAAAA2dlZAAAAYkFAAAA9gsAgIOFsCAI8AABQABCDgAFAADE0RhR7TU9yAfuXZhhByzFV1VhgBUDBo/YLA1wPQyEBlKurs7p5DZTkAiEjXrZP6Kmy17/8W5d20uA1KUhg0fEIs7jhCxlJ1OQFgymNbGCD0xb8+z0rAwtUy3K9jNAsRlUyidfIpM+KnO8aajfVVnPXgaP8hf8LMsv1w3xutc4eUBEEAAAO69fADswAAABAABCABkA+gEAAAYCAABMBA4AYgQBAHAEAABRBQEAJAcBACgHAAAgCQEAOwkBAKoLCQB9DAAAqA8AAAEQAABpEAMALBIBAGQSAQDdEgEADRMBAGgTAQCSEwQAsRMAAOATAQAFFAAAGxQBAAEBAPV7BQAAwQwBAKQAAQABAAA6MAAAAQAAAAAADgAQAAAAAgIDAn4FjwaQBhwMHQykD6UPpg+nD8EPbRBuEHoSAQMBoFAAABEJaAFPEAAAAQACoMAAABLJoGAAABAaY3LypwQAAMkAAQEA9SoRAAABAAEAAQABADOAA6EgAAATkG5vcAGCArBwEwQAAbCAEzsAAWNzI4ACsEAP1gABYW8BCAE/1sHl46Bj9d0PAAABAL4AAQABAAEEAbAwEokAAWjzchMAAAEAawATgAOg4AAAEzigcAAAErxob3MBCAA7MAAAAQAABQABAEwSBQAAA293bgAAAZcEAAABSQcAAAEAAaDAAAATo2n02xIAAAgAGwAbAAEGAPQHFAAAAQABAAEAAQAA9HcFAAABACQHAQATgAKwcBKxAFlubwEKAbBAE8oAAWX1khMAAAEAAQABAAEACFEAAPI1EgAAAQAA8gVwZGF0ZQEAZQDyVxIAAAEAAAAAAPLwAQAAAQA7MAAAAQAADwADADsQCAA1EQMAMhICAAADYWlyAADyKgcAAAEAAAhXAAAB0AYAAAD2BAAAhIOwIBCTAimwwBQPAAEAiAoYAQAAOjAAAAEAAAAAAAwAEAAAACYHJwcOCdML1AvaC9sLKwwsDHYMdwyFEoYSAA5wYWxpdmVpbnRlcnZhbAAA8g0TAAABAPSxEwAAVAAWAAEAdhIAAIKITjtHghpOsQATqAABFyD9zkP7dv2NV4fVN0fyH5edEABADDgHADswAAABAAAOAAQAdQQFANILAAA9EQMAHhIDAPbeAACCirBAEKwAAaAgAAAMtxAgAK2BCwA7MAAAAQAAFgAKAAkAAAByAAEABwIAAH8EAQDTBgcANQcBAE8PAQDcDwAA/A8BAKgQAQABAAKhkAAAFAagMAAACPdldPLaDwAAAQABAQGwQBCSAhJ28z4SAAABAAEAI4ACoBAAABP5ZWwBAAEIwwSgTbBsOzAAAAEAAAgAAwA5CQEAYxABAL4QBAABAAGwYBN4AAFl9AMMAAABAAEAqgcBBQD0pRIAAAEARQEBAAECAWni+gob/XQ7MAAAAQAACAACAL0LAADrCwcA84ACYWUBgAKwIAj4AAGg4AAAE2dibAEIAPQeEgAAAQABAAEAAQQBsAAQbQABcwHcDwAAAQIBoFAAABJ6YwF9DAAAAQIA9L8SAAABAAcBAQAAA3RvcgAAAdgIAAAB/g8AAFIAAQKgIAAAC8hhaXIAAQkMAAB2AQAAgYawQAy4AAGwEBLfAAGgAAAAErkAAAGVEAIAOjAAAAEAAAAAAA0AEAAAAKYEqARzBXQFdQWADIEMSw9MD00PWQ8wEzETNBM2FgAAgYgNRFRkwZBZAuzzdKiwEAVtAAGwIAdKAAEQAACBCUcAOzAAAAEAAJUACgB8BAAA8ggCAHcQAADEEAAAAxEAAIARhgAIEgMAGBIAAOUSAABwEwEAAAlhbGlkcmV0cnkAAPQvEQAAAQABAAEAAAAEcnZlcgAA8g0MAAABAAAADG1lY29ubmVjdGlvbgAAAdwSAAAA8oACAGFlAA5vYmFibHlzYW1lcGF0aAAAAXUTAAAAAA10aHJlY292ZXJhYmxlAADyCxMAAAEAADKAAgGgIAAAByJhcmwACWVnb3RpYXRlZAAAAbATAAAAAAZuYWJsZWQAAAFGEwAAAPKHbHRpcGF0aAIAZW4SgAEBsDAReAABdWEBAAGgQAAAEHtl89QIAAABAEQJE4ACoDAAAA9lZHIACW5kc2hha2luZwAA9SoRAAABAAEAAQABAADyAAEBYWUA88IGAAABAAEAAAZyYWluZWQAAPI6DwAAAQAAAQQBbXvcbOFWYwEiEgAAAANzZWQAAAEMDAAAAAADZW50AADyCgwAAAEAAPKAAgBpb6KAAgLQAAVPAAGwQAvLAAFlbGFvAANpdmUAAAEqCQAAABKAAQGwMAjOAAFsYgADcnR0AADytQcAAAEAAPQ/AIAJAgABAwgJDREUF98wI/kpdqIwYWNkaG1wc3ZidAGAAqCAAAATsFkcLap9yWVvIwEDoGAAABNGc7cZ+A/sZW5wAdkLAAAAAmRyAAABiAUAAADygAEBZHQWAAAAAQRD15qN6nuhEAAAE5CwMA+EAAEyicHpio5haHN0dgA7MAAAAQAACAADALQGAAABBwIALQkEAAEQAPT+EwAAAQABAAEAAQIA9DkJAAABACkHAQATgAKgUAAAEBppdQAGaWNlbXV0AAABlQwAAADyAAEAbPKgAQAAAQAAFgMAAAEFoMAAABLJsFASugABFOavZgTIc2NsbnJ1APKnBAAAyQAIaQAA8oEQAAABAAAACWVydmVybmFtZQAA8ocSAAABAAAADGVtb3RlYWRkcmVzcwAA8y0TAAABAAEAAAAGZXNzYWdlAADz8RAAAAEAAQAAAAVlYWRlcgAAAYQQAAAAAAZyYW1laWQAAAHwEAAAAAATbmNyeXB0ZWRjbGllbnRoZWxsbwAA8ukTAAABAAAADWV2b2NhdGlvbmxpc3QAAPLMEwAAAQAAAAZmaWNhdGUAAPK0EgAAAQAA8oJydAIAaXISgAIA9kAMkwABZWnyhGFsaWSIgLQQBwAIbm9yZGVyZWQAAAEpEQAAAAAGZXF1ZXN0AADzaA8AANwAAQAACB0AAAH+DwAAAPICZXIBAGEBCQwAAAAIAAAA8jgPAAABAAAABW9taW5nAADyqhAAAAEAAPKAAgBjbvKAAgBudAAFdXR1cmUAADswAAABAAAOAAIAkgwAAJEPDQAAAAJueQAAOzAAAAEAAAcAAQAiCQcAAAgVAAABCAwAAAD2AwAABgGgsAAAE5cwYWZpcnVtOzAAAAEAAOcAAgDvAQAAVAPmADswAAABAABuAQMASAcAAMMK5gCqDYYAAAJhbAAA8iAJAAABADowAAABAAAAAAAIABAAAACoD90S3hINEw4TsRMFFBsUHBQAB2FsZXJyb3IAAPLtEAAAAQAAAAhhY2VpbmRleAAAAQwSAAAAcgADAbAgEI4A6WZudnIAAcgHAAAACXJpdHlsaW1pdAAA8goSAAABAAAygAIBfCMm7EG3Z3J2NgAAAAIEsNATNQABsFAQ6gABoDAAAA9OIQQVJRGWZW9iY2pzADswAAABAAAUAAkAVwUCAKIFAQARBwAA0QgCAP8IAQAyDAMA9g8CABQSAACJEgEAAAJudAAAASkHAADy8BIAAAEAEoABAaAwAAAQKmFyCA8AADswAAABAAAFAAEAygYFADswAAABAAAFAAEATBIFAPKAAgBldPEBATpl88IGAAABAAEAABFuYXR0cmF2ZXJzYWxyb3VuZAAA8vwTAAABAAASgAIA9yAMBgABZW8ABWluZG93AAA7MAAAAQAADQABABsRDQAAAAJ0dAAA844PAAABAAEAAAhhAAD0ig8AAAEAAQABAAAAA2V5cwAAOzAAAAEAAAgAAQA7EAgAAAANc3RjaWRwcm92aWRlcgAA8sATAAABAAD2AQAAhYKwoBMwAAGgUAAAE48IFBGEAAABKAcAADswAAABAAAFAAIAaRADACwSAQDygWECAGx08gABAGkAOzAAAAEAAIcAAgB3EAAAgBGGAFKAAQKwgBEzAAF0bXMBAQA7MAAAAQAAJAAIABQHBwDKDwIAGxENAEIRAgAWEgEAmRIBAOoSAQB+EwIAAAF4AADyTQUAAAEAAQwSAABSAAEDoHAAABISoFAAAA9/ZWFvcwAB5gYAAAALc2lzdGVudGtleXMAAPMyEgAAAQABAAABBgDzPhIAAAEAAQAIEQAAAe8QAAAAAARvdGFsAADy4BMAAAEAAPIDaXplAQB08kQTAAABAAAIRwAAAXQTAAAA8oV1ZmZlcgIAYnMABGxwbnMAAAGDEAAAAPICbmcDAGFiZvPWCAAAAQBIAPRKEAAAAQBfAAEA8oABAWlw8oFvAgBtbgEDAPOGDwAAAQABAAGAAqAgAAAJAbCAEjAAAWlzCCcAAPQpEwAAAQABAAEAAAAPYW5kc2hha2VtZXNzYWdlAAD0BxQAAAEAAQABAADyiXByb3ByaWF0ZQIAaG3ygAECcGx09gcAAMfGPytMmIl3sBAMrgNFYNwca69jsCAHvwABsCAPOAABsMAS3QABQEMACwAcjAAAOjAAAAEAAAAAAAkAEAAAAIkAqAE7BDwEPQQ+BD8EcQTBDMIM8QECtbZlcvQKEgAAAQBlAQEAAAllZGlhdGVhY2sAAPT8DwAAAQCrAAEAABYBAIACBMAAAAABn7AwEA4AAUN01I3m9LBwETMAAW1wYWVpdfEAAap082QRAADkAAEAEwACsGARbAABZGYBUxMAAAEAAqBgAAATN6DgAAATkWV0OzAAAAEAAAgAAQCsBAgAAQMBsGATzgABZjswAAABAAAGAAMAwAsCAPYSAQB8EwEAAARhbHVlAAAB+w8AAAAACnJkZXJlZHJlYWQAAAGzEgAAAPKEZWdhbAIAb3bygAEDbGFkZQGCAqBQAAASUqEAAAAT+WN0AQQDsCAQywABoFAAABFwoEAAABOjbHN28p4TAAABAAAKaGFuZHNoYWtlcwAAAdsSAAAA8gJyZQEAZPLIBgAAAQAAMgABAgQ2rlXSHG9hZQA7MAAAAQAACAADAGsEAQC8CwAAuwwFABYCAAABBbBQEFMAAbBAD1wAAaEQAAATZ7BQDBEAAW5kZWlydQA7MAAAAQAANwAWAJoGAQDDCwEAoQwBAGEPAQDgDwUAERAFAIwQAQDqEAEAdBECAEESAwBxEgQAoRIBAKcSAQC2EgEAORMBAEwTAQBqEwEAbhMBAJETAAC4EwEAvBMBANsTAAABBwD1cxAAAAEAAQABAIICI4ACsHAShwABcngBBgD0aBEAAAEANQEBAPOAAmJlAYEDoEAAABI3KcyyA6APPJJfhUYDYW10AYACsEASrQFZsGATwAABYXIBDgD02BMAAAwAHgAPABMAArBgE/AAAXJzOjAAAAEAAAAAAAcAEAAAAPQQ9RBiEmMSxxLIEl0TXhMBCAD3oRAAAAEAAQDCAgEAggAFAAEFAPQhEAAAAQABAAEAE4ACsHATxwABZm0BAAD0TQcAAAEAAQABAAAGaW1lb3V0AADyZg8AAAEA9mASAAABAPkAggAxAAEA8gABAXRuAAF8DAAA8oABAWVpFuoAAIGMfs6YIM8gQKzdY221XeyXKFgIoGAAABDwoFAAABCEcPUxfK4nsEAQgQABAAgA9ZEHOzAAAAEAAA4AAgAIAAAAYQANADswAAABAAAgARkAkQUBAKEFAACpBwcAxwcAAMoHBADXB+YA6AgBABkJBADXCwEANgwAAJMMAQCfDwEA8A8CADQQAwBTEAEA8BAAAGURAQCcEgEAvRIBAPQSAQBWEwEAjRMBAJwTAQCjEwAA2RMBAOa/IADKyeMgAAABnm+8P/xVeErg1D80USWGVPsw3UbqsBqP3TYJxxVI+HRCdekYHELPU6QHAwQSPgPADYCoADowAAABAAAAAAAcABAAAAACAAMAfACKAIsAigUyB8YHxgg4CbsL6gu6DIkQihD0EPUQDxIQEmISYxKTEpQSxxLIEiMTJBNdE14TAQABNrTvyZ6ac/V/BAAAAQDPCgEAjAATgAKwsBNsAAFrcxOAAqBAAAAQw250AQUCoCAAABFVoDAAABIaYmgBVQ8AACOAArDQE6AAAW91I4ACcEakip8qZW8BAQKgIAAAEVWgMAAAEhpiaAFVDwAAg4CEanx/2dI6sOAT5gABsEAP2gABAQgJAQsA89wTAAAxAAEAAANrZXkAAPImBwAAAQAA8oABAWN48gABAGEAAfISAAABAAA7MAAAAQAABQACADIMAwCJEgEAAQQA9GkQAAABAAEAAQDzgAJpdAAEZ3JhbQAAAdULAAAA8gF0AQBvAPKnEAAAcwFSgAECE1riIOkrc2RuAQMBsAAMngMhc/LeCwAAAQABAAFuiJih3L5tOzAAAAEAABAABQB+DAAA7BAAAFkSBQAbEwIAshMFAAECAPTdCwAAiAN7AQEAIwADoEAAAAyaO9W6w1IoZXJz9JgEAAABAO4ACgEBgAOgQAAAE0agYAAAFCawMBJoAAFhZXMBAQGgAAAAE8ZzAXARAAABAgGgQAAAE8ll8ukTAAABAAEAAqFAAAAT6KBAAAAQe2NlOjAAAAEAAAAAAAcAEAAAANQI1QgZEjcSpRKmEusT7BMRgQLEsBAS2QABYWUAAmV5AADy0wsAAAEAAPIDZGVyAQBr8sYGAAABAPSEEAAA5gABACQC9h8AAMHJsFAQnwABQAAAAAADjikA80USAAABAKgAAQIA8/oQAAABAAEAAQQA9XMQAAABAAEAAQCCAgEFAPSQEAAAAQCoAAEAAQACsCAMnAABsAAMHAABZXPyNQcAAAEAI4ACoDAAAAjIaGsACXViY29tbWFuZAAAARoRAAAAABFlbmRpbmdyZXRyYW5zbWl0cwAAAa8TAAAAABVjb25uZWN0aW9uaWRnZW5lcmF0b3IAAAHoEwAAABKAAgDAAAAABYdkcvIAAQBlOzAAAAEAABUAAgDuAQAAPwMUAAAIKQAAAR4JAAAA8oAEADBocHMBAQKwQBQPAAGwMBKJAAFnaPUzEQAAAQA+AgEAawABAgD1KhEAAAEAAQABAAEAAAJwZQAAAYAQAAAAAAZrZW5rZXkAAPKFEgAAAQAA8oACAG95AAxnbmF0dXJldmFsaWQAAAGjEwAAAPIAAQBpAPTbEgAACAAbABsAAApvdGNvbXBsZXRlAADyJxMAAAEAAAACbmUAAPR+EAAAAQCZAAEAAAAEZWFkeQAAAbISAAAA8gJ0YQEAcjswAAABAAAHAAIAfBABABIRBQAA8oACAGFvAAhvbmZpcm1lZAAA8rESAABZAADwAAUBAAEFBgjeY2Ruc3RtAdILAAA7MAAAAQAABwACAD0RAwAeEgMA8oNoYWsBAWVpCBIAAAEREQAAAAAMZXR3b3JrY2hhbmdlAADychMAAAEAAAAEdmVudAAA8jkQAAABAAAAC2xpZW50c3RyZWFtAAABQxMAAADyAWWEgBQgBAHFBgAA9dYPAAABADIBIQEOAfKAAgBsc/KAAQFkZzZpAIDCyaAQAAAIyDAq/RrMsaBwAAASuD/G4h1vzKAgAAAG9wAACAGCA4MM9sACAISKoCAAAAc3QlBAoqz+oFAAABEJPk2stsnhX1oE6puXEGA0Vp/fI930ug9cEREAhuQLADswAAABAAA7ABgA7gEAAPUBAgA/AxQARQQBAKsEAADCBgIA4ggAAEEJAQDZCwAAGgwBAB4MAACDDAMAMQ4AAEkPAQB8DwAAABAAACYQAABPEAAA9hABADsRAQB4EQEAdRMAALoTAQDOEwEAAQYA9FQTAAABAFMAAQAjgAKhEAAAFAZjchOAAqAgAAAI2mh5AYECsDASeAABsAAH1QABY24BgAKgcAAAErigcAAAExlkbhOAAgx6Vx+pl2FwAYCEYc+/1cMjsJARbAABaKM0YbWKoEAAABDvAQEJAYACoBAAAAk9sEAQUwABaXMBggKwIAyhAAGgoAAAEv1mbgGABKAAAAAI+qCgAAASs6AgAAAQg6BAAAAP+2dvcHYBAQD0TxEAAAEAAQABAPOAAmRsAAFkAAD1GQkAAAEAAQABAAEAAPIBcAEAaQDzmAwAAHcHAQAAB2VnbWVudHMAAAE4EAAAAPKAAgBzdQAJc2VxdWljYml0AADyCBIAAAEAABKAAQGggAAAE69hdDKAAgI516KedbCwcBIKAAFlb2FpCG8AAPQVCQAAAQABAAEAABKAAQEEpugzEyB0aRKAAQKgwAAAExmgQAAAEvJ0aXIBAwD0XA8AAAEAyAMBAAAZbW90ZW5hdHRyYXZlcnNhbGFkZHJlc3NlcwAA8iEUAAABAAAABWFpbGVkAAABZBEAAAAShG5kb20BAbBAE4YAAWZi8oACAGFlABBheHVkcHBheWxvYWRzaXplAADyvhMAAAEAAAANcG1hbnlzZWdtZW50cwAAAZgTAAAAABdhbG5hdHRyYXZlcnNhbGFkZHJlc3NlcwAA8h8UAAABAAD6rAIAY28AD250b21hbnlzZWdtZW50cwAAAZcTAAAA9gAAAAQBsKAThAABaWxtcmPynAEAAAEAAAEBAPehEAAAAQABAMICAQCCAAUAAA1lbGZzaWduZWRjZXJ0AAAB1xMAAAAAAmlkAAD0NBAAAAEAAQABAADygAIAY3PygAEBZW8ig2VyYQIA0AAHJAABbHQ2AgAAgoWgAAAABYmwQBQPAAGwMBKJAAFmFuqH5FoAIATIAAMAOzAAAAEAABYACgCaBAAA8AgBAJAQAQDxEAIAMxEBADkRAQApEwMAchMBAN4TAAAHFAMA9K4wAIOPABIVHEymIVgzhx8gIaAgAAAFiSKhEAAAE2ckJFvFk7LNAHaCvDvtoDAAAAweRBg/NHCGJYAQQAHvuQ4AOzAAAAEAAKsAMQCmAQEA8gEBAPgBAQBIBAMAWwQAAIYEAACgBQAAmAYDANAGAAAzBwEARgcAANYIAQDjCAAA7QgCAPoIAAAfCQAAwwsBAC0MBAA3DD4AiAwAAKEMAQBhDwEAdQ8BAOAPBQADEAEAERAFAEoQAQBlEAEAcRABAIwQAQCqEAEA6hABACoRBAB0EQIAfxEAAC4SAQBBEgMAcRIEAKESAQCnEgEAthIBADkTAQBMEwEAahMBAG4TAQCREwAAuBMBALwTAQDbEwAAAYMCoJAAABOeoJAAABOfMjMBgAKgUAAAE8aggAAAEu9jZfMAAnN08hIHAAABAAGAA6CAAAAT+LAQBtEAAaCAAAAT12FlaQEBAVg8pl2O6WTy5wYAAAEAAAN1cmUAAAGGBQAAOzAAAAEAABAABADlCwAAkgwAAJEPDQDvEAAA8oABAXRzAQYBP9bB5eOgY/XdDwAAAQC+AAEAAQAACG5jaGVja2VkAADy2RIAAAEAAPIBNAEAdfITCQAAAQAAIoACAPMgCREAATM2AAJ0cgAA8yMHAADsAQEAAAAFZW1vdGUAAAGJDwAAAAgoAAABDgkAAAAAAm52AADyDAkAAAEA8sUQAAABAAACdHMAAPMDDAAAAQABAAASgAIA9mAJCgABaXUAAnV0AAA7MAAAAQAABQABAD0TBQA7MAAAAQAABQABAPITBQDyCXJnbWF0Y2hlcwEAbTswAAABAAAGAAIA7BAAAFkSBQA7MAAAAQAABQABALITBQD2BwABbYeDoDAAABNToHAAABF3sDAROwABEwQLIIEAOzAAAAEAACwBAgDtAQAAEwIrATswAAABAAD5AAIARwcAAMoJ+AAIKAAA9NALAAABAGUDAQAAAAAAAPQGCQAAAQABAAEAAPKAAgB4eQAEdGF0cwAA8pAMAAABAAAIRwAA9AIJAAABAAEAAQAAAAxuY29kaW5nZXJyb3IAAPIlEwAAAQAA/gAAHwQBoBAAABDwZXJzdGnySwUAAAEA8pYMAAABABKAAQE3jcaaf9BtZ/KAAgFhb2UABnJ0dXBsZQAAAc8LAAAAAQUAOzAAAAEAAAoAAwDSEgQAqhMEABUUAAAABHR0ZXIAAAHOCwAAABKAAQKgEAAAC9awcBPmAAFhZXYACG5uZWN0aW9uAAD0DREAAAEAAQABAAAACWtleXVwZGF0ZQAA8lcSAAABAADygAIAZW+ygAICsDATzgABY21wdfIAAgBydQDyrgwAAEUDAQEA9H0FAABQAzQDAQAAAAAAOzAAAAEAAOkAAQCyAOkAAPKAAQF0dQAMY29udHJvbGVycm9yAADyrxIAAAEAABKAAQGwEBPuAAF3YRKAAQGwIA9JAAFvdQEBAbBgEWwAAWYBUxMAAAEAAaCwAAATN2LzxBIAACIBAQAjgAKwAA97A0hkcgEAA6AgAAAQ36BAAAASJ1pZPWlR72Rlc/OADwAANAMBABOCAqAgAAATkGVpABlkbGVuZ3RoY29ubmVjdGlvbmlkcGFyc2VyAAABBhQAAADyAAEAZQDy2g8AAAEAAANyb3IAAAFlDwAAAAAEYXJseQAAAXsQAAAA8gABAGXy1AgAAAEAARkSAADygAIAZHLyAnNoAQBl88IGAAABAAEAAAAIaXplZXJyb3IAAPIwEgAAAQAAAAJ6ZQAAAQEJAAAA8oFsAgBpc/KAAgBhaXYFAICChrDgE3AAAVyPw1ijrCiF1PRHggAgIFwIAQEAADowAAABAAAAAAAKABAAAABtD24PWBBZEOIQbBFtEYESghILFAwU8wIBefJ2EwAAAQAjgAKgUAAAEgxldAAKYW5kb21ieXRlcwAA8oYTAAABAAAACnVycmVudHRpbWUAAPKEEwAAAQAA8oRvZ2V0AgBjcvICZWQBAHQA82QRAADkAAEAEoABAbBAEMkAAWxyMoABAgIPpxmvUmljdcY7KADKyOMgAAAAsONAAAAAscAAAAAAB7BQD2kAAaCwAAASuaAAAAAB5XemsMLKx014UwKdY6DwAAAT3mRAngSADwBDADowAAABAAAAAAALABAAAAB7AEcEfQSHBEgFSQU3BzgHCgkLCTYJtwwBgAKhIAAAFBGwYBFyAAFucwGCAqAgAAAQk7BQElcAAWR1AQQA9DUTAAABAEsAAQATgAKwkBQPAAFlaAECAaBAAAARAWUBUQ8AAAEHAPQ1EQAAAQABAAEAAQcA8zITAABoAAEAABFzaW9ubm90bmVnb3RpYXRlZAAAAYMTAAAA8oABAW5y8gABAWUxADowAAABAAAAAAAJABAAAABABEEEIAfZCB8MIAwhDCIM1xDYEAAEcnJvcgAA8soTAAABAADyDWV5aW5nbWF0ZXJpYWwBAGX1khMAAAEAAQABAAEAABrlAQGwABCfAAFrcwAEeXBlcwAA9DAQAAABAAEAAQAAEoJjdAEBWxEukQ1DdGXygAIAZW/2AAAAAgNP1FCfvtFwdGFjaADzTQUAAAEAvgwBgAKgEAAAE6OwEBCSAhJpdROAAqBQAAARWWxyAARyZWFtAAABLxAAAADyAAEAdAD1ngwAACED2AIBALYA+moBAHPzlAQAAAEAAQA7MAAAAQAAFQAHAN4LAQB3DwEAORABAHgQAQBgEQEAERMHAP4TAwAygAECdwsJfQ//ZWFvAQICoHAAABF6f57NgoFBYXIBTAcAABMAAmwNJfzMenJ18gACAAABAAGAAjZuNZ+QD6CwAAAT3mFlAYACsFASgwABUV8ZCie3ZWkBBQDzGxMAAAEAAQATgISwMA/UAAGgoAAAEzegMAAAE3QQQEgBiAKwABNPAAGwABNRAAE0NhOAAqAwAAARBGRzAANvZGUAADswAAABAAAGAAEALw8GAPLKEgAAAQDyAXIBAGM7MAAAAQAADAACAIgECwBKBQAAOjAAAAEAAAAAAEkAEAAAAN0I3gjdC+IL4wvkC5oMpgynDKgMuAy5DFcPXA9dD18PYA9lD+0P7g/vD/QP9Q/5D/oPGRCOEJQQ4BDhEO0Q7hABEQIRBREGEQcRXhFfEXERchFzEXcRJxIwEjESNRI2EnsSfBKLEowSjxKQEq8SsBK/EsASwRLCEsUSxhIlEyYTNxOiE8cTyBPJE8oTyxPQE9ET0hPyAAEBb2UBfwAAAABWcAAAwc8kIzgS73lChV2iM8diJMYj1gMMALjCEokH60iS6jOwIAvTAAFpZQX+Bt9LjlkpVZga5Jr/t3Z6lRP6delMNlfHNV0AAIAAwE0dawA6MAAAAQAAAAAANAAQAAAAmASZBIcFmQWaBZsFkQbGBscG8gbzBvQG9Qb2BsgHzgvnC/QLCQwNDA4MEwwUDBUMfwyMDI0MOA85D0IPog+jD8cPUBCEEJMQpBClEN8QahFrEZUSlhKtErwSxBKPE8ATwRPmE+cT+RMGFAAFYWxlbnQAADswAAABAAD3AAIAjgwBADkO9QAAEoABAbAwEggAAXZjEoABAS6Z1UNPXWll8gABAHU7MAAAAQAAVQABAAsAVQAB3AsAAAEAAPQMCQAAAQC4BwEAAYACoAAAAAvpfUzwvEmObW4BBAGgMAAAEWd0ARoTAAABAgD2tQwAAAEAGwMBACYBAQDzgAJvciOAA6DwAAATg7AgEmgAAWl0dQECAbBQEmgAAWX04ggAADgDAQDlAxOAAqAQAAAMeGFvAYACoGAAABMzsHATJwABYWMjAAOwUBCMAAGgsAAAErhjdHX0LwcAAAEAAQAEAgEKAPNFEgAAAQCoAAEBAPfuCAAAAQAUBwEAbQABAA0BI4ACsGATWAABaW8BAgD0dgwAAAEADgYBAAEBAaEAAAAT2GTyigUAADwCAQUA9coPAAABAAEASgIBAAEFAaAAAAAQYHP1qQwAAAEAAQAdAwEAAQIBoKAAABOvcvR1DwAAAQDvAAEAAQABoCAAABECcvPnCwAAWwNiASOAAqAAAAATjGRyAQMCsEASjwABoDAAABLlZXfyEBAAALgAE4MCoHAAABMeZ28BAgD1bxIAAAEA7AB5AAEAE4ACsDASoAE/aXABBgDzGxMAAAEAAQDzBQJicwHHDwAAAQMA9KQPAAABAAEAAQAABXBwaW5nAADyLhIAAAEAAAgkAAABehAAAAD60QIAYW8IQAABoAAAABNOcwF5EAAAAAAFb25maWcAAPLqEAAAAQAA8gRvaW50AwBjZXP10QgAAAEAAQAsAAEAARQSAAD2VQAAgYqwcBDJAAGxUBQSAAGgkAAAEhMAgAA7QRoAOjAAAAEAAAAAAAcAEAAAAPwBZARlBGYEtAsnDMIPmhABAAE/1sHl46Bj9d0PAAABAL4AAQABAAGAAoATGwAQAbBQEJ8AAXN48wABZQGrBAAACBoAAPL5DwAAAQAACBAAAAHJEwAAAPILY2xpZW50aGVsbG8BAGUA8ukTAAABAPKAAgBkcvIDeXB0AQBl9LEHAAABAAEAAQAAAQIA9G4TAAABAEkAAQATgAKwcBJmAAFmbgAAAAA7MAAAAQAADAABALUGDAAAAANibGUAAAHNCwAAADKAAgGwcBMlAAFhZWnygAEBZG62AQCAAgOgAAAADCpvcmVoeQEBAPUhFAAAAQABAAEAAQDzBgFl8gMUAAABABOJArBAE/wAAWFyABJlZ21lbnRhdGlvbm9mZmxvYWQAAPLuEwAAAQAAEoJsZQEBsAATRgDgc2TygAEBYnT2fA0Aw81SVQYzEdRxKgjErgawkBFyAAF1xyU0Q75AAwAAgBS3DwA7MAAAAQAAGQALAKIBAwBCBAIAbwUAAEoHAQBNBwMA1QcBAN8IAQAWDAEAgRABAMsQAQB2EgEAAQADBIF3PQAioDAAAAjmF+6VA8yNYm1z9F8EAAABAAEAxQcBgAKwcBIsAAGwMA/0AAFkcvMDAWU7MAAAAQAABQABAG4HBQABBAGgUAAAE0NzAVISAAABgAJxxnTITLWwEBLZAAFhZQEAAaCQAAAS+HP0NBAAAAEAAQABABOAAqAwAAAPe2RmAQMBsAAQbQABcwHcDwAAAAAAAPPqAQAAAQABAAAAAAAA8+cBAAABAAEAADYAAAACBaBQAAARCmAUIG4DmRgKu+RichqroS4zcaAwAAAQJjAxY2VpdHcA8mwHAAABAAAIb2RlcG9pbnQAAPP2DwAAAQABAADyAAEAY/SsAAAAAQABAAEA9HcFAAABACQHAQC2NwAAwsglpdGOf01jMtGTJsMAAAgCAGSTCAABjAAAAAEBADswAAABAAAKAAQA3wYGAFsPAAAlEAAAjRIBACOAArBwEggAAWVvAQABoFAAABJ6YwF9DAAA8wABbPJiBAAAAQABgAOg8AAAEziwUA/WAAGgkAAAEQljaHAAC2F0YWFjY2VwdGVkAAD0BhMAAAEAAQABAAAABXJ5cHRvAAD0KxAAAAEAAQABAADyAmx5AgBjZAABexAAABYWAICBibBwEW4AAQYCBy3lTh7eAYMDt6EAAAAT3hku9f2J+qBwAAAQpAAAAS4cBgAAx9IDQjMiSu87x+L/79VqFfzj82QQWc0gyZss2OBM5UFetx1IrBlXxMWAkQdEBjaHjaoeS60Dwd16NfAZQbgG6r038yVXy3quK+VxJgF0aNNacoXKvC0xwY8GEgRU1Z0UPbNYDlLbSqwwDaEFHSUUH0//EiQgMYDAtlFmbYgVR29ELQMBSYIPbowtnmFoBF9PDEkyp3lshmlAAcgogP43VwA7MAAAAQAA/wGLAAQAAgD0AQAA/QEBAAgCAABpBAEAbQQCAHUEBQCBBAEAmgQAAKYEAACoBAAAuwSLAEsFAQBPBQEAUwUBAF8FAABtBQEAcQUEAIYFAACnBgwAtQYMAMUGAADIBgEA5wYEAPgGCAAIBwAAOgcBAFgHEwDJBwAAvggBANoIAgDkCAEA5wgAAPAIAQD3CAIAAQkAABUJAwAqCQIANAkAAD4JAAC1CwMAwAsCAMoLAADNCwAAzwsDAOULAAAqDAAAfAwAAIAMAgCHDAAAkgwAAJYMAQCsDAAAsAwCALUMAQAvDwgASA8AAEsPAgBTDwEAVg8AAFkPAABeDwAAcQ8AAHMPAQCADwAAiQ8AAJEPDQCpDwEAxQ8BAM0PBgDWDwEA+w8AAAIQAAAHEAEAGhAAACEQAwAnEAAAXBADAGEQAQB+EAIAjxADAJcQAgCmEAAAsRAKAO8QAADxEAIA+BABAAgRAQAYEQEAMxEBADkRAQA9EQMAWhEDAHARAAAHEgAAERIAABMSAAAeEgMAIxIDACoSAAA+EgIARRIBAEoSAQBTEgUAaBIBAG0SAwCHEgEAmxIAAKASAACkEgAAqRIBALQSAQDKEgEA0hIGAO4SAAD2EgEA+xICAAsTAQAnEwUAMBMBADQTAAA4EwAARBMBAEkTAgBTEwAAWBMBAFsTAQByEwEAfBMBAIQTAQCeEwEAqhMEAL4TAQDVEwEA3hMBAPgTAAD6EwEABxQDABUUAAABAwGAEuwAEPBzOzAAAAEAAAUAAQDMEgUAI4ICoJAAABPGaXMBgQKwUBL7AAGxABPTAAFtdAEFAPPxEAAAAQABACOAArDQEqkAAWFlAQQA84QQAADmAAEAAQcBgBLbAIAbc/Q9EQAAAQABAAEA84ACYWUBBwD3oRAAAAEAAQDCAgEAggAFABOAAqAwAAAMmGVyAQcA9dISAAABAAEAAQABAAGAAqBAAAAQ4rBQEMkAAWNpM4ADoFAAABDwYW9yAQAA9JMSAAABAI8AAQATgAOgYAAAEUGgcAAAEhNpb3IAA2lzdAAAAacQAAAA8gVhdGlvbgEAaPLQCAAALgABWBEAAFKAAQKwoBN2AAFyY24BgQE/xuIdb8xrAYACsHAShwABEUpoSbE7cngBAgGgAAAAEGBzOzAAAAEAAAsAAwCpDAIAyA8BAOYPBgATgAKgIAAAE2dldQg/AAGwcBPAAAFwOzAAAAEAAAcAAQCpBwcA8lMQAAABAJKAAgLnAAAABrSwIBBoAKRjaWFyVgEAAIGHGF4h3s/9oIAAABQVYYXHOW3EoEAAAA9/sIAQmAABAAAEskFAAPTJCAAAoAYBAJkDCE0AADswAAABAAAHAAIA5gEAAAwCBgAAAAV0cmVhbQAAASoQAAAACFAAAAGoBwAA8joPAAABAPKCaW4CAGVzMgACAhQiD/FfuwF2n0WZvWFvZXYAOjAAAAEAAAAAABIAEAAAAAQCBQKIBa0MPA89D1gPcg8FEAYQrxCwEDgSORI6EjsSMhOaE5sTAQEA8+oIAAABAAEAAQABP+IxkeqVZPR+EAAAAQCZAAEAEwADsDATugABsFASjQABZXBy9GsPAAABAOkAAQABAAOwQBOGAAGhQAAAE+2gUAAAEWRiY2YB3gYAAAADYXRzAAABDBEAAAAIKQAAAaYQAAAA8oRvYWRzAgBpdPIAAQBsAPPDEAAAQQIBAPIAAQBuADswAAABAAAkAAgAFAcHAMoPAgAbEQ0AQhECABYSAQCZEgEA6hIBAH4TAgDWAgCAAQWxQBQSAAGgwAAAE9J3Ym1ucHUBBAGwIBDbAAFl8joSAAABAAEEAbAgENkAAWXyOBIAAAEA84ECNDYBBQD0/A8AAAEAqwABAAADbGF5AAABIgcAAAAABHJkZWQAAPLLCwAAAQAAEoABAXGjrfO5lGFvAARibGVkAADyzggAAAEAAHKAAwGwUBPwAAFhY3B0AQ0A9NgTAAAMAB4ADwDyAAABZTswAAABAAAFAAIAfQABAKgAAwABPQkAAAASaXRhbGx5c2lnbmVkc3RydWN0AAABZxMAAAD2AgAAg4QXhQOOPxCwMBLfAAFAAAMBoAQAOjAAAAEAAAAAAAcAEAAAAPQQ9RBiEmMSxxLIEl0TXhMBCQDzMhMAAGgAAQDxAAKoAGF0800FAAABAL4MAQQA8/YPAAABAAEAAQEA9b4QAAABAAEAAQABACOBArCQE3AAAWF0AQABoBAAABOMZQGaEAAAo4CEsRAT6QABoIAAABMzDEAEAQAAOjAAAAEAAAAAAAcAEAAAAMsLzAvfDzUTNhOBE4ITjBMAB2luYXRpb24AAPOGDwAAAQABAAAAB3JpcHRpb24AAPKEDwAAAQAA8oACAGN0AQIA9eILAAABAAEANQTpAAECAbCAE1QAAXQB4wgAAAEAAT+/TLEsbHLyKREAABgACEMAAPPNCAAANAMBAADyAAEAbfOHBAAAwQABAAAygAECoDAAABM3ZmRysgABA7AgC9MAAWVpa3IAOjAAAAEAAAAAAA0AEAAAAMYGxwbnC0IPhBCTEKQQ3xBqEWsRvBKPE8ATwRMAEHVwcG9ydGVkdmVyc2lvbnMAAAHdEwAAAAAGdW50aW1lAAABBxIAAAAADWF4aWRsZXRpbWVvdXQAAPINFAAAAQAAABBlZXBhbGl2ZWludGVydmFsAADyGxQAAAEAAPKDYXRoAgBrbQEKAPNqEwAAAQBwAAAhbmN1cnJlbnRtdWx0aXBhdGhwYXRoc3doZW5lbmFibGVkAAABJhQAAADygAEBb2zyBGF1bHSEgASAAzswAAABAAA0AAIAIQcAAHQHMwAACCIAAPL0DwAAAQAAAAdpbml0aWFsAADyLBIAAAEAAPKAAgBkcvohAQBlOzAAAAEAAAUAAQBuBwUAAAAAAAGwQBKLAAFlOzAAAAEAAAwAAQCnBgwAAY8QAAAIIQAAAcoLAAAA+pYCAGFl8oACAG9yAAJ1ZwAAAYYEAAAA9mUBAIWIoDAAABB7sEASiwABsCAQrAABsFATOwABJgADGagkADswAAABAAAsAAsA/QEBAAgCAABpBAEApwYMALUGDAAIBwAAvggBAC8PBgCPEAAAyhIBAP0SAAABBAA7MAAAAQAABgACALwLAAC7DAUAAYACsAATTwABsAATUQABNDYjAgIx9sAU/cdydvN9DwAAAQD9A/MCAWX0BRAAAAEAqQABAAECAPSkDwAAAQABAAEAAQEBoEAAABCUZfTkCAAAAQDlAgMAE4ACoFAAABISbHMBBAFkjNK1Rp1j8nYSAAABACOCArBQEkgAAWZ0AAdyYW5zZmVyAAABpRAAAAAACG5ibG9ja2VkAAABrhIAAAAAA2FjZQAAAd8TAAAACBgAAPLVEwAAAQAA8oluZGJ1ZmZlcnMCAGlwMgACAaAgAAASm2V1afXJCwAANAABAAEAAQAAAAl1ZmZlcnNpemUAAPL6EwAAAQAAEoZlY2VpdmUCAMAAAAASK2JkAANuZm8AAAHzDwAAAAADZW50AAABeBAAAAASgAEBsDASjwABdnL2AAADcmFtBAGgMAAAEuVlaXJzd/XKCAAAAQABADAAAQD1CxAAAAUAtwABAKQBAAZsb2NrZWQAAPRjDwAAAQDEAAEA9JESAAABAI8AAQB2AAAAg4Nu5+ceY3GgcAAAEx6gQAAAErJCAAQBQAEBCwIAADswAAABAAAPAAYALQcBADIJAQB8EAEAhxABABIRBQANEgEAUoABAi8tNisHHWFlafYBAIABBbDgE84AAXRiY2RzdgAABxACpBmsFKduxazIg/Y8vCl4/4Z9ucHm0Hw8pgfoM/9L3NP1EetiAhsL3cugMAAAEJsecmdHDCROh9G32t4Et/1JPFpT5tYnzC0LpMYupfYcDOkz4yCw8BQPAAFFGwCHXRhumCvcwNBZXXzJ6RdgygPnMm1NU/EqE2hwtXF7ByUzN8+S40WgAAAAErJhZWlvcnN1MGJjZGZnaGtsbW5wdHZ3eQA7MAAAAQAAfwJ3AAgAAABhAA0AdAAAAIgAAACNAAUA5QEAAPsBAQAJAgEAXAQCAGQEAgCjBAAArAQIAIIFAACJBQAAiwUDAJEFAQChBQAAlwYAAOYGAAD3BgAAHAcDACwHAAA+BwUARQcAAFIHBQCoBwgAxwcAAMoHBgDXB+YAzggBANQIAQDhCAAA6AgBABkJBAA/CQEAQwmGALQLAAC5CwEAvgsBAMcLAADLCwEA1gsCAAwMAAAZDAAAIwwCACcMAAA2DAAAkwwBAJsMAACvDAAAOg8BAGMPAQB7DwAAnw8BAMIPAADUDwEA3w8AAPAPAgAJEAEAGxAAACgQAQA0EAMAUxABAG8QAQBzEAMAhRABAJoQAAC8EAEA3RAAAPAQAAD6EAIAGhEAACkRAABBEQAATxEDAFYRAQBkEQIAaBEBAG4RAQB6EQQAGRIAACgSAQArEgAANxIAAEgSAQBqEgEAfRIDAJESAQCcEgMApRIBAKsSAQCuEgAAsRIAALMSAAC9EgEAwxIAAMkSAADZEgEA9BIBAPgSAAAGEwQAIRMBADMTAAA1EwEAOxMBAEYTAABUEwMAgRMCAIgTBgCcEwEAoxMGALATAADDEwEA2RMBAOsTAQDuEwEA/BMBABkUAQAmFAAAAQACoGAAABK8sKASQwABOGU7MAAAAQAACQACALcHBwCDEgEAAQgA8/YPAAABAAEA8wABYzswAAABAAAHAAMArAADAHcFAQCcDAEAAIABAfZAAgkAAbAwDIAAAW5yAAJvcgAAAYUFAAAAAQkA8+ITAAABADUAAYACoEAAABLJsCAThAABaGkBgQKwgBPwAAGgYAAAFBRkcwEMAaCgAAAUJnfyFhQAAAEAAAF1AADzgQ8AAAEAAQAA8oABAXR1PgMAhAEFoEAAABPFsGATmQBMbWJwc3R18oACAHJzCDgAAPJhDwAAAQAA8gJpYwEAY/SDBAAAAQABAMIAADKAAgGgcAAAEN5icmQBAwD09A8AAAEABAABAAEKAaBAAAATyWXy6RMAAAEAE4ACsGASLAABY2nzgAJkcgAGZXNzaW9uAAABCxEAAAAIOAAA8l8PAAABAAAAA2l6ZQAA8tcSAAABAAAAB3hjZWVkZWQAAPKBEwAAAQAA8oV1ZmZlcgIAZXPyAAMAYmVzOzAAAAEAAAwAAgCDBQEAnAYKADswAAABAAAFAAIA2A8BACsQAwDyAnB0AQFvZQA7MAAAAQAACQACAG4HBQCxBwMAAAVlcmlvbgAAAcgLAAAAEoABAqAgAAAT+bBAD4QAAXRicAAHZXNlbmRlcgAAAaQQAAAAEoFhAQGwAAu+AAF0ZPKAAwBlaXkBggKwMBMLAAFMNlfHNV1heQEAAgcA1FauMbCAEroAAXN29DsJAAABACwKAQAABmV0cmljcwAA8oMSAAABAAAABmFjdG9yeQAA8oESAAABAPILFAAAAQDyAmVyAgBmbfKMDAAAAQAAEoJvbAEBsEASrwABbGUAA3lwZQAAAV4PAAAAKsoCAMAAAAAI+3N0EoACAOdAAAAHIG548oACAGVyAQkA8zISAAABAAEAAAdydmF0aXZlAAABJxAAAADygAEBZWkIbQAAATYOAAAAAANpdGgAAAEmEAAAAAg4AADyYhEAAAEAABIAAQGgIAAAEv10aQDyZhIAAAEAAAZlZnVzZWQAAPKrEgAAAQAAAANvc3QAADswAAABAAAGAAEA4xAGAAAABWFyc2VyAAABrRIAAAEGFAAAAAlpbWl0ZXJyb3IAAPLHEwAAAQAAAAhlbmVyYXRvcgAA8mUTAAABAPLoEwAABQD6KQMAZ2xw8/APAAABAAEAOjAAAAEAAAAAAA8AEAAAAGURZhGcEp0SvRK+EvQS9RJWE1cTjROOE5wTnRPZE9oTAAVhbmRsZQAAASoSAAABOBMAAAgcAADyYBEAAAEAAAgwAADyXhEAAAEAAPKAAgBydgAEbG9zZQEA0AASKAABZDswAAABAAAFAAIAWhEDAFUSAQAA8gFuh4CUCQP1iQwAAAEAAQCsAQEA94sQAACCAAEAAQABAJMBOQAigAIA5nAAAAyIbm8IAgAA8+0PAAABAAEAACKAAgDAAAAAC8dkcgAFbGllbnQAAAEKEQAAAPpkhIAUARDybAcAAAEAAPKAAgBlcwAFaW5kb3cAAPKZEgAAAQAAAAR0YXRlAADyUxIAAAEAAAheAQDQABKXAAFzADswAAABAAALAAIAERMHAP4TAwAAEG9udHJvbGxlcmZhY3RvcnkAAPILFAAAAQAAAAhsZ29yaXRobQAAAfISAAAA9gEABXN0aW9uBQGwgBQZAAFhY2Vzd3T0Mg4AAAEAAQABAAAAAmxnAAAB+ggAAADygAIAYWUAEHJhY2luZ3N1YnNjcmliZXIAAAH5EwAAAAgJAAABUhIAAADygnJlAgBjdAgpAADyXA8AAAEAAPIAAgBldfKaBgAAAQA7MAAAAQAANQAVAMMLAQChDAEAYQ8BAOAPBQAREAUAjBABAOoQAQB0EQIAQRIDAHESBAChEgEApxIBALYSAQA5EwEATBMBAGoTAQBuEwEAkRMAALgTAQC8EwEA2xMAAAAOZW50aWFsaXR5bGltaXQAAPJwEwAAAQAAMoFpAgGwMBKxAFlkZ3L2AQCABQFc+21hk35mZ25zdGMBAgOgQAAAEINMpiFYM4egUAAAEO9hYmb31ggAAAEASAArBwEAXwABAAEEAPM+EgAAAQABAAAAAAA7MAAAAQAAEwABAFgHEwAACEAAAAGHDAAAAPKAAgBhZfKAAQFydBKAAQGwMBMnAAFhbAAEbm9wdAAAAcYLAAAAAAAAAaCAAAAUFWYByQgAAAEDEwAAAAdydXBkYXRlAAD10hIAAAEAAQABAAEAAAAFY3RvcnkAAAHiEAAAAPKAAgBhb/ICbmQCAGZzOzAAAAEAAAYAAgAfBwAAUgcFAPKvDAAAawTygAIAYW/ygAIBbXBpAAJuZwABsEATJQABZfKYBgAAAQAAIAAAArBAEosAAZ9lcAEIAgAAOzAAAAEAACMABQCnBgwAtQYMAC8PBgCPEAAAyhIBADKAAgGwMAvKAANlaWH2BACAAwSwUBMEAAGwEBOmAAFkbW5sb3J2CF4AADswAAABAAATAAEAlAATADswAAABAAATAAEAqw8TAAAFZWFzb24AAPJbDwAAygAACAoAAPLgEAAAAQAA+k8BAGUBMQ4AAAAIYQAAOzAAAAEAAAYAAQDmDwYAAAgBAAD0gwwAAAEAAQABAADyAAIAcHPyggUAABUBOjAAAAEAAAAAAAoAEAAAAOEIDAwZDIUQhhAoEikSfRJ+En8SgBLyAWUDAGRwcvWCBAAAwQABAAEAAQA7MAAAAQAACgAEAEgPAABaEQMAIxIDAFUSAQAAB291bmluaXQAADswAAABAACHAAIAdxAAAIARhgAAAANudG8AADswAAABAACGAAEAqg2GAAAAAm94AAA7MAAAAQAABwABAPULBwAA+gMDAGJpdDswAAABAACHAAIAgQQAALwEhgAA8oACAG5zAQQBoEAAABPJZfLpEwAAAQAIfAAAAVoPAAAAEoABAaAwAAATQ2Fy8gABAHQBUQcAAAAIQQAAOzAAAAEAAAUAAQDgDwUA9kESAAABACgBAQBRAB8AAANkZHIAAAFYDwAAAPICbnQDAWFjc2g7MAAAAQAABwACAH8FAgCSBgQA9AoMAAABAP8ESAHyAAEAZQF8AAAAAPKAAgBpbwGBArAwD6kAAaCQAAAT+XJzAAR1aXRlAAGgAAAAErlzAVkPAADzMBMAAAEAAwD6OAEAcwGRBgAAAPIAAQBoAPMBBwAAAQABAAAIeGhhdXN0ZWQAAPRzEAAAAQABAAEAAfgSAAASgAEBGF4h3s/9ZWIABmZldGltZQAA9CEQAAABAAEAAQAACCkAAPRNBwAAAQABAAEAAPKAAgBlaQgwAADzoRAAAAEAAQAAdgAAAAMCsPATzgABsHATwAABZ2xzYXAAOzAAAAEAABQABQCpBwcAygcEAJMMAQA0EAMAUxABALYAAIACA6AwAAAPe7DAE6gAAWRwZm50AQIBN4vvVhl2YfIoDAAAAQAAAAAA834FAAARAQEA9MEPAACsAAEADALyAm5rAQBz8n8EAAABAPNPDwAAAQCMAAEAAPU3EgAAbgABAEUBAQAACG5kaW5zZXJ0AAA7MAAAAQAABQABAEwSBQAAEoFrAQGwEBLZAAFhZTYAAAABBG9ITQBODAggP8dHV7BQEJ8AAWNkbXN4APNFEgAAAQCoAAECArBAFA8AAbAwEokAAWdo9TMRAAABAD4CAQBrAAAEaGEyMAAAAcgIAAAAkoABA6AQAAAIyAQDjisNZGMybG72AAAAAwKgMAAADIJhZXVvcwDzqwQAAM0MAQABAwD0NRMAAAEASwABAAGAAqBwAAATU6AwAAAQl2Z0CBYAAAGiEwAAAPINZXZvY2F0aW9ubGlzdAEAZQDyzBMAAAEACAEAAAEnEgAAAAgLAAAB3xAAAAAyBmZpY2F0ZQIBWlk9aVHvZGVzAYAPAADytBIAAAEAekMCAkfwjDY1e2lyc3YA9HgSAAABAHYA6AA2AAAAgYZ2lJVChsawgBJXAAGwsBPrAAGgIAAADJU6uaAMj+cAAAEQnQDzBAAAAAEAAQA7MAAAAQAAEgAIAE8FAQBfBQAA+AYIACoMAACxDAEAzw8BAKASAADfEwAAAQIA80USAAABAKgAAAJzZQAAAbsEAAAANgAAgAEECW+FY/j0sDALywABTK+/wmrHdWNscnT2PwYAysiwIBIIAAFPW/yvyyt4FxHJzhw1PbQ7Usl9j98IN8xcz5vwJZVAZJYUgAEJSwD3dgAAABYAcwGEAgEAAQDCAAEAAbBQC8MAAWP0dwAAAAEAAQAaAAEGAWzttzSP1HPyrwwAAGsECHEAAAHHCAAAABIAAQGgIAAAEhFtaTswAAABAAAGAAIAfgQAALUEBQA6MAAAAQAAAAAABwAQAAAANwk+Dz8PQA9BD3QThhOHE/oWAQBzAAGxEAAAEoABAbAwEpUAAXRwAA5yYW5zcG9ydGNvbmZpZwAAAZETAAAAEgJsZAEBoGAAABM3dGU7MAAAAQAACAABAKwECAAAAYEBQ/WGq70/cggDAAABfQUAAADyAAEBbWYBewAAAPQ3BwAAAQDSAQEAMoADAeawAAACB6AAAAAEhmZpbGcBAgEMRQNmdNRz8tQPAAABAAAAAAABegAAADswAAABAAAHAAEA9QsHAAgAAAA7MAAAAQAA5wACAMULAADDDOYAAPIDcm93AQBtOzAAAAEAAOcAAgB8BQAAqAXmAADigAMB5sAAAAIGb3J4dQAJbXRva2VubG9nAADzcRAAAAEADQEAAQIA9JMSAAABAI8AAQABAwD0xxIAAAEAlQABAPIDa2VkAAJidfMcBwAAAQABADowAAABAAAAAAAQABAAAABjD2QPCRAKECgQKRC8EL0QaBFpEZESkhKeEp8SrhIhEyIT8oACAGNvAAhkZXRlY3RlZAAA8jsTAAABAAAAB29vbGRvd24AAPIEEwAAAQAA8oZja2hvbGUCAGNzMoACAhH06xojXaCAAAATdWFvZXkBAwFp4voKG/10OzAAAAEAAAgAAgC9CwAA6wsHABMAAoAMAwAQAXJz8ggSAAABAAEBArDgE9gAKrBgE/AAAXJzOjAAAAEAAAAAAAcAEAAAAPQQ9RBiEmMSxxLIEl0TXhMBAAGwUA9hAAFj9IMEAAABAAEAwgAABW9ja2V0AAABfw8AAAAaSAEBoHAAABISc2EAAeYGAAB2AQAAAQSgYAAAFBRuY2RzdPICAAAAAQD0igUAADwCAAEkAwEAAPQPEwAAAQAPAAEAAQQA8/oQAAABAAEAAAVwb3J0cwAA8p8QAAABAAASgAEBgBMbABABeHPyAmNoAQBlAasEAAAAVgEAgAEEsEAMlgABoAAAABP5bmZocnMIIwAA8sMLAAABAADyAXIBAGP0dwAAAAEAAQAaAAABAQD0uQsAAAEAtAUBABMDA7AwE7oAAbBQEo0AAWVwcvRrDwAAAQDpAAEAAAZjaHNpemUAAAGCDAAAAAAPbWF4ZnJhZ21lbnRzaXplAADyqRIAAAEAAAADa3VwAAABewUAAPQ8EgAAAQCkAAEAdgEAgAMCoKAAABN1Y2R0Ym72XwAAiISgEAAAEVVSJo1kiPUTSUgEgAMA8lMRAAABAAAGaWxhYmxlAAGwYBPOAAFm88ALAAABAAEA9PYSAAABAIUAAQASgAEBXaElz+SyYWUBAgD1cxAAAAEAAQABAIICI4ACoAAAAAS7ZXQACG9ydXBkYXRlAAABFRQAAADyCnViY29tbWFuZHMBAGYBAxMAAAAIAQAA9aoTAAABAAEAAQABAADyA3JncwEAZvUcEAAAAQABAAEAAQAA8oRtZW50AgBhc1KAAQIq4Rl2sS9nbHMBgAKhUAAAE+igAAAABYdkcvMAAWU7MAAAAQAAFQACAO4BAAA/AxQAAARyaXRlAADygAwAAAEAAAAIZHBzb2NrZXQAAAHeEAAAAAAEaW1lcgAAAX8MAAAAAANlYWQAAPK+CwAAAQAA8oJuY4SAAAAdAQIAOzAAAAEAAAYAAgC8CwAAuwwFAAAFbWJsZXIAAAH0CwAAADKAAQKggAAAERplaXUABHN0bHMAAAHzCwAAACKAAgDmYAAABH1ldeYEAIAEBuZAAAAB5aAwAAAJHrBwEggAAT01vTaE1qEQAAATr6CAAAAQAGZyc3kwZWhvcHQBAAFp4voKG/10OzAAAAEAAAgAAgC9CwAA6wsHAAEBA6BwAAASEaBwAAAQjrAAEq0BWWJpcvJTBQAAAQABAQGw0BM1AAFi86IFAAABAG4BI4ACoDAAABFZYW4BAAKgIAAAErKgAAAABvdhZDswAAABAAATAAEAWAcTAAACYXkAAAGqBAAAAAEIAPWqEwAAAQABAAEAAQDyAAABZgHkAQAA9RwQAAABAAEAAQABAAAGYXRjaGVzAAFuiJih3L5tAX4MAAA7MAAAAQAADAADAOwQAABZEgUAshMFADKAAgGwAAjwAAFtc2UAB2FrZXJlc3QAAPT/EgAAAQABAAEAAPIGaXRyYXJ5AQB0OzAAAAEAAAgAAgC9CwAA6wsHAADWrACAhIjAAAAAAHYdUg5aX9mwIAvLAAE7MxLvc+ETttv9GTRGAAEZCUYBCADzGxIAAAEAAQABhwJ2va6ffudUf0kcFmVobQgqAADyexIAAAEAAAAAAAD0fRIAAAEAAQABAAD6XgEAZPQjEgAAAQABAAEAAAAKYmFuZG9ucGF0aAAA8roTAAABAAByh2ljYXRpb24DAbBwE2gAAWFjZXDygAEBbHLygAEBcHUBAAGgAAAAEVlz8ykHAADHCwEAAQECsEAUDwABsDASiQABZ2j2mgQAAJkMAQA+AgEAawAAAAACoIAAABJHsHATlwABYXMBdQAAADswAAABAAAHAAEAIgkHAFYBAIABBEcLShOa+RreD1qLOXlkZ3N0AQUAOzAAAAEAAA0AAQAbEQ0AAYACMTfpjABPsFAS8wCHZXABAgGwQBIwAAFlAVYPAAATgAIwJswUfzhpdAGAAkQawiaMeA2mRTzNKm90AQIBoHAAABKzZQGbDAAAAQMAOzAAAAEAAAgAAQA7EAgAAYADoEAAABCPsMATwAABoGAAABFYZXN1AYACsJATMAABXEMgo4wxaW0BAwE48eWOKPFl9TwPAAABAPUDaAABAAAAAAABqQQAAAGDEAAAGrYBAQR3Skq/i3NwAYACsFAQhQABoLAAABNnY3MBAwD0kBAAAAEAqAABAAADcGluAADywQwAAAEAABKBdwEBoBAAABMzc2XSAAEDoFAAABJ6b2NleQABfQwAAAEBADswAAABAAD3AAIAjgwBADkO9QABAgD07RAAAAEA3AIBAAAIcmVjZWl2ZWQAAPJvEAAAAQAA8oABAXRyMoABAqAAAAAL3HJucfZDXgDD0KBQAAAL1nrZP6Kmy17/8W5d2zO1Bmm5WCxlJ1OQFrFAFB8AAaBAAAAP+wAEIgBAe50dADowAAABAAAAAAAhABAAAABiBGMEUQVSBSQHJQcoByAJIQmoDwEQaRBqEGsQbBAsEi0SZBJlEt0S3hINEw4TkhOTE5QTlROWE7ET4BPhEwUUGxQcFAACNTYAAAF6BQAAAAACMjgAAAF5BQAAAPKAAgAxMgANZGxpbWl0cmVhY2hlZAAA8qUSAAABAADygAIAYXMBAgGgQAAAEQJlAcIPAAATgQKwIA9DAAFlbQEIAPQ9EQAAAQABAAEAAQMBoAAAAA/Bc/JPDwAAAQAjgAKgsAAAE1NlaAEDAaBAAAAQlGXy5AgAAAEAAQEAOzAAAAEAAAgAAwBHEgAAuBIAAB8UBgAABG92ZWQAAAHdEAAAABqwAQE5kXo5BtNtcAAIaXNjb3ZlcnkAAAEiEgAAAAAEZGRlZAAAAd8PAAAA9gAAAnNzAwJJtifVPyVhZHJldgA7MAAAAQAAFgAIAH0PAQCVEAEA2RADAEgRBgAtEwIAexMAANMTAQADFAEAEgABAQF2n0WZvWV28gQCAAABADowAAABAAAAAAAQABAAAACIBa0MPA89D1gPcg8FEAYQrxCwEDgSORI6EjsSMhOaE5sTABJhdHRyYXZlcnNhbGFkZHJlc3MAAPLTEwAAAQAAAAdhZGRyZXNzAADy2xAAAAEAAAgAAADy2RAAAAEAAPKBdgIANDYSgAEBsBAHMwABcG4ABHNpZ24AADswAAABAAAGAAIAvAsAALsMBQAAAAVkcmVzcwAA8n0PAAABAAAygAIBsFAQCwC8ZHN09gAAAAQBoBAAAA/fYWlucmU7MAAAAQAABgACAHQAAACNAAUA9E8RAAABAAEAAQC2IgAAgYugIAAABzhAX0JdceawsBKlAAGw4BKpAAEvfDm5A/KggAAAEUGgAAAAErIIAACXGE4AOjAAAAEAAAAAAAwAEAAAAPsBXARdBF4Evgu/CyMMJAwlDLMSyRLuE+8TAYICsDAPqQABoJAAABP5cnMBAAGgQAAAEgxp8qASAAA/AQGDArBwEwQAAbCAEzsAAWNzAAAAAPICAgAAAQA7MAAAAQAABQACABwMAQCkDwMACCsAAPSnEgAAAQCRAAEAAPIIcmVxdWVuY3kBAGP13Q8AAAEAvgABAAEAAAEAhLCgEosAAbAgC9oAATGEFRkSwbCAEmoAAQgEBvPbBgAAAQABAAAQaWNpdGluZ3RocmVzaG9sZAAA8qgTAAABAAAIFAAA8ncFAAABAPKcDAAAAQBygAICsAAHJgABY2x0eXYBAACDg7BAEKwAAT8gB4STnjAAAogACPJyAAAAAQA7MAAAAQAADQAEANMGBwA1BwEA/A8BAKgQAQAAA2l0aAAAAXwPAAAAAAJuaQAA8rsLAAD/AAAIdwAAAVcPAAAAAAlhbmRzaGFrZXMAAAH+EgAAAAADcnR0AAABmxAAAADyAAIAMGgA9XoRAACMAQEAAQABAPKAAgBkcuIDZXB0hID2kAjGAyQSABj1dgUAAC4AAQABAAEAAHYBAIACBAcCbJg8UVMs58EOZ2NrZWhpdAEFAaBQAAATwnMBEhIAAAg4AADyuQsAAAEA8m4RAAABABIEbmRvbgECsDATugABsFASjQABZXByAPRrDwAAAQDpAAEAUoABAg4WjikRn2FscwAAy8wXzhhd12oHIANL0ghu2uSNdZpTAGo0TDgH6dSuYsJPFuxm04kZGkwzhlQISdy2sp0mCd4EkutYz2XMs7F46XBLy4igEAAACMhu5+ceY3GhAAAAE95Cu1uwuUYMIzze5iV8859xIIlmOwvhpGugcAAAEx4Sdky6h+cYK09u9kl6DRWt3ktTbYl/LT2AB6oNQlgVcgA7MAAAAQAAEQAIAAsCAAAtBwEA5ggAADIJAQB8EAEAhxABABIRBQANEgEAAIAaDuKQAAAAAOPgAAAAAeXQAAAACmbO4Z9L+xXYtpFw/yr2/KzCZ1ZD7EG7N3X7lT3rWES1aOvdvCYQbP3ZrG6pNLaiDgiWwhuc3jUBX9pJjQ4mHEDXOE3N6efcU173t1JNETbXvdkG3VH4lew+61p/lnpzKQDHxBLQaSTlif655WBfH8W10z0deGcNJkgkEU5api15gtS2OXjAZjpV1aAAAAAAADvDcdyyiSHNP0u8bw+TV3I2cktT5VJ+j0tgOPX8mqAQAAAFenxRw/XbJyRTR7zdJaAAAAAAAaAAAAAAClqZLUd8mQyG/yEIcAaJaigDGigtW2FiY2RlZmdoaWtsbW5vcHFyc3R1dnd6KTAxMjM0NTY4Pl1qeHk=","N":"ADBg","E":"OjAAAAAAAAA=","H":"EsWEWAg0"},"crateNames":{"N":"j","E":"OjAAAAAAAAA=","H":"JFDJy0NX"},"name":{"N":"ADBg","E":"OjAAAAAAAAA=","H":"+RVafadn"},"path":{"N":"BAo","E":"OzAAAAEAAAcSugACAAQACQAAAAsAZQByAAEAeQAAAH8ABACKAAEAjQAFAJQAGwCyAOsAoAEIAKoBJADQAQ4A4wEAAOcBBQDzAQEA9wECAPsBAAAAAgUACAI8AkYEAABIBBIAXAQCAGAEAwBlBAoAcQQJAIUEAACXBAIAmwQDAKAEAACiBAAApwQAAKkEAACsBJoASAUBAEwFCABWBQgAYAUCAGYFCABzBQIAdwUEAH8FBQCNBQEAmQUCAJ0FAgCkBe0AkwYEAJkGAACbBgAAngY8ANwGDwDuBgMA8wYDAPgGGAASBwwAJAcBACgHAAAtBwEAMQcAADMHAwA/BwAAQQcCAEYHAABJBwAATAd0AMIHBQDKBwYA0gfzAMgIAADKCAEAzggBANUIAADbCAUA5QgAAOcIAADqCAIA8AgBAPkIBQABCR0AIAkUADcJgQK6CwAAwQsBAMcLAADMCwAA0gsAANYLAwDiCwAA6gsJAPULBwD+CxkAGQwQACsMTQB6DAMAggwAAIQMAQCcDAEAugx3ATQOAgA5Dh0BWA8AAGMPAQBpDwMAbw8BAHIPAQB1DwEAfA8DAIEPQQDEDwIAyQ8WAOYPAQDpDwIA9A8BAPkPBAD/DwIABhAEAA0QAAAcEBIAMBAgAFIQHgBzEAMAexAAAH4QAQCBEAEAhBAHAJAQAQCVEAEAmxADAKAQAACiEAIAphA3AOQQBQDtEAEA8hAFAPsQBQAFEQEAChFQAFwRAABgEQAAZREBAGgRAQBvEQAAeBEBAHsRAwCAEaEAIxIAACUSAAAoEgEAKxIAAC4SAwAzEgoAPxIBAEcSAgBLEhgAZRIXAH4SAgCHEgEAkRIRAKQSAgCpEgMArhIHALgSAwC9EgUAxxICAM0SAADPEgEA0hIbAO8SAgD0EgQA+xIfAB0TCwArEwQAMxMAADkTJQBgEwQAaBMFAHATGgCMEwIAkRMQAKQTFwC+EwoAzBMFANMTFADpEwMA7hMXAAkUHQA=","H":"DECPfczH"},"entry":{"N":"ACAo","E":"OjAAAAEAAAAAAAcBEAAAAAAAAQAHAAgACgBxAHQAdQB2AHoAewCEAIgAiQCMAJMAsACxAJ4BnwGpAd8B4AHhAeIB5AHlAeYB7QHuAe8B8gH1AfoB/AH/AQYCRQRbBF8EZARwBHsEfAR9BH4EgQSCBIYEhwSIBIkEigSLBIwEjQSOBI8ElASaBJ8EoQSjBKYEqASqBEcFSgVLBVUFXwVjBWQFZQVvBXAFcQVyBXwFfQWFBYYFhwWIBYsFjAWPBZAFkwWUBZUFlgWXBZwFoAWhBZIGmAaaBpwGnQbbBuwG7QbyBvcGEQcfByAHIQciByMHKQcsBzcHOAc5BzoHPgdFB0cHSAfIB8kH0QfHCM0I0AjRCNQI2AjZCOMI5AjtCPcI+Aj/CAAJHwk1CbkLvAu9C74LvwvAC8ULyAvLC84L1QvcC94L5QvmC+gL6Qv0C/0LKgx5DH4MgAyBDIMMhwyJDI4MjwySDJUMlgyYDJkMmgybDJ8MowypDKwMrQyvDLAMMg4zDjcOOA5bD14PaA93D3sPww/HD8gP4A/hD+0P8A/+DwIQBRAMEA4QERASEBcQGBAbEC8QURB3EIAQjhCSEJMQlxCfEKEQ3xDgEOIQ4xDsEPEQ+hBkEWoRbhFwEXERdBF3EX8RJxIsEjISPhJKEmQSfRKLEo0SvBLDEsQSxRLMEu4SGxMcEykTKhM0EzcTXxNnE6IToxPJE9ITBxQIFA==","H":"hLo4pVqR"},"desc":{"N":"FNl","E":"OzAAAAEAADoNhgEAAAEABwABAAoAVgBvAAAAcQAFAHkAAwCEAAEAhwACAIwAGwCwAOsAngEBAKkBAgDMAQIA0AEBANUBAQDYAQAA3QEJAO0BAgDyAQAA9QEAAPgBAgD8AQAA/wEAAAICAQAGAgEADAIGACoCAAA6AgAAPAICAEECAABGAgIASgIAAFECBABZAgAAYQIAAGMCAQBqAgAAbwIAAHECAAB0AgAAdgIAAHsCAACBAgAAjQIAAJICBQCZAgQAtgIEAL8CAADTAgAA2AIAAN0CAADjAgEA6wIAAPECAAD6AgAA/wIAAAEDAAAJAwAADgMAABMDAAAYAwkAIwMAADADAAA/AxQAOwQEAEEEAABFBAAARwQAAEkEAABLBAAATQQMAFsEAABfBAAAYQQAAGQEAABtBAAAcAQAAHYEAQB5BAUAgQQBAIUECgCUBAAAmgQAAJ8EAAChBAAAowQFAKoEAQCtBAIAsQQDALwEhgBHBQQAVAUBAFcFAgBfBQAAYQUFAGwFAABvBQMAdwUDAHwFAQCDBQUAiwUBAI8FAQCTBQQAnAUBAJ8FAgCoBeYAkgYBAJUGAQCYBgAAmgYAAJwGAQCgBgAApAYAAKcGCACxBgEAtQYLAMQGAADLBgEAzgYBANQGAgDYBgMA7AYCAPAGAADyBgEA9QYLAAYHAQARBwAAFQcCABkHAgAfBwQAKQcAACwHAgAxBwAAMwcHAD4HAABFBwAARwcBAE8HAABSBxkAdAcwAKYHAQC4BwIAvAcCAMMHAADFBwAAyAcBANEHAADTBwAA1wfmAMcIBADNCAAA0AgBANQIAADYCAEA3wgBAOMIAQDtCAAA9wgBAPwIBAAPCQEAGQkEAB8JAAAjCQIAJwkCADIJAQA1CQIAQwm6AAAKAAACCk0AUwpgAbgLAQC8CwQAxQsBAMgLAADLCwAAzgsAANALAQDVCwAA1wsBANwLAADeCwAA5QsBAOgLAQDrCwkA9gsCAPoLAwABDAEACQwAABQMAwAcDAEAHwwEACUMAAAoDAIALgwAADAMBQA3DD4AeQwAAH4MAACADAEAgwwAAIcMAACJDAAAjgwBAJIMAACVDAEAmAwFAJ8MAACjDAAAqQwAAKwMBAC7DAUAwwxtATIOAQA3DvcAQg8AAEgPAwBNDwEAVQ8BAFgPAwBeDwAAYw8BAGgPAABrDwEAbw8EAHUPAgB5DwIAfQ8DAJEPDwCiDwEApQ8AAKcPAQCrDxMAww8AAMcPAQDdDwEA4A8BAO0PAADwDwAA8w8AAPwPAwACEAAABRAAAAcQAwAMEAAADhAAABEQAQAXEAEAGxAFACMQAQAoEAIALBAAAC4QAQA2EAEAPRABAEEQBABQEAIAVRABAFoQAQBlEAMAdxAAAH4QAgCHEAMAjhAAAJAQAwCVEAIAnBABAJ8QAAChEAAApRAAAKcQAgCvEAIAsxACALcQBgDDEAAAzxABANMQCQDfEAEA4hABAOwQAADxEAAA9BABAPoQAAD9EAMABBEAAAwRAAAOEQAAEBEAABURAAAXEQMAHBEAAB4RAAAgEQAAIxEAACURAAAnEQAAKxEAAC4RAAAwEQAAMhEAADYRAAA4EQIAPhEAAEARAABNEQEAVREAAFgRAgBcEQAAZBECAGgRAgBuEQAAcBEBAHQRAAB3EQAAfxGHAA0SBAATEgAAGRIBABwSAQAfEgAAIRIAACMSAAAlEgAAJxIAACwSAAAyEgAAOBIGAEoSAABNEgEAUBICAFUSAQBZEgUAYhICAGwSAABxEgAAfRIAAIsSAACNEgAAkRIDAJwSAwCjEgEAuRIAALwSAgDDEgIAxxICAMwSAADSEgQA4RIBAO4SAQDyEgAA9BIDAP8SBAAHEwAACRMAABITAgAWEwIAGxMBAB4TAAAhEwMAKRMBADQTAAA3EwAAPRMGAFMTAABWEwEAXRMCAGETAABkEwAAZxMAAHwTAQCNEwEAkBMBAJQTAACWEwAAnBMDAKITAQCqEwQAshMFALwTAQDGEwAAyRMAANITAADXEwMA5BMAAPITBQD5EwAA/xMAAAEUAQAHFAEAERQAABUUAAA=","H":"qFWkrVd+"},"function":{"N":"A@Jc","E":"OzAAAAEAAIMDWAAAAAoAcQAbAJMAAACwAAEAngEBAKkBAADPAQAA3wEiAAYCAQBFBAAARwQAAFsEAABfBAAAZAQAAHAEAAB7BC0AqgQBAEcFAABKBQEAVQUAAF8FAABjBQMAbAUAAG8FAwB2BS0AkgYAAJUGAACYBgIAnAYCAKIGAADbBgAA7AYGAPUGAAD3BgAAEQcAABwHMADBBwAAyAcBANEHAADGCDMA/wgBAB8JAAA1CQEAuQswAPQLAAD9CwAAGAwAACoMAAB5DAAAfgwDAIMMNgAyDgMANw4BAFcPAABZDxgAdA8HAIAPAADDDwAAxw8BAN0PIQAAEBsALxAAAFEQAQBvECsAnxACAKUQAADZEDAAWhElACISKQBkEgEAexIbAKMSAAClEhMAuhIXAO4SAADyEgsAGxMCACUTEwBfEwAAYhMAAGUTCgCBEw8AohMFALoTAwDHEwsA3hMAAOgTBQAGFAQA","H":"5B67DzET"},"type":{"N":"AJl","E":"OzAAAAEAAHoSmwACAAQACQAAAAsAZQByAAIAeQAAAH8ABQCIAAAAigABAI0AIgCyAOsAnwEJAKoBNADjAQEA5gEIAPMBAQD3AQIA+wEAAAACBQAHAnMCgQQAAIUEAgCKBAEAlAQAAJcEAgCbBAMAoAQAAKIEAACnBAAAqQQAAKsEswBgBRAAcwUCAHcFBQB/BQUAjQUBAJkFBgCkBXoBIQcEACgHAAAtBwEAMQcAADMHAwA/BwAAQQcCAEUHBABMB3sAyQf8AMgIAADKCAEAzQgCANUIAADYCAEA2wgFAOUIAADnCAAA6ggCAPAIAQD5CL8CugsAALwLAwDBCwEAxQsAAMcLAADMCwAA0gsAANYLAwDcCwAA3gsAAOILAADlCwEA6QtAACsMUgCADAIAhAwBAIcMAACODAEAkgwAAJsMAgCvDAAAugycAlgPAABjDwEAaA8EAG8PAQByDwEAdQ8CAHwPYwDmDwEA6Q8CAPQPAQD5DwgABhAEAA0QAAAcEFQAcxAEAHsQAAB+EAEAgRABAIQQBwCQEAEAlRABAJsQQgDiEAAA5BAFAOwQAgDyEAUA+xAFAAURAQAKEVAAXBEAAGARAABlEQEAaBECAG8RAAB4EQEAexGmACMSAAAlEgAAKBIBACsSAAAuEgMAMxIKAD8SAQBHEgIASxIxAH4SAgCHEgEAixIAAI0SAACREhUAqRIDAK4SBwC4EgMAvRIFAMQSAADHEgIAzRIAAM8SAQDSEh8A9BIEAPsSLQArEwQAMxMAADkTKwBoEwUAcBMaAIwTAgCRExAApBMXAL4TCgDMEwUA0xMUAOkTAwDuExcACRQdAA==","H":"zYwvkhew"},"alias":{"N":"`","E":"OzAAAAEAACYUAQAAACYU","H":"p2IVDFMs"},"generic_inverted_index":{"N":"b","E":"OjAAAAAAAAA=","H":"9aRB+vFv"}}') \ No newline at end of file diff --git a/pr/580/docs/search.index/type/3e6b4613c076.js b/pr/580/docs/search.index/type/cd8c2f9217b0.js similarity index 99% rename from pr/580/docs/search.index/type/3e6b4613c076.js rename to pr/580/docs/search.index/type/cd8c2f9217b0.js index c66a8ea12..d0e3a161e 100644 --- a/pr/580/docs/search.index/type/3e6b4613c076.js +++ b/pr/580/docs/search.index/type/cd8c2f9217b0.js @@ -1 +1 @@ -rd_("CBg[\"\",\"ADswAAABAAAFAAIAOwQEAPkTAAACyAYAAOcGAAA6MAAAAQAAAAAACgAQAAAA3QHeAVkFfAwTElcSbBLYE+QTAhQRFDowAAABAAAAAAAaABAAAAAMAg0CDgIPAhACEQISAkoEWAVdBZYGxAbzBjcJsRAWElgS6hKXE5gT2xP+E/8TABQBFBQUGBQ7MAAAAQAALAESAEgEAABFBQAAVwUAAMkGAADmBgAA9gYAADIMAwC7DAUAqg2GADkQAACyEAcAEREAAIARhgAXEgAAGRIAAKESAADrEgAAChMAADowAAABAAAAAAAdABAAAABaBWAFYQViBcIGwwbKBssGzAbNBs4Gzwa1C7YLtwu4CwgMTg9SD2MQyBASEh4TWxNcE3IT0xPXE+UTAxQ7MAAAAQAAPQAUAD8DFABmBAAAcgQCAEMFAQBGBQAAWwUBAHUFAAC1BgwAwgcDALQLAAAeDAAAqA8AANwPAABkEAAAChEAAKISAADmEgMAUxMAANQTAAAEFAAAOzAAAAEAAFcADQDbAD0AigEBAGUEAABwBwAAcwcAALIHAAC0BwAAKxADAEwSBQBDEwAAcxMAALITBQDFEwAAOzAAAAEAABUABwBMBAAAfQwAADEOAACkDwMAFBIAABETBwDyEwUAOzAAAAEAABMACQBiBAEAawQBANMGBwCxBwAAswcAAEgPAgBRDwAAwxAAAHoSAAADEgcAABMHAABpEgAAAScMAAAEbQcAAG8HAAByBwAAJQwAAAA7MAAAAQAABQACAMIBAACSEwQAAAABpwUAAA==\"]Bo[\"AAAAAAAAAAACwBMAAMETAAAAAAAAAqIQAACjEAAA\",\"\"]0Bg[\"\",\"AAAFGQkAABoJAAAbCQAAHAkAAB0JAAA=\"]AGg[\"AAAAAAKzAQAAwwEAAAAAAkMFAABEBQAABHAHAABzBwAAsgcAALQHAAA7MAAAAQAADQAFAHMFAQA/CQEALQwEAH0MAAA9EQMAOjAAAAEAAAAAAAsAEAAAAGsEbASxB7MHUQ9tEG4QLxEwETERMhF6EgRcBAAAEgcAABMHAADBDwAABEIEAABEBAAAnhMAAJ8TAAAFYQQAAG8HAAByBwAASw8AAE0PAAADIwwAACQMAABMDwAAOzAAAAEAAAYAAwDCAQAAsAYAAJITBAAB7xIAAAEmDAAA\",\"AAAAAVkRAAAAAkgFAABJBQAAAAIBDAAAAgwAAAAFLQwAAC4MAAAvDAAAMAwAADEMAAAAAAJCBAAARAQAAA==\"]ANg[\"AAAEUgIAALgCAACfBgAAowYAAAMDDAAABAwAAAUMAAACswEAAMMBAAA7MAAAAQAAhgABAIARhgAAOzAAAAEAAAcAAwBDBQEA5hIDACQUAQAEcAcAAHMHAACyBwAAtAcAADswAAABAAASAAcAcwUBAOgGAAA/CQEALQwEAH0MAAA9EQMAHhIDADowAAABAAAAAAAKABAAAABiBGMEawRsBLEHswdRDy8RMBExETIRBVwEAABeBQAAEgcAABMHAADEEAAABEIEAABEBAAAnhMAAJ8TAAAEbwcAAHIHAABLDwAATQ8AAATFBgAAIwwAACQMAABMDwAABZITAACTEwAAlBMAAJUTAACWEwAAAe8SAAAAAacFAAA=\",\"AAAAAAACSAUAAEkFAAAAAgEMAAACDAAAAcIPAAAFLQwAAC4MAAAvDAAAMAwAADEMAAAAAAJCBAAARAQAAAAAAAAAA94GAAAYEQAAGREAAA==\"]Dc[\"\",\"AAAAADswAAABAAAHAAEAIgkHADswAAABAAAJAAIAvhAEABMRBAAAARIRAAA=\"]ADm[\"AAAABrABAACyAQAAvwEAAMEBAADYDwAA2Q8AAAS2AQAAyQEAADYKAAA4CgAAOjAAAAEAAAAAAAkAEAAAALEBtwG4AcABygHLAaYKqgqgE6ETOzAAAAEAAA0ABACsBAcAfA8AAGkQAwByEwAAArsBAACiEgAAOzAAAAEAABUACgCmAQEArQEAACsMAQB2DAEAzw8DAFgQAQByEgMAQxMAAMATAQALFAEAAcITAAAAAAAAAAAAAAGnBQAA\",\"AAABqwEAAAK0BAAABxIAAAAAAAJCDwAAUBAAAAAAAAAAAAAAAAAEoQYAAKUGAAB6DAAAewwAAA==\",1]Fk[\"AAAABOsEAAAVBwAAuAcAABwRAAACIwkAAPYLAAABsxAAAAABwwcAAAELAQAAAqUPAAASEwAAAdQGAAA=\",\"AAAAAesEAAABtgEAAA==\"]Fk[\"AAAABDUFAAAZBwAAvAcAACMRAAACJwkAAPoLAAABtxAAAAGOAQAAAcUHAAAAAqcPAAAWEwAAAdgGAAA=\",\"AAAAATUFAAAByQEAAA==\"]AEa[\"AAAAAq4BAAC6AQAAOzAAAAEAAAcAAQAiCQcAAARgBQAAYQUAAGIFAAASEgAAAAABwhMAAAAAAAKiEAAAoxAAAA==\",\"AAAAADswAAABAAAQAAMAlgYAACIJBwD1CwcAOzAAAAEAAAsABAD2BgAApBAAAL4QBAATEQQAOzAAAAEAAA8ABQCsBAcAEwwCABsSAgBTEgAA1xMAADowAAABAAAAAAAKABAAAADOENAQ0hDUENYQEhE1ETYRNxE4EVMTBCsQAAAsEAAALRAAAC4QAAAAAAXNEAAAzxAAANEQAADTEAAA1RAAAAAAAAAAAAKnBQAARw8AAA==\",1]Ec[\"AAAAAAAAOzAAAAEAAAYAAgCsBgMAsQYCADswAAABAAAGAAIApwYEAAoJAQADXgQAAFMFAABUBQAA\",\"\"]Dg[\"AAAAAAAAAAABsxMAAAHzEwAAAAAAAAAAAAABVAcAAA==\",\"AAAAAAABWhIAAAE+EwAA\"]Eo[\"AAAAAekEAAABtQEAAAIqAAAAmQAAAAGwDwAAAUQDAAACBgEAAAcBAAA=\",\"AAABqAAAAAHpBAAAAQATAAAAAe0LAAA=\"]Ic[\"AAAAASsFAAADxwEAABoTAACZEwAAAlgAAACmAAAABnsBAAB8AQAAQwQAAKYFAAC9DwAA5RMAAAFRAwAA\",\"AAABqQAAAAIrBQAAAhMAAAAB8QsAAAAAAAAAAAAAAAAAAAKqAAAAqwAAAA==\"]Ik[\"AAAAArwEAABxEgAAAfMGAAABkwYAAAGyAAAAAQoRAAABshMAAAIUEgAA8hMAAAAAAAAAAAAAOjAAAAEAAAAAAAkAEAAAAGcFkQZRB9IHig+hD9MPXBCmEEER\",\"AAAAAbwEAAAAAVkSAAABPRMAAA==\"]Ck[\"AAAAAd0BAAAAAAAAAbYTAAAB9hMAAA==\",\"AAAAAAABXRIAAAFBEwAA\"]Ck[\"AAAAAd4BAAAAAAAAAbcTAAAB9xMAAA==\",\"AAAAAAABXhIAAAFCEwAA\"]Kk[\"AAAAAAAABFoFAABgBQAAYQUAAGIFAAAAOzAAAAEAAAkAAQCqCwkAOzAAAAEAAA0AAQBMBA0AOzAAAAEAAAkABAAfDAMASA8CAMMQAADXEAEAAAEnDAAAAyUMAABLDwAATQ8AAAIjDAAATA8AAA==\",\"AAAAAAABpBAAAAMTDAAAFAwAABUMAAA=\"]Nk[\"AAAAAAAAAngSAAB5EgAABOYSAADnEgAA6BIAAOkSAAAC7BIAAO0SAAAF6AYAAB4SAAAfEgAAIBIAACESAAACYgQAAGMEAAACXgUAAMQQAAAAAAHFBgAAAAAAAacFAAA=\",\"AAAAAAJWBQAAxhMAAAAF/BMAAB8UAAAgFAAAIRQAACIUAAABUxMAAALCDwAA/RMAAAAAAAAAAAAAAAQwEAAAMRAAADIQAAAzEAAA\"]Bg[\"AAAAAAAAAARWEQAAVxEAAHYTAAB3EwAA\",\"\"]Bk[\"\",\"AAAAAVURAAAAAAAAAAAAAAAAAAAAAAFVDwAA\"]Cc[\"AAAAAAAAAWMQAAABZBAAAA==\",\"AAAAAAACOQkAADoJAAA=\"]FGo[\"AAAAADswAAABAAAVAAkADAIGAEoEAABrBQAA1AcAAP8LAAA0EAMAWBIAAJcTAQD+EwMAOzAAAAEAABMCEgBBBAAAWgQAAGAEAADJBgAA7wsDALsMBQDDDG0BxA8AAMkPAAA5EAAAVxAAALIQBwAREQAAgBGGABcSAAAZEgAA6xIAAE4TAAA7MAAAAQAAwwAPALIAKAAZAXAAjAEPAEMEAABaBQAApgUAAKwGAwCxBgIAwgYBAOsLAwBGDwAAHhMAAD0TBQDlEwAA+BMAADswAAABAACiAEIAPwMUAF0EAABnBAEAcgQCAEYFAABbBQEAdQUAAKcGBAC1BgwAvwcBAMIHAwDACAEACgkBACAJAQArCQEAAQwBABEMAQAeDAAAwQwBAEMPAQBTDwEAiw8BAI4PAQCoDwAAyg8BANQPAQDcDwAAOhAAAEoQAQBhEAEAZBAAAMkQAQASEQAAHREAAB8RAAAhEQAAJBEAACYRAAAoEQAAMxEFAEIRAQBFEQIAVhEBAAgSAQBqEgEAohIAANcSAQDdEgEA5hIDAAQTAQBEEwEAVBMBAFgTAQB2EwEAfhMBAKgTAQC4EwEA1BMCAOATAwDuEwMABBQAABIUAQAWFAEAGRQBAB0UAQAkFAEAOzAAAAEAAI8AJgDbAD0AigEBAKYBAQBABAAAXgQAAGUEAABTBQEAbQUBAHAHAABzBwAAsgcAALQHAACqCwkAKwwBAHYMAQBPDwEAhA8BAMIPAADPDwMAWBABAKwQAQDFEAEAFRIAAGASAQByEgMA7BIBAA0TAQA5EwEATBMBAE8TAwBzEwAAshMFAMATAQDFEwAA+hMBAP0TAAALFAMAGxQBADswAAABAAAxAA0ATAQNAHMFAQDoBgAAPwkBABsMAAB9DAAAMQ4AAKQPAwA9EQMAHhIDABETBwBJEwEA8hMFADswAAABAAAcAA0AYgQBAGsEAQDTBgcAsQcAALMHAAAfDAMASA8CAFEPAABtEAEAwxAAANcQAQB6EgAABRQAADowAAABAAAAAAAHABAAAABcBF4FwQ/EEDsRPBFpEtwTA0IEAABEBAAAJwwAADowAAABAAAAAAAIABAAAABhBG0HbwdyByUMSw9ND6IQoxAExQYAACMMAAAkDAAATA8AADswAAABAAAFAAIAsAYAAJITBAAAASYMAAABpwUAAA==\",\"AAAAAAA7MAAAAQAA5gABAMMM5gAAOjAAAAEAAAAAAFkAEAAAAGcEaAS/B8AHwAjBCCAJIQkrCSwJAQwCDBEMEgzBDMIMQw9ED1MPVA+LD4wPjg+PD8oPyw/UD9UPShBLEGEQYhDJEMoQHREfESERJBEmESgRMxE0EUIRQxFWEVcRCBIJEmoSaxLXEtgS3RLeEgQTBRNEE0UTVBNVE1gTWRN2E3cTfhN/E6gTqRO4E7kT1RPWE+AT4RPiE+MT7hPvE/AT8RMSFBMUFhQXFBkUGhQdFB4UJBQlFDswAAABAAAvABQApgEBAG0FAQArDAEAdgwBAIQPAQDPDwMAWBABAKwQAQDFEAEAYBIBAHISAwDsEgEADRMBADkTAQBMEwEATxMDAMATAQD6EwEACxQDABsUAQAEPwkAAEAJAABJEwAAShMAAAACOxEAADwRAAAAAqIQAACjEAAA\"]Ic[\"AAAAARoRAAAABFcFAAAPCQAAEAkAABESAAA7MAAAAQAADAADAHUEBQDKBgUAkRMAAAADbAcAAMUQAADGEAAAASYQAAAAB80QAADPEAAA0RAAANMQAADVEAAAOxEAADwRAAAAAW0HAAA=\",\"\"]Lk[\"AAACUwIAALYCAAAAArYBAADJAQAAOzAAAAEAAAsAAwC3AQEAygEBALIQBwA7MAAAAQAABwABAKwEBwA6MAAAAQAAAAAABwAQAAAAvwfAB4sPjA/UD9UPMxE0EQACSRMAAEoTAAA=\",\"AAAAAYIPAAAAAAAAAAAAAAAAAAAAAAWBDwAAgw8AAIoPAACNDwAASxMAAA==\"]AAg[\"AAAEVQIAALcCAAARCQAAEgkAAASsAQAAtAEAALkBAADGAQAAAlkCAAC/AgAAAAA6MAAAAQAAAAAAEwAQAAAAZwRoBMAIwQg8ED4QQBBCEEMQzhDQENIQ1BDWEGoSaxIWFBcUGRQaFALsEgAA7RIAAAUtDAAALgwAAC8MAAAwDAAAMQwAAAAFzRAAAM8QAADREAAA0xAAANUQAAAAAAACwgEAALAGAAA=\",\"AAAAAAAAAAAAAAAAAAAAAAAABMIIAADDCAAAxAgAAMUIAAA=\"]BLk[\"AAADDgkAANkSAADaEgAABaoBAAAYCgAAVREAAN8SAADgEgAAOjAAAAEAAAAAAAcAEAAAALUBxwETCRQJ/wlQCnoKFhIBFxIAAAEeEwAAOjAAAAEAAAAAABEAEAAAAMIHwwfEB8UHQg/KD8sPUBAdER8RIREkESYRKBFEE0UT4BPhEwFDEwAAOzAAAAEAAAsAAgCkDwMAERMHADswAAABAAAJAAMA0wYHALEHAACzBwAAAAACbwcAAHIHAAA=\",\"AAAETQUAAE4FAAA4DwAAOQ8AADswAAABAAAWAAsAFAcHABsRAQAeEQAAIBEAACIRAQAlEQAAJxEAAAoSAQBwEwEAdBMAAL4TAQACGhMAAJkTAAABERIAAAAAAAAAAAAAAAAAADowAAABAAAAAABvABAAAACgAaEBowGkAQICAwIJAgoCSQRLBG0EtgS5BKAGpAbRBtIGBgcHB/wI/QgyCTMJ/gsADBYMFwwcDB0MKAwpDD4PPw9AD0EPVg99D34Pnw+gD9MPKBApEEYQRxBIEEkQVRBWEFoQWxBlEGYQnBCdEKYQqBCpEK8QsBC6ELsQvBC9EDkROhFNEU4RDRIOEg8SEBJVElYSYhJjEm4ScBKXEpgSmRKaEpwSnRKeEp8S2xLhEuIS4xL+Eg8TEBMZEx8TIBMhEyITIxMkEzsTPBNWE1cTXRNeE3wTfROcE50T2RPaEw==\"]Ac[\"AAAAAAEwAwAA\",\"\"]Ca[\"AAAAAAJZAgAAvwIAADswAAABAAAFAAEATxEFAA==\",\"\",1]Ek[\"AAAAAAAAAAAAAAAAAAAAAAAAAsYGAADcBgAA\",\"AAAAAAACOxAAAD0QAAAAAjwQAAA+EAAAAAIeEgAAHxIAAA==\"]Eo[\"AAAAAAAAAAAAAAAAAAAAAAAAAscGAADdBgAA\",\"AAAAAAACPxAAAEEQAAAAA0AQAABCEAAAQxAAAAACIBIAACESAAA=\"]Ck[\"AAAAAAAAAAAAAAAAAAAAAAAABXAAAACkAQAArQcAAMwHAADECAAA\",\"\"]Bg[\"AAAAAAAAAU4PAAAAAAAAAjsRAAA8EQAA\",\"\"]Gk[\"AAAABGEAAADFBAAAagUAANcPAAABDgIAAAYOAAAASAQAAEUFAAAEBwAASxEAAJsTAAACxwAAAFIPAAAAAloTAACxEwAA\",\"AAAAAcUEAAABvwgAAAFGBAAA\"]Ic[\"\",\"AAAAAAAAAAA7MAAAAQAACQABAKoLCQA7MAAAAQAADQABAEwEDQA7MAAAAQAACQAEAB8MAwBIDwIAwxAAANcQAQAAAScMAAADJQwAAEsPAABNDwAAAyMMAAAkDAAATA8AAAAAASYMAAA=\"]Bg[\"AAAAAAAAAAAAAAAAAAKiEAAAoxAAAA==\",\"\"]Hk[\"AAAD0AEAAAoMAAANDAAAAegEAAABtQEAAAQpAAAAmAAAADsQAAA9EAAAAa8PAAABQwMAAAMFAQAADREAAA4RAAA=\",\"AAAC0AEAAAYMAAACaQQAAOgEAAAB/xIAAAAB7AsAAA==\"]Hk[\"AAAD0QEAAAsMAAAODAAAASoFAAABxwEAAARXAAAApQAAAD8QAABBEAAAAnoBAAC8DwAAAVADAAADXgQAAA8RAAAQEQAA\",\"AAAC0QEAAAcMAAADagQAACoFAAABEwAAAAHwCwAA\"]2ALo[\"AAAAAAEqEAAAAAA6MAAAAQAAAAAAEQAQAAAAuwFdBBEMEgzBDMIMQw9ED8kQyhAIEgkS7hPvExIUExQdFB4UAmUEAABDEwAAOzAAAAEAAAsAAgCkDwMAERMHADswAAABAAAHAAEA0wYHAAAAAAACwgEAALAGAAA=\",\"AAAHTwUAAFAFAAAKDAAACwwAAA0MAAAODAAAGBIAADowAAABAAAAAAAXABAAAAC1B7YHHgkqCQwMDwwQDDoPOw9MEE0QThCbEBoRKhErESwRLREuEUYTrxOwE8MTxBM7MAAAAQAA+QACADkO9QAGEwMAOzAAAAEAAFkABAALAFUA3BIAAAsTAQB1EwAAAfgTAAAAAAQ9EQAAPhEAAD8RAABAEQAABC8RAAAwEQAAMREAADIRAAABaRIAAAAAAAAAAAdxBAAAZwUAANAGAAA2DgAAnhAAAK4QAABBEQAA\"]Dk[\"AAAAAAIBCgAAUQoAAAAAADswAAABAAAFAAEATBIFAAACYgQAAGMEAAAAAkIEAABEBAAA\",\"\"]BNo[\"\",\"ADswAAABAAAFAAIAOwQEAPkTAAACyAYAAOcGAAA6MAAAAQAAAAAACgAQAAAA3QHeAVkFfAwTElcSbBLYE+QTAhQRFDowAAABAAAAAAAaABAAAAAMAg0CDgIPAhACEQISAkoEWAVdBZYGxAbzBjcJsRAWElgS6hKXE5gT2xP+E/8TABQBFBQUGBQ7MAAAAQAAKAERAEgEAABFBQAAVwUAAMkGAADmBgAA9gYAALsMBQCqDYYAORAAALIQBwAREQAAgBGGABcSAAAZEgAAoRIAAOsSAAAKEwAAOjAAAAEAAAAAABsAEAAAAFoFYAVhBWIFwgbDBsoGywbMBs0GzgbPBrULtgu3C7gLTg9SD2MQyBASEh4TWxNcE3IT0xPlEwMUOzAAAAEAADsAEgA/AxQAZgQAAHIEAgBDBQEARgUAAFsFAQB1BQAAtQYMAMIHAwC0CwAAHgwAAKgPAADcDwAAZBAAAKISAADmEgMA1BMAAAQUAAA7MAAAAQAAUgALANsAPQCKAQEAZQQAAHAHAABzBwAAsgcAALQHAABMEgUAcxMAALITBQDFEwAAOzAAAAEAABQABgBMBAAAfQwAADEOAACkDwMAERMHAPITBQA7MAAAAQAAEwAJAGIEAQBrBAEA0wYHALEHAACzBwAASA8CAFEPAADDEAAAehIAAAISBwAAEwcAAAEnDAAAA28HAAByBwAAJQwAAAAFkhMAAJMTAACUEwAAlRMAAJYTAAA=\"]Bc[\"AAAAAAAAAAAAAAACOxEAADwRAAA=\",\"\"]Kc[\"AAAAAAHlEgAAADswAAABAAAGAAIAygYFAMgQAAACRgUAANwPAAABZQQAAAADbRAAAG4QAAB6EgAAAcEPAAA=\",\"AAAAAAABYAQAADswAAABAAAFAAEAdQQFAAAAAAAAAAAAAAAABwsCAAC1BAAAuAQAAN8GAADgBgAA4QYAAOIGAAA=\"]Do[\"AAAAAAABGAAAAAAAAd8AAAAAAAAAAAAAAAACtQQAANEGAAA=\",\"AAAAAAAAAAACTw8AAFAPAAA=\"]Dk[\"AAAAAAABMAAAAAEfAQAAAAAAAAAAAAAAAAACuAQAANIGAAA=\",\"AAAAAAAAAAABQAQAAA==\"]Ac[\"AAABYQIAAA==\",\"\"]Fg[\"AAAABO0EAAAWBwAAuQcAAB4RAAADJAkAAPcLAAD/EwAAAbQQAAAAAAENAQAAARMTAAAB1QYAAA==\",\"AAAAAe0EAAAAAbcBAAA=\"]Fg[\"AAAABDcFAAAaBwAAvQcAACURAAADKAkAAPsLAAABFAAAAbgQAAABkAEAAAAAARcTAAAB2QYAAA==\",\"AAAAATcFAAAAAcoBAAA=\"]Bk[\"\",\"AAAAAAAAAAA7MAAAAQAAPwACANsAPQCKAQEA\"]Ck[\"\",\"AAAAAAGWBgAAOzAAAAEAAAkAAgD2BgAA+AYIAAHXEwAAAVMTAAA=\"]Bo[\"\",\"AAAAAAAAAAAAAAAAAp4TAACfEwAAAAAAAe8SAAA=\"]Ck[\"AAACYwIAAHQCAAA=\",\"AAAAAAAAAmATAABhEwAAAAACPREAAD4RAAA=\"]Eo[\"\",\"AAAAAAA7MAAAAQAABQABAFkSBQA7MAAAAQAABQABAD0TBQAAOzAAAAEAAAUAAQCyEwUAOzAAAAEAAAUAAQDyEwUA\"]Cc[\"\",\"AAAAAAL/EgAAABMAAAAE6wsAAOwLAADtCwAA7gsAAA==\"]Eo[\"AAAAAfEEAAAAAS0AAAAAAAIVAQAAFgEAAA==\",\"AAA7MAAAAQAACgACAJICBQCZAgQAAvEEAADmEwAAAAABeBIAAA==\"]Eo[\"AAAAATEFAAAAAV8AAAAAAAKKAQAAiwEAAA==\",\"AAA7MAAAAQAACgACABgDCQAjAwAAAjEFAADnEwAAAAABeRIAAA==\"]Dg[\"AAAB/wIAAAEwBQAAAAFdAAAAAoUBAACGAQAA\",\"AAABDgMAAAEwBQAAAAAAAAFeBAAA\"]Eo[\"AAAAAAAAApUBAACWAQAA\",\"AAAAAAAAB9MTAAD8EwAAAxQAAB8UAAAgFAAAIRQAACIUAAAC1BMAAAQUAAAB/RMAAA==\"]Bk[\"AAAAAAAAAUUBAAA=\",\"AAAB2AIAAAAAAVoEAAA=\"]Bg[\"AAAAATsFAAAAAAGXAQAA\",\"AAAAATsFAAA=\"]Bg[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAXgMAAA=\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA64HAADNBwAAxQgAAA==\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAnEEAACvBwAA\",\"\"]Cc[\"AAAAAAAAAAIKCQAACwkAAAAAAAAAAAACwgEAALAGAAA=\",\"\"]Fo[\"AAAAAAACVwUAABkSAAAAAAAAAAAAAAAAAAAE0wcAAFYPAABnEAAAWBEAAA==\",\"AAF1BwAAAAAAAAAAAAAAAAAAAAAAAAJoEAAADBEAAA==\"]Bk[\"AAAAAVkFAAAAAAFODwAAAagPAAA=\",\"AAGmBwAA\"]Bg[\"AAAAAAAABGkQAABqEAAAaxAAAGwQAAA=\",\"\"]Ag[\"AAAAAq4BAAC6AQAA\",\"\"]Dg[\"AAAAAAAAAAAAAj8JAABACQAA\",\"AAAAAAAAAAAABS0MAAAuDAAALwwAADAMAAAxDAAA\"]AEg[\"AAAAAAKzAQAAwwEAAAAAAkMFAABEBQAABHAHAABzBwAAsgcAALQHAAA7MAAAAQAACwAEAHMFAQAtDAQAfQwAAD0RAwA6MAAAAQAAAAAACwAQAAAAawRsBLEHswdRD20QbhAvETARMREyEXoSBFwEAAASBwAAEwcAAMEPAAAEQgQAAEQEAACeEwAAnxMAAAVhBAAAbwcAAHIHAABLDwAATQ8AAAMjDAAAJAwAAEwPAAA7MAAAAQAABgADAMIBAACwBgAAkhMEAAHvEgAAASYMAAA=\",\"AAAAAVkRAAAAAkgFAABJBQAAAAIBDAAAAgwAAAAAAAACQgQAAEQEAAA=\"]He[\"\",\"AAAAAAAEMgwAADMMAAA0DAAANQwAAAIIDAAA1xMAAAIKEQAAUxMAAAUrEAAALBAAAC0QAAAuEAAAQxMAAAEUEgAAAAFpEgAAAAFtBwAAAAHCAQAAAAABpwUAAA==\",1]AMk[\"AAACvAEAAMUBAAAGrAEAALQBAAC5AQAAxgEAAN8SAADgEgAABFgFAAA3CQAA/gkAAFIKAAAEMgwAADMMAAA0DAAANQwAAAJbEwAAXBMAADowAAABAAAAAAAHABAAAAAKCQsJShBLENcS2BLVE9YTOjAAAAEAAAAAAAkAEAAAAEAEcAdzB7IHtAdPD1APwg/6E/sTAAKxBwAAswcAAA==\",\"AAAAOjAAAAEAAAAAABAAEAAAAKIBTQdOB08HUAfVB9YHNgzFD8YPYBDLEMwQZhJnEqAS3xMDNAkAACoQAACbEgAABjIMAAAzDAAANAwAADUMAABtEgAAbxIAAAAAAAJzBQAAdAUAAAACXAQAAMEPAAAAA2EEAABLDwAATQ8AAAMjDAAAJAwAAEwPAAAAAAImDAAAggwAADowAAABAAAAAAALABAAAAClAW4EbwS3BLoEjwaQBggHUQfSB9MHoQ8=\"]Bg[\"AAAAAAAAAAAAAVcEAAA=\",\"AAAAAaQFAAA=\"]Bk[\"AAAAAAAAADswAAABAAANAAIAdQUAALUGDAA=\",\"\"]Cc[\"AAABAQkAAAABEgIAAAAAAAFABAAA\",\"AAAAAAAAAAFdBAAA\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAbAGAAA=\",\"\"]Be[\"AAAAAAAAA2AFAABhBQAAYgUAAA==\",\"\",1]Bg[\"AAAAAAAAADswAAABAAAUAAEAPwMUAA==\",\"\"]Dk[\"AAAAAAHIAQAA\",\"AAAAAAUtCQAALgkAAC8JAAAwCQAAMQkAAAAAAAAAAAAAAAAAAAH/DwAA\"]Cc[\"AAAAAcQEAAAAAQ0AAAACvwAAAMAAAAA=\",\"AAAAAcQEAAA=\"]Bg[\"AAAAAAAAAAAAAVIEAAA=\",\"AAAAAcYHAAA=\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWYAAAA=\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAaoAAAA=\",\"\"]C@i[\"AAAAAAHIAQAAAaESAAABchMAAAK7AQAAohIAADowAAABAAAAAAAbABAAAACtAW0FbgWED4UPrBCtEGASYRINEw4TORM6E0wTTRNPE1ATURNSE1oTcxOxE/oT+xMNFA4UGxQcFDswAAABAAAGAAMAPwkBAKQPAwDCEwAAAQUUAAAB3BMAAAAAAcUGAAAAAAABpwUAAA==\",\"AAAFGQkAABoJAAAbCQAAHAkAAB0JAAAEAwwAAAQMAAAFDAAABxIAADowAAABAAAAAAAXABAAAACcAakEbgdxB8cHvgi/CC0JLgkvCTAJMQk0CSEQIhAjECQQJRCbEqQSBhMHEwgTCRM7MAAAAQAAIAAOANkBAADbAQAAQQQAAEYEAABaBAAAYAQAAPgGCAAyDAMARQ8AAFcQAAC+EAQAExEEAOQSAABOEwAAOzAAAAEAACMACQBDBAAAdQQFAKYFAADQBwAARg8AAKsPEwBTEgEAYBMBAGMTAQA7MAAAAQAACAAEADoQAAA1EQMARRECAHsTAAA7MAAAAQAADAAGAEAEAABPDwEAKxADAA0RAwBaEwAAsRMAAAQeEgAAHxIAACASAAAhEgAAOzAAAAEAAAYAAwAfDAMA1xABAAUUAAAEXAQAAMEPAADEEAAA3BMAAAAAAcUGAAABwgEAAAAAOjAAAAEAAAAAABwAEAAAAKwArQCuAK8Apga0BgEHAgcDB/oIOwk8CT0JPglBCUIJkA+pD6oPzA/ND84PXRBeEF8QRBEMEoATIxQ=\",1]Bg[\"AAAAAAAAAAAAAAAAAAKiEAAAoxAAAA==\",\"\"]Jo[\"AAAAAc8EAAAAOjAAAAEAAAAAAAcAEAAAABkAlQDZAUYERQ9QEVMRCxMCrA8AAFMSAAACQAMAALYGAAAC4AAAAOEAAAAAAbEHAAAAAAFvBwAA\",\"AAF6BwAAAANhAAAAYgAAAM8EAAACWQIAAMcHAAACUBEAAFMRAAAAAagGAAA=\"]A@c[\"AAAAAfgEAAAABzIAAACdAAAA2wEAAFIRAABUEQAA5BIAAAwTAAAHIgEAACMBAABGDwAAtA8AAMAPAABPEAAAVBIAAARIAwAAuwYAAB4MAAB7EwAAARUSAAABMQ4AAAKzBwAABRQAAAHcEwAAAAFyBwAA\",\"AAGPBwAAAAH4BAAAAr8CAABWBQAAAlIRAABUEQAAAa0GAAAAAAEbDAAAAAFpEgAAAAAAAAAABWYAAABnAAAAaAAAAGkAAABqAAAA\"]Bo[\"\",\"AAAAAAAAOzAAAAEAAKkAAwCyACgAGQFwAIwBDwA=\"]CCm[\"\",\"AAA7MAAAAQAA5gABAMMK5gA7MAAAAQAA7QAMAMoJMwAACgAAAgozADcKAAA5ChYAUwofAHQKBQB7CikApwoCAKwKFgBSEgAA5hMBADowAAABAAAAAAASABAAAABdBaUFlgYTCRQJ/gn/CQEKNgo4ClAKUQpSCnMKegqlCqsK/xIAEzowAAABAAAAAAASABAAAABIBEUF9gYEBzkJOgmmCqoKSxFZEloSWxJcEl0SXhIKE5sToBOhEzowAAABAAAAAAApABAAAADCBsMG0Ae1C7YLtwu4C+sL7AvtC+4LCAxSD3wPwA9PEGMQaRBqEGsQbBDIEHgSeRI9Ez4TPxNAE0ETQhNgE2ETYxNkE9MT1xP8EwMUHxQgFCEUIhQ6MAAAAQAAAAAAGgAQAAAAXQRyBHMEdARbBVwFpwaoBqkGqgarBh4M3A88ED4QQBBCEEMQZBASEUURRhFHEVMTexPUEwQUOzAAAAEAAFkADwDbAD0AigEBAEAEAABeBAAAZQQAAFMFAQBsBwAATw8BAMIPAAAVEgAATBIFAFoTAACxEwYAxRMAAP0TAAA7MAAAAQAAEQAIAHMFAQAbDAAAfQwAADEOAAAmEAAAPREDAEkTAQDyEwUAOjAAAAEAAAAAAAgAEAAAAGIEYwRRD20QbhDXENgQehIFFDowAAABAAAAAAALABAAAABcBF4FEgcTB8EPzRDPENEQ0xDVEGkS3BMEQgQAAEQEAACeEwAAnxMAAANtBwAAbwcAAHIHAAACJAwAAEwPAAA7MAAAAQAABgADAMIBAACwBgAAkhMEAAHvEgAAAAGnBQAA\",1]Le[\"\",\"AAAAAswBAACUBgAAA/QGAAA8DwAAPQ8AAAPmBgAAbRIAAG8SAAA6MAAAAQAAAAAABwAQAAAATg8SEhsSHBIdElsTXBOREwJmBAAAtAsAAAGtAQAAAcITAAAESA8AAEkPAABKDwAAwxAAAAABJwwAAARhBAAAJQwAAEsPAABNDwAAASMMAAAAAAEmDAAA\",1]Gc[\"\",\"AAAAOjAAAAEAAAAAAAcAEAAAAN0B3gETEmwS2BPkEwIUERQC8wYAACoQAAAFkwYAAA8JAAAQCQAAfw8AABESAAABHhMAAAEKEQAAAUMTAAA=\"]Bo[\"\",\"AAAAAgETAAACEwAAAATvCwAA8AsAAPELAADyCwAA\"]Bk[\"\",\"AAAAAAAAOzAAAAEAAAYAAgCsBgMAsQYCAA==\"]Fc[\"AAAAAcQBAAAAAAAABG0FAABuBQAAhA8AAIUPAAA=\",\"AAA7MAAAAQAAPgABADcMPgAAAAAAAAAAAAAAAAAAAAAB4wYAAA==\"]Ao[\"\",\"AAA7MAAAAQAA5gABANcH5gA=\"]A@o[\"AAAEagIAAHsCAACBAgAAOA8AAAHNBAAAA+oSAAAUFAAAGBQAAAMWAAAAlAAAAE8RAAABqw8AADowAAABAAAAAAAMABAAAAA/A3IEcwRDBUQFWwW1BkIRVBN+E6gT4hPwEwLbAAAA3AAAAA==\",\"AAF5BwAAOzAAAAEAAAYAAwBRAgQAEQkAANkSAAABzQQAAAQTCQAA/gkAAP8JAAABCgAAAU8RAAAB6wsAAAOnBgAARREAAEYRAAAAAAAAAAAAAAAAATAPAAA=\"]AAk[\"AAAE3QIAAAEDAAAJAwAAOQ8AAAH1BAAAAAQuAAAAmwAAAFERAADrEgAABBsBAAAcAQAAsg8AAOUTAAA6MAAAAQAAAAAACgAQAAAARgN0BEYFXAW6BkMRVRN/E6kT4xPxEwABMQ4AAA==\",\"AAGOBwAAOzAAAAEAAAYAAwC2AgQAEgkAANoSAAAB9QQAAAQUCQAAUAoAAFEKAABSCgAAAu8LAABREQAAAqwGAADQBwAAAUcRAAAAAAAAAAAAAAAABDIPAAAzDwAANA8AADUPAAA=\"]Gc[\"AAA7MAAAAQAACwAEABwQBAADEwAAqhMEABUUAAA=\",\"ADswAAABAAAJAAMAUgcBAFUHAgDSEgQAOzAAAAEAAAsABAAcEAQAAxMAAKoTBAAVFAAA\"]Ic[\"AAAAAAAAAAA7MAAAAQAACQABAKoLCQA7MAAAAQAADQABAEwEDQA7MAAAAQAACQAEAB8MAwBIDwIAwxAAANcQAQAAAScMAAADJQwAAEsPAABNDwAAAyMMAAAkDAAATA8AAAAAASYMAAA=\",\"\"]Cc[\"AAAAArABAADLEAAAAAAAAAErDAAAAAFrBAAAARIHAAA=\",\"\"]Cc[\"AAAAAr8BAADMEAAAAAAAAAEsDAAAAAFsBAAAARMHAAA=\",\"\"]ABg[\"AAAAAvASAADxEgAAAAW3AQAAuAEAAMoBAADLAQAAEREAADswAAABAAALAAMArAQHAFoFAAATDAIAOjAAAAEAAAAAAAcAEAAAAEYFwgfDB8QHxQdTD1QPqA8HDREAAA4RAAAPEQAAEBEAAHMTAADFEwAA/RMAADswAAABAAANAAQAGwwAADEOAACkDwMAERMHADswAAABAAAHAAEA0wYHAAPEEAAAaRIAANwTAAAAAW0HAAABxQYAAAAAAAGnBQAA\",\"AAAAA9MBAADUAQAA1QEAAAABVxAAAA==\"]Ek[\"AAAAAAAAAAAAAAAAAAAAAAACUQUAAOkGAAA=\",\"AAAAAAAAAAI1EQAANhEAAAAAAAAAAAAAAAACxgYAANwGAAA=\"]Ek[\"AAAAAAAAAAAAAAAAAAAAAAACUgUAAOsGAAA=\",\"AAAAAAAAAAI3EQAAOBEAAAAAAAAAAAAAAAACxwYAAN0GAAA=\"]Ak[\"\",\"AAAAAAKiDwAAow8AAA==\"]Eo[\"AAAABO8EAAAXBwAAugcAACARAAACJQkAAPgLAAABtRAAAAAAAQ8BAAABFBMAAAHWBgAA\",\"AAAAAe8EAAAAAbgBAAA=\"]Eo[\"AAAABDkFAAAbBwAAvgcAACcRAAACKQkAAPwLAAABuRAAAAGSAQAAAAABGBMAAAHaBgAA\",\"AAAAATkFAAAAAcsBAAA=\"]Bg[\"AAAAAAAAAAAAAVEEAAA=\",\"AAAAATgJAAA=\"]Ag[\"AAACrwEAAL4BAAA=\",\"\"]Ao[\"AAAAAAAAAAAAAAAAAAElDAAA\",\"\"]Ag[\"\",\"AAACRBAAAEUQAAA=\"]Bg[\"AAAAAAAAAAAAARQSAAA=\",\"AAABbwAAAA==\"]Dg[\"AAAAAtMBAADUAQAAAAADYAUAABMMAAAbEgAAAAGtAQAAAcITAAA=\",\"AAAAAQcSAAA=\"]Hg[\"AAAAASoRAAABBhMAAAM7EAAAvxAAABQRAAABYBMAAAE1EQAAASsQAAACPREAAB4SAAABLxEAAAAAAAABkxMAAA==\",\"AAAAAAAAAALOEAAA0BAAAAAAAALNEAAAzxAAAA==\"]Ig[\"AAAAAS0RAAABCBMAAAM/EAAAwRAAABYRAAABYxMAAAE3EQAAAS0QAAACPxEAACASAAABMREAAAAAAAABlRMAAA==\",\"AAAAAAELEQAAAAAD0hAAANQQAADWEAAAAAAAA9EQAADTEAAA1RAAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAm4AAAA1DwAA\",\"\"]Bk[\"AAAAAAAAAdoAAAAAAAFZBAAA\",\"AAAAAc8HAAA=\"]Cc[\"AAAAAWAQAAABGhMAAAACQwQAAKYFAAA=\",\"AAAAAAHUBwAA\"]Ek[\"AAAAAdQEAAAAAR0AAAAAAAHmAAAAAAAAAAAAAAAAArcEAACPBgAA\",\"AAF/BwAAAAHUBAAAAAAAAAAAAW0QAAA=\"]Ek[\"AAAAAQUFAAAAAT0AAAABNAEAAAAAAAAAAAAAAAAAAroEAACQBgAA\",\"AAGWBwAAAAEFBQAAAAAAAAAAAW4QAAA=\"]Be[\"AAAAAAA7MAAAAQAAhgABAIARhgA=\",\"\",1]Bg[\"AAAAAAAAAAAAAVQEAAA=\",\"AAAAAeoLAAA=\"]Ec[\"AAAAAAAAAAAAAAAAAAJvBwAAcgcAAAHFBgAAAsIBAACwBgAA\",\"AAAAAAAAAAAAAAAAAAAAAcIBAAA=\"]Dk[\"AAAAAAAAAAABtBMAAAH0EwAA\",\"AAAAAAABWxIAAAE/EwAAAAAAAAAAAAAAAAABVAcAAA==\"]Dg[\"AAAAAR0FAAAAAAJfAQAAYAEAAAG+BgAAAAAAAAAAAAAAAAELAgAA\",\"AAAAAR0FAAA=\"]ABc[\"AAAAA6oBAAAQCgAAVREAAAPEBgAAcwoAALEQAAAAADowAAABAAAAAAANABAAAAAgCSEJKwksCY4Pjw9hEGIQ3RLeEgQTBRNYE1kTOzAAAAEAAA8ABwCsEAEATBIFAA0TAQBaEwAAsRMAAA0UAQAbFAEAAAEFFAAAAdwTAAA=\",\"AAAAA50BAACoAQAAJxAAAAQhEAAAIhAAACMQAAAkEAAAAtkBAADbAQAAAAACWhMAALETAAAAAQUUAAAB3BMAAAAAAAAAAATaAQAA3AEAAP4IAABYEQAA\"]Bk[\"AAAAAAHzBgAA\",\"AAAAAAAAAAEKEQAAAAEUEgAA\"]Ho[\"AAAABcIEAABpBQAApAUAAHwMAABmEgAAAj0PAADbEwAAAuYGAAChEgAAA70AAAASEgAAchMAAAFEBQAAAWwHAAABJhAAAA==\",\"AAAAAsIEAACUBgAAAfQGAAAAAAABrQEAAAHCEwAA\"]Gc[\"AAAAAmcSAAB0EwAAAZsGAAAByQYAAAEaAQAAAjoQAACiEgAAAAHoBgAAAAFeBQAAAAFtBwAAAcUGAAAAAAABpwUAAA==\",\"AAAAAAAAAAG7AQAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAW0AAAA=\",\"\"]Fg[\"AAADyAYAAOcGAACcDwAABA8MAABTEAAAShEAAMMTAAAFDQIAAF0FAAClBQAAbgcAAC8JAAAAAsMAAAB8DwAA\",\"AAABqhAAAA==\"]Fg[\"AAAABBAMAABUEAAATBEAAMQTAAACcQcAADAJAAAByQYAAAFiAQAAAAAB6AYAAAABXgUAAAAAAAAAAAGnBQAA\",\"AAABqxAAAA==\"]Dg[\"AAAAASIFAAAAAVEAAAABawEAAA==\",\"AAAAASIFAAAAAAAAAAAAAAAAAAAAAAFwAAAA\"]Bk[\"AAAAAAEMAgAAAAAAAAFOBAAA\",\"AAAAARkMAAA=\"]Cc[\"AAAAAAHHBwAAAAAAAAFPBAAA\",\"AAAAAAACGgwAAGgSAAA=\"]Dk[\"\",\"AAAAADswAAABAAATAAEAWAcTADswAAABAAATAAEAlAATADswAAABAAATAAEAqw8TAA==\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWsAAAA=\",\"\"]Fg[\"AAAAATwFAAAAAAGZAQAAAAAAAAAAAWEEAAAAAAABJgwAAAauAAAApQEAAAUCAAC0BgAACAcAAAwSAAA=\",\"AAGlBwAAAAE8BQAA\"]Hk[\"AAAEqAAAAFECAABNBQAABgwAAAHqBAAAAAIrAAAAmgAAAAGxDwAAAkUDAAC5BgAAAggBAAAJAQAA\",\"AAABgQIAAARjAAAAZAAAAGUAAADqBAAAAbUBAAAAAe4LAAABqwYAAA==\"]Kc[\"AAAEqQAAALkCAABOBQAABwwAAAEsBQAAAARZAAAApwAAAMQPAADJDwAAA30BAAB+AQAAvg8AAAJSAwAAwAYAAA==\",\"AAABCQMAAAEsBQAAAccBAAAB8gsAAANDBAAApgUAALIGAAAAAAAAAAAAAAAAAARrAAAAbAAAAG0AAABuAAAA\"]Ak[\"AAAAAALaDwAA2w8AAA==\",\"\"]Ao[\"AAAAAAAAAAACpgEAAEwSAAA=\",\"\"]Ao[\"AAAAAAAAAAACpwEAAE8SAAA=\",\"\"]Dc[\"AAAAAAAAAAABCgEAAAAAAAAAAAAAAAWsAAAAbgQAAAEHAACGDwAAXRAAAA==\",\"\"]Fc[\"AAAAAAAAAX8BAAAAAAAAAAAAAAAAAAWtAAAAbwQAAAIHAACHDwAAXhAAAA==\",\"AAAAAAAAAAAAAegGAAAAAl4FAADEEAAA\"]Fc[\"AAAAAT0FAAAAAAGaAQAAAmYEAAC0CwAAAAAAAAEnDAAAAAAAAAAFrwAAAAMHAAD7CAAAiA8AAF8QAAA=\",\"AAAAAT0FAAA=\"]Hg[\"AAABjQAAAAHQBAAAAAIaAAAAuwwAAAAAAeIAAAAAAAAAAAAAAAADoAEAALYEAAD+CwAA\",\"AAF7BwAAAAHQBAAAAAAAAAAAAAAAAAAAAAAECQcAAAoHAAANBwAADgcAAA==\"]Hg[\"AAAAApAAAAD/BAAAAAI4AAAAvgwAAAEsAQAAAAAAAAAAAAAAAAADoQEAALkEAAAADAAA\",\"AAGSBwAAAAH/BAAAAAAAAAAAAAAAAAAAAAAECwcAAAwHAAAPBwAAEAcAAA==\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAAHvEgAA\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWwAAAA=\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmcAAADlBgAA\",\"\"]Bg[\"AAAAAAAAAAAAAVMEAAA=\",\"AAAAAboMAAA=\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAasAAAA=\",\"\"]Dk[\"AAAAAewEAAABtgEAAAABrQQAAAEdEQAAAQwBAAA=\",\"AAGIBwAAAAHsBAAAAAAAAR0RAAA=\"]Dk[\"AAAAATYFAAAByQEAAAACjwEAALEEAAABJBEAAA==\",\"AAGhBwAAAAE2BQAAAAAAASQRAAA=\"]Hc[\"AAAAAAABfw8AAAGREwAAAAG1EwAAAfUTAAAAAAAAAAAAADowAAABAAAAAAANABAAAADQBvoIPQk2Do0PkA/MD54QrhBEEW4ScBJLE4AT\",\"AAAAAAABXBIAAAFAEwAA\"]Ak[\"AAAAAAKXEwAAmBMAAA==\",\"\"]Cg[\"AAAAAaASAAABNAkAAAFgBAAAAAABZQQAAA==\",\"AAAAAAH/CwAA\"]Ag[\"\",\"AAAAAAAAAbMGAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmgAAABHDwAA\",\"\"]Ag[\"AAAAAAAAAAHBBgAA\",\"\"]Dk[\"AAAAAAAAOzAAAAEAAKkAAwCyACgAGQFwAIwBDwAAOzAAAAEAAD8AAgDbAD0AigEBAA==\",\"\"]Hg[\"AAAAAi0FAADqBgAAATEJAAAEWgAAAAsTAAAMEwAAdRMAAAOAAQAAgQEAAPgTAAABUwMAAAABGwwAAAABaRIAAAAAAcUGAAA=\",\"AAABiQ8AAAEtBQAAAcgBAAAAAU8QAAA=\"]Dk[\"AAAAAeAEAAAAASIAAAAAAbcGAAAC9gAAAPcAAAA=\",\"AAAAAuAEAAAYCgAAAAAAAakGAAA=\"]Dk[\"AAAAARcFAAAAAUgAAAACUQEAAFIBAAABvAYAAA==\",\"AAAAARcFAAABegoAAAABrgYAAA==\"]Ck[\"AAAAAcUPAAAAAAAAAnAHAACyBwAA\",\"AAAAAAAAAAACKxAAACwQAAA=\"]Ck[\"AAAAAcYPAAAAAAAAAnMHAAC0BwAA\",\"AAAAAAAAAAACLRAAAC4QAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAqcQAAAaEgAA\"]Ek[\"AAAAA9UHAAAKEgAAcBMAAAAAAAAAAAGxBwAAAAABbwcAAA==\",\"AAAAAAAAAAI1EQAANhEAAAIrEAAALBAAAA==\"]Ek[\"AAAAA9YHAAALEgAAcRMAAAAAAAAAAAGzBwAAAAABcgcAAA==\",\"AAAAAAAAAAI3EQAAOBEAAAItEAAALhAAAA==\"]Dg[\"AAAAAQsFAAAAAUQAAAACPwEAAEABAAA=\",\"AAAAAQsFAAAAAAAAAAEbDAAAAAFpEgAA\"]Cc[\"AAAB2AIAAAH7BAAAAAE0AAAAASYBAAA=\",\"AAAAAfsEAAA=\"]Ic[\"AAABjwAAAAHSBAAAAAIcAAAAvQwAAAAAAeQAAAAAAAAAAAAAAAA6MAAAAQAAAAAADAAQAAAA2gEJAgkHDQcCCQYJPg+BD0YQlxIPEx8TOxM=\",\"AAF9BwAAAALSBAAAagUAAAABRQ8AAA==\"]Ho[\"AAAAApIAAAABBQAAAAI6AAAAwAwAAAEuAQAAAAAAAAAAAAAAAAA6MAAAAQAAAAAADAAQAAAA3AEKAgsHDwcECQgJQA+DD0gQmBIQEyATPBM=\",\"AAGUBwAAAAEBBQAAAAABRg8AAA==\"]Gg[\"AAACOgIAAEECAAAByAQAAAACEQAAAPoGAAACzQAAAM4AAAA=\",\"AAACPAIAAD0CAAAByAQAAAAAAAACTw8AAFAPAAAAAAJcBAAAwQ8AAAAAASQMAAA=\"]Do[\"AAAAAQMFAAAAAjsAAACeAAAAAzABAAAxAQAAtQ8AAAFJAwAA\",\"AAAAAQMFAAAAAAAAAUAEAAA=\"]Ck[\"AAAAAngTAAB5EwAAAAAAAAAAAAABJwwAAA==\",\"AAAAAAABpBAAAA==\"]Co[\"AAAAAAAB5gYAAAMbEgAAHBIAAB0SAAAAAa0BAAA=\",\"AAAAAAABfw8AAA==\"]K@i[\"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\",1]Eo[\"AAAAAAA7MAAAAQAABQABAFkSBQA7MAAAAQAABQABAD0TBQAAOzAAAAEAAAUAAQCyEwUAOzAAAAEAAAUAAQDyEwUA\",\"\"]Ck[\"AAAAAAAAAVoFAAAAAAFMBAAA\",\"AAAAAAAAAxMMAAAUDAAAFQwAAA==\"]Cc[\"\",\"AAAAAAAESAQAAAQHAABLEQAAmxMAAAAAAloTAACxEwAA\"]Fc[\"AAAAAf4EAAAAATcAAAACKgEAACsBAAA=\",\"AAGRBwAAAAH+BAAAAAACwA8AAE8QAAACHgwAAHsTAAAAAAEFFAAAAdwTAAA=\"]Eo[\"AAAAAUgRAAABLQkAAAACuAAAAAgMAAABEhEAAAABUAQAAA==\",\"AAAAAAGlBQAAAAIIDAAAfA8AAAABbAcAAAEmEAAA\"]Dk[\"AAAABhMSAABsEgAA2BMAAOQTAAACFAAAERQAAAAAAAABQxMAAA==\",\"AAAAAAAAAAEKEQAA\"]A@g[\"AAAAOjAAAAEAAAAAABIAEAAAAGkEvwRoBZcGxgc4CeoLGQw2DLoMvw/WD8cQSRFXEkYTehOaE98TOjAAAAEAAAAAAAcAEAAAAC4JJRAWEpsS5RLqEhQUGBQ6MAAAAQAAAAAABwAQAAAA2QFGBBoMRQ++EBMRaBIKEzowAAABAAAAAAAHABAAAAC5AMgQUxLTE/wTAxQfFCEUAUMFAAAAAAAAAAAAAZITAAA=\",\"AAAAAb8EAAABvggAAAABCAwAAA==\"]ACk[\"AAAAOjAAAAEAAAAAAAgAEAAAAGoEHgkMDDoPgg+bECwRrxOwEzowAAABAAAAAAAHABAAAABKBFYFawXUB/8LCxFYEpkTOjAAAAEAAAAAAAoAEAAAANsBWgTED8kPORBXEBERFxLkEusSThM6MAAAAQAAAAAABwAQAAAAGQFGD8APTxBUEuUTIBQiFAVGBQAAHgwAAHsTAADUEwAABBQAAAQVEgAAcxMAAMUTAAD9EwAAAhsMAAAxDgAAAQUUAAADxBAAAGkSAADcEwAA\",\"AAAAAAAAAAAAAAAAAAFtBwAAAAAAAAGnBQAA\"]Ho[\"AAAAAxQHAAC3BwAAGxEAAAMiCQAA9QsAAP4TAAABshAAAAABwgcAAAACpA8AABETAAAB0wYAAA==\",\"AAAAAAT1CwAA9gsAAPcLAAD4CwAAAAWsBAAArQQAAK4EAACvBAAAUxIAAA==\"]Ho[\"AAAAAxgHAAC7BwAAIhEAAAMmCQAA+QsAAAAUAAABthAAAAABxAcAAAACpg8AABUTAAAB1wYAAA==\",\"AAAAAAT5CwAA+gsAAPsLAAD8CwAAAAWwBAAAsQQAALIEAACzBAAAVBIAAA==\"]No[\"AAABjgAAAAHRBAAAAAIbAAAAvAwAAAAAAeMAAAAAAAAAAAAAAAA6MAAAAQAAAAAAJAAQAAAAAgJJBKAGBgf8CDIJFgwcDCgMfQ+fDygQVRBaEGUQnBCoEK8QuhC8EBgRORFNEQ0SDxJVEmISnBKeEuESIRMjE1YTXRN8E5wT2RM=\",\"AAF8BwAAAAHRBAAAAAAAAAAAAAAAAAAAAAAEAgkAAAMJAAAGCQAABwkAAA==\"]No[\"AAAAApEAAAAABQAAAAI5AAAAvwwAAAEtAQAAAAAAAAAAAAAAAAA6MAAAAQAAAAAAJAAQAAAAAwJLBKQGBwf9CDMJFwwdDCkMfg+gDykQVhBbEGYQnRCpELAQuxC9EBkROhFOEQ4SEBJWEmMSnRKfEuISIhMkE1cTXhN9E50T2hM=\",\"AAGTBwAAAAEABQAAAAAAAAAAAAAAAAAAAAAEBAkAAAUJAAAICQAACQkAAA==\"]Cc[\"AAAAAecEAAAAAAAAAQMBAAA=\",\"AAAAAecEAAAAAAG1CwAA\"]Ck[\"AAAAASgFAAAAAAF3AQAA\",\"AAAAASgFAAAAAAO2CwAAtwsAALgLAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAFhBAAAAAAAASYMAAA=\",\"\"]Bg[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAATYPAAA=\"]Eo[\"AAAAARgFAAAAAUoAAAACVQEAAFYBAAABvQYAAA==\",\"AAAAARgFAAAAAAGvBgAAAAAAAAAAAAAAAAACTAUAADcPAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAg8UAAAQFAAA\"]Ck[\"AAAAAAAAAAABxRMAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAABJhQAAA==\"]Ag[\"AAAClwIAABoDAAA=\",\"\"]Bo[\"AAAAAAAAAcEAAAAAAAABIQwAAA==\",\"AAAAAb8PAAA=\"]Cc[\"AAAAAAACGgwAAGgSAAABUg8AAA==\",\"AAAAAAABBAcAAA==\"]Gc[\"AAAAAfoEAAAAATMAAAABJQEAAAABFRIAAAEbDAAAAAFpEgAA\",\"AAGQBwAAAAH6BAAAAAHkEgAAAcAPAAAAARUSAAAAAAAAAAAAAAABBQcAAA==\"]Do[\"AAAAAAAAAAFTDwAAAm0FAACEDwAA\",\"AAAAAa4BAAAAAAABUw8AAARtBQAAhA8AAA0RAAAOEQAA\"]Do[\"AAAAAAAAAAFUDwAAAm4FAACFDwAA\",\"AAAAAboBAAAAAAABVA8AAARuBQAAhQ8AAA8RAAAQEQAA\"]Ao[\"AAAAAAEqEAAAAAABUBAAAA==\",\"\"]Fk[\"AAABKREAAAJjAAAAtQcAAAEQAgAAAAHJAAAAAnIEAABFEQAAAk8PAADCDwAAAAFRDwAAAlwEAADBDwAAAAElDAAAAiMMAAAkDAAA\",\"\"]Cc[\"AAAAAAAAAANdBAAAdAQAAEcRAAA=\",\"AAAAAAABxA8AAA==\"]Ec[\"AAABPAIAAAHJBAAAAAISAAAA+wYAAALPAAAA0AAAAA==\",\"AAABPgIAAAHJBAAAAAAAAkURAABGEQAA\"]Bo[\"AAABqhAAAAAAAALEAAAAxQAAAA==\",\"AAAAAAFdBQAA\"]Ck[\"AAABqxAAAAAAAAJmAQAAZwEAAA==\",\"AAAAAAAAAAAAAAABXgUAAA==\"]Ao[\"AAAAAAAAAR4TAAABQg8AAA==\",\"\"]Hg[\"AAAAAmUAAADPBwAAARECAAABOQkAAAPVAAAAwgYAAGMQAAACWwUAANwPAAAAAnMFAAB9DAAABkgPAABJDwAASg8AAG0QAADDEAAAehIAAAAAAksPAABNDwAAAUwPAAA=\",\"\"]Dk[\"AAAAAAABOgkAAALDBgAA0AcAAAJcBQAAZBAAAAABdAUAAAFuEAAA\",\"AAAAAAAByQ8AAA==\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAAHvEgAA\",\"\"]ABc[\"AAABiQ8AAAGUBgAAAsgBAAD0BgAABJMGAAAaDAAAfw8AAGgSAAAC0xMAAAMUAAADChEAANQTAAAEFAAABWwHAAANEQAADhEAAA8RAAAQEQAAASYQAAAAAAABbQcAAA==\",\"AAAABeoGAABIEQAASREAAEoRAABMEQAAA5wBAAA8DwAAPQ8AAAFLEQAABfwTAAAfFAAAIBQAACEUAAAiFAAAAXsTAAAB/RMAAAEUEgAAAAAAAAAAAAJYDwAAcg8AAAUEAgAABQIAAIYPAACHDwAAiA8AAA==\"]Cc[\"AAAAARkFAAAAAUsAAAACVwEAAFgBAAA=\",\"AAAAARkFAAA=\"]Dc[\"AAAAAAAAAAA7MAAAAQAABQABAEwSBQA=\",\"AAAABNIBAADWAQAA1wEAANgBAAA=\"]Ao[\"AAAAAdIBAAAAAAAAAc8PAAA=\",\"\"]Ao[\"AAAAAdcBAAAAAAAAAdAPAAA=\",\"\"]Eo[\"AAAAASsRAAABBxMAAAM9EAAAwBAAABURAAABYRMAAAE2EQAAASwQAAACPhEAAB8SAAABMBEAAAAAAAABlBMAAA==\",\"\"]Eo[\"AAAAAS4RAAABCRMAAANBEAAAwhAAABcRAAABZBMAAAE4EQAAAS4QAAACQBEAACESAAABMhEAAAAAAAABlhMAAA==\",\"\"]Bc[\"AAAAAAAAAnUEAADKBgAAAAHRDwAA\",\"\"]Bc[\"AAAAAAAAAngEAADNBgAAAAHSDwAA\",\"\"]Ec[\"AAAAAcwBAAAAAm0SAABvEgAAAlsTAABcEwAAAmYEAAC0CwAAAAAAAAABYQQAAA==\",\"AAAAAAEwAwAA\"]Gg[\"AAAAAcsEAAAAAhQAAAD9BgAAAtYAAADXAAAA\",\"AAADRgIAAEcCAABIAgAAAcsEAAAAAAAB3A8AAAACcwUAAH0MAAACbRAAAHoSAAAAAAABTA8AAA==\"]Eg[\"AAAAAQYFAAAAAj4AAACgAAAAAzUBAAA2AQAAtw8AAAFLAwAA\",\"AAAAAQYFAAAAAAAAAAF0BQAAAW4QAAA=\"]Ec[\"AAAAAAAAAWUBAAAAAAAAAAAAAAAAAAK7BAAAPgkAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAacFAAA=\"]Ec[\"AAAB8wsAAAG+BAAAAAELAAAAAbQAAAA=\",\"AAAAAb4EAAAAARAJAAAAAAAAAAAAAAAAAAABkQYAAA==\"]Dg[\"AAAAAAFYBQAAAAAAAAAAAAAAAAAAAAJoEAAADBEAAA==\",\"AAF2BwAAAAAAAZMGAAA=\"]Ac[\"AAABZAIAAA==\",\"\"]Do[\"AAAAAd8EAAAAASEAAAAAAAL0AAAA9QAAAA==\",\"AAACbwIAAHECAAAB3wQAAAAAAAAAAUkTAAA=\"]Dk[\"AAAAARYFAAAAAUcAAAACTwEAAFABAAA=\",\"AAAC4wIAAOQCAAABFgUAAAAAAAAAAUoTAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAhUJAAAXCQAA\"]Dk[\"AAAAAAAAAAABEwEAAA==\",\"AAABjQIAAAAAAAAAAAABYgQAAAESBwAAAUIEAAABbwcAAA==\"]Dg[\"AAAAAAAAAYgBAAA=\",\"AAABEwMAAAAAAAAAAAABYwQAAAETBwAAAUQEAAABcgcAAA==\"]Dk[\"AAAAAe4EAAAAAbcBAAABrgQAAAEfEQAAAQ4BAAA=\",\"AAGJBwAAAAHuBAAAAAAAAR8RAAA=\"]Dk[\"AAAAATgFAAAAAcoBAAACkQEAALIEAAABJhEAAA==\",\"AAGiBwAAAAE4BQAAAAAAASYRAAA=\"]Ck[\"AAAAAQcFAAAAAT8AAAACNwEAADgBAAA=\",\"AAAAAQcFAAAAAAHDBgAA\"]Eg[\"AAAAAdoEAAAAAiAAAACWAAAAAa0PAAABQQMAAALvAAAAYBIAAA==\",\"AAGEBwAAAWoCAAAC2gQAABAKAAA=\"]Eg[\"AAAAAREFAAAAAkYAAAChAAAAAkoBAAC4DwAAAUwDAAABYRIAAA==\",\"AAGcBwAAAd0CAAABEQUAAAFzCgAA\"]Ao[\"AAAAAAAAAAACWBAAAA0RAAA=\",\"\"]Ao[\"AAAAAAAAAAACWRAAAA8RAAA=\",\"\"]Do[\"AAABbwAAAAG9BAAAAAABswAAAA==\",\"AAAAAb0EAAAAAQ8JAAAAAAAAAAAAAAAAAAABXBAAAA==\"]Bg[\"AAAAAAAABNQAAABiBQAAFQwAAB0SAAA=\",\"\"]Ak[\"AAAAAAABQAAAAAE5AQAA\",\"\"]Do[\"AAAAAAAAAAAAAAAAAAAAAAAAAqcQAAAaEgAA\",\"AAF0BwAAAAAAAAAAAAAAAAAAAAAAAAFnEAAA\"]Cg[\"AAAAAAPEBgAANwkAALEQAAA=\",\"AAAAAAAAAAJCDwAAUBAAAA==\"]Ag[\"AAACjQIAABMDAAA=\",\"\"]Cc[\"AAAAATUKAAACNgoAAKUKAAABpgoAAAJpEAAAaxAAAA==\",\"\"]Ac[\"\",\"AAAAAVISAAA=\"]Gg[\"AAAAAd4EAAAB2xMAAAAAAcAIAAAE8wAAANEPAABzEgAAwBMAAAEmEAAA\",\"AAAAA7IBAADeBAAA5hMAAAABoBMAAAABwAgAAAPRDwAAcxIAAMATAAA=\"]Bc[\"AAAAAbIBAAAAAAAAAAAAAc0QAAA=\",\"\"]Gg[\"AAAAARUFAAAAAAFOAQAAAcEIAAAD0g8AAHUSAADBEwAAAAAAAAFtBwAA\",\"AAAAA8EBAAAVBQAA5xMAAAABoRMAAAABwQgAAAPSDwAAdRIAAMETAAA=\"]Bc[\"AAAAAcEBAAAAAAAAAAAAAdEQAAA=\",\"\"]Fg[\"AAABRgIAAAHVBAAAAAEeAAAAAAAC5wAAAOgAAAA=\",\"AAGABwAAAAHVBAAAAAE5CQAAAsIGAABjEAAAA3IEAABzBAAAWwUAAA==\"]Eo[\"AAAAAQkFAAAAAUIAAAACOwEAADwBAAA=\",\"AAGYBwAAAAEJBQAAAAE6CQAAAdAHAAAEdAQAAFwFAABkEAAARxEAAA==\"]Ao[\"\",\"AAAAAAAAAAAAAAAB1RAAAA==\"]Ek[\"AAAAAeMEAAAAASUAAAAAAAL8AAAA/QAAAA==\",\"AAABdgIAAAHjBAAAAAAAAAFsBwAAASYQAAAAAs0QAADPEAAA\"]Eg[\"AAAAAR8FAAAAAVAAAAACYwEAAGQBAAA=\",\"AAAB8QIAAAEfBQAAAAAAAAAAAALREAAA0xAAAAABbQcAAA==\"]Ao[\"AAAAAAAAAAFDEAAAAAExDAAA\",\"\"]Jk[\"AAAAAeQEAAAABSYAAACXAAAASAUAADsQAAA9EAAAArULAACuDwAABEIDAAABDAAAPBAAAD4QAAAE/gAAAP8AAAANEQAADhEAAAItDAAALgwAAAIvEQAAMBEAAA==\",\"AAAAAuQEAABTEAAAArMBAAA0EAAAAAABCgkAAA==\"]Og[\"AAAAASQFAAAABVMAAACkAAAASQUAAD8QAABBEAAABnABAABxAQAAtgsAALcLAAC4CwAAuw8AAARPAwAAAgwAAEAQAABCEAAAAg8RAAAQEQAAAi8MAAAwDAAAAjERAAAyEQAA\",\"AAAABCQFAACpBwAAqgcAAFQQAAAEwwEAADUQAAA2EAAANxAAAAAAAQsJAAACUwUAAFQFAAAAAAAAAAAAAAA7MAAAAQAACgACAKsHBQDKBwQA\"]Cc[\"AAAAARoFAAAAAUwAAAACWQEAAFoBAAA=\",\"AAAAARoFAAA=\"]Ck[\"AAABTwUAAAHlBAAAAAEnAAAAAAABAAEAAA==\",\"AAAAAuUEAAADDAAA\"]Dg[\"AAABUAUAAAElBQAAAAFUAAAAAXIBAAAAAAAAAAAAAcUGAAA=\",\"AAAAAiUFAAAEDAAA\"]Cc[\"AAAAAT4FAAAAAWAAAAABmwEAAA==\",\"AAAAAj4FAAAFDAAA\"]Dg[\"AAAAAAAAAAAAAAABxBAAAA==\",\"AAAABjgQAABfEgAARxMAAEgTAAB4EwAAeRMAAA==\"]Ak[\"AAAAAAAAAAABThIAAA==\",\"\"]Ak[\"AAAAAAAAAAABURIAAA==\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmoAAAAEAgAA\",\"\"]Bg[\"AAAAAAAAAAAAAVUEAAA=\",\"AAAAAccQAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmkAAAAFBwAA\",\"\"]Bk[\"AAAAAAAAAAAAAATTBgAA1AYAANUGAADWBgAA\",\"\"]Ec[\"AAAABJ0BAACoAQAA+QQAACcQAAAAAAEkAQAAAAAABNcGAADYBgAA2QYAANoGAAA=\",\"AAAAAfkEAAA=\"]Bg[\"AAAAAAAAAAAAAVYEAAA=\",\"AAAAAAHlEgAA\"]Cc[\"AAAAAToKAAACOAoAAKsKAAABqgoAAAJqEAAAbBAAAA==\",\"\"]Ag[\"AAAAAAAB9gYAAA==\",\"\"]No[\"AAAAAdwEAAAB9AYAAAGhEgAAAXwPAAAGEQwAAEoQAABEEwAAWBMAALgTAADgEwAAB/EAAACtAQAAdgwAAM8PAAByEgAATxMAAFETAAABwhMAAAAAAAAAAAAAA6EGAAB6DAAAdhIAAA==\",\"AAAAAtwEAADYDwAAAAGxAQAAAXgSAAAGEQwAAEoQAABEEwAAWBMAALgTAADgEwAABXYMAADPDwAAchIAAE8TAABREwAA\"]Bo[\"AAAAAdgPAAAAAbEBAAAAAjwQAADOEAAAAAEtDAAA\",\"\"]Nc[\"AAAAARMFAAAAAAFMAQAAOjAAAAEAAAAAAAcAEAAAALsBEgxLEKISRRNZE7kT4RMFdwwAANAPAAB0EgAAUBMAAFITAAAAAAAAAAAAAAAEpwUAAKUGAAB7DAAAdxIAAA==\",\"AAAAAhMFAADZDwAAAAHAAQAAAXkSAAAGEgwAAEsQAABFEwAAWRMAALkTAADhEwAABXcMAADQDwAAdBIAAFATAABSEwAA\"]Bo[\"AAAAAdkPAAAAAcABAAAAAkAQAADSEAAAAAEvDAAA\",\"\"]Ao[\"AAAAAAAAAAACTxMAAFATAAA=\",\"\"]Ao[\"AAAAAAAAAAACURMAAFITAAA=\",\"\"]Dc[\"AAABRwIAAAHMBAAAAAIVAAAA/gYAAALYAAAA2QAAAA==\",\"AAABSgIAAAHMBAAA\"]Bk[\"AAAAAdUBAAAAAATTAAAAYQUAABQMAAAcEgAA\",\"\"]Ec[\"AAAAAgETAAACEwAAAv8SAAAAEwAABO8LAADwCwAA8QsAAPILAAAE6wsAAOwLAADtCwAA7gsAAA==\",\"\"]Cc[\"AAAAAAAAAAABTRIAAA==\",\"AAF3BwAAAAKsAQAA3xIAAA==\"]Cc[\"AAAAAAAAAAABUBIAAA==\",\"AAGMBwAAAAK5AQAA4BIAAA==\"]Bc[\"\",\"AAAAAAAAAAAAAAAAAAABxQYAAA==\"]Cg[\"AAAAATsPAAAAAAFvAQAAAToQAAA=\",\"AAGoBwAAAAAAAU4TAAA=\"]Ek[\"AAAAAcMEAAAAAAG+AAAAAAAAAAAAAAAAAAAE2xIAAOMSAAD+EgAAGRMAAA==\",\"AAF4BwAAAALDBAAAaQUAAA==\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAAzsJAADNDwAADxQAAA==\",\"\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAAzwJAADODwAAEBQAAA==\",\"\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAhYJAAAYCQAA\"]Bc[\"AAAAAAABQQQAAA==\",\"AAAAAAGpBAAA\"]Ec[\"AAAAAfAEAAAAAbgBAAABrwQAAAIhEQAAdhMAAAEQAQAA\",\"AAGKBwAAAAHwBAAAAAAAAiERAAB2EwAA\"]Ec[\"AAAAAToFAAAAAcsBAAACkwEAALMEAAACKBEAAHcTAAA=\",\"AAGjBwAAAAE6BQAAAAAAAigRAAB3EwAA\"]Ag[\"\",\"AAAAAAABERIAAA==\"]Co[\"AAAAAqIBAACpBwAAAAABaAEAAA==\",\"AAAAAAAAAAAAAAAAAAAAAcIBAAA=\"]Ac[\"\",\"AAAAAAGkEgAA\"]Cg[\"AAAAAAAAAngSAAB5EgAAAAABFBIAAA==\",\"AAAAAAAAAAFTEwAA\"]Do[\"AAAAAQQFAAAAAjwAAACfAAAAAzIBAAAzAQAAtg8AAAFKAwAA\",\"AAAAAQQFAAAAAAABXQQAAA==\"]Ak[\"AAAAAAACoBMAAKETAAA=\",\"\"]Ac[\"AAAAAdYBAAA=\",\"\"]Ac[\"AAAAAdgBAAA=\",\"\"]Eo[\"AAAC+gIAAA4DAAABLgUAAAABWwAAAAKCAQAAgwEAAA==\",\"AAAAAS4FAAAAAAAFpwYAAKgGAACpBgAAqgYAAKsGAAA=\"]Fk[\"AAAABEwQAABNEAAARxMAAEgTAAABPA8AAAGkEAAAARISAAAAAAHCEwAAAAAAAAAAAAEmDAAA\",\"AAAAAAAAAxsSAAAcEgAAHRIAAA==\"]Fc[\"AAAAAAABkwYAAAJ4EgAAeRIAAAEKEQAAAAEUEgAAAAACnhMAAJ8TAAAAAAAB7xIAAA==\",\"AAAAAAAAAdcTAAABUxMAAA==\"]Ag[\"\",\"AAAAAAABRQUAAA==\"]Co[\"AAAAAQwFAAAAAUUAAAACQQEAAEIBAAA=\",\"AAAAAQwFAAAAAAAAAAExDgAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAeQGAAA=\",\"\"]Jc[\"AAAAAtsEAAC+EwAAAAAAAggSAADdEgAABPAAAACtAQAAKwwAAOwSAAADPwkAAEkTAADCEwAAAAAAAaIQAAA=\",\"AAGFBwAAAAKwAQAA2wQAAAAAAAIIEgAA3RIAAAIrDAAA7BIAAAI/CQAASRMAAAAAAAGiEAAA\"]Jg[\"AAAAAhIFAAC/EwAAAAABSwEAAAO7AQAACRIAAN4SAAACLAwAAO0SAAACQAkAAEoTAAAAAAABoxAAAA==\",\"AAGdBwAAAAK/AQAAEgUAAAGbBgAAAAACCRIAAN4SAAACLAwAAO0SAAACQAkAAEoTAAAAAAABoxAAAA==\"]Ao[\"AAAAAAAAAcYAAAAAAAFYBAAA\",\"\"]Bc[\"AAAAAAABSQAAAAJTAQAAVAEAAA==\",\"\"]Ag[\"AAAClgIAABsDAAA=\",\"\"]Ak[\"AAAAAAAAAnYEAADLBgAA\",\"\"]Ak[\"AAAAAAAAAnkEAADOBgAA\",\"\"]Ag[\"AAAClQIAAB8DAAA=\",\"\"]Dk[\"AAAAAcoEAAAAAhMAAAD8BgAAAtEAAADSAAAA\",\"AAABQQIAAAHKBAAAAAAAAAAAAVEPAAA=\"]Dg[\"AAAAAccEAAAAAhAAAAD5BgAAAssAAADMAAAA\",\"AAABOgIAAAHHBAAAAAAAAAHCDwAA\"]Co[\"AAABGBIAAAEIBQAAAAFBAAAAAToBAAA=\",\"AAGXBwAAAQEJAAABCAUAAA==\"]Ec[\"AAAAAAABGRIAAAG1AAAAAAAAAAAAAAAAAAADbQQAAP4IAABVDwAA\",\"AAAAAaoBAAAAAAAAAUMTAAA=\"]Hk[\"AAAC0wIAAOsCAAABJgUAAAABVQAAAAJzAQAAdAEAAAAAAAAAAAAAAAAABAgCAABMBQAApgYAAOMGAAA=\",\"AAAB/wIAAALEAQAAJgUAAAAAAmMTAABkEwAAAAACPxEAAEARAAA=\"]Fc[\"AAAAAzgQAABOEAAAXxIAAAACbRIAAG8SAAADmAEAAFsTAABcEwAAAmYEAAC0CwAAAAAAAAABYQQAAA==\",\"AAAAAcwBAAA=\"]Dc[\"AAAAAmIAAADGBAAAAg8CAAC/CAAAAQ8AAAAByAAAAA==\",\"AAAAAsYEAADXDwAA\"]Eg[\"AAAAAeEEAAAAASMAAAAAAAL4AAAA+QAAAAAAAAAAAAAAAAPfBgAALw8AADYPAAA=\",\"AAABdAIAAAHhBAAA\"]Eg[\"AAAAARsFAAAAAU0AAAACWwEAAFwBAAAAAAAAAAAAAAAAAAPhBgAAMQ8AADcPAAA=\",\"AAAB6wIAAAEbBQAA\"]Hk[\"AAAFKgIAAD0CAAA+AgAASAIAAEoCAAAB1gQAAAACHwAAAP8GAAAAAALpAAAA6gAAAA==\",\"AAADYQIAAGMCAABkAgAAAtYEAACXBgAAAqUFAAAlEAAAAQoTAAABfA8AAAESEQAA\"]Ek[\"AAAAAQoFAAAAAkMAAAAABwAAAj0BAAA+AQAA\",\"AAAB0wIAAAEKBQAAAAAAAAAAAAAAAAAAAAACuwQAAOQGAAA=\"]Bk[\"AAAAAAABORAAAAFuAQAA\",\"AAAAAAAAAAE6EAAA\"]Fo[\"AAABjwAAAAHTBAAAAAG9DAAAAAAB5QAAAAAAAAAAAAAAAAYKBwAADgcAAAMJAAAHCQAAPw8AAEcQAAA=\",\"AAF+BwAAAALTBAAAaAUAAA==\"]Fo[\"AAAAApIAAAACBQAAAAHADAAAAS8BAAAAAAAAAAAAAAAAAAYMBwAAEAcAAAUJAAAJCQAAQQ8AAEkQAAA=\",\"AAGVBwAAAAECBQAAAWsFAAA=\"]Ag[\"AAACkwIAAB0DAAA=\",\"\"]Cg[\"AAAAAUAFAAAAAAADQg8AAKgPAABQEAAA\",\"AAGnBwAAAAFABQAA\"]Dc[\"AAAAAiAFAACqBwAAAAABaQEAAA==\",\"AAAAASAFAAAAAAAAAAAAAAAAAAGwBgAA\"]Dg[\"AAAAAfASAAAB2g8AAAAAAALrAAAADhEAAA==\",\"AAEMCQAAAa8BAAAB8BIAAAHaDwAA\"]Dg[\"AAAAAfESAAAB2w8AAAABRgEAAAABEBEAAA==\",\"AAENCQAAAb4BAAAB8RIAAAHbDwAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAATQPAAA=\",\"\"]Ac[\"\",\"AAAAAAHGEwAA\"]Ag[\"AAACkgIAACEDAAA=\",\"\"]Bc[\"\",\"AAAAAAAAAAADTBIAAE0SAABOEgAA\"]Bc[\"\",\"AAAAAAAAAAADTxIAAFASAABREgAA\"]Ak[\"\",\"AAAAAXESAAAAAAGREwAA\"]ADc[\"AAAAAdcEAAAAAAA6MAAAAQAAAAAAFAAQAAAAvwfBDEMPiw+OD8oPyRBCEVYRahLXEn4T1RPiE+4T8BMSFBYUGRQdFCQUOjAAAAEAAAAAAAwAEAAAAOwAWBDFEGASchJzEg0TORNME/oTCxQNFBsUAAABOxEAAA==\",\"AAGBBwAAAAHXBAAAAAAAOjAAAAEAAAAAABQAEAAAAL8HwQxDD4sPjg/KD8kQQhFWEWoS1xJ+E9UT4hPuE/ATEhQWFBkUHRQkFDowAAABAAAAAAAJABAAAABYEMUQYBINEzkTTBP6EwsUDRQbFAAAATsRAAA=\"]ADc[\"AAAAAQ4FAAAAAAFHAQAAOjAAAAEAAAAAABQAEAAAAMAHwgxED4wPjw/LD8oQQxFXEWsS2BJ/E9YT4xPvE/ETExQXFBoUHhQlFDowAAABAAAAAAALABAAAABZEMYQYRJ0EnUSDhM6E00T+xMMFA4UHBQAAAE8EQAA\",\"AAGZBwAAAAEOBQAAAAAAOjAAAAEAAAAAABQAEAAAAMAHwgxED4wPjw/LD8oQQxFXEWsS2BJ/E9YT4xPvE/ETExQXFBoUHhQlFDowAAABAAAAAAAJABAAAABZEMYQYRIOEzoTTRP7EwwUDhQcFAAAATwRAAA=\"]Ag[\"AAACbwIAAOMCAAA=\",\"\"]Bk[\"AAAAAAAAAAAAAU0EAAA=\",\"AAAAAAAAAQgMAAA=\"]Bk[\"AAAAAAAAAAAAAAEgDAAA\",\"AAAAAAABmxMAAA==\"]Do[\"AAAAAeIEAAAAASQAAAAAAAL6AAAA+wAAAAAAAAAAAAAAAALgBgAAMA8AAA==\",\"AAAAAeIEAAA=\"]Do[\"AAAAARwFAAAAAU4AAAACXQEAAF4BAAAAAAAAAAAAAAAAAALiBgAAMg8AAA==\",\"AAAAARwFAAA=\"]Ag[\"AAACmQIAABgDAAA=\",\"\"]Fc[\"AAAAAR4FAAAAAk8AAACiAAAAAmEBAAC5DwAAAk0DAAA6EAAA\",\"AAAAAR4FAAAAAAAAAAAAAAABbQcAAAAAAAABpwUAAA==\"]Ac[\"\",\"AAAAAAFuBwAA\"]Ao[\"AAAAAAGpBAAA\",\"AAAAAAFxBwAA\"]Ag[\"AAAClAIAABwDAAA=\",\"\"]Ag[\"AAACmwIAACADAAA=\",\"\"]Dg[\"AAAAAfIEAAAAAAAB5hIAAAAAAAHPEAAA\",\"AAAAAvIEAAA1CgAAATYKAAAAAWkQAAA=\"]Do[\"AAABzQEAAAEyBQAAAAAAAegSAAAAAAAB0xAAAA==\",\"AAAAATIFAAABpQoAAAGmCgAAAWsQAAA=\"]Do[\"AAAAAfQEAAAAAAADPhAAANAQAADnEgAAAAEuDAAA\",\"AAAAAvQEAAA6CgAAATgKAAAAAWoQAAA=\"]Eg[\"AAABzgEAAAE0BQAAAAAAA0IQAADUEAAA6RIAAAABMAwAAA==\",\"AAAAATQFAAABqwoAAAGqCgAAAWwQAAA=\"]Cc[\"AAAAAAAAAncEAADMBgAAAAEEAQAA\",\"AAGHBwAAAAG0AQAA\"]Cc[\"AAAAAAAAA3kBAAB6BAAAzwYAAA==\",\"AAGgBwAAAAHGAQAA\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA94GAACwBwAAzgcAAA==\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAATMPAAA=\",\"\"]Ao[\"AAAAAAAAAawEAAAAAQsUAAA=\",\"\"]Bk[\"AAAAAAAAAbAEAAAAAQwUAAA=\",\"AAAAAbQEAAA=\"]Eg[\"AAAAAAAAAAABEQEAAAAAAAAAAAAAAANBCQAAqQ8AAJkSAAA=\",\"AAGLBwAAAAS3BwAAuAcAALkHAAC6BwAA\"]Eg[\"AAAAAAAAAZQBAAAAAAAAAAAAAAAAAANCCQAAqg8AAJoSAAA=\",\"AAGkBwAAAAS7BwAAvAcAAL0HAAC+BwAA\"]Bo[\"AAAAAAABsQEAAAAAAXYMAAAAAWIEAAAAAUIEAAA=\",\"\"]Bo[\"AAAAAAABwAEAAAAAAXcMAAAAAWMEAAAAAUQEAAA=\",\"\"]Ak[\"AAAAAAABCxMAAAFyEwAA\",\"\"]Ao[\"AAAAAAABDBMAAAAAAXMTAAA=\",\"\"]Fo[\"AAAAASMFAAAAAlIAAACjAAAAA2wBAABtAQAAug8AAAFOAwAA\",\"AAAB+gIAAAEjBQAAAAAAAAJTBQAAVAUAAAAAAAAAAALCAQAAsAYAAA==\"]Dg[\"AAAAAfwEAAAAATUAAAABJwEAAA==\",\"AAAAAfwEAAAAAAAAAAAAAAAAAAAAAAHlBgAA\"]Dg[\"AAAAAcEEAAAAAgwAAAD4BgAAArsAAAC8AAAA\",\"AAABKgIAAAHBBAAAAAAByBAAAA==\"]Do[\"AAAAAfcEAAAAAjEAAACcAAAAAyABAAAhAQAAsw8AAAFHAwAA\",\"AAAAAfcEAAAAAAAAAWUEAAA=\"]Ek[\"AAAAAdgEAAAAAAACVBMAAKgTAAAD7QAAAKwQAAA5EwAA\",\"AAGCBwAAAAHYBAAAAAAAAlQTAACoEwAAAawQAAA=\"]Ek[\"AAAAAQ8FAAAAAAFIAQAAAlUTAACpEwAAAq0QAAA6EwAA\",\"AAGaBwAAAAEPBQAAAAAAAlUTAACpEwAAAa0QAAA=\"]Bo[\"AAAAAAAAAAABUwUAAAAAAAAAAALCAQAAsAYAAA==\",\"\"]Fg[\"AAAAAdkEAAAAAAAEIAkAANQPAAAzEQAABBMAAALuAAAATBMAAA==\",\"AAGDBwAAAAHZBAAAAAAABCAJAADUDwAAMxEAAAQTAAA=\"]Fg[\"AAAAARAFAAAAAAFJAQAABCEJAADVDwAANBEAAAUTAAABTRMAAA==\",\"AAGbBwAAAAEQBQAAAAAABCEJAADVDwAANBEAAAUTAAA=\"]Ag[\"\",\"AAAAAAAAAdcTAAA=\"]Bc[\"\",\"AAAAAAAAAAAAAAAAAAAAAAHvEgAA\"]Ag[\"\",\"AAAAAAAAAVIPAAA=\"]Co[\"AAAAAf0EAAAAATYAAAACKAEAACkBAAA=\",\"AAAAAf0EAAAAAAAAARUSAAA=\"]Fg[\"AAABVAIAAAHmBAAAAAEoAAAAAAG4BgAAAgEBAAACAQAA\",\"AAACewIAAJ8GAAAB5gQAAAAAAAGqBgAAAAAAAAAAAAAAAAEvDwAA\"]Gc[\"AAABugIAAALEAQAAJwUAAAABVgAAAAJ1AQAAdgEAAAG/BgAA\",\"AAACAQMAAKMGAAABJwUAAAAAAbEGAAAAAAAAAAAAAAAAAAIIAgAAMQ8AAA==\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA6wHAADLBwAAwwgAAA==\",\"\"]Cg[\"AAABdgIAAAAAAAAAARQBAAA=\",\"AAAAAAAAAAI8EAAAPhAAAA==\"]Cg[\"AAAB8QIAAAAAAAGJAQAA\",\"AAAAAAAAAANAEAAAQhAAAEMQAAA=\"]Bo[\"AAAAArQEAAA/BQAAAaQSAAA=\",\"AAAAAj8FAABZEQAA\"]Bo[\"AAAAAAAAAcIAAAAAAAABIgwAAA==\",\"AAAAAXoTAAA=\"]Io[\"AAAAAS8FAAAAAVwAAAABhAEAAAZ1BQAAzhAAANAQAADSEAAA1BAAANYQAAAAAAAFzRAAAM8QAADREAAA0xAAANUQAAAAAAAAAAABIxQAAA==\",\"AAAAAS8FAAAAAARgEwAAYRMAAGMTAABkEwAAAAFeBAAA\"]Co[\"AAAAAmQAAAC2BwAAAAABygAAAAJzBAAARhEAAAFQDwAA\",\"AAABKREAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhUJAAAwEAAA\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhcJAAAyEAAA\",\"\"]Co[\"AAAAAfMEAAAAAAAAAhcBAAAYAQAA\",\"AAAAAfMEAAAAAAJpEAAAahAAAA==\"]Dc[\"AAAAATMFAAAAAAKMAQAAjQEAAA==\",\"AAAAAjMFAABSEgAAAAACaxAAAGwQAAA=\"]Cc[\"AAAAAAGcAQAAAAG3AAAAAAAAAR8MAAA=\",\"AAAAAZoTAAA=\"]Ac[\"\",\"AAAB8wsAAA==\"]Ec[\"AAABcQIAAAHOBAAAAAEXAAAAAAAC3QAAAN4AAAA=\",\"AAAAAc4EAAAEEwkAAP4JAAD/CQAAAQoAAA==\"]Do[\"AAAB5AIAAAH2BAAAAAEvAAAAAh0BAAAeAQAA\",\"AAAAAfYEAAAEFAkAAFAKAABRCgAAUgoAAA==\"]Ak[\"\",\"AAAAAAACoBMAAKETAAA=\"]Ck[\"AAAAAsAEAAAqCQAAAb4IAAAB3BIAAAG6AAAA\",\"AAAAAsAEAADWDwAA\"]Cg[\"AAAAAU0HAAACIRAAADQQAAAAAbULAAAAAAAAAAABohAAAA==\",\"\"]Ck[\"AAAAAU4HAAACIhAAADUQAAAAArYLAAC3CwAAAAAAAAAAAaMQAAA=\",\"\"]Bc[\"AAAAAAAAAAAAAAAAAp4TAACfEwAA\",\"\"]Fo[\"AAAAAd0EAAAAAAADZwQAACsJAAC4EwAAAvIAAACmAQAA\",\"AAGGBwAAAAHdBAAAAAAAAmcEAAArCQAAAaYBAAAAAAAAAAAAAAABdhIAAA==\"]Fo[\"AAAAARQFAAAAAAFNAQAAA2gEAAAsCQAAuRMAAAGnAQAA\",\"AAGeBwAAAAEUBQAAAAAAAmgEAAAsCQAAAacBAAAAAAAAAAAAAAABdxIAAA==\"]Ck[\"AAAAAQ0FAAAAAAJDAQAARAEAAA==\",\"AAAAAQ0FAAAAAAAAAcUTAAA=\"]Ec[\"AAAAASEFAAAAAAFqAQAAAAAAAAAAAAAAAAAFowEAAKsHAADKBwAAwggAAHgMAAA=\",\"AAAAASEFAAA=\"]Dg[\"AAAAAAHGEwAAAAG2AAAAAAAAAAACnhMAAJ8TAAAAAAAB7xIAAA==\",\"AAABqwEAAA==\"]Ag[\"AAACnQIAACMDAAA=\",\"\"]Bc[\"\",\"AAAAAAAAAAAAAAAAAp4TAACfEwAA\"]Cc[\"AAAAAUEFAAAAAAAAAAAAAdUQAAA=\",\"AAABzQEAAAFBBQAA\"]Ck[\"AAAAAUIFAAAAAAACQxAAANYQAAAAATEMAAA=\",\"AAABzgEAAAFCBQAA\"]Ag[\"AAACmgIAABkDAAA=\",\"\"]Dg[\"AAAAAAABLAAAAAAAARIBAAA=\",\"AAAAAAAAAAAAAAAAAAAAA5ITAACTEwAAlBMAAA==\"]Ck[\"AAAAAAABXgAAAAGHAQAA\",\"AAAAAAAAAAAAAAAAAAAAApUTAACWEwAA\"]Ag[\"AAACnAIAAB4DAAA=\",\"\"]Do[\"AAAAAU8HAAACIxAAADYQAAAAAbgLAAABYRAAAA==\",\"AAK9AQAAjQcAAAEOCQAAAAAAAAFhEAAA\"]Ec[\"AAAAAikFAABQBwAAAiQQAAA3EAAAAAF4AQAAAWIQAAA=\",\"AAGfBwAAAcUBAAABKQUAAAAAAAFiEAAA\"]Bg[\"AAAAAAAAAAABVAUAAA==\",\"AAABvAEAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhYJAAAxEAAA\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhgJAAAzEAAA\",\"\"]") \ No newline at end of file +rd_("CBg[\"\",\"ADswAAABAAAFAAIAOwQEAPkTAAACyAYAAOcGAAA6MAAAAQAAAAAACgAQAAAA3QHeAVkFfAwTElcSbBLYE+QTAhQRFDowAAABAAAAAAAaABAAAAAMAg0CDgIPAhACEQISAkoEWAVdBZYGxAbzBjcJsRAWElgS6hKXE5gT2xP+E/8TABQBFBQUGBQ7MAAAAQAALAESAEgEAABFBQAAVwUAAMkGAADmBgAA9gYAADIMAwC7DAUAqg2GADkQAACyEAcAEREAAIARhgAXEgAAGRIAAKESAADrEgAAChMAADowAAABAAAAAAAdABAAAABaBWAFYQViBcIGwwbKBssGzAbNBs4Gzwa1C7YLtwu4CwgMTg9SD2MQyBASEh4TWxNcE3IT0xPXE+UTAxQ7MAAAAQAAPQAUAD8DFABmBAAAcgQCAEMFAQBGBQAAWwUBAHUFAAC1BgwAwgcDALQLAAAeDAAAqA8AANwPAABkEAAAChEAAKISAADmEgMAUxMAANQTAAAEFAAAOzAAAAEAAFcADQDbAD0AigEBAGUEAABwBwAAcwcAALIHAAC0BwAAKxADAEwSBQBDEwAAcxMAALITBQDFEwAAOzAAAAEAABUABwBMBAAAfQwAADEOAACkDwMAFBIAABETBwDyEwUAOzAAAAEAABMACQBiBAEAawQBANMGBwCxBwAAswcAAEgPAgBRDwAAwxAAAHoSAAADEgcAABMHAABpEgAAAScMAAAEbQcAAG8HAAByBwAAJQwAAAA7MAAAAQAABQACAMIBAACSEwQAAAABpwUAAA==\"]Bo[\"AAAAAAAAAAACwBMAAMETAAAAAAAAAqIQAACjEAAA\",\"\"]0Bg[\"\",\"AAAFGQkAABoJAAAbCQAAHAkAAB0JAAA=\"]AGg[\"AAAAAAKzAQAAwwEAAAAAAkMFAABEBQAABHAHAABzBwAAsgcAALQHAAA7MAAAAQAADQAFAHMFAQA/CQEALQwEAH0MAAA9EQMAOjAAAAEAAAAAAAsAEAAAAGsEbASxB7MHUQ9tEG4QLxEwETERMhF6EgRcBAAAEgcAABMHAADBDwAABEIEAABEBAAAnhMAAJ8TAAAFYQQAAG8HAAByBwAASw8AAE0PAAADIwwAACQMAABMDwAAOzAAAAEAAAYAAwDCAQAAsAYAAJITBAAB7xIAAAEmDAAA\",\"AAAAAVkRAAAAAkgFAABJBQAAAAIBDAAAAgwAAAAFLQwAAC4MAAAvDAAAMAwAADEMAAAAAAJCBAAARAQAAA==\"]ANg[\"AAAEUgIAALgCAACfBgAAowYAAAMDDAAABAwAAAUMAAACswEAAMMBAAA7MAAAAQAAhgABAIARhgAAOzAAAAEAAAcAAwBDBQEA5hIDACQUAQAEcAcAAHMHAACyBwAAtAcAADswAAABAAASAAcAcwUBAOgGAAA/CQEALQwEAH0MAAA9EQMAHhIDADowAAABAAAAAAAKABAAAABiBGMEawRsBLEHswdRDy8RMBExETIRBVwEAABeBQAAEgcAABMHAADEEAAABEIEAABEBAAAnhMAAJ8TAAAEbwcAAHIHAABLDwAATQ8AAATFBgAAIwwAACQMAABMDwAABZITAACTEwAAlBMAAJUTAACWEwAAAe8SAAAAAacFAAA=\",\"AAAAAAACSAUAAEkFAAAAAgEMAAACDAAAAcIPAAAFLQwAAC4MAAAvDAAAMAwAADEMAAAAAAJCBAAARAQAAAAAAAAAA94GAAAYEQAAGREAAA==\"]Dc[\"\",\"AAAAADswAAABAAAHAAEAIgkHADswAAABAAAJAAIAvhAEABMRBAAAARIRAAA=\"]ADm[\"AAAABrABAACyAQAAvwEAAMEBAADYDwAA2Q8AAAS2AQAAyQEAADYKAAA4CgAAOjAAAAEAAAAAAAkAEAAAALEBtwG4AcABygHLAaYKqgqgE6ETOzAAAAEAAA0ABACsBAcAfA8AAGkQAwByEwAAArsBAACiEgAAOzAAAAEAABUACgCmAQEArQEAACsMAQB2DAEAzw8DAFgQAQByEgMAQxMAAMATAQALFAEAAcITAAAAAAAAAAAAAAGnBQAA\",\"AAABqwEAAAK0BAAABxIAAAAAAAJCDwAAUBAAAAAAAAAAAAAAAAAEoQYAAKUGAAB6DAAAewwAAA==\",1]Fk[\"AAAABOsEAAAVBwAAuAcAABwRAAACIwkAAPYLAAABsxAAAAABwwcAAAELAQAAAqUPAAASEwAAAdQGAAA=\",\"AAAAAesEAAABtgEAAA==\"]Fk[\"AAAABDUFAAAZBwAAvAcAACMRAAACJwkAAPoLAAABtxAAAAGOAQAAAcUHAAAAAqcPAAAWEwAAAdgGAAA=\",\"AAAAATUFAAAByQEAAA==\"]AEa[\"AAAAAq4BAAC6AQAAOzAAAAEAAAcAAQAiCQcAAARgBQAAYQUAAGIFAAASEgAAAAABwhMAAAAAAAKiEAAAoxAAAA==\",\"AAAAADswAAABAAAQAAMAlgYAACIJBwD1CwcAOzAAAAEAAAsABAD2BgAApBAAAL4QBAATEQQAOzAAAAEAAA8ABQCsBAcAEwwCABsSAgBTEgAA1xMAADowAAABAAAAAAAKABAAAADOENAQ0hDUENYQEhE1ETYRNxE4EVMTBCsQAAAsEAAALRAAAC4QAAAAAAXNEAAAzxAAANEQAADTEAAA1RAAAAAAAAAAAAKnBQAARw8AAA==\",1]Ec[\"AAAAAAAAOzAAAAEAAAYAAgCsBgMAsQYCADswAAABAAAGAAIApwYEAAoJAQADXgQAAFMFAABUBQAA\",\"\"]Dg[\"AAAAAAAAAAABsxMAAAHzEwAAAAAAAAAAAAABVAcAAA==\",\"AAAAAAABWhIAAAE+EwAA\"]Eo[\"AAAAAekEAAABtQEAAAIqAAAAmQAAAAGwDwAAAUQDAAACBgEAAAcBAAA=\",\"AAABqAAAAAHpBAAAAQATAAAAAe0LAAA=\"]Ic[\"AAAAASsFAAADxwEAABoTAACZEwAAAlgAAACmAAAABnsBAAB8AQAAQwQAAKYFAAC9DwAA5RMAAAFRAwAA\",\"AAABqQAAAAIrBQAAAhMAAAAB8QsAAAAAAAAAAAAAAAAAAAKqAAAAqwAAAA==\"]Ik[\"AAAAArwEAABxEgAAAfMGAAABkwYAAAGyAAAAAQoRAAABshMAAAIUEgAA8hMAAAAAAAAAAAAAOjAAAAEAAAAAAAkAEAAAAGcFkQZRB9IHig+hD9MPXBCmEEER\",\"AAAAAbwEAAAAAVkSAAABPRMAAA==\"]Ck[\"AAAAAd0BAAAAAAAAAbYTAAAB9hMAAA==\",\"AAAAAAABXRIAAAFBEwAA\"]Ck[\"AAAAAd4BAAAAAAAAAbcTAAAB9xMAAA==\",\"AAAAAAABXhIAAAFCEwAA\"]Kk[\"AAAAAAAABFoFAABgBQAAYQUAAGIFAAAAOzAAAAEAAAkAAQCqCwkAOzAAAAEAAA0AAQBMBA0AOzAAAAEAAAkABAAfDAMASA8CAMMQAADXEAEAAAEnDAAAAyUMAABLDwAATQ8AAAIjDAAATA8AAA==\",\"AAAAAAABpBAAAAMTDAAAFAwAABUMAAA=\"]Nk[\"AAAAAAAAAngSAAB5EgAABOYSAADnEgAA6BIAAOkSAAAC7BIAAO0SAAAF6AYAAB4SAAAfEgAAIBIAACESAAACYgQAAGMEAAACXgUAAMQQAAAAAAHFBgAAAAAAAacFAAA=\",\"AAAAAAJWBQAAxhMAAAAF/BMAAB8UAAAgFAAAIRQAACIUAAABUxMAAALCDwAA/RMAAAAAAAAAAAAAAAQwEAAAMRAAADIQAAAzEAAA\"]Bg[\"AAAAAAAAAARWEQAAVxEAAHYTAAB3EwAA\",\"\"]Bk[\"\",\"AAAAAVURAAAAAAAAAAAAAAAAAAAAAAFVDwAA\"]Cc[\"AAAAAAAAAWMQAAABZBAAAA==\",\"AAAAAAACOQkAADoJAAA=\"]FGo[\"AAAAADswAAABAAAVAAkADAIGAEoEAABrBQAA1AcAAP8LAAA0EAMAWBIAAJcTAQD+EwMAOzAAAAEAABMCEgBBBAAAWgQAAGAEAADJBgAA7wsDALsMBQDDDG0BxA8AAMkPAAA5EAAAVxAAALIQBwAREQAAgBGGABcSAAAZEgAA6xIAAE4TAAA7MAAAAQAAwwAPALIAKAAZAXAAjAEPAEMEAABaBQAApgUAAKwGAwCxBgIAwgYBAOsLAwBGDwAAHhMAAD0TBQDlEwAA+BMAADswAAABAACiAEIAPwMUAF0EAABnBAEAcgQCAEYFAABbBQEAdQUAAKcGBAC1BgwAvwcBAMIHAwDACAEACgkBACAJAQArCQEAAQwBABEMAQAeDAAAwQwBAEMPAQBTDwEAiw8BAI4PAQCoDwAAyg8BANQPAQDcDwAAOhAAAEoQAQBhEAEAZBAAAMkQAQASEQAAHREAAB8RAAAhEQAAJBEAACYRAAAoEQAAMxEFAEIRAQBFEQIAVhEBAAgSAQBqEgEAohIAANcSAQDdEgEA5hIDAAQTAQBEEwEAVBMBAFgTAQB2EwEAfhMBAKgTAQC4EwEA1BMCAOATAwDuEwMABBQAABIUAQAWFAEAGRQBAB0UAQAkFAEAOzAAAAEAAI8AJgDbAD0AigEBAKYBAQBABAAAXgQAAGUEAABTBQEAbQUBAHAHAABzBwAAsgcAALQHAACqCwkAKwwBAHYMAQBPDwEAhA8BAMIPAADPDwMAWBABAKwQAQDFEAEAFRIAAGASAQByEgMA7BIBAA0TAQA5EwEATBMBAE8TAwBzEwAAshMFAMATAQDFEwAA+hMBAP0TAAALFAMAGxQBADswAAABAAAxAA0ATAQNAHMFAQDoBgAAPwkBABsMAAB9DAAAMQ4AAKQPAwA9EQMAHhIDABETBwBJEwEA8hMFADswAAABAAAcAA0AYgQBAGsEAQDTBgcAsQcAALMHAAAfDAMASA8CAFEPAABtEAEAwxAAANcQAQB6EgAABRQAADowAAABAAAAAAAHABAAAABcBF4FwQ/EEDsRPBFpEtwTA0IEAABEBAAAJwwAADowAAABAAAAAAAIABAAAABhBG0HbwdyByUMSw9ND6IQoxAExQYAACMMAAAkDAAATA8AADswAAABAAAFAAIAsAYAAJITBAAAASYMAAABpwUAAA==\",\"AAAAAAA7MAAAAQAA5gABAMMM5gAAOjAAAAEAAAAAAFkAEAAAAGcEaAS/B8AHwAjBCCAJIQkrCSwJAQwCDBEMEgzBDMIMQw9ED1MPVA+LD4wPjg+PD8oPyw/UD9UPShBLEGEQYhDJEMoQHREfESERJBEmESgRMxE0EUIRQxFWEVcRCBIJEmoSaxLXEtgS3RLeEgQTBRNEE0UTVBNVE1gTWRN2E3cTfhN/E6gTqRO4E7kT1RPWE+AT4RPiE+MT7hPvE/AT8RMSFBMUFhQXFBkUGhQdFB4UJBQlFDswAAABAAAvABQApgEBAG0FAQArDAEAdgwBAIQPAQDPDwMAWBABAKwQAQDFEAEAYBIBAHISAwDsEgEADRMBADkTAQBMEwEATxMDAMATAQD6EwEACxQDABsUAQAEPwkAAEAJAABJEwAAShMAAAACOxEAADwRAAAAAqIQAACjEAAA\"]Ic[\"AAAAARoRAAAABFcFAAAPCQAAEAkAABESAAA7MAAAAQAADAADAHUEBQDKBgUAkRMAAAADbAcAAMUQAADGEAAAASYQAAAAB80QAADPEAAA0RAAANMQAADVEAAAOxEAADwRAAAAAW0HAAA=\",\"\"]Lk[\"AAACUwIAALYCAAAAArYBAADJAQAAOzAAAAEAAAsAAwC3AQEAygEBALIQBwA7MAAAAQAABwABAKwEBwA6MAAAAQAAAAAABwAQAAAAvwfAB4sPjA/UD9UPMxE0EQACSRMAAEoTAAA=\",\"AAAAAYIPAAAAAAAAAAAAAAAAAAAAAAWBDwAAgw8AAIoPAACNDwAASxMAAA==\"]AAg[\"AAAEVQIAALcCAAARCQAAEgkAAASsAQAAtAEAALkBAADGAQAAAlkCAAC/AgAAAAA6MAAAAQAAAAAAEwAQAAAAZwRoBMAIwQg8ED4QQBBCEEMQzhDQENIQ1BDWEGoSaxIWFBcUGRQaFALsEgAA7RIAAAUtDAAALgwAAC8MAAAwDAAAMQwAAAAFzRAAAM8QAADREAAA0xAAANUQAAAAAAACwgEAALAGAAA=\",\"AAAAAAAAAAAAAAAAAAAAAAAABMIIAADDCAAAxAgAAMUIAAA=\"]BLk[\"AAADDgkAANkSAADaEgAABaoBAAAYCgAAVREAAN8SAADgEgAAOjAAAAEAAAAAAAcAEAAAALUBxwETCRQJ/wlQCnoKFhIBFxIAAAEeEwAAOjAAAAEAAAAAABEAEAAAAMIHwwfEB8UHQg/KD8sPUBAdER8RIREkESYRKBFEE0UT4BPhEwFDEwAAOzAAAAEAAAsAAgCkDwMAERMHADswAAABAAAJAAMA0wYHALEHAACzBwAAAAACbwcAAHIHAAA=\",\"AAAETQUAAE4FAAA4DwAAOQ8AADswAAABAAAWAAsAFAcHABsRAQAeEQAAIBEAACIRAQAlEQAAJxEAAAoSAQBwEwEAdBMAAL4TAQACGhMAAJkTAAABERIAAAAAAAAAAAAAAAAAADowAAABAAAAAABvABAAAACgAaEBowGkAQICAwIJAgoCSQRLBG0EtgS5BKAGpAbRBtIGBgcHB/wI/QgyCTMJ/gsADBYMFwwcDB0MKAwpDD4PPw9AD0EPVg99D34Pnw+gD9MPKBApEEYQRxBIEEkQVRBWEFoQWxBlEGYQnBCdEKYQqBCpEK8QsBC6ELsQvBC9EDkROhFNEU4RDRIOEg8SEBJVElYSYhJjEm4ScBKXEpgSmRKaEpwSnRKeEp8S2xLhEuIS4xL+Eg8TEBMZEx8TIBMhEyITIxMkEzsTPBNWE1cTXRNeE3wTfROcE50T2RPaEw==\"]Ac[\"AAAAAAEwAwAA\",\"\"]Ca[\"AAAAAAJZAgAAvwIAADswAAABAAAFAAEATxEFAA==\",\"\",1]Ek[\"AAAAAAAAAAAAAAAAAAAAAAAAAsYGAADcBgAA\",\"AAAAAAACOxAAAD0QAAAAAjwQAAA+EAAAAAIeEgAAHxIAAA==\"]Eo[\"AAAAAAAAAAAAAAAAAAAAAAAAAscGAADdBgAA\",\"AAAAAAACPxAAAEEQAAAAA0AQAABCEAAAQxAAAAACIBIAACESAAA=\"]Ck[\"AAAAAAAAAAAAAAAAAAAAAAAABXAAAACkAQAArQcAAMwHAADECAAA\",\"\"]Bg[\"AAAAAAAAAU4PAAAAAAAAAjsRAAA8EQAA\",\"\"]Gk[\"AAAABGEAAADFBAAAagUAANcPAAABDgIAAAYOAAAASAQAAEUFAAAEBwAASxEAAJsTAAACxwAAAFIPAAAAAloTAACxEwAA\",\"AAAAAcUEAAABvwgAAAFGBAAA\"]Ic[\"\",\"AAAAAAAAAAA7MAAAAQAACQABAKoLCQA7MAAAAQAADQABAEwEDQA7MAAAAQAACQAEAB8MAwBIDwIAwxAAANcQAQAAAScMAAADJQwAAEsPAABNDwAAAyMMAAAkDAAATA8AAAAAASYMAAA=\"]Bg[\"AAAAAAAAAAAAAAAAAAKiEAAAoxAAAA==\",\"\"]Hk[\"AAAD0AEAAAoMAAANDAAAAegEAAABtQEAAAQpAAAAmAAAADsQAAA9EAAAAa8PAAABQwMAAAMFAQAADREAAA4RAAA=\",\"AAAC0AEAAAYMAAACaQQAAOgEAAAB/xIAAAAB7AsAAA==\"]Hk[\"AAAD0QEAAAsMAAAODAAAASoFAAABxwEAAARXAAAApQAAAD8QAABBEAAAAnoBAAC8DwAAAVADAAADXgQAAA8RAAAQEQAA\",\"AAAC0QEAAAcMAAADagQAACoFAAABEwAAAAHwCwAA\"]2ALo[\"AAAAAAEqEAAAAAA6MAAAAQAAAAAAEQAQAAAAuwFdBBEMEgzBDMIMQw9ED8kQyhAIEgkS7hPvExIUExQdFB4UAmUEAABDEwAAOzAAAAEAAAsAAgCkDwMAERMHADswAAABAAAHAAEA0wYHAAAAAAACwgEAALAGAAA=\",\"AAAHTwUAAFAFAAAKDAAACwwAAA0MAAAODAAAGBIAADowAAABAAAAAAAXABAAAAC1B7YHHgkqCQwMDwwQDDoPOw9MEE0QThCbEBoRKhErESwRLREuEUYTrxOwE8MTxBM7MAAAAQAA+QACADkO9QAGEwMAOzAAAAEAAFkABAALAFUA3BIAAAsTAQB1EwAAAfgTAAAAAAQ9EQAAPhEAAD8RAABAEQAABC8RAAAwEQAAMREAADIRAAABaRIAAAAAAAAAAAdxBAAAZwUAANAGAAA2DgAAnhAAAK4QAABBEQAA\"]Dk[\"AAAAAAIBCgAAUQoAAAAAADswAAABAAAFAAEATBIFAAACYgQAAGMEAAAAAkIEAABEBAAA\",\"\"]BNo[\"\",\"ADswAAABAAAFAAIAOwQEAPkTAAACyAYAAOcGAAA6MAAAAQAAAAAACgAQAAAA3QHeAVkFfAwTElcSbBLYE+QTAhQRFDowAAABAAAAAAAaABAAAAAMAg0CDgIPAhACEQISAkoEWAVdBZYGxAbzBjcJsRAWElgS6hKXE5gT2xP+E/8TABQBFBQUGBQ7MAAAAQAAKAERAEgEAABFBQAAVwUAAMkGAADmBgAA9gYAALsMBQCqDYYAORAAALIQBwAREQAAgBGGABcSAAAZEgAAoRIAAOsSAAAKEwAAOjAAAAEAAAAAABsAEAAAAFoFYAVhBWIFwgbDBsoGywbMBs0GzgbPBrULtgu3C7gLTg9SD2MQyBASEh4TWxNcE3IT0xPlEwMUOzAAAAEAADsAEgA/AxQAZgQAAHIEAgBDBQEARgUAAFsFAQB1BQAAtQYMAMIHAwC0CwAAHgwAAKgPAADcDwAAZBAAAKISAADmEgMA1BMAAAQUAAA7MAAAAQAAUgALANsAPQCKAQEAZQQAAHAHAABzBwAAsgcAALQHAABMEgUAcxMAALITBQDFEwAAOzAAAAEAABQABgBMBAAAfQwAADEOAACkDwMAERMHAPITBQA7MAAAAQAAEwAJAGIEAQBrBAEA0wYHALEHAACzBwAASA8CAFEPAADDEAAAehIAAAISBwAAEwcAAAEnDAAAA28HAAByBwAAJQwAAAAFkhMAAJMTAACUEwAAlRMAAJYTAAA=\"]Bc[\"AAAAAAAAAAAAAAACOxEAADwRAAA=\",\"\"]Kc[\"AAAAAAHlEgAAADswAAABAAAGAAIAygYFAMgQAAACRgUAANwPAAABZQQAAAADbRAAAG4QAAB6EgAAAcEPAAA=\",\"AAAAAAABYAQAADswAAABAAAFAAEAdQQFAAAAAAAAAAAAAAAABwsCAAC1BAAAuAQAAN8GAADgBgAA4QYAAOIGAAA=\"]Do[\"AAAAAAABGAAAAAAAAd8AAAAAAAAAAAAAAAACtQQAANEGAAA=\",\"AAAAAAAAAAACTw8AAFAPAAA=\"]Dk[\"AAAAAAABMAAAAAEfAQAAAAAAAAAAAAAAAAACuAQAANIGAAA=\",\"AAAAAAAAAAABQAQAAA==\"]Ac[\"AAABYQIAAA==\",\"\"]Fg[\"AAAABO0EAAAWBwAAuQcAAB4RAAADJAkAAPcLAAD/EwAAAbQQAAAAAAENAQAAARMTAAAB1QYAAA==\",\"AAAAAe0EAAAAAbcBAAA=\"]Fg[\"AAAABDcFAAAaBwAAvQcAACURAAADKAkAAPsLAAABFAAAAbgQAAABkAEAAAAAARcTAAAB2QYAAA==\",\"AAAAATcFAAAAAcoBAAA=\"]Bk[\"\",\"AAAAAAAAAAA7MAAAAQAAPwACANsAPQCKAQEA\"]Ck[\"\",\"AAAAAAGWBgAAOzAAAAEAAAkAAgD2BgAA+AYIAAHXEwAAAVMTAAA=\"]Ck[\"AAACYwIAAHQCAAA=\",\"AAAAAAAAAmATAABhEwAAAAACPREAAD4RAAA=\"]Bo[\"\",\"AAAAAAAAAAAAAAAAAp4TAACfEwAAAAAAAe8SAAA=\"]Eo[\"\",\"AAAAAAA7MAAAAQAABQABAFkSBQA7MAAAAQAABQABAD0TBQAAOzAAAAEAAAUAAQCyEwUAOzAAAAEAAAUAAQDyEwUA\"]Cc[\"\",\"AAAAAAL/EgAAABMAAAAE6wsAAOwLAADtCwAA7gsAAA==\"]Eo[\"AAAAAfEEAAAAAS0AAAAAAAIVAQAAFgEAAA==\",\"AAA7MAAAAQAACgACAJICBQCZAgQAAvEEAADmEwAAAAABeBIAAA==\"]Eo[\"AAAAATEFAAAAAV8AAAAAAAKKAQAAiwEAAA==\",\"AAA7MAAAAQAACgACABgDCQAjAwAAAjEFAADnEwAAAAABeRIAAA==\"]Dg[\"AAAB/wIAAAEwBQAAAAFdAAAAAoUBAACGAQAA\",\"AAABDgMAAAEwBQAAAAAAAAFeBAAA\"]Eo[\"AAAAAAAAApUBAACWAQAA\",\"AAAAAAAAB9MTAAD8EwAAAxQAAB8UAAAgFAAAIRQAACIUAAAC1BMAAAQUAAAB/RMAAA==\"]Bk[\"AAAAAAAAAUUBAAA=\",\"AAAB2AIAAAAAAVoEAAA=\"]Bg[\"AAAAATsFAAAAAAGXAQAA\",\"AAAAATsFAAA=\"]Bg[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAXgMAAA=\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA64HAADNBwAAxQgAAA==\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAnEEAACvBwAA\",\"\"]Cc[\"AAAAAAAAAAIKCQAACwkAAAAAAAAAAAACwgEAALAGAAA=\",\"\"]Fo[\"AAAAAAACVwUAABkSAAAAAAAAAAAAAAAAAAAE0wcAAFYPAABnEAAAWBEAAA==\",\"AAF1BwAAAAAAAAAAAAAAAAAAAAAAAAJoEAAADBEAAA==\"]Bk[\"AAAAAVkFAAAAAAFODwAAAagPAAA=\",\"AAGmBwAA\"]Bg[\"AAAAAAAABGkQAABqEAAAaxAAAGwQAAA=\",\"\"]Ag[\"AAAAAq4BAAC6AQAA\",\"\"]Dg[\"AAAAAAAAAAAAAj8JAABACQAA\",\"AAAAAAAAAAAABS0MAAAuDAAALwwAADAMAAAxDAAA\"]AEg[\"AAAAAAKzAQAAwwEAAAAAAkMFAABEBQAABHAHAABzBwAAsgcAALQHAAA7MAAAAQAACwAEAHMFAQAtDAQAfQwAAD0RAwA6MAAAAQAAAAAACwAQAAAAawRsBLEHswdRD20QbhAvETARMREyEXoSBFwEAAASBwAAEwcAAMEPAAAEQgQAAEQEAACeEwAAnxMAAAVhBAAAbwcAAHIHAABLDwAATQ8AAAMjDAAAJAwAAEwPAAA7MAAAAQAABgADAMIBAACwBgAAkhMEAAHvEgAAASYMAAA=\",\"AAAAAVkRAAAAAkgFAABJBQAAAAIBDAAAAgwAAAAAAAACQgQAAEQEAAA=\"]He[\"\",\"AAAAAAAEMgwAADMMAAA0DAAANQwAAAIIDAAA1xMAAAIKEQAAUxMAAAUrEAAALBAAAC0QAAAuEAAAQxMAAAEUEgAAAAFpEgAAAAFtBwAAAAHCAQAAAAABpwUAAA==\",1]AMk[\"AAACvAEAAMUBAAAGrAEAALQBAAC5AQAAxgEAAN8SAADgEgAABFgFAAA3CQAA/gkAAFIKAAAEMgwAADMMAAA0DAAANQwAAAJbEwAAXBMAADowAAABAAAAAAAHABAAAAAKCQsJShBLENcS2BLVE9YTOjAAAAEAAAAAAAkAEAAAAEAEcAdzB7IHtAdPD1APwg/6E/sTAAKxBwAAswcAAA==\",\"AAAAOjAAAAEAAAAAABAAEAAAAKIBTQdOB08HUAfVB9YHNgzFD8YPYBDLEMwQZhJnEqAS3xMDNAkAACoQAACbEgAABjIMAAAzDAAANAwAADUMAABtEgAAbxIAAAAAAAJzBQAAdAUAAAACXAQAAMEPAAAAA2EEAABLDwAATQ8AAAMjDAAAJAwAAEwPAAAAAAImDAAAggwAADowAAABAAAAAAALABAAAAClAW4EbwS3BLoEjwaQBggHUQfSB9MHoQ8=\"]Bg[\"AAAAAAAAAAAAAVcEAAA=\",\"AAAAAaQFAAA=\"]Bk[\"AAAAAAAAADswAAABAAANAAIAdQUAALUGDAA=\",\"\"]Cc[\"AAABAQkAAAABEgIAAAAAAAFABAAA\",\"AAAAAAAAAAFdBAAA\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAbAGAAA=\",\"\"]Be[\"AAAAAAAAA2AFAABhBQAAYgUAAA==\",\"\",1]Bg[\"AAAAAAAAADswAAABAAAUAAEAPwMUAA==\",\"\"]Dk[\"AAAAAAHIAQAA\",\"AAAAAAUtCQAALgkAAC8JAAAwCQAAMQkAAAAAAAAAAAAAAAAAAAH/DwAA\"]Cc[\"AAAAAcQEAAAAAQ0AAAACvwAAAMAAAAA=\",\"AAAAAcQEAAA=\"]Bg[\"AAAAAAAAAAAAAVIEAAA=\",\"AAAAAcYHAAA=\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWYAAAA=\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAaoAAAA=\",\"\"]C@i[\"AAAAAAHIAQAAAaESAAABchMAAAK7AQAAohIAADowAAABAAAAAAAbABAAAACtAW0FbgWED4UPrBCtEGASYRINEw4TORM6E0wTTRNPE1ATURNSE1oTcxOxE/oT+xMNFA4UGxQcFDswAAABAAAGAAMAPwkBAKQPAwDCEwAAAQUUAAAB3BMAAAAAAcUGAAAAAAABpwUAAA==\",\"AAAFGQkAABoJAAAbCQAAHAkAAB0JAAAEAwwAAAQMAAAFDAAABxIAADowAAABAAAAAAAXABAAAACcAakEbgdxB8cHvgi/CC0JLgkvCTAJMQk0CSEQIhAjECQQJRCbEqQSBhMHEwgTCRM7MAAAAQAAIAAOANkBAADbAQAAQQQAAEYEAABaBAAAYAQAAPgGCAAyDAMARQ8AAFcQAAC+EAQAExEEAOQSAABOEwAAOzAAAAEAACMACQBDBAAAdQQFAKYFAADQBwAARg8AAKsPEwBTEgEAYBMBAGMTAQA7MAAAAQAACAAEADoQAAA1EQMARRECAHsTAAA7MAAAAQAADAAGAEAEAABPDwEAKxADAA0RAwBaEwAAsRMAAAQeEgAAHxIAACASAAAhEgAAOzAAAAEAAAYAAwAfDAMA1xABAAUUAAAEXAQAAMEPAADEEAAA3BMAAAAAAcUGAAABwgEAAAAAOjAAAAEAAAAAABwAEAAAAKwArQCuAK8Apga0BgEHAgcDB/oIOwk8CT0JPglBCUIJkA+pD6oPzA/ND84PXRBeEF8QRBEMEoATIxQ=\",1]Bg[\"AAAAAAAAAAAAAAAAAAKiEAAAoxAAAA==\",\"\"]Jo[\"AAAAAc8EAAAAOjAAAAEAAAAAAAcAEAAAABkAlQDZAUYERQ9QEVMRCxMCrA8AAFMSAAACQAMAALYGAAAC4AAAAOEAAAAAAbEHAAAAAAFvBwAA\",\"AAF6BwAAAANhAAAAYgAAAM8EAAACWQIAAMcHAAACUBEAAFMRAAAAAagGAAA=\"]A@c[\"AAAAAfgEAAAABzIAAACdAAAA2wEAAFIRAABUEQAA5BIAAAwTAAAHIgEAACMBAABGDwAAtA8AAMAPAABPEAAAVBIAAARIAwAAuwYAAB4MAAB7EwAAARUSAAABMQ4AAAKzBwAABRQAAAHcEwAAAAFyBwAA\",\"AAGPBwAAAAH4BAAAAr8CAABWBQAAAlIRAABUEQAAAa0GAAAAAAEbDAAAAAFpEgAAAAAAAAAABWYAAABnAAAAaAAAAGkAAABqAAAA\"]Bo[\"\",\"AAAAAAAAOzAAAAEAAKkAAwCyACgAGQFwAIwBDwA=\"]CCm[\"\",\"AAA7MAAAAQAA5gABAMMK5gA7MAAAAQAA7QAMAMoJMwAACgAAAgozADcKAAA5ChYAUwofAHQKBQB7CikApwoCAKwKFgBSEgAA5hMBADowAAABAAAAAAASABAAAABdBaUFlgYTCRQJ/gn/CQEKNgo4ClAKUQpSCnMKegqlCqsK/xIAEzowAAABAAAAAAASABAAAABIBEUF9gYEBzkJOgmmCqoKSxFZEloSWxJcEl0SXhIKE5sToBOhEzowAAABAAAAAAApABAAAADCBsMG0Ae1C7YLtwu4C+sL7AvtC+4LCAxSD3wPwA9PEGMQaRBqEGsQbBDIEHgSeRI9Ez4TPxNAE0ETQhNgE2ETYxNkE9MT1xP8EwMUHxQgFCEUIhQ6MAAAAQAAAAAAGgAQAAAAXQRyBHMEdARbBVwFpwaoBqkGqgarBh4M3A88ED4QQBBCEEMQZBASEUURRhFHEVMTexPUEwQUOzAAAAEAAFkADwDbAD0AigEBAEAEAABeBAAAZQQAAFMFAQBsBwAATw8BAMIPAAAVEgAATBIFAFoTAACxEwYAxRMAAP0TAAA7MAAAAQAAEQAIAHMFAQAbDAAAfQwAADEOAAAmEAAAPREDAEkTAQDyEwUAOjAAAAEAAAAAAAgAEAAAAGIEYwRRD20QbhDXENgQehIFFDowAAABAAAAAAALABAAAABcBF4FEgcTB8EPzRDPENEQ0xDVEGkS3BMEQgQAAEQEAACeEwAAnxMAAANtBwAAbwcAAHIHAAACJAwAAEwPAAA7MAAAAQAABgADAMIBAACwBgAAkhMEAAHvEgAAAAGnBQAA\",1]Le[\"\",\"AAAAAswBAACUBgAAA/QGAAA8DwAAPQ8AAAPmBgAAbRIAAG8SAAA6MAAAAQAAAAAABwAQAAAATg8SEhsSHBIdElsTXBOREwJmBAAAtAsAAAGtAQAAAcITAAAESA8AAEkPAABKDwAAwxAAAAABJwwAAARhBAAAJQwAAEsPAABNDwAAASMMAAAAAAEmDAAA\",1]Gc[\"\",\"AAAAOjAAAAEAAAAAAAcAEAAAAN0B3gETEmwS2BPkEwIUERQC8wYAACoQAAAFkwYAAA8JAAAQCQAAfw8AABESAAABHhMAAAEKEQAAAUMTAAA=\"]Bo[\"\",\"AAAAAgETAAACEwAAAATvCwAA8AsAAPELAADyCwAA\"]Bk[\"\",\"AAAAAAAAOzAAAAEAAAYAAgCsBgMAsQYCAA==\"]Fc[\"AAAAAcQBAAAAAAAABG0FAABuBQAAhA8AAIUPAAA=\",\"AAA7MAAAAQAAPgABADcMPgAAAAAAAAAAAAAAAAAAAAAB4wYAAA==\"]Ao[\"\",\"AAA7MAAAAQAA5gABANcH5gA=\"]A@o[\"AAAEagIAAHsCAACBAgAAOA8AAAHNBAAAA+oSAAAUFAAAGBQAAAMWAAAAlAAAAE8RAAABqw8AADowAAABAAAAAAAMABAAAAA/A3IEcwRDBUQFWwW1BkIRVBN+E6gT4hPwEwLbAAAA3AAAAA==\",\"AAF5BwAAOzAAAAEAAAYAAwBRAgQAEQkAANkSAAABzQQAAAQTCQAA/gkAAP8JAAABCgAAAU8RAAAB6wsAAAOnBgAARREAAEYRAAAAAAAAAAAAAAAAATAPAAA=\"]AAk[\"AAAE3QIAAAEDAAAJAwAAOQ8AAAH1BAAAAAQuAAAAmwAAAFERAADrEgAABBsBAAAcAQAAsg8AAOUTAAA6MAAAAQAAAAAACgAQAAAARgN0BEYFXAW6BkMRVRN/E6kT4xPxEwABMQ4AAA==\",\"AAGOBwAAOzAAAAEAAAYAAwC2AgQAEgkAANoSAAAB9QQAAAQUCQAAUAoAAFEKAABSCgAAAu8LAABREQAAAqwGAADQBwAAAUcRAAAAAAAAAAAAAAAABDIPAAAzDwAANA8AADUPAAA=\"]Gc[\"AAA7MAAAAQAACwAEABwQBAADEwAAqhMEABUUAAA=\",\"ADswAAABAAAJAAMAUgcBAFUHAgDSEgQAOzAAAAEAAAsABAAcEAQAAxMAAKoTBAAVFAAA\"]Ic[\"AAAAAAAAAAA7MAAAAQAACQABAKoLCQA7MAAAAQAADQABAEwEDQA7MAAAAQAACQAEAB8MAwBIDwIAwxAAANcQAQAAAScMAAADJQwAAEsPAABNDwAAAyMMAAAkDAAATA8AAAAAASYMAAA=\",\"\"]Cc[\"AAAAArABAADLEAAAAAAAAAErDAAAAAFrBAAAARIHAAA=\",\"\"]Cc[\"AAAAAr8BAADMEAAAAAAAAAEsDAAAAAFsBAAAARMHAAA=\",\"\"]ABg[\"AAAAAvASAADxEgAAAAW3AQAAuAEAAMoBAADLAQAAEREAADswAAABAAALAAMArAQHAFoFAAATDAIAOjAAAAEAAAAAAAcAEAAAAEYFwgfDB8QHxQdTD1QPqA8HDREAAA4RAAAPEQAAEBEAAHMTAADFEwAA/RMAADswAAABAAANAAQAGwwAADEOAACkDwMAERMHADswAAABAAAHAAEA0wYHAAPEEAAAaRIAANwTAAAAAW0HAAABxQYAAAAAAAGnBQAA\",\"AAAAA9MBAADUAQAA1QEAAAABVxAAAA==\"]Ek[\"AAAAAAAAAAAAAAAAAAAAAAACUQUAAOkGAAA=\",\"AAAAAAAAAAI1EQAANhEAAAAAAAAAAAAAAAACxgYAANwGAAA=\"]Ek[\"AAAAAAAAAAAAAAAAAAAAAAACUgUAAOsGAAA=\",\"AAAAAAAAAAI3EQAAOBEAAAAAAAAAAAAAAAACxwYAAN0GAAA=\"]Ak[\"\",\"AAAAAAKiDwAAow8AAA==\"]Eo[\"AAAABO8EAAAXBwAAugcAACARAAACJQkAAPgLAAABtRAAAAAAAQ8BAAABFBMAAAHWBgAA\",\"AAAAAe8EAAAAAbgBAAA=\"]Eo[\"AAAABDkFAAAbBwAAvgcAACcRAAACKQkAAPwLAAABuRAAAAGSAQAAAAABGBMAAAHaBgAA\",\"AAAAATkFAAAAAcsBAAA=\"]Bg[\"AAAAAAAAAAAAAVEEAAA=\",\"AAAAATgJAAA=\"]Ag[\"AAACrwEAAL4BAAA=\",\"\"]Ao[\"AAAAAAAAAAAAAAAAAAElDAAA\",\"\"]Ag[\"\",\"AAACRBAAAEUQAAA=\"]Bg[\"AAAAAAAAAAAAARQSAAA=\",\"AAABbwAAAA==\"]Dg[\"AAAAAtMBAADUAQAAAAADYAUAABMMAAAbEgAAAAGtAQAAAcITAAA=\",\"AAAAAQcSAAA=\"]Hg[\"AAAAASoRAAABBhMAAAM7EAAAvxAAABQRAAABYBMAAAE1EQAAASsQAAACPREAAB4SAAABLxEAAAAAAAABkxMAAA==\",\"AAAAAAAAAALOEAAA0BAAAAAAAALNEAAAzxAAAA==\"]Ig[\"AAAAAS0RAAABCBMAAAM/EAAAwRAAABYRAAABYxMAAAE3EQAAAS0QAAACPxEAACASAAABMREAAAAAAAABlRMAAA==\",\"AAAAAAELEQAAAAAD0hAAANQQAADWEAAAAAAAA9EQAADTEAAA1RAAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAm4AAAA1DwAA\",\"\"]Bk[\"AAAAAAAAAdoAAAAAAAFZBAAA\",\"AAAAAc8HAAA=\"]Cc[\"AAAAAWAQAAABGhMAAAACQwQAAKYFAAA=\",\"AAAAAAHUBwAA\"]Ek[\"AAAAAdQEAAAAAR0AAAAAAAHmAAAAAAAAAAAAAAAAArcEAACPBgAA\",\"AAF/BwAAAAHUBAAAAAAAAAAAAW0QAAA=\"]Ek[\"AAAAAQUFAAAAAT0AAAABNAEAAAAAAAAAAAAAAAAAAroEAACQBgAA\",\"AAGWBwAAAAEFBQAAAAAAAAAAAW4QAAA=\"]Be[\"AAAAAAA7MAAAAQAAhgABAIARhgA=\",\"\",1]Bg[\"AAAAAAAAAAAAAVQEAAA=\",\"AAAAAeoLAAA=\"]Ec[\"AAAAAAAAAAAAAAAAAAJvBwAAcgcAAAHFBgAAAsIBAACwBgAA\",\"AAAAAAAAAAAAAAAAAAAAAcIBAAA=\"]Dk[\"AAAAAAAAAAABtBMAAAH0EwAA\",\"AAAAAAABWxIAAAE/EwAAAAAAAAAAAAAAAAABVAcAAA==\"]Dg[\"AAAAAR0FAAAAAAJfAQAAYAEAAAG+BgAAAAAAAAAAAAAAAAELAgAA\",\"AAAAAR0FAAA=\"]ABc[\"AAAAA6oBAAAQCgAAVREAAAPEBgAAcwoAALEQAAAAADowAAABAAAAAAANABAAAAAgCSEJKwksCY4Pjw9hEGIQ3RLeEgQTBRNYE1kTOzAAAAEAAA8ABwCsEAEATBIFAA0TAQBaEwAAsRMAAA0UAQAbFAEAAAEFFAAAAdwTAAA=\",\"AAAAA50BAACoAQAAJxAAAAQhEAAAIhAAACMQAAAkEAAAAtkBAADbAQAAAAACWhMAALETAAAAAQUUAAAB3BMAAAAAAAAAAATaAQAA3AEAAP4IAABYEQAA\"]Bk[\"AAAAAAHzBgAA\",\"AAAAAAAAAAEKEQAAAAEUEgAA\"]Ho[\"AAAABcIEAABpBQAApAUAAHwMAABmEgAAAj0PAADbEwAAAuYGAAChEgAAA70AAAASEgAAchMAAAFEBQAAAWwHAAABJhAAAA==\",\"AAAAAsIEAACUBgAAAfQGAAAAAAABrQEAAAHCEwAA\"]Gc[\"AAAAAmcSAAB0EwAAAZsGAAAByQYAAAEaAQAAAjoQAACiEgAAAAHoBgAAAAFeBQAAAAFtBwAAAcUGAAAAAAABpwUAAA==\",\"AAAAAAAAAAG7AQAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAW0AAAA=\",\"\"]Fg[\"AAADyAYAAOcGAACcDwAABA8MAABTEAAAShEAAMMTAAAFDQIAAF0FAAClBQAAbgcAAC8JAAAAAsMAAAB8DwAA\",\"AAABqhAAAA==\"]Fg[\"AAAABBAMAABUEAAATBEAAMQTAAACcQcAADAJAAAByQYAAAFiAQAAAAAB6AYAAAABXgUAAAAAAAAAAAGnBQAA\",\"AAABqxAAAA==\"]Dg[\"AAAAASIFAAAAAVEAAAABawEAAA==\",\"AAAAASIFAAAAAAAAAAAAAAAAAAAAAAFwAAAA\"]Bk[\"AAAAAAEMAgAAAAAAAAFOBAAA\",\"AAAAARkMAAA=\"]Cc[\"AAAAAAHHBwAAAAAAAAFPBAAA\",\"AAAAAAACGgwAAGgSAAA=\"]Dk[\"\",\"AAAAADswAAABAAATAAEAWAcTADswAAABAAATAAEAlAATADswAAABAAATAAEAqw8TAA==\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWsAAAA=\",\"\"]Fg[\"AAAAATwFAAAAAAGZAQAAAAAAAAAAAWEEAAAAAAABJgwAAAauAAAApQEAAAUCAAC0BgAACAcAAAwSAAA=\",\"AAGlBwAAAAE8BQAA\"]Hk[\"AAAEqAAAAFECAABNBQAABgwAAAHqBAAAAAIrAAAAmgAAAAGxDwAAAkUDAAC5BgAAAggBAAAJAQAA\",\"AAABgQIAAARjAAAAZAAAAGUAAADqBAAAAbUBAAAAAe4LAAABqwYAAA==\"]Kc[\"AAAEqQAAALkCAABOBQAABwwAAAEsBQAAAARZAAAApwAAAMQPAADJDwAAA30BAAB+AQAAvg8AAAJSAwAAwAYAAA==\",\"AAABCQMAAAEsBQAAAccBAAAB8gsAAANDBAAApgUAALIGAAAAAAAAAAAAAAAAAARrAAAAbAAAAG0AAABuAAAA\"]Ak[\"AAAAAALaDwAA2w8AAA==\",\"\"]Ao[\"AAAAAAAAAAACpgEAAEwSAAA=\",\"\"]Ao[\"AAAAAAAAAAACpwEAAE8SAAA=\",\"\"]Dc[\"AAAAAAAAAAABCgEAAAAAAAAAAAAAAAWsAAAAbgQAAAEHAACGDwAAXRAAAA==\",\"\"]Fc[\"AAAAAAAAAX8BAAAAAAAAAAAAAAAAAAWtAAAAbwQAAAIHAACHDwAAXhAAAA==\",\"AAAAAAAAAAAAAegGAAAAAl4FAADEEAAA\"]Fc[\"AAAAAT0FAAAAAAGaAQAAAmYEAAC0CwAAAAAAAAEnDAAAAAAAAAAFrwAAAAMHAAD7CAAAiA8AAF8QAAA=\",\"AAAAAT0FAAA=\"]Hg[\"AAABjQAAAAHQBAAAAAIaAAAAuwwAAAAAAeIAAAAAAAAAAAAAAAADoAEAALYEAAD+CwAA\",\"AAF7BwAAAAHQBAAAAAAAAAAAAAAAAAAAAAAECQcAAAoHAAANBwAADgcAAA==\"]Hg[\"AAAAApAAAAD/BAAAAAI4AAAAvgwAAAEsAQAAAAAAAAAAAAAAAAADoQEAALkEAAAADAAA\",\"AAGSBwAAAAH/BAAAAAAAAAAAAAAAAAAAAAAECwcAAAwHAAAPBwAAEAcAAA==\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAAHvEgAA\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAWwAAAA=\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmcAAADlBgAA\",\"\"]Bg[\"AAAAAAAAAAAAAVMEAAA=\",\"AAAAAboMAAA=\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAasAAAA=\",\"\"]Dk[\"AAAAAewEAAABtgEAAAABrQQAAAEdEQAAAQwBAAA=\",\"AAGIBwAAAAHsBAAAAAAAAR0RAAA=\"]Dk[\"AAAAATYFAAAByQEAAAACjwEAALEEAAABJBEAAA==\",\"AAGhBwAAAAE2BQAAAAAAASQRAAA=\"]Hc[\"AAAAAAABfw8AAAGREwAAAAG1EwAAAfUTAAAAAAAAAAAAADowAAABAAAAAAANABAAAADQBvoIPQk2Do0PkA/MD54QrhBEEW4ScBJLE4AT\",\"AAAAAAABXBIAAAFAEwAA\"]Ak[\"AAAAAAKXEwAAmBMAAA==\",\"\"]Cg[\"AAAAAaASAAABNAkAAAFgBAAAAAABZQQAAA==\",\"AAAAAAH/CwAA\"]Ag[\"\",\"AAAAAAAAAbMGAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmgAAABHDwAA\",\"\"]Ag[\"AAAAAAAAAAHBBgAA\",\"\"]Dk[\"AAAAAAAAOzAAAAEAAKkAAwCyACgAGQFwAIwBDwAAOzAAAAEAAD8AAgDbAD0AigEBAA==\",\"\"]Hg[\"AAAAAi0FAADqBgAAATEJAAAEWgAAAAsTAAAMEwAAdRMAAAOAAQAAgQEAAPgTAAABUwMAAAABGwwAAAABaRIAAAAAAcUGAAA=\",\"AAABiQ8AAAEtBQAAAcgBAAAAAU8QAAA=\"]Dk[\"AAAAAeAEAAAAASIAAAAAAbcGAAAC9gAAAPcAAAA=\",\"AAAAAuAEAAAYCgAAAAAAAakGAAA=\"]Dk[\"AAAAARcFAAAAAUgAAAACUQEAAFIBAAABvAYAAA==\",\"AAAAARcFAAABegoAAAABrgYAAA==\"]Ck[\"AAAAAcUPAAAAAAAAAnAHAACyBwAA\",\"AAAAAAAAAAACKxAAACwQAAA=\"]Ck[\"AAAAAcYPAAAAAAAAAnMHAAC0BwAA\",\"AAAAAAAAAAACLRAAAC4QAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAqcQAAAaEgAA\"]Ek[\"AAAAA9UHAAAKEgAAcBMAAAAAAAAAAAGxBwAAAAABbwcAAA==\",\"AAAAAAAAAAI1EQAANhEAAAIrEAAALBAAAA==\"]Ek[\"AAAAA9YHAAALEgAAcRMAAAAAAAAAAAGzBwAAAAABcgcAAA==\",\"AAAAAAAAAAI3EQAAOBEAAAItEAAALhAAAA==\"]Dg[\"AAAAAQsFAAAAAUQAAAACPwEAAEABAAA=\",\"AAAAAQsFAAAAAAAAAAEbDAAAAAFpEgAA\"]Cc[\"AAAB2AIAAAH7BAAAAAE0AAAAASYBAAA=\",\"AAAAAfsEAAA=\"]Ic[\"AAABjwAAAAHSBAAAAAIcAAAAvQwAAAAAAeQAAAAAAAAAAAAAAAA6MAAAAQAAAAAADAAQAAAA2gEJAgkHDQcCCQYJPg+BD0YQlxIPEx8TOxM=\",\"AAF9BwAAAALSBAAAagUAAAABRQ8AAA==\"]Ho[\"AAAAApIAAAABBQAAAAI6AAAAwAwAAAEuAQAAAAAAAAAAAAAAAAA6MAAAAQAAAAAADAAQAAAA3AEKAgsHDwcECQgJQA+DD0gQmBIQEyATPBM=\",\"AAGUBwAAAAEBBQAAAAABRg8AAA==\"]Gg[\"AAACOgIAAEECAAAByAQAAAACEQAAAPoGAAACzQAAAM4AAAA=\",\"AAACPAIAAD0CAAAByAQAAAAAAAACTw8AAFAPAAAAAAJcBAAAwQ8AAAAAASQMAAA=\"]Do[\"AAAAAQMFAAAAAjsAAACeAAAAAzABAAAxAQAAtQ8AAAFJAwAA\",\"AAAAAQMFAAAAAAAAAUAEAAA=\"]Ck[\"AAAAAngTAAB5EwAAAAAAAAAAAAABJwwAAA==\",\"AAAAAAABpBAAAA==\"]Co[\"AAAAAAAB5gYAAAMbEgAAHBIAAB0SAAAAAa0BAAA=\",\"AAAAAAABfw8AAA==\"]K@i[\"AAA7MAAAAQAArAEDANcH5gBDCYYANww+ADswAAABAADrAUMAYQAEAJ0BAACiAQAAqAEAANIBBgBpBAEAvASGAFkFAABoBQIApAUAAKgF5gCXBgAA6gYAABQHBwBNBwMAqQcBALUHCQDGBwAAzwcAANUHAQAeCQAAKgkAADgJAADqCwAADAwAAA8MAQAZDAAANgwAAHwMAAC6DAAAOg8BAIIPAAC/DwAAxQ8BANYPAQAnEAAAOBAAAEwQAgBTEAEAYBAAAJsQAADHEAAAyxABABoRAgAeEQAAIBEAACIRAQAlEQAAJxEAACoRBABIEQIATBEAAAoSAQBXEgAAXxIAAGYSAQBxEgAAoBIAAEYTAgBwEwEAdBMAAHgTAgCaEwAArxMBAL4TAQDDEwEA3xMAADswAAABAABWASwAnAEAALMBAADDAQAADAIGADADAABKBAAAqQQAAFYFAABYBQAAawUAAJsGAADEBgAAWAcTAG4HAABxBwAAxwcAANQHAAC+CAEALQkEADQJAAA3CQAA9QsHAP8LAAA5DvUAPA8BAKIPAQAhEAQANBADALEQAAALEQAAFhIAAFgSAACbEgAApBIAAOUSAADqEgAABhMDABoTAACXEwIAxhMAANsTAAD+EwMAFBQAABgUAAA7MAAAAQAAuQI2AAsAVQCUABMA2QEAANsBAABBBAAARgQAAEgEAABaBAAAYAQAAEUFAABIBQEAVwUAAMkGAADmBgAA+AYIAAQHAAAPCQEAOQkBAO8LAwAaDAAAuwwFAMMMbQFFDwAAfw8AAMQPAADJDwAAORAAADsQAAA9EAAAPxAAAEEQAABXEAAApBAAALIQBwC+EAQAEREAABMRBABLEQAAgBGGABESAAAXEgAAGRIAAFkSBQBoEgAAbRIAAG8SAAChEgAA3BIAAOQSAADrEgAAChMCAE4TAAB1EwAAmxMAADswAAABAAAJASgAsgAoABkBcACMAQ8AQwQAAHUEBQBaBQAAYAUCAKYFAACsBgMAsQYCAMIGAQDKBgUA0AcAALULAwDrCwMAEwwCAEYPAABODwAAUg8AAKsPEwDADwAATxAAAGMQAADIEAAAEhIAABsSAgBTEgEAHhMAAD0TBQBbEwEAYBMBAGMTAQByEwAAkRMAANMTAADlEwAA+BMAAPwTAAADFAAAHxQDADswAAABAACzAE8APwMUAF0EAABmBAIAcgQCAEMFAQBGBQAAWwUBAHUFAACnBgQAtQYMAL8HAQDCBwMAwAgBAAoJAQAgCQEAKwkBALQLAAABDAEAEQwBAB4MAADBDAEAQg8CAFMPAQCLDwEAjg8BAKgPAADKDwEA1A8BANwPAAA6EAAAPBAAAD4QAABAEAAAQhABAEoQAQBQEAAAYRABAGQQAADJEAEAzhAAANAQAADSEAAA1BAAANYQAAASEQAAHREAAB8RAAAhEQAAJBEAACYRAAAoEQAAMxEFAEIRAQBFEQIAVhEBAAgSAQBqEgEAohIAANcSAQDdEgEA5hIDAAQTAQBEEwEAVBMBAFgTAQB2EwEAexMAAH4TAQCoEwEAuBMBANQTAgDgEwMA7hMDAAQUAAASFAEAFhQBABkUAQAdFAEAJBQBADswAAABAACgACsA2wA9AIoBAQCmAQEAQAQAAF4EAABlBAAAUwUBAG0FAQBsBwAAcAcAAHMHAACyBwAAtAcAAKoLCQArDAEAdgwBAE8PAQCEDwEAwg8AAM8PAwArEAMAWBABAKwQAQDFEAEADREDABUSAABMEgUAYBIBAHISAwDsEgEADRMBADkTAQBMEwEATxMDAFoTAABzEwAAsRMGAMATAQDFEwAA+hMBAP0TAAALFAMAGxQBADswAAABAAA4ABAATAQNAHMFAQDoBgAAPwkBABsMAAAtDAQAfQwAADEOAACkDwMAJhAAAD0RAwAUEgAAHhIDABETBwBJEwEA8hMFADswAAABAAAgAA4AYgQBAGsEAQDTBgcAsQcAALMHAAAfDAMASA8CAFEPAABtEAEAwxAAANcQAQAvEQMAehIAAAUUAAA6MAAAAQAAAAAADgAQAAAAXAReBRIHEwfBD8QQzRDPENEQ0xDVEDsRPBFpEtwTBUIEAABEBAAAJwwAAJ4TAACfEwAAOjAAAAEAAAAAAAgAEAAAAGEEbQdvB3IHJQxLD00PohCjEATFBgAAIwwAACQMAABMDwAAOzAAAAEAAAYAAwDCAQAAsAYAAJITBAAB7xIAAAEmDAAAAacFAAA=\",\"AAAAOzAAAAEAAOcAAgCoBeYAWREAAAKbBgAACxEAADswAAABAADxAAMASAUBAPgGCADDDOYAAVQSAAA6MAAAAQAAAAAAWQAQAAAAZwRoBL8HwAfACMEIIAkhCSsJLAkBDAIMEQwSDMEMwgxDD0QPUw9UD4sPjA+OD48Pyg/LD9QP1Q9KEEsQYRBiEMkQyhAdER8RIREkESYRKBEzETQRQhFDEVYRVxEIEgkSahJrEtcS2BLdEt4SBBMFE0QTRRNUE1UTWBNZE3YTdxN+E38TqBOpE7gTuRPVE9YT4BPhE+IT4xPuE+8T8BPxExIUExQWFBcUGRQaFB0UHhQkFCUUOzAAAAEAAC8AFACmAQEAbQUBACsMAQB2DAEAhA8BAM8PAwBYEAEArBABAMUQAQBgEgEAchIDAOwSAQANEwEAORMBAEwTAQBPEwMAwBMBAPoTAQALFAMAGxQBAAQ/CQAAQAkAAEkTAABKEwAAAAI7EQAAPBEAAAJCBAAARAQAAAKiEAAAoxAAAAAAAANzDwAAuRIAAN0TAAAB+wgAAA==\",1]Eo[\"AAAAAAA7MAAAAQAABQABAFkSBQA7MAAAAQAABQABAD0TBQAAOzAAAAEAAAUAAQCyEwUAOzAAAAEAAAUAAQDyEwUA\",\"\"]Ck[\"AAAAAAAAAVoFAAAAAAFMBAAA\",\"AAAAAAAAAxMMAAAUDAAAFQwAAA==\"]Cc[\"\",\"AAAAAAAESAQAAAQHAABLEQAAmxMAAAAAAloTAACxEwAA\"]Fc[\"AAAAAf4EAAAAATcAAAACKgEAACsBAAA=\",\"AAGRBwAAAAH+BAAAAAACwA8AAE8QAAACHgwAAHsTAAAAAAEFFAAAAdwTAAA=\"]Eo[\"AAAAAUgRAAABLQkAAAACuAAAAAgMAAABEhEAAAABUAQAAA==\",\"AAAAAAGlBQAAAAIIDAAAfA8AAAABbAcAAAEmEAAA\"]Dk[\"AAAABhMSAABsEgAA2BMAAOQTAAACFAAAERQAAAAAAAABQxMAAA==\",\"AAAAAAAAAAEKEQAA\"]A@g[\"AAAAOjAAAAEAAAAAABIAEAAAAGkEvwRoBZcGxgc4CeoLGQw2DLoMvw/WD8cQSRFXEkYTehOaE98TOjAAAAEAAAAAAAcAEAAAAC4JJRAWEpsS5RLqEhQUGBQ6MAAAAQAAAAAABwAQAAAA2QFGBBoMRQ++EBMRaBIKEzowAAABAAAAAAAHABAAAAC5AMgQUxLTE/wTAxQfFCEUAUMFAAAAAAAAAAAAAZITAAA=\",\"AAAAAb8EAAABvggAAAABCAwAAA==\"]ACk[\"AAAAOjAAAAEAAAAAAAgAEAAAAGoEHgkMDDoPgg+bECwRrxOwEzowAAABAAAAAAAHABAAAABKBFYFawXUB/8LCxFYEpkTOjAAAAEAAAAAAAoAEAAAANsBWgTED8kPORBXEBERFxLkEusSThM6MAAAAQAAAAAABwAQAAAAGQFGD8APTxBUEuUTIBQiFAVGBQAAHgwAAHsTAADUEwAABBQAAAQVEgAAcxMAAMUTAAD9EwAAAhsMAAAxDgAAAQUUAAADxBAAAGkSAADcEwAA\",\"AAAAAAAAAAAAAAAAAAFtBwAAAAAAAAGnBQAA\"]Ho[\"AAAAAxQHAAC3BwAAGxEAAAMiCQAA9QsAAP4TAAABshAAAAABwgcAAAACpA8AABETAAAB0wYAAA==\",\"AAAAAAT1CwAA9gsAAPcLAAD4CwAAAAWsBAAArQQAAK4EAACvBAAAUxIAAA==\"]Ho[\"AAAAAxgHAAC7BwAAIhEAAAMmCQAA+QsAAAAUAAABthAAAAABxAcAAAACpg8AABUTAAAB1wYAAA==\",\"AAAAAAT5CwAA+gsAAPsLAAD8CwAAAAWwBAAAsQQAALIEAACzBAAAVBIAAA==\"]No[\"AAABjgAAAAHRBAAAAAIbAAAAvAwAAAAAAeMAAAAAAAAAAAAAAAA6MAAAAQAAAAAAJAAQAAAAAgJJBKAGBgf8CDIJFgwcDCgMfQ+fDygQVRBaEGUQnBCoEK8QuhC8EBgRORFNEQ0SDxJVEmISnBKeEuESIRMjE1YTXRN8E5wT2RM=\",\"AAF8BwAAAAHRBAAAAAAAAAAAAAAAAAAAAAAEAgkAAAMJAAAGCQAABwkAAA==\"]No[\"AAAAApEAAAAABQAAAAI5AAAAvwwAAAEtAQAAAAAAAAAAAAAAAAA6MAAAAQAAAAAAJAAQAAAAAwJLBKQGBwf9CDMJFwwdDCkMfg+gDykQVhBbEGYQnRCpELAQuxC9EBkROhFOEQ4SEBJWEmMSnRKfEuISIhMkE1cTXhN9E50T2hM=\",\"AAGTBwAAAAEABQAAAAAAAAAAAAAAAAAAAAAEBAkAAAUJAAAICQAACQkAAA==\"]Cc[\"AAAAAecEAAAAAAAAAQMBAAA=\",\"AAAAAecEAAAAAAG1CwAA\"]Ck[\"AAAAASgFAAAAAAF3AQAA\",\"AAAAASgFAAAAAAO2CwAAtwsAALgLAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAFhBAAAAAAAASYMAAA=\",\"\"]Bg[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAATYPAAA=\"]Eo[\"AAAAARgFAAAAAUoAAAACVQEAAFYBAAABvQYAAA==\",\"AAAAARgFAAAAAAGvBgAAAAAAAAAAAAAAAAACTAUAADcPAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAg8UAAAQFAAA\"]Ck[\"AAAAAAAAAAABxRMAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAABJhQAAA==\"]Ag[\"AAAClwIAABoDAAA=\",\"\"]Bo[\"AAAAAAAAAcEAAAAAAAABIQwAAA==\",\"AAAAAb8PAAA=\"]Cc[\"AAAAAAACGgwAAGgSAAABUg8AAA==\",\"AAAAAAABBAcAAA==\"]Gc[\"AAAAAfoEAAAAATMAAAABJQEAAAABFRIAAAEbDAAAAAFpEgAA\",\"AAGQBwAAAAH6BAAAAAHkEgAAAcAPAAAAARUSAAAAAAAAAAAAAAABBQcAAA==\"]Do[\"AAAAAAAAAAFTDwAAAm0FAACEDwAA\",\"AAAAAa4BAAAAAAABUw8AAARtBQAAhA8AAA0RAAAOEQAA\"]Do[\"AAAAAAAAAAFUDwAAAm4FAACFDwAA\",\"AAAAAboBAAAAAAABVA8AAARuBQAAhQ8AAA8RAAAQEQAA\"]Ao[\"AAAAAAEqEAAAAAABUBAAAA==\",\"\"]Fk[\"AAABKREAAAJjAAAAtQcAAAEQAgAAAAHJAAAAAnIEAABFEQAAAk8PAADCDwAAAAFRDwAAAlwEAADBDwAAAAElDAAAAiMMAAAkDAAA\",\"\"]Cc[\"AAAAAAAAAANdBAAAdAQAAEcRAAA=\",\"AAAAAAABxA8AAA==\"]Ec[\"AAABPAIAAAHJBAAAAAISAAAA+wYAAALPAAAA0AAAAA==\",\"AAABPgIAAAHJBAAAAAAAAkURAABGEQAA\"]Bo[\"AAABqhAAAAAAAALEAAAAxQAAAA==\",\"AAAAAAFdBQAA\"]Ck[\"AAABqxAAAAAAAAJmAQAAZwEAAA==\",\"AAAAAAAAAAAAAAABXgUAAA==\"]Ao[\"AAAAAAAAAR4TAAABQg8AAA==\",\"\"]Hg[\"AAAAAmUAAADPBwAAARECAAABOQkAAAPVAAAAwgYAAGMQAAACWwUAANwPAAAAAnMFAAB9DAAABkgPAABJDwAASg8AAG0QAADDEAAAehIAAAAAAksPAABNDwAAAUwPAAA=\",\"\"]Dk[\"AAAAAAABOgkAAALDBgAA0AcAAAJcBQAAZBAAAAABdAUAAAFuEAAA\",\"AAAAAAAByQ8AAA==\"]Bc[\"AAAAAAAAAAAAAAAAAAAAAAHvEgAA\",\"\"]ABc[\"AAABiQ8AAAGUBgAAAsgBAAD0BgAABJMGAAAaDAAAfw8AAGgSAAAC0xMAAAMUAAADChEAANQTAAAEFAAABWwHAAANEQAADhEAAA8RAAAQEQAAASYQAAAAAAABbQcAAA==\",\"AAAABeoGAABIEQAASREAAEoRAABMEQAAA5wBAAA8DwAAPQ8AAAFLEQAABfwTAAAfFAAAIBQAACEUAAAiFAAAAXsTAAAB/RMAAAEUEgAAAAAAAAAAAAJYDwAAcg8AAAUEAgAABQIAAIYPAACHDwAAiA8AAA==\"]Cc[\"AAAAARkFAAAAAUsAAAACVwEAAFgBAAA=\",\"AAAAARkFAAA=\"]Dc[\"AAAAAAAAAAA7MAAAAQAABQABAEwSBQA=\",\"AAAABNIBAADWAQAA1wEAANgBAAA=\"]Ao[\"AAAAAdIBAAAAAAAAAc8PAAA=\",\"\"]Ao[\"AAAAAdcBAAAAAAAAAdAPAAA=\",\"\"]Eo[\"AAAAASsRAAABBxMAAAM9EAAAwBAAABURAAABYRMAAAE2EQAAASwQAAACPhEAAB8SAAABMBEAAAAAAAABlBMAAA==\",\"\"]Eo[\"AAAAAS4RAAABCRMAAANBEAAAwhAAABcRAAABZBMAAAE4EQAAAS4QAAACQBEAACESAAABMhEAAAAAAAABlhMAAA==\",\"\"]Bc[\"AAAAAAAAAnUEAADKBgAAAAHRDwAA\",\"\"]Bc[\"AAAAAAAAAngEAADNBgAAAAHSDwAA\",\"\"]Ec[\"AAAAAcwBAAAAAm0SAABvEgAAAlsTAABcEwAAAmYEAAC0CwAAAAAAAAABYQQAAA==\",\"AAAAAAEwAwAA\"]Gg[\"AAAAAcsEAAAAAhQAAAD9BgAAAtYAAADXAAAA\",\"AAADRgIAAEcCAABIAgAAAcsEAAAAAAAB3A8AAAACcwUAAH0MAAACbRAAAHoSAAAAAAABTA8AAA==\"]Eg[\"AAAAAQYFAAAAAj4AAACgAAAAAzUBAAA2AQAAtw8AAAFLAwAA\",\"AAAAAQYFAAAAAAAAAAF0BQAAAW4QAAA=\"]Ec[\"AAAAAAAAAWUBAAAAAAAAAAAAAAAAAAK7BAAAPgkAAA==\",\"AAAAAAAAAAAAAAAAAAAAAAAAAacFAAA=\"]Ec[\"AAAB8wsAAAG+BAAAAAELAAAAAbQAAAA=\",\"AAAAAb4EAAAAARAJAAAAAAAAAAAAAAAAAAABkQYAAA==\"]Dg[\"AAAAAAFYBQAAAAAAAAAAAAAAAAAAAAJoEAAADBEAAA==\",\"AAF2BwAAAAAAAZMGAAA=\"]Ac[\"AAABZAIAAA==\",\"\"]Do[\"AAAAAd8EAAAAASEAAAAAAAL0AAAA9QAAAA==\",\"AAACbwIAAHECAAAB3wQAAAAAAAAAAUkTAAA=\"]Dk[\"AAAAARYFAAAAAUcAAAACTwEAAFABAAA=\",\"AAAC4wIAAOQCAAABFgUAAAAAAAAAAUoTAAA=\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAhUJAAAXCQAA\"]Dk[\"AAAAAAAAAAABEwEAAA==\",\"AAABjQIAAAAAAAAAAAABYgQAAAESBwAAAUIEAAABbwcAAA==\"]Dg[\"AAAAAAAAAYgBAAA=\",\"AAABEwMAAAAAAAAAAAABYwQAAAETBwAAAUQEAAABcgcAAA==\"]Dk[\"AAAAAe4EAAAAAbcBAAABrgQAAAEfEQAAAQ4BAAA=\",\"AAGJBwAAAAHuBAAAAAAAAR8RAAA=\"]Dk[\"AAAAATgFAAAAAcoBAAACkQEAALIEAAABJhEAAA==\",\"AAGiBwAAAAE4BQAAAAAAASYRAAA=\"]Ck[\"AAAAAQcFAAAAAT8AAAACNwEAADgBAAA=\",\"AAAAAQcFAAAAAAHDBgAA\"]Eg[\"AAAAAdoEAAAAAiAAAACWAAAAAa0PAAABQQMAAALvAAAAYBIAAA==\",\"AAGEBwAAAWoCAAAC2gQAABAKAAA=\"]Eg[\"AAAAAREFAAAAAkYAAAChAAAAAkoBAAC4DwAAAUwDAAABYRIAAA==\",\"AAGcBwAAAd0CAAABEQUAAAFzCgAA\"]Ao[\"AAAAAAAAAAACWBAAAA0RAAA=\",\"\"]Ao[\"AAAAAAAAAAACWRAAAA8RAAA=\",\"\"]Do[\"AAABbwAAAAG9BAAAAAABswAAAA==\",\"AAAAAb0EAAAAAQ8JAAAAAAAAAAAAAAAAAAABXBAAAA==\"]Bg[\"AAAAAAAABNQAAABiBQAAFQwAAB0SAAA=\",\"\"]Ak[\"AAAAAAABQAAAAAE5AQAA\",\"\"]Do[\"AAAAAAAAAAAAAAAAAAAAAAAAAqcQAAAaEgAA\",\"AAF0BwAAAAAAAAAAAAAAAAAAAAAAAAFnEAAA\"]Cg[\"AAAAAAPEBgAANwkAALEQAAA=\",\"AAAAAAAAAAJCDwAAUBAAAA==\"]Ag[\"AAACjQIAABMDAAA=\",\"\"]Ac[\"\",\"AAAAAVISAAA=\"]Cc[\"AAAAATUKAAACNgoAAKUKAAABpgoAAAJpEAAAaxAAAA==\",\"\"]Gg[\"AAAAAd4EAAAB2xMAAAAAAcAIAAAE8wAAANEPAABzEgAAwBMAAAEmEAAA\",\"AAAAA7IBAADeBAAA5hMAAAABoBMAAAABwAgAAAPRDwAAcxIAAMATAAA=\"]Bc[\"AAAAAbIBAAAAAAAAAAAAAc0QAAA=\",\"\"]Gg[\"AAAAARUFAAAAAAFOAQAAAcEIAAAD0g8AAHUSAADBEwAAAAAAAAFtBwAA\",\"AAAAA8EBAAAVBQAA5xMAAAABoRMAAAABwQgAAAPSDwAAdRIAAMETAAA=\"]Bc[\"AAAAAcEBAAAAAAAAAAAAAdEQAAA=\",\"\"]Fg[\"AAABRgIAAAHVBAAAAAEeAAAAAAAC5wAAAOgAAAA=\",\"AAGABwAAAAHVBAAAAAE5CQAAAsIGAABjEAAAA3IEAABzBAAAWwUAAA==\"]Eo[\"AAAAAQkFAAAAAUIAAAACOwEAADwBAAA=\",\"AAGYBwAAAAEJBQAAAAE6CQAAAdAHAAAEdAQAAFwFAABkEAAARxEAAA==\"]Ao[\"\",\"AAAAAAAAAAAAAAAB1RAAAA==\"]Ek[\"AAAAAeMEAAAAASUAAAAAAAL8AAAA/QAAAA==\",\"AAABdgIAAAHjBAAAAAAAAAFsBwAAASYQAAAAAs0QAADPEAAA\"]Eg[\"AAAAAR8FAAAAAVAAAAACYwEAAGQBAAA=\",\"AAAB8QIAAAEfBQAAAAAAAAAAAALREAAA0xAAAAABbQcAAA==\"]Ao[\"AAAAAAAAAAFDEAAAAAExDAAA\",\"\"]Jk[\"AAAAAeQEAAAABSYAAACXAAAASAUAADsQAAA9EAAAArULAACuDwAABEIDAAABDAAAPBAAAD4QAAAE/gAAAP8AAAANEQAADhEAAAItDAAALgwAAAIvEQAAMBEAAA==\",\"AAAAAuQEAABTEAAAArMBAAA0EAAAAAABCgkAAA==\"]Og[\"AAAAASQFAAAABVMAAACkAAAASQUAAD8QAABBEAAABnABAABxAQAAtgsAALcLAAC4CwAAuw8AAARPAwAAAgwAAEAQAABCEAAAAg8RAAAQEQAAAi8MAAAwDAAAAjERAAAyEQAA\",\"AAAABCQFAACpBwAAqgcAAFQQAAAEwwEAADUQAAA2EAAANxAAAAAAAQsJAAACUwUAAFQFAAAAAAAAAAAAAAA7MAAAAQAACgACAKsHBQDKBwQA\"]Cc[\"AAAAARoFAAAAAUwAAAACWQEAAFoBAAA=\",\"AAAAARoFAAA=\"]Ck[\"AAABTwUAAAHlBAAAAAEnAAAAAAABAAEAAA==\",\"AAAAAuUEAAADDAAA\"]Dg[\"AAABUAUAAAElBQAAAAFUAAAAAXIBAAAAAAAAAAAAAcUGAAA=\",\"AAAAAiUFAAAEDAAA\"]Cc[\"AAAAAT4FAAAAAWAAAAABmwEAAA==\",\"AAAAAj4FAAAFDAAA\"]Dg[\"AAAAAAAAAAAAAAABxBAAAA==\",\"AAAABjgQAABfEgAARxMAAEgTAAB4EwAAeRMAAA==\"]Ak[\"AAAAAAAAAAABThIAAA==\",\"\"]Ak[\"AAAAAAAAAAABURIAAA==\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmoAAAAEAgAA\",\"\"]Bg[\"AAAAAAAAAAAAAVUEAAA=\",\"AAAAAccQAAA=\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAmkAAAAFBwAA\",\"\"]Bk[\"AAAAAAAAAAAAAATTBgAA1AYAANUGAADWBgAA\",\"\"]Ec[\"AAAABJ0BAACoAQAA+QQAACcQAAAAAAEkAQAAAAAABNcGAADYBgAA2QYAANoGAAA=\",\"AAAAAfkEAAA=\"]Bg[\"AAAAAAAAAAAAAVYEAAA=\",\"AAAAAAHlEgAA\"]Ag[\"AAAAAAAB9gYAAA==\",\"\"]Cc[\"AAAAAToKAAACOAoAAKsKAAABqgoAAAJqEAAAbBAAAA==\",\"\"]No[\"AAAAAdwEAAAB9AYAAAGhEgAAAXwPAAAGEQwAAEoQAABEEwAAWBMAALgTAADgEwAAB/EAAACtAQAAdgwAAM8PAAByEgAATxMAAFETAAABwhMAAAAAAAAAAAAAA6EGAAB6DAAAdhIAAA==\",\"AAAAAtwEAADYDwAAAAGxAQAAAXgSAAAGEQwAAEoQAABEEwAAWBMAALgTAADgEwAABXYMAADPDwAAchIAAE8TAABREwAA\"]Bo[\"AAAAAdgPAAAAAbEBAAAAAjwQAADOEAAAAAEtDAAA\",\"\"]Nc[\"AAAAARMFAAAAAAFMAQAAOjAAAAEAAAAAAAcAEAAAALsBEgxLEKISRRNZE7kT4RMFdwwAANAPAAB0EgAAUBMAAFITAAAAAAAAAAAAAAAEpwUAAKUGAAB7DAAAdxIAAA==\",\"AAAAAhMFAADZDwAAAAHAAQAAAXkSAAAGEgwAAEsQAABFEwAAWRMAALkTAADhEwAABXcMAADQDwAAdBIAAFATAABSEwAA\"]Bo[\"AAAAAdkPAAAAAcABAAAAAkAQAADSEAAAAAEvDAAA\",\"\"]Ao[\"AAAAAAAAAAACTxMAAFATAAA=\",\"\"]Ao[\"AAAAAAAAAAACURMAAFITAAA=\",\"\"]Dc[\"AAABRwIAAAHMBAAAAAIVAAAA/gYAAALYAAAA2QAAAA==\",\"AAABSgIAAAHMBAAA\"]Bk[\"AAAAAdUBAAAAAATTAAAAYQUAABQMAAAcEgAA\",\"\"]Ec[\"AAAAAgETAAACEwAAAv8SAAAAEwAABO8LAADwCwAA8QsAAPILAAAE6wsAAOwLAADtCwAA7gsAAA==\",\"\"]Cc[\"AAAAAAAAAAABTRIAAA==\",\"AAF3BwAAAAKsAQAA3xIAAA==\"]Cc[\"AAAAAAAAAAABUBIAAA==\",\"AAGMBwAAAAK5AQAA4BIAAA==\"]Bc[\"\",\"AAAAAAAAAAAAAAAAAAABxQYAAA==\"]Cg[\"AAAAATsPAAAAAAFvAQAAAToQAAA=\",\"AAGoBwAAAAAAAU4TAAA=\"]Ek[\"AAAAAcMEAAAAAAG+AAAAAAAAAAAAAAAAAAAE2xIAAOMSAAD+EgAAGRMAAA==\",\"AAF4BwAAAALDBAAAaQUAAA==\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAAzsJAADNDwAADxQAAA==\",\"\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAAzwJAADODwAAEBQAAA==\",\"\"]Bk[\"\",\"AAAAAAAAAAAAAAAAAAAAAAAAAhYJAAAYCQAA\"]Bc[\"AAAAAAABQQQAAA==\",\"AAAAAAGpBAAA\"]Ec[\"AAAAAfAEAAAAAbgBAAABrwQAAAIhEQAAdhMAAAEQAQAA\",\"AAGKBwAAAAHwBAAAAAAAAiERAAB2EwAA\"]Ec[\"AAAAAToFAAAAAcsBAAACkwEAALMEAAACKBEAAHcTAAA=\",\"AAGjBwAAAAE6BQAAAAAAAigRAAB3EwAA\"]Ag[\"\",\"AAAAAAABERIAAA==\"]Co[\"AAAAAqIBAACpBwAAAAABaAEAAA==\",\"AAAAAAAAAAAAAAAAAAAAAcIBAAA=\"]Ac[\"\",\"AAAAAAGkEgAA\"]Cg[\"AAAAAAAAAngSAAB5EgAAAAABFBIAAA==\",\"AAAAAAAAAAFTEwAA\"]Do[\"AAAAAQQFAAAAAjwAAACfAAAAAzIBAAAzAQAAtg8AAAFKAwAA\",\"AAAAAQQFAAAAAAABXQQAAA==\"]Ak[\"AAAAAAACoBMAAKETAAA=\",\"\"]Ac[\"AAAAAdYBAAA=\",\"\"]Ac[\"AAAAAdgBAAA=\",\"\"]Eo[\"AAAC+gIAAA4DAAABLgUAAAABWwAAAAKCAQAAgwEAAA==\",\"AAAAAS4FAAAAAAAFpwYAAKgGAACpBgAAqgYAAKsGAAA=\"]Fk[\"AAAABEwQAABNEAAARxMAAEgTAAABPA8AAAGkEAAAARISAAAAAAHCEwAAAAAAAAAAAAEmDAAA\",\"AAAAAAAAAxsSAAAcEgAAHRIAAA==\"]Fc[\"AAAAAAABkwYAAAJ4EgAAeRIAAAEKEQAAAAEUEgAAAAACnhMAAJ8TAAAAAAAB7xIAAA==\",\"AAAAAAAAAdcTAAABUxMAAA==\"]Ag[\"\",\"AAAAAAABRQUAAA==\"]Co[\"AAAAAQwFAAAAAUUAAAACQQEAAEIBAAA=\",\"AAAAAQwFAAAAAAAAAAExDgAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAAeQGAAA=\",\"\"]Jc[\"AAAAAtsEAAC+EwAAAAAAAggSAADdEgAABPAAAACtAQAAKwwAAOwSAAADPwkAAEkTAADCEwAAAAAAAaIQAAA=\",\"AAGFBwAAAAKwAQAA2wQAAAAAAAIIEgAA3RIAAAIrDAAA7BIAAAI/CQAASRMAAAAAAAGiEAAA\"]Jg[\"AAAAAhIFAAC/EwAAAAABSwEAAAO7AQAACRIAAN4SAAACLAwAAO0SAAACQAkAAEoTAAAAAAABoxAAAA==\",\"AAGdBwAAAAK/AQAAEgUAAAGbBgAAAAACCRIAAN4SAAACLAwAAO0SAAACQAkAAEoTAAAAAAABoxAAAA==\"]Ao[\"AAAAAAAAAcYAAAAAAAFYBAAA\",\"\"]Bc[\"AAAAAAABSQAAAAJTAQAAVAEAAA==\",\"\"]Ag[\"AAAClgIAABsDAAA=\",\"\"]Ak[\"AAAAAAAAAnYEAADLBgAA\",\"\"]Ak[\"AAAAAAAAAnkEAADOBgAA\",\"\"]Ag[\"AAAClQIAAB8DAAA=\",\"\"]Dk[\"AAAAAcoEAAAAAhMAAAD8BgAAAtEAAADSAAAA\",\"AAABQQIAAAHKBAAAAAAAAAAAAVEPAAA=\"]Dg[\"AAAAAccEAAAAAhAAAAD5BgAAAssAAADMAAAA\",\"AAABOgIAAAHHBAAAAAAAAAHCDwAA\"]Co[\"AAABGBIAAAEIBQAAAAFBAAAAAToBAAA=\",\"AAGXBwAAAQEJAAABCAUAAA==\"]Ec[\"AAAAAAABGRIAAAG1AAAAAAAAAAAAAAAAAAADbQQAAP4IAABVDwAA\",\"AAAAAaoBAAAAAAAAAUMTAAA=\"]Hk[\"AAAC0wIAAOsCAAABJgUAAAABVQAAAAJzAQAAdAEAAAAAAAAAAAAAAAAABAgCAABMBQAApgYAAOMGAAA=\",\"AAAB/wIAAALEAQAAJgUAAAAAAmMTAABkEwAAAAACPxEAAEARAAA=\"]Fc[\"AAAAAzgQAABOEAAAXxIAAAACbRIAAG8SAAADmAEAAFsTAABcEwAAAmYEAAC0CwAAAAAAAAABYQQAAA==\",\"AAAAAcwBAAA=\"]Dc[\"AAAAAmIAAADGBAAAAg8CAAC/CAAAAQ8AAAAByAAAAA==\",\"AAAAAsYEAADXDwAA\"]Eg[\"AAAAAeEEAAAAASMAAAAAAAL4AAAA+QAAAAAAAAAAAAAAAAPfBgAALw8AADYPAAA=\",\"AAABdAIAAAHhBAAA\"]Eg[\"AAAAARsFAAAAAU0AAAACWwEAAFwBAAAAAAAAAAAAAAAAAAPhBgAAMQ8AADcPAAA=\",\"AAAB6wIAAAEbBQAA\"]Hk[\"AAAFKgIAAD0CAAA+AgAASAIAAEoCAAAB1gQAAAACHwAAAP8GAAAAAALpAAAA6gAAAA==\",\"AAADYQIAAGMCAABkAgAAAtYEAACXBgAAAqUFAAAlEAAAAQoTAAABfA8AAAESEQAA\"]Ek[\"AAAAAQoFAAAAAkMAAAAABwAAAj0BAAA+AQAA\",\"AAAB0wIAAAEKBQAAAAAAAAAAAAAAAAAAAAACuwQAAOQGAAA=\"]Bk[\"AAAAAAABORAAAAFuAQAA\",\"AAAAAAAAAAE6EAAA\"]Fo[\"AAABjwAAAAHTBAAAAAG9DAAAAAAB5QAAAAAAAAAAAAAAAAYKBwAADgcAAAMJAAAHCQAAPw8AAEcQAAA=\",\"AAF+BwAAAALTBAAAaAUAAA==\"]Fo[\"AAAAApIAAAACBQAAAAHADAAAAS8BAAAAAAAAAAAAAAAAAAYMBwAAEAcAAAUJAAAJCQAAQQ8AAEkQAAA=\",\"AAGVBwAAAAECBQAAAWsFAAA=\"]Ag[\"AAACkwIAAB0DAAA=\",\"\"]Cg[\"AAAAAUAFAAAAAAADQg8AAKgPAABQEAAA\",\"AAGnBwAAAAFABQAA\"]Dc[\"AAAAAiAFAACqBwAAAAABaQEAAA==\",\"AAAAASAFAAAAAAAAAAAAAAAAAAGwBgAA\"]Dg[\"AAAAAfASAAAB2g8AAAAAAALrAAAADhEAAA==\",\"AAEMCQAAAa8BAAAB8BIAAAHaDwAA\"]Dg[\"AAAAAfESAAAB2w8AAAABRgEAAAABEBEAAA==\",\"AAENCQAAAb4BAAAB8RIAAAHbDwAA\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAATQPAAA=\",\"\"]Ac[\"\",\"AAAAAAHGEwAA\"]Ag[\"AAACkgIAACEDAAA=\",\"\"]Bc[\"\",\"AAAAAAAAAAADTBIAAE0SAABOEgAA\"]Bc[\"\",\"AAAAAAAAAAADTxIAAFASAABREgAA\"]Ak[\"\",\"AAAAAXESAAAAAAGREwAA\"]ADc[\"AAAAAdcEAAAAAAA6MAAAAQAAAAAAFAAQAAAAvwfBDEMPiw+OD8oPyRBCEVYRahLXEn4T1RPiE+4T8BMSFBYUGRQdFCQUOjAAAAEAAAAAAAwAEAAAAOwAWBDFEGASchJzEg0TORNME/oTCxQNFBsUAAABOxEAAA==\",\"AAGBBwAAAAHXBAAAAAAAOjAAAAEAAAAAABQAEAAAAL8HwQxDD4sPjg/KD8kQQhFWEWoS1xJ+E9UT4hPuE/ATEhQWFBkUHRQkFDowAAABAAAAAAAJABAAAABYEMUQYBINEzkTTBP6EwsUDRQbFAAAATsRAAA=\"]ADc[\"AAAAAQ4FAAAAAAFHAQAAOjAAAAEAAAAAABQAEAAAAMAHwgxED4wPjw/LD8oQQxFXEWsS2BJ/E9YT4xPvE/ETExQXFBoUHhQlFDowAAABAAAAAAALABAAAABZEMYQYRJ0EnUSDhM6E00T+xMMFA4UHBQAAAE8EQAA\",\"AAGZBwAAAAEOBQAAAAAAOjAAAAEAAAAAABQAEAAAAMAHwgxED4wPjw/LD8oQQxFXEWsS2BJ/E9YT4xPvE/ETExQXFBoUHhQlFDowAAABAAAAAAAJABAAAABZEMYQYRIOEzoTTRP7EwwUDhQcFAAAATwRAAA=\"]Ag[\"AAACbwIAAOMCAAA=\",\"\"]Bk[\"AAAAAAAAAAAAAU0EAAA=\",\"AAAAAAAAAQgMAAA=\"]Bk[\"AAAAAAAAAAAAAAEgDAAA\",\"AAAAAAABmxMAAA==\"]Do[\"AAAAAeIEAAAAASQAAAAAAAL6AAAA+wAAAAAAAAAAAAAAAALgBgAAMA8AAA==\",\"AAAAAeIEAAA=\"]Do[\"AAAAARwFAAAAAU4AAAACXQEAAF4BAAAAAAAAAAAAAAAAAALiBgAAMg8AAA==\",\"AAAAARwFAAA=\"]Ag[\"AAACmQIAABgDAAA=\",\"\"]Fc[\"AAAAAR4FAAAAAk8AAACiAAAAAmEBAAC5DwAAAk0DAAA6EAAA\",\"AAAAAR4FAAAAAAAAAAAAAAABbQcAAAAAAAABpwUAAA==\"]Ac[\"\",\"AAAAAAFuBwAA\"]Ao[\"AAAAAAGpBAAA\",\"AAAAAAFxBwAA\"]Ag[\"AAAClAIAABwDAAA=\",\"\"]Ag[\"AAACmwIAACADAAA=\",\"\"]Dg[\"AAAAAfIEAAAAAAAB5hIAAAAAAAHPEAAA\",\"AAAAAvIEAAA1CgAAATYKAAAAAWkQAAA=\"]Do[\"AAABzQEAAAEyBQAAAAAAAegSAAAAAAAB0xAAAA==\",\"AAAAATIFAAABpQoAAAGmCgAAAWsQAAA=\"]Do[\"AAAAAfQEAAAAAAADPhAAANAQAADnEgAAAAEuDAAA\",\"AAAAAvQEAAA6CgAAATgKAAAAAWoQAAA=\"]Eg[\"AAABzgEAAAE0BQAAAAAAA0IQAADUEAAA6RIAAAABMAwAAA==\",\"AAAAATQFAAABqwoAAAGqCgAAAWwQAAA=\"]Cc[\"AAAAAAAAAncEAADMBgAAAAEEAQAA\",\"AAGHBwAAAAG0AQAA\"]Cc[\"AAAAAAAAA3kBAAB6BAAAzwYAAA==\",\"AAGgBwAAAAHGAQAA\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA94GAACwBwAAzgcAAA==\",\"\"]Bg[\"AAAAAAAAAAAAAAAAAAAAAAAAATMPAAA=\",\"\"]Ao[\"AAAAAAAAAawEAAAAAQsUAAA=\",\"\"]Bk[\"AAAAAAAAAbAEAAAAAQwUAAA=\",\"AAAAAbQEAAA=\"]Eg[\"AAAAAAAAAAABEQEAAAAAAAAAAAAAAANBCQAAqQ8AAJkSAAA=\",\"AAGLBwAAAAS3BwAAuAcAALkHAAC6BwAA\"]Eg[\"AAAAAAAAAZQBAAAAAAAAAAAAAAAAAANCCQAAqg8AAJoSAAA=\",\"AAGkBwAAAAS7BwAAvAcAAL0HAAC+BwAA\"]Bo[\"AAAAAAABsQEAAAAAAXYMAAAAAWIEAAAAAUIEAAA=\",\"\"]Bo[\"AAAAAAABwAEAAAAAAXcMAAAAAWMEAAAAAUQEAAA=\",\"\"]Ak[\"AAAAAAABCxMAAAFyEwAA\",\"\"]Ao[\"AAAAAAABDBMAAAAAAXMTAAA=\",\"\"]Fo[\"AAAAASMFAAAAAlIAAACjAAAAA2wBAABtAQAAug8AAAFOAwAA\",\"AAAB+gIAAAEjBQAAAAAAAAJTBQAAVAUAAAAAAAAAAALCAQAAsAYAAA==\"]Dg[\"AAAAAfwEAAAAATUAAAABJwEAAA==\",\"AAAAAfwEAAAAAAAAAAAAAAAAAAAAAAHlBgAA\"]Dg[\"AAAAAcEEAAAAAgwAAAD4BgAAArsAAAC8AAAA\",\"AAABKgIAAAHBBAAAAAAByBAAAA==\"]Do[\"AAAAAfcEAAAAAjEAAACcAAAAAyABAAAhAQAAsw8AAAFHAwAA\",\"AAAAAfcEAAAAAAAAAWUEAAA=\"]Ek[\"AAAAAdgEAAAAAAACVBMAAKgTAAAD7QAAAKwQAAA5EwAA\",\"AAGCBwAAAAHYBAAAAAAAAlQTAACoEwAAAawQAAA=\"]Ek[\"AAAAAQ8FAAAAAAFIAQAAAlUTAACpEwAAAq0QAAA6EwAA\",\"AAGaBwAAAAEPBQAAAAAAAlUTAACpEwAAAa0QAAA=\"]Bo[\"AAAAAAAAAAABUwUAAAAAAAAAAALCAQAAsAYAAA==\",\"\"]Fg[\"AAAAAdkEAAAAAAAEIAkAANQPAAAzEQAABBMAAALuAAAATBMAAA==\",\"AAGDBwAAAAHZBAAAAAAABCAJAADUDwAAMxEAAAQTAAA=\"]Fg[\"AAAAARAFAAAAAAFJAQAABCEJAADVDwAANBEAAAUTAAABTRMAAA==\",\"AAGbBwAAAAEQBQAAAAAABCEJAADVDwAANBEAAAUTAAA=\"]Ag[\"\",\"AAAAAAAAAdcTAAA=\"]Bc[\"\",\"AAAAAAAAAAAAAAAAAAAAAAHvEgAA\"]Ag[\"\",\"AAAAAAAAAVIPAAA=\"]Co[\"AAAAAf0EAAAAATYAAAACKAEAACkBAAA=\",\"AAAAAf0EAAAAAAAAARUSAAA=\"]Fg[\"AAABVAIAAAHmBAAAAAEoAAAAAAG4BgAAAgEBAAACAQAA\",\"AAACewIAAJ8GAAAB5gQAAAAAAAGqBgAAAAAAAAAAAAAAAAEvDwAA\"]Gc[\"AAABugIAAALEAQAAJwUAAAABVgAAAAJ1AQAAdgEAAAG/BgAA\",\"AAACAQMAAKMGAAABJwUAAAAAAbEGAAAAAAAAAAAAAAAAAAIIAgAAMQ8AAA==\"]Cc[\"AAAAAAAAAAAAAAAAAAAAAAAAA6wHAADLBwAAwwgAAA==\",\"\"]Cg[\"AAABdgIAAAAAAAAAARQBAAA=\",\"AAAAAAAAAAI8EAAAPhAAAA==\"]Cg[\"AAAB8QIAAAAAAAGJAQAA\",\"AAAAAAAAAANAEAAAQhAAAEMQAAA=\"]Bo[\"AAAAArQEAAA/BQAAAaQSAAA=\",\"AAAAAj8FAABZEQAA\"]Bo[\"AAAAAAAAAcIAAAAAAAABIgwAAA==\",\"AAAAAXoTAAA=\"]Io[\"AAAAAS8FAAAAAVwAAAABhAEAAAZ1BQAAzhAAANAQAADSEAAA1BAAANYQAAAAAAAFzRAAAM8QAADREAAA0xAAANUQAAAAAAAAAAABIxQAAA==\",\"AAAAAS8FAAAAAARgEwAAYRMAAGMTAABkEwAAAAFeBAAA\"]Co[\"AAAAAmQAAAC2BwAAAAABygAAAAJzBAAARhEAAAFQDwAA\",\"AAABKREAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhUJAAAwEAAA\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhcJAAAyEAAA\",\"\"]Co[\"AAAAAfMEAAAAAAAAAhcBAAAYAQAA\",\"AAAAAfMEAAAAAAJpEAAAahAAAA==\"]Dc[\"AAAAATMFAAAAAAKMAQAAjQEAAA==\",\"AAAAAjMFAABSEgAAAAACaxAAAGwQAAA=\"]Cc[\"AAAAAAGcAQAAAAG3AAAAAAAAAR8MAAA=\",\"AAAAAZoTAAA=\"]Ac[\"\",\"AAAB8wsAAA==\"]Ec[\"AAABcQIAAAHOBAAAAAEXAAAAAAAC3QAAAN4AAAA=\",\"AAAAAc4EAAAEEwkAAP4JAAD/CQAAAQoAAA==\"]Do[\"AAAB5AIAAAH2BAAAAAEvAAAAAh0BAAAeAQAA\",\"AAAAAfYEAAAEFAkAAFAKAABRCgAAUgoAAA==\"]Ak[\"\",\"AAAAAAACoBMAAKETAAA=\"]Ck[\"AAAAAsAEAAAqCQAAAb4IAAAB3BIAAAG6AAAA\",\"AAAAAsAEAADWDwAA\"]Cg[\"AAAAAU0HAAACIRAAADQQAAAAAbULAAAAAAAAAAABohAAAA==\",\"\"]Ck[\"AAAAAU4HAAACIhAAADUQAAAAArYLAAC3CwAAAAAAAAAAAaMQAAA=\",\"\"]Bc[\"AAAAAAAAAAAAAAAAAp4TAACfEwAA\",\"\"]Fo[\"AAAAAd0EAAAAAAADZwQAACsJAAC4EwAAAvIAAACmAQAA\",\"AAGGBwAAAAHdBAAAAAAAAmcEAAArCQAAAaYBAAAAAAAAAAAAAAABdhIAAA==\"]Fo[\"AAAAARQFAAAAAAFNAQAAA2gEAAAsCQAAuRMAAAGnAQAA\",\"AAGeBwAAAAEUBQAAAAAAAmgEAAAsCQAAAacBAAAAAAAAAAAAAAABdxIAAA==\"]Ck[\"AAAAAQ0FAAAAAAJDAQAARAEAAA==\",\"AAAAAQ0FAAAAAAAAAcUTAAA=\"]Ec[\"AAAAASEFAAAAAAFqAQAAAAAAAAAAAAAAAAAFowEAAKsHAADKBwAAwggAAHgMAAA=\",\"AAAAASEFAAA=\"]Dg[\"AAAAAAHGEwAAAAG2AAAAAAAAAAACnhMAAJ8TAAAAAAAB7xIAAA==\",\"AAABqwEAAA==\"]Ag[\"AAACnQIAACMDAAA=\",\"\"]Bc[\"\",\"AAAAAAAAAAAAAAAAAp4TAACfEwAA\"]Cc[\"AAAAAUEFAAAAAAAAAAAAAdUQAAA=\",\"AAABzQEAAAFBBQAA\"]Ck[\"AAAAAUIFAAAAAAACQxAAANYQAAAAATEMAAA=\",\"AAABzgEAAAFCBQAA\"]Ag[\"AAACmgIAABkDAAA=\",\"\"]Dg[\"AAAAAAABLAAAAAAAARIBAAA=\",\"AAAAAAAAAAAAAAAAAAAAA5ITAACTEwAAlBMAAA==\"]Ck[\"AAAAAAABXgAAAAGHAQAA\",\"AAAAAAAAAAAAAAAAAAAAApUTAACWEwAA\"]Ag[\"AAACnAIAAB4DAAA=\",\"\"]Do[\"AAAAAU8HAAACIxAAADYQAAAAAbgLAAABYRAAAA==\",\"AAK9AQAAjQcAAAEOCQAAAAAAAAFhEAAA\"]Ec[\"AAAAAikFAABQBwAAAiQQAAA3EAAAAAF4AQAAAWIQAAA=\",\"AAGfBwAAAcUBAAABKQUAAAAAAAFiEAAA\"]Bg[\"AAAAAAAAAAABVAUAAA==\",\"AAABvAEAAA==\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhYJAAAxEAAA\",\"\"]Bk[\"AAAAAAAAAAAAAAAAAAAAAAAAAhgJAAAzEAAA\",\"\"]") \ No newline at end of file diff --git a/pr/580/docs/settings.html b/pr/580/docs/settings.html index abf467830..eb1ebf9ed 100644 --- a/pr/580/docs/settings.html +++ b/pr/580/docs/settings.html @@ -1 +1 @@ -Settings

All

Rustdoc settings

Back
\ No newline at end of file +Settings

All

Rustdoc settings

Back
\ No newline at end of file diff --git a/pr/580/docs/src/noq_proto/connection/mod.rs.html b/pr/580/docs/src/noq_proto/connection/mod.rs.html index 7a3198e56..d16914091 100644 --- a/pr/580/docs/src/noq_proto/connection/mod.rs.html +++ b/pr/580/docs/src/noq_proto/connection/mod.rs.html @@ -1035,6610 +1035,6616 @@ 1035 // Check whether we need to send a close message 1036 let connection_close_pending = match self.state.as_type() { 1037 StateType::Drained => { -1038 return None; -1039 } -1040 StateType::Draining | StateType::Closed => { -1041 // self.connection_close_pending is only reset once the associated packet -1042 // had been encoded successfully -1043 if !self.connection_close_pending { -1044 return None; -1045 } -1046 true -1047 } -1048 _ => false, -1049 }; -1050 -1051 // Schedule an ACK_FREQUENCY frame if a new one needs to be sent. -1052 if let Some(config) = &self.config.ack_frequency_config { -1053 let rtt = self -1054 .paths -1055 .values() -1056 .map(|p| p.data.rtt.get()) -1057 .min() -1058 .expect("one path exists"); -1059 self.spaces[SpaceId::Data].pending.ack_frequency = self -1060 .ack_frequency -1061 .should_send_ack_frequency(rtt, config, &self.peer_params) -1062 && self.highest_space == SpaceKind::Data -1063 && self.peer_supports_ack_frequency(); -1064 } -1065 -1066 let mut next_path_id = self.paths.first_entry().map(|e| *e.key()); -1067 while let Some(path_id) = next_path_id { -1068 if !connection_close_pending -1069 && let Some(transmit) = self.poll_transmit_off_path(now, buf, path_id) -1070 { -1071 return Some(transmit); -1072 } -1073 -1074 let info = self.scheduling_info(path_id); -1075 if let Some(transmit) = self.poll_transmit_on_path( -1076 now, -1077 buf, -1078 path_id, -1079 max_datagrams, -1080 &info, -1081 connection_close_pending, -1082 ) { -1083 return Some(transmit); -1084 } -1085 -1086 // Continue checking other paths, tail-loss probes may need to be sent -1087 // in all spaces. -1088 debug_assert!( -1089 buf.is_empty(), -1090 "nothing to send on path but buffer not empty" -1091 ); -1092 -1093 next_path_id = self.paths.keys().find(|i| **i > path_id).copied(); -1094 } -1095 -1096 // We didn't produce any application data packet -1097 debug_assert!( -1098 buf.is_empty(), -1099 "there was data in the buffer, but it was not sent" -1100 ); +1038 for path in self.paths.values_mut() { +1039 path.data.app_limited = true; +1040 } +1041 return None; +1042 } +1043 StateType::Draining | StateType::Closed => { +1044 // self.connection_close_pending is only reset once the associated packet +1045 // had been encoded successfully +1046 if !self.connection_close_pending { +1047 for path in self.paths.values_mut() { +1048 path.data.app_limited = true; +1049 } +1050 return None; +1051 } +1052 true +1053 } +1054 _ => false, +1055 }; +1056 +1057 // Schedule an ACK_FREQUENCY frame if a new one needs to be sent. +1058 if let Some(config) = &self.config.ack_frequency_config { +1059 let rtt = self +1060 .paths +1061 .values() +1062 .map(|p| p.data.rtt.get()) +1063 .min() +1064 .expect("one path exists"); +1065 self.spaces[SpaceId::Data].pending.ack_frequency = self +1066 .ack_frequency +1067 .should_send_ack_frequency(rtt, config, &self.peer_params) +1068 && self.highest_space == SpaceKind::Data +1069 && self.peer_supports_ack_frequency(); +1070 } +1071 +1072 let mut next_path_id = self.paths.first_entry().map(|e| *e.key()); +1073 while let Some(path_id) = next_path_id { +1074 if !connection_close_pending +1075 && let Some(transmit) = self.poll_transmit_off_path(now, buf, path_id) +1076 { +1077 return Some(transmit); +1078 } +1079 +1080 let info = self.scheduling_info(path_id); +1081 if let Some(transmit) = self.poll_transmit_on_path( +1082 now, +1083 buf, +1084 path_id, +1085 max_datagrams, +1086 &info, +1087 connection_close_pending, +1088 ) { +1089 return Some(transmit); +1090 } +1091 +1092 // Continue checking other paths, tail-loss probes may need to be sent +1093 // in all spaces. +1094 debug_assert!( +1095 buf.is_empty(), +1096 "nothing to send on path but buffer not empty" +1097 ); +1098 +1099 next_path_id = self.paths.keys().find(|i| **i > path_id).copied(); +1100 } 1101 -1102 if self.state.is_established() { -1103 // Try MTU probing now -1104 let mut next_path_id = self.paths.first_entry().map(|e| *e.key()); -1105 while let Some(path_id) = next_path_id { -1106 if let Some(transmit) = self.poll_transmit_mtu_probe(now, buf, path_id) { -1107 return Some(transmit); -1108 } -1109 next_path_id = self.paths.keys().find(|i| **i > path_id).copied(); -1110 } -1111 } -1112 -1113 None -1114 } -1115 -1116 /// Computes the packet scheduling information for this path. -1117 /// -1118 /// While this information is only returned for a single path, it is important to know -1119 /// that this information remains static for the entire span of a single -1120 /// [`Connection::poll_transmit`] call. In other words, the return value is purely -1121 /// functional and only depends on the [`PathId`] **during a single** `poll_transmit` -1122 /// call. It can be computed up-front for all paths but we don't do that because it -1123 /// involves an allocation. -1124 /// -1125 /// See the inline comments for how the packet scheduling works. -1126 /// -1127 /// # Panics -1128 /// -1129 /// This will panic if called for a path for which we do not have any [`PathData`], like -1130 /// so many other functions we have. But this is the only one to document this in its -1131 /// doc comment. Maybe that should change. Eventually we'll refactor things for this -1132 /// panic to go away. -1133 fn scheduling_info(&self, path_id: PathId) -> PathSchedulingInfo { -1134 // Such a space is preferred for SpaceKind::Data frames. -1135 let have_validated_status_available_space = self.paths.iter().any(|(path_id, path)| { -1136 self.remote_cids.contains_key(path_id) -1137 && !self.abandoned_paths.contains(path_id) -1138 && path.data.validated -1139 && path.data.local_status() == PathStatus::Available -1140 }); -1141 -1142 // Such a space is able to send SpaceKind::Data frames. -1143 let have_validated_space = self.paths.iter().any(|(path_id, path)| { -1144 self.remote_cids.contains_key(path_id) -1145 && !self.abandoned_paths.contains(path_id) -1146 && path.data.validated -1147 }); -1148 -1149 let is_handshaking = self.is_handshaking(); -1150 let has_cids = self.remote_cids.contains_key(&path_id); -1151 let is_abandoned = self.abandoned_paths.contains(&path_id); -1152 let path_data = self.path_data(path_id); -1153 let validated = path_data.validated; -1154 let status = path_data.local_status(); -1155 -1156 // This is the core packet scheduling, whether this space ID may send -1157 // SpaceKind::Data frames. -1158 let may_send_data = has_cids -1159 && !is_abandoned -1160 && if is_handshaking { -1161 // There is only one path during the handshake. We want to -1162 // already send 0-RTT and 0.5-RTT (permitting anti-amplification -1163 // limit) data. -1164 true -1165 } else if !validated { -1166 // TODO(flub): When we have a network change we might end up -1167 // having to abandon all paths and re-open new ones to the -1168 // same remotes. This leaves us without any validated -1169 // path. Perhaps we should have a way to figure out if the -1170 // path is to a previously-validated remote address and allow -1171 // sending data to such remotes immediately. -1172 false -1173 } else { -1174 match status { -1175 PathStatus::Available => { -1176 // Best possible space to send data on. -1177 true -1178 } -1179 PathStatus::Backup => { -1180 // If there is a status-available path we prefer that. -1181 !have_validated_status_available_space -1182 } -1183 } -1184 }; -1185 -1186 // CONNECTION_CLOSE is allowed to be sent on a non-validated -1187 // path. Particularly during the handshake we want to send it before the -1188 // path is validated. Later if there is no validated path available we -1189 // will also accept sending it on an un-validated path. -1190 let may_send_close = has_cids -1191 && !is_abandoned -1192 && if !validated && have_validated_status_available_space { -1193 // We have a better space to send on. -1194 false -1195 } else { -1196 // No other validated space, this is as good as it gets. -1197 true -1198 }; -1199 -1200 // PATH_ABANDON is normally sent together with other SpaceKind::Data frames. But if -1201 // there is no other validated space to send it on, it can be sent on the path to be -1202 // abandoned itself if that was validated. -1203 let may_self_abandon = has_cids && validated && !have_validated_space; -1204 -1205 PathSchedulingInfo { -1206 is_abandoned, -1207 may_send_data, -1208 may_send_close, -1209 may_self_abandon, -1210 } -1211 } -1212 -1213 fn build_transmit(&mut self, path_id: PathId, transmit: TransmitBuf<'_>) -> Transmit { -1214 debug_assert!( -1215 !transmit.is_empty(), -1216 "must not be called with an empty transmit buffer" -1217 ); +1102 // We didn't produce any application data packet +1103 debug_assert!( +1104 buf.is_empty(), +1105 "there was data in the buffer, but it was not sent" +1106 ); +1107 +1108 if self.state.is_established() { +1109 // Try MTU probing now +1110 let mut next_path_id = self.paths.first_entry().map(|e| *e.key()); +1111 while let Some(path_id) = next_path_id { +1112 if let Some(transmit) = self.poll_transmit_mtu_probe(now, buf, path_id) { +1113 return Some(transmit); +1114 } +1115 next_path_id = self.paths.keys().find(|i| **i > path_id).copied(); +1116 } +1117 } +1118 +1119 None +1120 } +1121 +1122 /// Computes the packet scheduling information for this path. +1123 /// +1124 /// While this information is only returned for a single path, it is important to know +1125 /// that this information remains static for the entire span of a single +1126 /// [`Connection::poll_transmit`] call. In other words, the return value is purely +1127 /// functional and only depends on the [`PathId`] **during a single** `poll_transmit` +1128 /// call. It can be computed up-front for all paths but we don't do that because it +1129 /// involves an allocation. +1130 /// +1131 /// See the inline comments for how the packet scheduling works. +1132 /// +1133 /// # Panics +1134 /// +1135 /// This will panic if called for a path for which we do not have any [`PathData`], like +1136 /// so many other functions we have. But this is the only one to document this in its +1137 /// doc comment. Maybe that should change. Eventually we'll refactor things for this +1138 /// panic to go away. +1139 fn scheduling_info(&self, path_id: PathId) -> PathSchedulingInfo { +1140 // Such a space is preferred for SpaceKind::Data frames. +1141 let have_validated_status_available_space = self.paths.iter().any(|(path_id, path)| { +1142 self.remote_cids.contains_key(path_id) +1143 && !self.abandoned_paths.contains(path_id) +1144 && path.data.validated +1145 && path.data.local_status() == PathStatus::Available +1146 }); +1147 +1148 // Such a space is able to send SpaceKind::Data frames. +1149 let have_validated_space = self.paths.iter().any(|(path_id, path)| { +1150 self.remote_cids.contains_key(path_id) +1151 && !self.abandoned_paths.contains(path_id) +1152 && path.data.validated +1153 }); +1154 +1155 let is_handshaking = self.is_handshaking(); +1156 let has_cids = self.remote_cids.contains_key(&path_id); +1157 let is_abandoned = self.abandoned_paths.contains(&path_id); +1158 let path_data = self.path_data(path_id); +1159 let validated = path_data.validated; +1160 let status = path_data.local_status(); +1161 +1162 // This is the core packet scheduling, whether this space ID may send +1163 // SpaceKind::Data frames. +1164 let may_send_data = has_cids +1165 && !is_abandoned +1166 && if is_handshaking { +1167 // There is only one path during the handshake. We want to +1168 // already send 0-RTT and 0.5-RTT (permitting anti-amplification +1169 // limit) data. +1170 true +1171 } else if !validated { +1172 // TODO(flub): When we have a network change we might end up +1173 // having to abandon all paths and re-open new ones to the +1174 // same remotes. This leaves us without any validated +1175 // path. Perhaps we should have a way to figure out if the +1176 // path is to a previously-validated remote address and allow +1177 // sending data to such remotes immediately. +1178 false +1179 } else { +1180 match status { +1181 PathStatus::Available => { +1182 // Best possible space to send data on. +1183 true +1184 } +1185 PathStatus::Backup => { +1186 // If there is a status-available path we prefer that. +1187 !have_validated_status_available_space +1188 } +1189 } +1190 }; +1191 +1192 // CONNECTION_CLOSE is allowed to be sent on a non-validated +1193 // path. Particularly during the handshake we want to send it before the +1194 // path is validated. Later if there is no validated path available we +1195 // will also accept sending it on an un-validated path. +1196 let may_send_close = has_cids +1197 && !is_abandoned +1198 && if !validated && have_validated_status_available_space { +1199 // We have a better space to send on. +1200 false +1201 } else { +1202 // No other validated space, this is as good as it gets. +1203 true +1204 }; +1205 +1206 // PATH_ABANDON is normally sent together with other SpaceKind::Data frames. But if +1207 // there is no other validated space to send it on, it can be sent on the path to be +1208 // abandoned itself if that was validated. +1209 let may_self_abandon = has_cids && validated && !have_validated_space; +1210 +1211 PathSchedulingInfo { +1212 is_abandoned, +1213 may_send_data, +1214 may_send_close, +1215 may_self_abandon, +1216 } +1217 } 1218 -1219 let network_path = self.path_data(path_id).network_path; -1220 trace!( -1221 segment_size = transmit.segment_size(), -1222 last_datagram_len = transmit.len() % transmit.segment_size(), -1223 %network_path, -1224 "sending {} bytes in {} datagrams", -1225 transmit.len(), -1226 transmit.num_datagrams() -1227 ); -1228 self.path_data_mut(path_id) -1229 .inc_total_sent(transmit.len() as u64); -1230 -1231 self.path_stats -1232 .for_path(path_id) -1233 .udp_tx -1234 .on_sent(transmit.num_datagrams() as u64, transmit.len()); -1235 -1236 Transmit { -1237 destination: network_path.remote, -1238 size: transmit.len(), -1239 ecn: if self.path_data(path_id).sending_ecn { -1240 Some(EcnCodepoint::Ect0) -1241 } else { -1242 None -1243 }, -1244 segment_size: match transmit.num_datagrams() { -1245 1 => None, -1246 _ => Some(transmit.segment_size()), -1247 }, -1248 src_ip: network_path.local_ip, -1249 } -1250 } -1251 -1252 /// poll_transmit logic for off-path data. -1253 fn poll_transmit_off_path( -1254 &mut self, -1255 now: Instant, -1256 buf: &mut Vec<u8>, -1257 path_id: PathId, -1258 ) -> Option<Transmit> { -1259 if let Some(challenge) = self.send_prev_path_challenge(now, buf, path_id) { -1260 return Some(challenge); -1261 } -1262 if let Some(response) = self.send_off_path_path_response(now, buf, path_id) { -1263 return Some(response); -1264 } -1265 if let Some(challenge) = self.send_nat_traversal_path_challenge(now, buf, path_id) { +1219 fn build_transmit(&mut self, path_id: PathId, transmit: TransmitBuf<'_>) -> Transmit { +1220 debug_assert!( +1221 !transmit.is_empty(), +1222 "must not be called with an empty transmit buffer" +1223 ); +1224 +1225 let network_path = self.path_data(path_id).network_path; +1226 trace!( +1227 segment_size = transmit.segment_size(), +1228 last_datagram_len = transmit.len() % transmit.segment_size(), +1229 %network_path, +1230 "sending {} bytes in {} datagrams", +1231 transmit.len(), +1232 transmit.num_datagrams() +1233 ); +1234 self.path_data_mut(path_id) +1235 .inc_total_sent(transmit.len() as u64); +1236 +1237 self.path_stats +1238 .for_path(path_id) +1239 .udp_tx +1240 .on_sent(transmit.num_datagrams() as u64, transmit.len()); +1241 +1242 Transmit { +1243 destination: network_path.remote, +1244 size: transmit.len(), +1245 ecn: if self.path_data(path_id).sending_ecn { +1246 Some(EcnCodepoint::Ect0) +1247 } else { +1248 None +1249 }, +1250 segment_size: match transmit.num_datagrams() { +1251 1 => None, +1252 _ => Some(transmit.segment_size()), +1253 }, +1254 src_ip: network_path.local_ip, +1255 } +1256 } +1257 +1258 /// poll_transmit logic for off-path data. +1259 fn poll_transmit_off_path( +1260 &mut self, +1261 now: Instant, +1262 buf: &mut Vec<u8>, +1263 path_id: PathId, +1264 ) -> Option<Transmit> { +1265 if let Some(challenge) = self.send_prev_path_challenge(now, buf, path_id) { 1266 return Some(challenge); 1267 } -1268 None -1269 } -1270 -1271 /// poll_transmit logic for on-path data. -1272 /// -1273 /// This is not quite the same as for a multipath packet space, since [`PathId::ZERO`] -1274 /// has 3 packet spaces, which this handles. -1275 /// -1276 /// See [`Self::poll_transmit_off_path`] for off-path data. -1277 #[must_use] -1278 fn poll_transmit_on_path( -1279 &mut self, -1280 now: Instant, -1281 buf: &mut Vec<u8>, -1282 path_id: PathId, -1283 max_datagrams: NonZeroUsize, -1284 scheduling_info: &PathSchedulingInfo, -1285 connection_close_pending: bool, -1286 ) -> Option<Transmit> { -1287 // Check if there is at least one active CID to use for sending -1288 let Some(remote_cid) = self.remote_cids.get(&path_id).map(CidQueue::active) else { -1289 if !self.abandoned_paths.contains(&path_id) { -1290 debug!(%path_id, "no remote CIDs for path"); -1291 } -1292 return None; -1293 }; -1294 -1295 // Whether the last packet in the datagram must be padded so the datagram takes up -1296 // an exact size. An earlier space can decide to not fill an entire datagram and -1297 // require the next space to fill it further. But may need a specific size of the -1298 // datagram containing the packet. The final packet built in the datagram must pad -1299 // to this size. -1300 let mut pad_datagram = PadDatagram::No; -1301 -1302 // The packet number of the last built packet. This is kept kept across spaces. -1303 // QUIC is supposed to have a single congestion controller for the Initial, -1304 // Handshake and Data(PathId::ZERO) spaces. -1305 let mut last_packet_number = None; -1306 -1307 // If we end up not sending anything, we need to know if that was because there was -1308 // nothing to send or because we were congestion blocked. -1309 let mut congestion_blocked = false; -1310 -1311 // Set the segment size to this path's MTU for on-path data. -1312 let pmtu = self.path_data(path_id).current_mtu().into(); -1313 let mut transmit = TransmitBuf::new(buf, max_datagrams, pmtu); -1314 -1315 // Iterate over the available spaces. -1316 for space_id in SpaceId::iter() { -1317 // Only PathId::ZERO uses non Data space ids. -1318 if path_id != PathId::ZERO && space_id != SpaceId::Data { -1319 continue; -1320 } -1321 match self.poll_transmit_path_space( -1322 now, -1323 &mut transmit, -1324 path_id, -1325 space_id, -1326 remote_cid, -1327 scheduling_info, -1328 connection_close_pending, -1329 pad_datagram, -1330 ) { -1331 PollPathSpaceStatus::NothingToSend { -1332 congestion_blocked: cb, -1333 } => { -1334 congestion_blocked |= cb; -1335 // Continue checking other spaces, tail-loss probes may need to be sent -1336 // in all spaces. -1337 } -1338 PollPathSpaceStatus::WrotePacket { -1339 last_packet_number: pn, -1340 pad_datagram: pad, -1341 } => { -1342 debug_assert!(!transmit.is_empty(), "transmit must contain packets"); -1343 last_packet_number = Some(pn); -1344 pad_datagram = pad; -1345 // Always check higher spaces. If the transmit is full or they have -1346 // nothing to send they will not write packets. But if they can, they -1347 // must always be allowed to add to this transmit because coalescing may -1348 // be required. -1349 continue; -1350 } -1351 PollPathSpaceStatus::Send { -1352 last_packet_number: pn, -1353 } => { -1354 debug_assert!(!transmit.is_empty(), "transmit must contain packets"); -1355 last_packet_number = Some(pn); -1356 break; -1357 } -1358 } -1359 } -1360 -1361 if last_packet_number.is_some() || congestion_blocked { -1362 self.qlog.emit_recovery_metrics( -1363 path_id, -1364 &mut self.paths.get_mut(&path_id).unwrap().data, -1365 now, -1366 ); -1367 } -1368 -1369 self.path_data_mut(path_id).app_limited = -1370 last_packet_number.is_none() && !congestion_blocked; -1371 -1372 match last_packet_number { -1373 Some(last_packet_number) => { -1374 // Note that when sending in multiple spaces the last packet number will be -1375 // the one from the highest space. -1376 self.path_data_mut(path_id).congestion.on_sent( -1377 now, -1378 transmit.len() as u64, -1379 last_packet_number, -1380 ); -1381 Some(self.build_transmit(path_id, transmit)) -1382 } -1383 None => None, -1384 } -1385 } -1386 -1387 /// poll_transmit logic for a QUIC-MULTIPATH packet number space (PathID + SpaceId). -1388 #[must_use] -1389 fn poll_transmit_path_space( -1390 &mut self, -1391 now: Instant, -1392 transmit: &mut TransmitBuf<'_>, -1393 path_id: PathId, -1394 space_id: SpaceId, -1395 remote_cid: ConnectionId, -1396 scheduling_info: &PathSchedulingInfo, -1397 // If we need to send a CONNECTION_CLOSE frame. -1398 connection_close_pending: bool, -1399 // Whether the current datagram needs to be padded to a certain size. -1400 mut pad_datagram: PadDatagram, -1401 ) -> PollPathSpaceStatus { -1402 // Keep track of the last packet number we wrote. If None we did not write any -1403 // packets. -1404 let mut last_packet_number = None; -1405 -1406 // Each loop of this may build one packet. It works logically as follows: -1407 // -1408 // - Check if something *needs* to be sent in this space and *can* be sent. -1409 // - If not, return to the caller who will call us again for the next space. -1410 // - Start a new datagram. -1411 // - Unless coalescing the packet into an existing datagram. -1412 // - Write the packet header and payload. -1413 // - Check if coalescing a next packet into the datagram is possible. -1414 // - If coalescing, finish packet without padding to leave space in the datagram. -1415 // - If not coalescing, complete the datagram: -1416 // - Finish packet with padding. -1417 // - Set the transmit segment size if this is the first datagram. -1418 // - Loop: next iteration will exit the loop if nothing more to send in this -1419 // space. The TransmitBuf will contain a started datagram with space if -1420 // coalescing, or completely filled datagram if not coalescing. -1421 loop { -1422 // Determine if anything can be sent in this packet number space. -1423 let max_packet_size = if transmit.datagram_remaining_mut() > 0 { -1424 // A datagram is started already, we are coalescing another packet into it. -1425 transmit.datagram_remaining_mut() -1426 } else { -1427 // A new datagram needs to be started. -1428 transmit.segment_size() -1429 }; -1430 let can_send = -1431 self.space_can_send(space_id, path_id, max_packet_size, connection_close_pending); -1432 let needs_loss_probe = self.spaces[space_id].for_path(path_id).loss_probes > 0; -1433 let space_will_send = { -1434 if scheduling_info.is_abandoned { -1435 // If this path is abandoned then we might still have to send -1436 // PATH_ABANDON itself on it if there was no better space -1437 // available. Otherwise we want to send the PATH_ABANDON as permitted by -1438 // may_send_data however. -1439 scheduling_info.may_self_abandon -1440 && self.spaces[space_id] -1441 .pending -1442 .path_abandon -1443 .contains_key(&path_id) -1444 } else if can_send.close && scheduling_info.may_send_close { -1445 // This is the best path to send a CONNECTION_CLOSE on. -1446 true -1447 } else if needs_loss_probe || can_send.space_specific { -1448 // We always send a loss probe or space-specific frames if the path is -1449 // not abandoned. -1450 true -1451 } else { -1452 // Anything else we only send if we're the best path for SpaceKind::Data -1453 // frames. -1454 !can_send.is_empty() && scheduling_info.may_send_data -1455 } -1456 }; -1457 -1458 if !space_will_send { -1459 // Nothing more to send. Previous iterations of this loop may have built -1460 // packets already. -1461 return match last_packet_number { -1462 Some(pn) => PollPathSpaceStatus::WrotePacket { -1463 last_packet_number: pn, -1464 pad_datagram, -1465 }, -1466 None => { -1467 // Only log for spaces which have crypto. -1468 if self.crypto_state.has_keys(space_id.encryption_level()) -1469 || (space_id == SpaceId::Data -1470 && self.crypto_state.has_keys(EncryptionLevel::ZeroRtt)) -1471 { -1472 trace!(?space_id, %path_id, "nothing to send in space"); -1473 } -1474 PollPathSpaceStatus::NothingToSend { -1475 congestion_blocked: false, -1476 } -1477 } -1478 }; -1479 } -1480 -1481 // We want to send on this space, check congestion control if we can. But only -1482 // if we will need to start a new datagram. If we are coalescing into an already -1483 // started datagram we do not need to check congestion control again. -1484 if transmit.datagram_remaining_mut() == 0 { -1485 let congestion_blocked = -1486 self.path_congestion_check(space_id, path_id, transmit, &can_send, now); -1487 if congestion_blocked != PathBlocked::No { -1488 // Previous iterations of this loop may have built packets already. -1489 return match last_packet_number { -1490 Some(pn) => PollPathSpaceStatus::WrotePacket { -1491 last_packet_number: pn, -1492 pad_datagram, -1493 }, -1494 None => { -1495 return PollPathSpaceStatus::NothingToSend { -1496 congestion_blocked: true, -1497 }; -1498 } -1499 }; -1500 } -1501 -1502 // If the datagram is full (or there never was one started), we need to start a -1503 // new one. -1504 if transmit.num_datagrams() >= transmit.max_datagrams().get() { -1505 // No more datagrams allowed. -1506 // Previous iterations of this loop may have built packets already. -1507 return match last_packet_number { -1508 Some(pn) => PollPathSpaceStatus::WrotePacket { -1509 last_packet_number: pn, -1510 pad_datagram, -1511 }, -1512 None => { -1513 return PollPathSpaceStatus::NothingToSend { -1514 congestion_blocked: false, -1515 }; -1516 } -1517 }; -1518 } -1519 -1520 if needs_loss_probe { -1521 // Ensure we have something to send for a tail-loss probe. -1522 let request_immediate_ack = -1523 space_id == SpaceId::Data && self.peer_supports_ack_frequency(); -1524 self.spaces[space_id].queue_tail_loss_probe( -1525 path_id, -1526 request_immediate_ack, -1527 &self.streams, -1528 ); -1529 -1530 self.spaces[space_id].for_path(path_id).loss_probes -= 1; // needs_loss_probe ensures loss_probes > 0 -1531 -1532 // Clamp the datagram to at most the minimum MTU to ensure that loss -1533 // probes can get through and enable recovery even if the path MTU -1534 // has shrank unexpectedly. -1535 transmit.start_new_datagram_with_size(std::cmp::min( -1536 usize::from(INITIAL_MTU), -1537 transmit.segment_size(), -1538 )); -1539 } else { -1540 transmit.start_new_datagram(); -1541 } -1542 trace!(count = transmit.num_datagrams(), "new datagram started"); -1543 -1544 // We started a new datagram, we decide later if it needs padding. -1545 pad_datagram = PadDatagram::No; -1546 } -1547 -1548 // If coalescing another packet into the existing datagram, there should -1549 // still be enough space for a whole packet. -1550 if transmit.datagram_start_offset() < transmit.len() { -1551 debug_assert!(transmit.datagram_remaining_mut() >= MIN_PACKET_SPACE); +1268 if let Some(response) = self.send_off_path_path_response(now, buf, path_id) { +1269 return Some(response); +1270 } +1271 if let Some(challenge) = self.send_nat_traversal_path_challenge(now, buf, path_id) { +1272 return Some(challenge); +1273 } +1274 None +1275 } +1276 +1277 /// poll_transmit logic for on-path data. +1278 /// +1279 /// This is not quite the same as for a multipath packet space, since [`PathId::ZERO`] +1280 /// has 3 packet spaces, which this handles. +1281 /// +1282 /// See [`Self::poll_transmit_off_path`] for off-path data. +1283 #[must_use] +1284 fn poll_transmit_on_path( +1285 &mut self, +1286 now: Instant, +1287 buf: &mut Vec<u8>, +1288 path_id: PathId, +1289 max_datagrams: NonZeroUsize, +1290 scheduling_info: &PathSchedulingInfo, +1291 connection_close_pending: bool, +1292 ) -> Option<Transmit> { +1293 // Check if there is at least one active CID to use for sending +1294 let Some(remote_cid) = self.remote_cids.get(&path_id).map(CidQueue::active) else { +1295 if !self.abandoned_paths.contains(&path_id) { +1296 debug!(%path_id, "no remote CIDs for path"); +1297 } +1298 return None; +1299 }; +1300 +1301 // Whether the last packet in the datagram must be padded so the datagram takes up +1302 // an exact size. An earlier space can decide to not fill an entire datagram and +1303 // require the next space to fill it further. But may need a specific size of the +1304 // datagram containing the packet. The final packet built in the datagram must pad +1305 // to this size. +1306 let mut pad_datagram = PadDatagram::No; +1307 +1308 // The packet number of the last built packet. This is kept kept across spaces. +1309 // QUIC is supposed to have a single congestion controller for the Initial, +1310 // Handshake and Data(PathId::ZERO) spaces. +1311 let mut last_packet_number = None; +1312 +1313 // If we end up not sending anything, we need to know if that was because there was +1314 // nothing to send or because we were congestion blocked. +1315 let mut congestion_blocked = false; +1316 +1317 // Set the segment size to this path's MTU for on-path data. +1318 let pmtu = self.path_data(path_id).current_mtu().into(); +1319 let mut transmit = TransmitBuf::new(buf, max_datagrams, pmtu); +1320 +1321 // Iterate over the available spaces. +1322 for space_id in SpaceId::iter() { +1323 // Only PathId::ZERO uses non Data space ids. +1324 if path_id != PathId::ZERO && space_id != SpaceId::Data { +1325 continue; +1326 } +1327 match self.poll_transmit_path_space( +1328 now, +1329 &mut transmit, +1330 path_id, +1331 space_id, +1332 remote_cid, +1333 scheduling_info, +1334 connection_close_pending, +1335 pad_datagram, +1336 ) { +1337 PollPathSpaceStatus::NothingToSend { +1338 congestion_blocked: cb, +1339 } => { +1340 congestion_blocked |= cb; +1341 // Continue checking other spaces, tail-loss probes may need to be sent +1342 // in all spaces. +1343 } +1344 PollPathSpaceStatus::WrotePacket { +1345 last_packet_number: pn, +1346 pad_datagram: pad, +1347 } => { +1348 debug_assert!(!transmit.is_empty(), "transmit must contain packets"); +1349 last_packet_number = Some(pn); +1350 pad_datagram = pad; +1351 // Always check higher spaces. If the transmit is full or they have +1352 // nothing to send they will not write packets. But if they can, they +1353 // must always be allowed to add to this transmit because coalescing may +1354 // be required. +1355 continue; +1356 } +1357 PollPathSpaceStatus::Send { +1358 last_packet_number: pn, +1359 } => { +1360 debug_assert!(!transmit.is_empty(), "transmit must contain packets"); +1361 last_packet_number = Some(pn); +1362 break; +1363 } +1364 } +1365 } +1366 +1367 if last_packet_number.is_some() || congestion_blocked { +1368 self.qlog.emit_recovery_metrics( +1369 path_id, +1370 &mut self.paths.get_mut(&path_id).unwrap().data, +1371 now, +1372 ); +1373 } +1374 +1375 self.path_data_mut(path_id).app_limited = +1376 last_packet_number.is_none() && !congestion_blocked; +1377 +1378 match last_packet_number { +1379 Some(last_packet_number) => { +1380 // Note that when sending in multiple spaces the last packet number will be +1381 // the one from the highest space. +1382 self.path_data_mut(path_id).congestion.on_sent( +1383 now, +1384 transmit.len() as u64, +1385 last_packet_number, +1386 ); +1387 Some(self.build_transmit(path_id, transmit)) +1388 } +1389 None => None, +1390 } +1391 } +1392 +1393 /// poll_transmit logic for a QUIC-MULTIPATH packet number space (PathID + SpaceId). +1394 #[must_use] +1395 fn poll_transmit_path_space( +1396 &mut self, +1397 now: Instant, +1398 transmit: &mut TransmitBuf<'_>, +1399 path_id: PathId, +1400 space_id: SpaceId, +1401 remote_cid: ConnectionId, +1402 scheduling_info: &PathSchedulingInfo, +1403 // If we need to send a CONNECTION_CLOSE frame. +1404 connection_close_pending: bool, +1405 // Whether the current datagram needs to be padded to a certain size. +1406 mut pad_datagram: PadDatagram, +1407 ) -> PollPathSpaceStatus { +1408 // Keep track of the last packet number we wrote. If None we did not write any +1409 // packets. +1410 let mut last_packet_number = None; +1411 +1412 // Each loop of this may build one packet. It works logically as follows: +1413 // +1414 // - Check if something *needs* to be sent in this space and *can* be sent. +1415 // - If not, return to the caller who will call us again for the next space. +1416 // - Start a new datagram. +1417 // - Unless coalescing the packet into an existing datagram. +1418 // - Write the packet header and payload. +1419 // - Check if coalescing a next packet into the datagram is possible. +1420 // - If coalescing, finish packet without padding to leave space in the datagram. +1421 // - If not coalescing, complete the datagram: +1422 // - Finish packet with padding. +1423 // - Set the transmit segment size if this is the first datagram. +1424 // - Loop: next iteration will exit the loop if nothing more to send in this +1425 // space. The TransmitBuf will contain a started datagram with space if +1426 // coalescing, or completely filled datagram if not coalescing. +1427 loop { +1428 // Determine if anything can be sent in this packet number space. +1429 let max_packet_size = if transmit.datagram_remaining_mut() > 0 { +1430 // A datagram is started already, we are coalescing another packet into it. +1431 transmit.datagram_remaining_mut() +1432 } else { +1433 // A new datagram needs to be started. +1434 transmit.segment_size() +1435 }; +1436 let can_send = +1437 self.space_can_send(space_id, path_id, max_packet_size, connection_close_pending); +1438 let needs_loss_probe = self.spaces[space_id].for_path(path_id).loss_probes > 0; +1439 let space_will_send = { +1440 if scheduling_info.is_abandoned { +1441 // If this path is abandoned then we might still have to send +1442 // PATH_ABANDON itself on it if there was no better space +1443 // available. Otherwise we want to send the PATH_ABANDON as permitted by +1444 // may_send_data however. +1445 scheduling_info.may_self_abandon +1446 && self.spaces[space_id] +1447 .pending +1448 .path_abandon +1449 .contains_key(&path_id) +1450 } else if can_send.close && scheduling_info.may_send_close { +1451 // This is the best path to send a CONNECTION_CLOSE on. +1452 true +1453 } else if needs_loss_probe || can_send.space_specific { +1454 // We always send a loss probe or space-specific frames if the path is +1455 // not abandoned. +1456 true +1457 } else { +1458 // Anything else we only send if we're the best path for SpaceKind::Data +1459 // frames. +1460 !can_send.is_empty() && scheduling_info.may_send_data +1461 } +1462 }; +1463 +1464 if !space_will_send { +1465 // Nothing more to send. Previous iterations of this loop may have built +1466 // packets already. +1467 return match last_packet_number { +1468 Some(pn) => PollPathSpaceStatus::WrotePacket { +1469 last_packet_number: pn, +1470 pad_datagram, +1471 }, +1472 None => { +1473 // Only log for spaces which have crypto. +1474 if self.crypto_state.has_keys(space_id.encryption_level()) +1475 || (space_id == SpaceId::Data +1476 && self.crypto_state.has_keys(EncryptionLevel::ZeroRtt)) +1477 { +1478 trace!(?space_id, %path_id, "nothing to send in space"); +1479 } +1480 PollPathSpaceStatus::NothingToSend { +1481 congestion_blocked: false, +1482 } +1483 } +1484 }; +1485 } +1486 +1487 // We want to send on this space, check congestion control if we can. But only +1488 // if we will need to start a new datagram. If we are coalescing into an already +1489 // started datagram we do not need to check congestion control again. +1490 if transmit.datagram_remaining_mut() == 0 { +1491 let congestion_blocked = +1492 self.path_congestion_check(space_id, path_id, transmit, &can_send, now); +1493 if congestion_blocked != PathBlocked::No { +1494 // Previous iterations of this loop may have built packets already. +1495 return match last_packet_number { +1496 Some(pn) => PollPathSpaceStatus::WrotePacket { +1497 last_packet_number: pn, +1498 pad_datagram, +1499 }, +1500 None => { +1501 return PollPathSpaceStatus::NothingToSend { +1502 congestion_blocked: true, +1503 }; +1504 } +1505 }; +1506 } +1507 +1508 // If the datagram is full (or there never was one started), we need to start a +1509 // new one. +1510 if transmit.num_datagrams() >= transmit.max_datagrams().get() { +1511 // No more datagrams allowed. +1512 // Previous iterations of this loop may have built packets already. +1513 return match last_packet_number { +1514 Some(pn) => PollPathSpaceStatus::WrotePacket { +1515 last_packet_number: pn, +1516 pad_datagram, +1517 }, +1518 None => { +1519 return PollPathSpaceStatus::NothingToSend { +1520 congestion_blocked: false, +1521 }; +1522 } +1523 }; +1524 } +1525 +1526 if needs_loss_probe { +1527 // Ensure we have something to send for a tail-loss probe. +1528 let request_immediate_ack = +1529 space_id == SpaceId::Data && self.peer_supports_ack_frequency(); +1530 self.spaces[space_id].queue_tail_loss_probe( +1531 path_id, +1532 request_immediate_ack, +1533 &self.streams, +1534 ); +1535 +1536 self.spaces[space_id].for_path(path_id).loss_probes -= 1; // needs_loss_probe ensures loss_probes > 0 +1537 +1538 // Clamp the datagram to at most the minimum MTU to ensure that loss +1539 // probes can get through and enable recovery even if the path MTU +1540 // has shrank unexpectedly. +1541 transmit.start_new_datagram_with_size(std::cmp::min( +1542 usize::from(INITIAL_MTU), +1543 transmit.segment_size(), +1544 )); +1545 } else { +1546 transmit.start_new_datagram(); +1547 } +1548 trace!(count = transmit.num_datagrams(), "new datagram started"); +1549 +1550 // We started a new datagram, we decide later if it needs padding. +1551 pad_datagram = PadDatagram::No; 1552 } 1553 -1554 // -1555 // From here on, we've determined that a packet will definitely be sent. -1556 // -1557 -1558 if self.crypto_state.has_keys(EncryptionLevel::Initial) -1559 && space_id == SpaceId::Handshake -1560 && self.side.is_client() -1561 { -1562 // A client stops both sending and processing Initial packets when it -1563 // sends its first Handshake packet. -1564 self.discard_space(now, SpaceKind::Initial); -1565 } -1566 if let Some(ref mut prev) = self.crypto_state.prev_crypto { -1567 prev.update_unacked = false; -1568 } -1569 -1570 let Some(mut builder) = -1571 PacketBuilder::new(now, space_id, path_id, remote_cid, transmit, self) -1572 else { -1573 // Confidentiality limit is exceeded and the connection has been killed. We -1574 // should not send any other packets. This works in a roundabout way: We -1575 // have started a datagram but not written anything into it. So even if we -1576 // get called again for another space we will see an already started -1577 // datagram and try and start another packet here. Then be stopped by the -1578 // same confidentiality limit. -1579 return PollPathSpaceStatus::NothingToSend { -1580 congestion_blocked: false, -1581 }; -1582 }; -1583 last_packet_number = Some(builder.packet_number); -1584 -1585 if space_id == SpaceId::Initial -1586 && (self.side.is_client() || can_send.is_ack_eliciting()) -1587 { -1588 // https://www.rfc-editor.org/rfc/rfc9000.html#section-14.1 -1589 pad_datagram |= PadDatagram::ToMinMtu; -1590 } -1591 if space_id == SpaceId::Data && self.config.pad_to_mtu { -1592 pad_datagram |= PadDatagram::ToSegmentSize; -1593 } -1594 -1595 if scheduling_info.may_send_close && can_send.close { -1596 trace!("sending CONNECTION_CLOSE"); -1597 // Encode ACKs before the ConnectionClose message, to give the receiver -1598 // a better approximate on what data has been processed. This is -1599 // especially important with ack delay, since the peer might not -1600 // have gotten any other ACK for the data earlier on. -1601 let is_multipath_negotiated = self.is_multipath_negotiated(); -1602 for path_id in self.spaces[space_id] -1603 .number_spaces -1604 .iter() -1605 .filter(|(_, pns)| !pns.pending_acks.ranges().is_empty()) -1606 .map(|(&path_id, _)| path_id) -1607 .collect::<Vec<_>>() -1608 { -1609 Self::populate_acks( -1610 now, -1611 self.receiving_ecn, -1612 path_id, -1613 space_id, -1614 &mut self.spaces[space_id], -1615 is_multipath_negotiated, -1616 &mut builder, -1617 &mut self.path_stats.for_path(path_id).frame_tx, -1618 self.crypto_state.has_keys(space_id.encryption_level()), -1619 ); -1620 } -1621 -1622 // Since there only 64 ACK frames there will always be enough space -1623 // to encode the ConnectionClose frame too. However we still have the -1624 // check here to prevent crashes if something changes. -1625 -1626 // TODO(flub): This needs fixing for multipath, to ensure we can always -1627 // write the CONNECTION_CLOSE even if we have many PATH_ACKs to send: -1628 // https://github.com/n0-computer/noq/issues/367. -1629 debug_assert!( -1630 builder.frame_space_remaining() > frame::ConnectionClose::SIZE_BOUND, -1631 "ACKs should leave space for ConnectionClose" -1632 ); -1633 let stats = &mut self.path_stats.for_path(path_id).frame_tx; -1634 if frame::ConnectionClose::SIZE_BOUND < builder.frame_space_remaining() { -1635 let max_frame_size = builder.frame_space_remaining(); -1636 let close: Close = match self.state.as_type() { -1637 StateType::Closed => { -1638 let reason: Close = -1639 self.state.as_closed().expect("checked").clone().into(); -1640 if space_id == SpaceId::Data || reason.is_transport_layer() { -1641 reason -1642 } else { -1643 TransportError::APPLICATION_ERROR("").into() -1644 } -1645 } -1646 StateType::Draining => TransportError::NO_ERROR("").into(), -1647 _ => unreachable!( -1648 "tried to make a close packet when the connection wasn't closed" -1649 ), -1650 }; -1651 builder.write_frame(close.encoder(max_frame_size), stats); -1652 } -1653 let last_pn = builder.packet_number; -1654 builder.finish_and_track(now, self, path_id, pad_datagram); -1655 if space_id.kind() == self.highest_space { -1656 // Don't send another close packet. Even with multipath we only send -1657 // CONNECTION_CLOSE on a single path since we expect our paths to work. -1658 self.connection_close_pending = false; -1659 } -1660 // Send a close frame in every possible space for robustness, per -1661 // RFC9000 "Immediate Close during the Handshake". Don't bother trying -1662 // to send anything else. -1663 // TODO(flub): This breaks during the handshake if we can not coalesce -1664 // packets due to space reasons: the next space would either fail a -1665 // debug_assert checking for enough packet space or produce an invalid -1666 // packet. We need to keep track of per-space pending CONNECTION_CLOSE to -1667 // be able to send these across multiple calls to poll_transmit. Then -1668 // check for coalescing space here because initial packets need to be in -1669 // padded datagrams. And also add space checks for CONNECTION_CLOSE in -1670 // space_can_send so it would stop a GSO batch if the datagram is too -1671 // small for another CONNECTION_CLOSE packet. -1672 return PollPathSpaceStatus::WrotePacket { -1673 last_packet_number: last_pn, -1674 pad_datagram, -1675 }; -1676 } -1677 -1678 self.populate_packet(now, space_id, path_id, scheduling_info, &mut builder); -1679 -1680 // ACK-only packets should only be sent when explicitly allowed. If we write them due to -1681 // any other reason, there is a bug which leads to one component announcing write -1682 // readiness while not writing any data. This degrades performance. The condition is -1683 // only checked if the full MTU is available and when potentially large fixed-size -1684 // frames aren't queued, so that lack of space in the datagram isn't the reason for just -1685 // writing ACKs. -1686 debug_assert!( -1687 !(builder.sent_frames().is_ack_only(&self.streams) -1688 && !can_send.acks -1689 && (can_send.other || can_send.space_specific) -1690 && builder.buf.segment_size() -1691 == self.path_data(path_id).current_mtu() as usize -1692 && self.datagrams.outgoing.is_empty()), -1693 "SendableFrames was {can_send:?}, but only ACKs have been written" -1694 ); -1695 if builder.sent_frames().requires_padding { -1696 pad_datagram |= PadDatagram::ToMinMtu; -1697 } -1698 -1699 for (path_id, _pn) in builder.sent_frames().largest_acked.iter() { -1700 self.spaces[space_id] -1701 .for_path(*path_id) -1702 .pending_acks -1703 .acks_sent(); -1704 self.timers.stop( -1705 Timer::PerPath(*path_id, PathTimer::MaxAckDelay), -1706 self.qlog.with_time(now), -1707 ); -1708 } -1709 -1710 // Now we need to finish the packet. Before we do so we need to know if we will -1711 // be coalescing the next packet into this one, or will be ending the datagram -1712 // as well. Because if this is the last packet in the datagram more padding -1713 // might be needed because of the packet type, or to fill the GSO segment size. -1714 -1715 // Are we allowed to coalesce AND is there enough space for another *packet* in -1716 // this datagram AND will we definitely send another packet? -1717 if builder.can_coalesce && path_id == PathId::ZERO && { -1718 let max_packet_size = builder -1719 .buf -1720 .datagram_remaining_mut() -1721 .saturating_sub(builder.predict_packet_end()); -1722 max_packet_size > MIN_PACKET_SPACE -1723 && self.has_pending_packet(space_id, max_packet_size, connection_close_pending) -1724 } { -1725 // We can append/coalesce the next packet into the current -1726 // datagram. Finish the current packet without adding extra padding. -1727 trace!("will coalesce with next packet"); -1728 builder.finish_and_track(now, self, path_id, PadDatagram::No); -1729 } else { -1730 // We need a new datagram for the next packet. Finish the current -1731 // packet with padding. -1732 // TODO(flub): if there isn't any more data to be sent, this will still pad -1733 // to the segment size and only discover there is nothing to send before -1734 // starting the next packet. That is wasting up to 32 bytes. -1735 if builder.buf.num_datagrams() > 1 && matches!(pad_datagram, PadDatagram::No) { -1736 // If too many padding bytes would be required to continue the -1737 // GSO batch after this packet, end the GSO batch here. Ensures -1738 // that fixed-size frames with heterogeneous sizes -1739 // (e.g. application datagrams) won't inadvertently waste large -1740 // amounts of bandwidth. The exact threshold is a bit arbitrary -1741 // and might benefit from further tuning, though there's no -1742 // universally optimal value. -1743 const MAX_PADDING: usize = 32; -1744 if builder.buf.datagram_remaining_mut() -1745 > builder.predict_packet_end() + MAX_PADDING -1746 { -1747 trace!( -1748 "GSO truncated by demand for {} padding bytes", -1749 builder.buf.datagram_remaining_mut() - builder.predict_packet_end() -1750 ); -1751 let last_pn = builder.packet_number; -1752 builder.finish_and_track(now, self, path_id, PadDatagram::No); -1753 return PollPathSpaceStatus::Send { -1754 last_packet_number: last_pn, -1755 }; -1756 } -1757 -1758 // Pad the current datagram to GSO segment size so it can be -1759 // included in the GSO batch. -1760 builder.finish_and_track(now, self, path_id, PadDatagram::ToSegmentSize); -1761 } else { -1762 builder.finish_and_track(now, self, path_id, pad_datagram); -1763 } -1764 -1765 // If this is the first datagram we set the segment size to the size of the -1766 // first datagram. -1767 if transmit.num_datagrams() == 1 { -1768 transmit.clip_segment_size(); +1554 // If coalescing another packet into the existing datagram, there should +1555 // still be enough space for a whole packet. +1556 if transmit.datagram_start_offset() < transmit.len() { +1557 debug_assert!(transmit.datagram_remaining_mut() >= MIN_PACKET_SPACE); +1558 } +1559 +1560 // +1561 // From here on, we've determined that a packet will definitely be sent. +1562 // +1563 +1564 if self.crypto_state.has_keys(EncryptionLevel::Initial) +1565 && space_id == SpaceId::Handshake +1566 && self.side.is_client() +1567 { +1568 // A client stops both sending and processing Initial packets when it +1569 // sends its first Handshake packet. +1570 self.discard_space(now, SpaceKind::Initial); +1571 } +1572 if let Some(ref mut prev) = self.crypto_state.prev_crypto { +1573 prev.update_unacked = false; +1574 } +1575 +1576 let Some(mut builder) = +1577 PacketBuilder::new(now, space_id, path_id, remote_cid, transmit, self) +1578 else { +1579 // Confidentiality limit is exceeded and the connection has been killed. We +1580 // should not send any other packets. This works in a roundabout way: We +1581 // have started a datagram but not written anything into it. So even if we +1582 // get called again for another space we will see an already started +1583 // datagram and try and start another packet here. Then be stopped by the +1584 // same confidentiality limit. +1585 return PollPathSpaceStatus::NothingToSend { +1586 congestion_blocked: false, +1587 }; +1588 }; +1589 last_packet_number = Some(builder.packet_number); +1590 +1591 if space_id == SpaceId::Initial +1592 && (self.side.is_client() || can_send.is_ack_eliciting()) +1593 { +1594 // https://www.rfc-editor.org/rfc/rfc9000.html#section-14.1 +1595 pad_datagram |= PadDatagram::ToMinMtu; +1596 } +1597 if space_id == SpaceId::Data && self.config.pad_to_mtu { +1598 pad_datagram |= PadDatagram::ToSegmentSize; +1599 } +1600 +1601 if scheduling_info.may_send_close && can_send.close { +1602 trace!("sending CONNECTION_CLOSE"); +1603 // Encode ACKs before the ConnectionClose message, to give the receiver +1604 // a better approximate on what data has been processed. This is +1605 // especially important with ack delay, since the peer might not +1606 // have gotten any other ACK for the data earlier on. +1607 let is_multipath_negotiated = self.is_multipath_negotiated(); +1608 for path_id in self.spaces[space_id] +1609 .number_spaces +1610 .iter() +1611 .filter(|(_, pns)| !pns.pending_acks.ranges().is_empty()) +1612 .map(|(&path_id, _)| path_id) +1613 .collect::<Vec<_>>() +1614 { +1615 Self::populate_acks( +1616 now, +1617 self.receiving_ecn, +1618 path_id, +1619 space_id, +1620 &mut self.spaces[space_id], +1621 is_multipath_negotiated, +1622 &mut builder, +1623 &mut self.path_stats.for_path(path_id).frame_tx, +1624 self.crypto_state.has_keys(space_id.encryption_level()), +1625 ); +1626 } +1627 +1628 // Since there only 64 ACK frames there will always be enough space +1629 // to encode the ConnectionClose frame too. However we still have the +1630 // check here to prevent crashes if something changes. +1631 +1632 // TODO(flub): This needs fixing for multipath, to ensure we can always +1633 // write the CONNECTION_CLOSE even if we have many PATH_ACKs to send: +1634 // https://github.com/n0-computer/noq/issues/367. +1635 debug_assert!( +1636 builder.frame_space_remaining() > frame::ConnectionClose::SIZE_BOUND, +1637 "ACKs should leave space for ConnectionClose" +1638 ); +1639 let stats = &mut self.path_stats.for_path(path_id).frame_tx; +1640 if frame::ConnectionClose::SIZE_BOUND < builder.frame_space_remaining() { +1641 let max_frame_size = builder.frame_space_remaining(); +1642 let close: Close = match self.state.as_type() { +1643 StateType::Closed => { +1644 let reason: Close = +1645 self.state.as_closed().expect("checked").clone().into(); +1646 if space_id == SpaceId::Data || reason.is_transport_layer() { +1647 reason +1648 } else { +1649 TransportError::APPLICATION_ERROR("").into() +1650 } +1651 } +1652 StateType::Draining => TransportError::NO_ERROR("").into(), +1653 _ => unreachable!( +1654 "tried to make a close packet when the connection wasn't closed" +1655 ), +1656 }; +1657 builder.write_frame(close.encoder(max_frame_size), stats); +1658 } +1659 let last_pn = builder.packet_number; +1660 builder.finish_and_track(now, self, path_id, pad_datagram); +1661 if space_id.kind() == self.highest_space { +1662 // Don't send another close packet. Even with multipath we only send +1663 // CONNECTION_CLOSE on a single path since we expect our paths to work. +1664 self.connection_close_pending = false; +1665 } +1666 // Send a close frame in every possible space for robustness, per +1667 // RFC9000 "Immediate Close during the Handshake". Don't bother trying +1668 // to send anything else. +1669 // TODO(flub): This breaks during the handshake if we can not coalesce +1670 // packets due to space reasons: the next space would either fail a +1671 // debug_assert checking for enough packet space or produce an invalid +1672 // packet. We need to keep track of per-space pending CONNECTION_CLOSE to +1673 // be able to send these across multiple calls to poll_transmit. Then +1674 // check for coalescing space here because initial packets need to be in +1675 // padded datagrams. And also add space checks for CONNECTION_CLOSE in +1676 // space_can_send so it would stop a GSO batch if the datagram is too +1677 // small for another CONNECTION_CLOSE packet. +1678 return PollPathSpaceStatus::WrotePacket { +1679 last_packet_number: last_pn, +1680 pad_datagram, +1681 }; +1682 } +1683 +1684 self.populate_packet(now, space_id, path_id, scheduling_info, &mut builder); +1685 +1686 // ACK-only packets should only be sent when explicitly allowed. If we write them due to +1687 // any other reason, there is a bug which leads to one component announcing write +1688 // readiness while not writing any data. This degrades performance. The condition is +1689 // only checked if the full MTU is available and when potentially large fixed-size +1690 // frames aren't queued, so that lack of space in the datagram isn't the reason for just +1691 // writing ACKs. +1692 debug_assert!( +1693 !(builder.sent_frames().is_ack_only(&self.streams) +1694 && !can_send.acks +1695 && (can_send.other || can_send.space_specific) +1696 && builder.buf.segment_size() +1697 == self.path_data(path_id).current_mtu() as usize +1698 && self.datagrams.outgoing.is_empty()), +1699 "SendableFrames was {can_send:?}, but only ACKs have been written" +1700 ); +1701 if builder.sent_frames().requires_padding { +1702 pad_datagram |= PadDatagram::ToMinMtu; +1703 } +1704 +1705 for (path_id, _pn) in builder.sent_frames().largest_acked.iter() { +1706 self.spaces[space_id] +1707 .for_path(*path_id) +1708 .pending_acks +1709 .acks_sent(); +1710 self.timers.stop( +1711 Timer::PerPath(*path_id, PathTimer::MaxAckDelay), +1712 self.qlog.with_time(now), +1713 ); +1714 } +1715 +1716 // Now we need to finish the packet. Before we do so we need to know if we will +1717 // be coalescing the next packet into this one, or will be ending the datagram +1718 // as well. Because if this is the last packet in the datagram more padding +1719 // might be needed because of the packet type, or to fill the GSO segment size. +1720 +1721 // Are we allowed to coalesce AND is there enough space for another *packet* in +1722 // this datagram AND will we definitely send another packet? +1723 if builder.can_coalesce && path_id == PathId::ZERO && { +1724 let max_packet_size = builder +1725 .buf +1726 .datagram_remaining_mut() +1727 .saturating_sub(builder.predict_packet_end()); +1728 max_packet_size > MIN_PACKET_SPACE +1729 && self.has_pending_packet(space_id, max_packet_size, connection_close_pending) +1730 } { +1731 // We can append/coalesce the next packet into the current +1732 // datagram. Finish the current packet without adding extra padding. +1733 trace!("will coalesce with next packet"); +1734 builder.finish_and_track(now, self, path_id, PadDatagram::No); +1735 } else { +1736 // We need a new datagram for the next packet. Finish the current +1737 // packet with padding. +1738 // TODO(flub): if there isn't any more data to be sent, this will still pad +1739 // to the segment size and only discover there is nothing to send before +1740 // starting the next packet. That is wasting up to 32 bytes. +1741 if builder.buf.num_datagrams() > 1 && matches!(pad_datagram, PadDatagram::No) { +1742 // If too many padding bytes would be required to continue the +1743 // GSO batch after this packet, end the GSO batch here. Ensures +1744 // that fixed-size frames with heterogeneous sizes +1745 // (e.g. application datagrams) won't inadvertently waste large +1746 // amounts of bandwidth. The exact threshold is a bit arbitrary +1747 // and might benefit from further tuning, though there's no +1748 // universally optimal value. +1749 const MAX_PADDING: usize = 32; +1750 if builder.buf.datagram_remaining_mut() +1751 > builder.predict_packet_end() + MAX_PADDING +1752 { +1753 trace!( +1754 "GSO truncated by demand for {} padding bytes", +1755 builder.buf.datagram_remaining_mut() - builder.predict_packet_end() +1756 ); +1757 let last_pn = builder.packet_number; +1758 builder.finish_and_track(now, self, path_id, PadDatagram::No); +1759 return PollPathSpaceStatus::Send { +1760 last_packet_number: last_pn, +1761 }; +1762 } +1763 +1764 // Pad the current datagram to GSO segment size so it can be +1765 // included in the GSO batch. +1766 builder.finish_and_track(now, self, path_id, PadDatagram::ToSegmentSize); +1767 } else { +1768 builder.finish_and_track(now, self, path_id, pad_datagram); 1769 } -1770 } -1771 } -1772 } -1773 -1774 fn poll_transmit_mtu_probe( -1775 &mut self, -1776 now: Instant, -1777 buf: &mut Vec<u8>, -1778 path_id: PathId, -1779 ) -> Option<Transmit> { -1780 let (active_cid, probe_size) = self.get_mtu_probe_data(now, path_id)?; -1781 -1782 // We are definitely sending a DPLPMTUD probe. -1783 let mut transmit = TransmitBuf::new(buf, NonZeroUsize::MIN, probe_size as usize); -1784 transmit.start_new_datagram_with_size(probe_size as usize); -1785 -1786 let mut builder = -1787 PacketBuilder::new(now, SpaceId::Data, path_id, active_cid, &mut transmit, self)?; -1788 -1789 // We implement MTU probes as ping packets padded up to the probe size -1790 trace!(?probe_size, "writing MTUD probe"); -1791 builder.write_frame(frame::Ping, &mut self.path_stats.for_path(path_id).frame_tx); -1792 -1793 // If supported by the peer, we want no delays to the probe's ACK -1794 if self.peer_supports_ack_frequency() { -1795 builder.write_frame( -1796 frame::ImmediateAck, -1797 &mut self.path_stats.for_path(path_id).frame_tx, -1798 ); -1799 } -1800 -1801 builder.finish_and_track(now, self, path_id, PadDatagram::ToSize(probe_size)); -1802 -1803 self.path_stats.for_path(path_id).sent_plpmtud_probes += 1; -1804 -1805 Some(self.build_transmit(path_id, transmit)) -1806 } -1807 -1808 /// Returns the CID and probe size if a DPLPMTUD probe is needed. -1809 /// -1810 /// We MTU probe all paths for which all of the following is true: -1811 /// - We have an active destination CID for the path. -1812 /// - The remote address *and* path are validated. -1813 /// - The path is not abandoned. -1814 /// - The MTU Discovery subsystem wants to probe the path. -1815 fn get_mtu_probe_data(&mut self, now: Instant, path_id: PathId) -> Option<(ConnectionId, u16)> { -1816 let active_cid = self.remote_cids.get(&path_id).map(CidQueue::active)?; -1817 let is_eligible = self.path_data(path_id).validated -1818 && !self.path_data(path_id).is_validating_path() -1819 && !self.abandoned_paths.contains(&path_id); -1820 -1821 if !is_eligible { -1822 return None; -1823 } -1824 let next_pn = self.spaces[SpaceId::Data] -1825 .for_path(path_id) -1826 .peek_tx_number(); -1827 let probe_size = self -1828 .path_data_mut(path_id) -1829 .mtud -1830 .poll_transmit(now, next_pn)?; -1831 -1832 Some((active_cid, probe_size)) -1833 } -1834 -1835 /// Returns true if there is a further packet to send on [`PathId::ZERO`]. -1836 /// -1837 /// In other words this is predicting whether the next call to -1838 /// [`Connection::space_can_send`] issued will return some frames to be sent. Including -1839 /// having to predict which packet number space it will be invoked with. This depends on -1840 /// how both [`Connection::poll_transmit_on_path`] and -1841 /// [`Connection::poll_transmit_path_space`] behave. +1770 +1771 // If this is the first datagram we set the segment size to the size of the +1772 // first datagram. +1773 if transmit.num_datagrams() == 1 { +1774 transmit.clip_segment_size(); +1775 } +1776 } +1777 } +1778 } +1779 +1780 fn poll_transmit_mtu_probe( +1781 &mut self, +1782 now: Instant, +1783 buf: &mut Vec<u8>, +1784 path_id: PathId, +1785 ) -> Option<Transmit> { +1786 let (active_cid, probe_size) = self.get_mtu_probe_data(now, path_id)?; +1787 +1788 // We are definitely sending a DPLPMTUD probe. +1789 let mut transmit = TransmitBuf::new(buf, NonZeroUsize::MIN, probe_size as usize); +1790 transmit.start_new_datagram_with_size(probe_size as usize); +1791 +1792 let mut builder = +1793 PacketBuilder::new(now, SpaceId::Data, path_id, active_cid, &mut transmit, self)?; +1794 +1795 // We implement MTU probes as ping packets padded up to the probe size +1796 trace!(?probe_size, "writing MTUD probe"); +1797 builder.write_frame(frame::Ping, &mut self.path_stats.for_path(path_id).frame_tx); +1798 +1799 // If supported by the peer, we want no delays to the probe's ACK +1800 if self.peer_supports_ack_frequency() { +1801 builder.write_frame( +1802 frame::ImmediateAck, +1803 &mut self.path_stats.for_path(path_id).frame_tx, +1804 ); +1805 } +1806 +1807 builder.finish_and_track(now, self, path_id, PadDatagram::ToSize(probe_size)); +1808 +1809 self.path_stats.for_path(path_id).sent_plpmtud_probes += 1; +1810 +1811 Some(self.build_transmit(path_id, transmit)) +1812 } +1813 +1814 /// Returns the CID and probe size if a DPLPMTUD probe is needed. +1815 /// +1816 /// We MTU probe all paths for which all of the following is true: +1817 /// - We have an active destination CID for the path. +1818 /// - The remote address *and* path are validated. +1819 /// - The path is not abandoned. +1820 /// - The MTU Discovery subsystem wants to probe the path. +1821 fn get_mtu_probe_data(&mut self, now: Instant, path_id: PathId) -> Option<(ConnectionId, u16)> { +1822 let active_cid = self.remote_cids.get(&path_id).map(CidQueue::active)?; +1823 let is_eligible = self.path_data(path_id).validated +1824 && !self.path_data(path_id).is_validating_path() +1825 && !self.abandoned_paths.contains(&path_id); +1826 +1827 if !is_eligible { +1828 return None; +1829 } +1830 let next_pn = self.spaces[SpaceId::Data] +1831 .for_path(path_id) +1832 .peek_tx_number(); +1833 let probe_size = self +1834 .path_data_mut(path_id) +1835 .mtud +1836 .poll_transmit(now, next_pn)?; +1837 +1838 Some((active_cid, probe_size)) +1839 } +1840 +1841 /// Returns true if there is a further packet to send on [`PathId::ZERO`]. 1842 /// -1843 /// This is needed to determine if packet coalescing can happen. Because the last packet -1844 /// in a datagram may need to be padded and thus we must know if another packet will -1845 /// follow or not. -1846 /// -1847 /// The next packet can be either in the same space, or in one of the following spaces -1848 /// on the same path. Because a 0-RTT packet can be coalesced with a 1-RTT packet and -1849 /// both are in the Data(PathId::ZERO) space. Previous spaces are not checked, because -1850 /// packets are built from Initial to Handshake to Data spaces. -1851 fn has_pending_packet( -1852 &mut self, -1853 current_space_id: SpaceId, -1854 max_packet_size: usize, -1855 connection_close_pending: bool, -1856 ) -> bool { -1857 let mut space_id = current_space_id; -1858 loop { -1859 let can_send = self.space_can_send( -1860 space_id, -1861 PathId::ZERO, -1862 max_packet_size, -1863 connection_close_pending, -1864 ); -1865 if !can_send.is_empty() { -1866 return true; -1867 } -1868 match space_id.next() { -1869 Some(next_space_id) => space_id = next_space_id, -1870 None => break, -1871 } -1872 } -1873 false -1874 } -1875 -1876 /// Checks if creating a new datagram would be blocked by congestion control -1877 fn path_congestion_check( -1878 &mut self, -1879 space_id: SpaceId, -1880 path_id: PathId, -1881 transmit: &TransmitBuf<'_>, -1882 can_send: &SendableFrames, -1883 now: Instant, -1884 ) -> PathBlocked { -1885 // Anti-amplification is only based on `total_sent`, which gets updated after -1886 // the transmit is sent. Therefore we pass the amount of bytes for datagrams -1887 // that are already created, as well as 1 byte for starting another datagram. If -1888 // there is any anti-amplification budget left, we always allow a full MTU to be -1889 // sent (see https://github.com/quinn-rs/quinn/issues/1082). -1890 if self.side().is_server() -1891 && self -1892 .path_data(path_id) -1893 .anti_amplification_blocked(transmit.len() as u64 + 1) -1894 { -1895 trace!(?space_id, %path_id, "blocked by anti-amplification"); -1896 return PathBlocked::AntiAmplification; -1897 } -1898 -1899 // Congestion control check. -1900 // Tail loss probes must not be blocked by congestion, or a deadlock could arise. -1901 let bytes_to_send = transmit.segment_size() as u64; -1902 let need_loss_probe = self.spaces[space_id].for_path(path_id).loss_probes > 0; -1903 -1904 if can_send.other && !need_loss_probe && !can_send.close { -1905 let path = self.path_data(path_id); -1906 if path.in_flight.bytes + bytes_to_send >= path.congestion.window() { -1907 trace!( -1908 ?space_id, -1909 %path_id, -1910 in_flight=%path.in_flight.bytes, -1911 congestion_window=%path.congestion.window(), -1912 "blocked by congestion control", -1913 ); -1914 return PathBlocked::Congestion; -1915 } -1916 } -1917 -1918 // Pacing check. -1919 if let Some(delay) = self.path_data_mut(path_id).pacing_delay(bytes_to_send, now) { -1920 let resume_time = now + delay; -1921 self.timers.set( -1922 Timer::PerPath(path_id, PathTimer::Pacing), -1923 resume_time, -1924 self.qlog.with_time(now), -1925 ); -1926 // Loss probes and CONNECTION_CLOSE should be subject to pacing, even though -1927 // they are not congestion controlled. -1928 trace!(?space_id, %path_id, ?delay, "blocked by pacing"); -1929 return PathBlocked::Pacing; -1930 } -1931 -1932 PathBlocked::No -1933 } -1934 -1935 /// Send PATH_CHALLENGE for a previous path if necessary -1936 /// -1937 /// QUIC-TRANSPORT section 9.3.3 -1938 /// <https://www.rfc-editor.org/rfc/rfc9000.html#name-off-path-packet-forwarding> -1939 fn send_prev_path_challenge( -1940 &mut self, -1941 now: Instant, -1942 buf: &mut Vec<u8>, -1943 path_id: PathId, -1944 ) -> Option<Transmit> { -1945 let (prev_cid, prev_path) = self.paths.get_mut(&path_id)?.prev.as_mut()?; -1946 // TODO (matheus23): We could use !prev_path.is_validating() here instead to -1947 // (possibly) also re-send challenges when they get lost. -1948 if !prev_path.pending_on_path_challenge { -1949 return None; -1950 }; -1951 prev_path.pending_on_path_challenge = false; -1952 let token = self.rng.random(); -1953 let network_path = prev_path.network_path; -1954 prev_path.record_path_challenge_sent(now, token, network_path); -1955 -1956 debug_assert_eq!( -1957 self.highest_space, -1958 SpaceKind::Data, -1959 "PATH_CHALLENGE queued without 1-RTT keys" -1960 ); -1961 let buf = &mut TransmitBuf::new(buf, NonZeroUsize::MIN, MIN_INITIAL_SIZE.into()); -1962 buf.start_new_datagram(); -1963 -1964 // Use the previous CID to avoid linking the new path with the previous path. We -1965 // don't bother accounting for possible retirement of that prev_cid because this is -1966 // sent once, immediately after migration, when the CID is known to be valid. Even -1967 // if a post-migration packet caused the CID to be retired, it's fair to pretend -1968 // this is sent first. -1969 let mut builder = PacketBuilder::new(now, SpaceId::Data, path_id, *prev_cid, buf, self)?; -1970 let challenge = frame::PathChallenge(token); -1971 let stats = &mut self.path_stats.for_path(path_id).frame_tx; -1972 builder.write_frame_with_log_msg(challenge, stats, Some("validating previous path")); -1973 -1974 // An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame -1975 // to at least the smallest allowed maximum datagram size of 1200 bytes, -1976 // unless the anti-amplification limit for the path does not permit -1977 // sending a datagram of this size -1978 builder.pad_to(MIN_INITIAL_SIZE); +1843 /// In other words this is predicting whether the next call to +1844 /// [`Connection::space_can_send`] issued will return some frames to be sent. Including +1845 /// having to predict which packet number space it will be invoked with. This depends on +1846 /// how both [`Connection::poll_transmit_on_path`] and +1847 /// [`Connection::poll_transmit_path_space`] behave. +1848 /// +1849 /// This is needed to determine if packet coalescing can happen. Because the last packet +1850 /// in a datagram may need to be padded and thus we must know if another packet will +1851 /// follow or not. +1852 /// +1853 /// The next packet can be either in the same space, or in one of the following spaces +1854 /// on the same path. Because a 0-RTT packet can be coalesced with a 1-RTT packet and +1855 /// both are in the Data(PathId::ZERO) space. Previous spaces are not checked, because +1856 /// packets are built from Initial to Handshake to Data spaces. +1857 fn has_pending_packet( +1858 &mut self, +1859 current_space_id: SpaceId, +1860 max_packet_size: usize, +1861 connection_close_pending: bool, +1862 ) -> bool { +1863 let mut space_id = current_space_id; +1864 loop { +1865 let can_send = self.space_can_send( +1866 space_id, +1867 PathId::ZERO, +1868 max_packet_size, +1869 connection_close_pending, +1870 ); +1871 if !can_send.is_empty() { +1872 return true; +1873 } +1874 match space_id.next() { +1875 Some(next_space_id) => space_id = next_space_id, +1876 None => break, +1877 } +1878 } +1879 false +1880 } +1881 +1882 /// Checks if creating a new datagram would be blocked by congestion control +1883 fn path_congestion_check( +1884 &mut self, +1885 space_id: SpaceId, +1886 path_id: PathId, +1887 transmit: &TransmitBuf<'_>, +1888 can_send: &SendableFrames, +1889 now: Instant, +1890 ) -> PathBlocked { +1891 // Anti-amplification is only based on `total_sent`, which gets updated after +1892 // the transmit is sent. Therefore we pass the amount of bytes for datagrams +1893 // that are already created, as well as 1 byte for starting another datagram. If +1894 // there is any anti-amplification budget left, we always allow a full MTU to be +1895 // sent (see https://github.com/quinn-rs/quinn/issues/1082). +1896 if self.side().is_server() +1897 && self +1898 .path_data(path_id) +1899 .anti_amplification_blocked(transmit.len() as u64 + 1) +1900 { +1901 trace!(?space_id, %path_id, "blocked by anti-amplification"); +1902 return PathBlocked::AntiAmplification; +1903 } +1904 +1905 // Congestion control check. +1906 // Tail loss probes must not be blocked by congestion, or a deadlock could arise. +1907 let bytes_to_send = transmit.segment_size() as u64; +1908 let need_loss_probe = self.spaces[space_id].for_path(path_id).loss_probes > 0; +1909 +1910 if can_send.other && !need_loss_probe && !can_send.close { +1911 let path = self.path_data(path_id); +1912 if path.in_flight.bytes + bytes_to_send >= path.congestion.window() { +1913 trace!( +1914 ?space_id, +1915 %path_id, +1916 in_flight=%path.in_flight.bytes, +1917 congestion_window=%path.congestion.window(), +1918 "blocked by congestion control", +1919 ); +1920 return PathBlocked::Congestion; +1921 } +1922 } +1923 +1924 // Pacing check. +1925 if let Some(delay) = self.path_data_mut(path_id).pacing_delay(bytes_to_send, now) { +1926 let resume_time = now + delay; +1927 self.timers.set( +1928 Timer::PerPath(path_id, PathTimer::Pacing), +1929 resume_time, +1930 self.qlog.with_time(now), +1931 ); +1932 // Loss probes and CONNECTION_CLOSE should be subject to pacing, even though +1933 // they are not congestion controlled. +1934 trace!(?space_id, %path_id, ?delay, "blocked by pacing"); +1935 return PathBlocked::Pacing; +1936 } +1937 +1938 PathBlocked::No +1939 } +1940 +1941 /// Send PATH_CHALLENGE for a previous path if necessary +1942 /// +1943 /// QUIC-TRANSPORT section 9.3.3 +1944 /// <https://www.rfc-editor.org/rfc/rfc9000.html#name-off-path-packet-forwarding> +1945 fn send_prev_path_challenge( +1946 &mut self, +1947 now: Instant, +1948 buf: &mut Vec<u8>, +1949 path_id: PathId, +1950 ) -> Option<Transmit> { +1951 let (prev_cid, prev_path) = self.paths.get_mut(&path_id)?.prev.as_mut()?; +1952 // TODO (matheus23): We could use !prev_path.is_validating() here instead to +1953 // (possibly) also re-send challenges when they get lost. +1954 if !prev_path.pending_on_path_challenge { +1955 return None; +1956 }; +1957 prev_path.pending_on_path_challenge = false; +1958 let token = self.rng.random(); +1959 let network_path = prev_path.network_path; +1960 prev_path.record_path_challenge_sent(now, token, network_path); +1961 +1962 debug_assert_eq!( +1963 self.highest_space, +1964 SpaceKind::Data, +1965 "PATH_CHALLENGE queued without 1-RTT keys" +1966 ); +1967 let buf = &mut TransmitBuf::new(buf, NonZeroUsize::MIN, MIN_INITIAL_SIZE.into()); +1968 buf.start_new_datagram(); +1969 +1970 // Use the previous CID to avoid linking the new path with the previous path. We +1971 // don't bother accounting for possible retirement of that prev_cid because this is +1972 // sent once, immediately after migration, when the CID is known to be valid. Even +1973 // if a post-migration packet caused the CID to be retired, it's fair to pretend +1974 // this is sent first. +1975 let mut builder = PacketBuilder::new(now, SpaceId::Data, path_id, *prev_cid, buf, self)?; +1976 let challenge = frame::PathChallenge(token); +1977 let stats = &mut self.path_stats.for_path(path_id).frame_tx; +1978 builder.write_frame_with_log_msg(challenge, stats, Some("validating previous path")); 1979 -1980 builder.finish(self, now); -1981 self.path_stats -1982 .for_path(path_id) -1983 .udp_tx -1984 .on_sent(1, buf.len()); +1980 // An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame +1981 // to at least the smallest allowed maximum datagram size of 1200 bytes, +1982 // unless the anti-amplification limit for the path does not permit +1983 // sending a datagram of this size +1984 builder.pad_to(MIN_INITIAL_SIZE); 1985 -1986 Some(Transmit { -1987 destination: network_path.remote, -1988 size: buf.len(), -1989 ecn: None, -1990 segment_size: None, -1991 src_ip: network_path.local_ip, -1992 }) -1993 } -1994 -1995 fn send_off_path_path_response( -1996 &mut self, -1997 now: Instant, -1998 buf: &mut Vec<u8>, -1999 path_id: PathId, -2000 ) -> Option<Transmit> { -2001 let path = self.paths.get_mut(&path_id).map(|state| &mut state.data)?; -2002 let cid_queue = self.remote_cids.get_mut(&path_id)?; -2003 let (token, network_path) = path.path_responses.pop_off_path(path.network_path)?; -2004 -2005 let cid = cid_queue -2006 .next_reserved() -2007 .unwrap_or_else(|| cid_queue.active()); -2008 // TODO(@divma): we should take a different approach when there is no fresh CID to use. -2009 // https://github.com/quinn-rs/quinn/issues/2184 +1986 builder.finish(self, now); +1987 self.path_stats +1988 .for_path(path_id) +1989 .udp_tx +1990 .on_sent(1, buf.len()); +1991 +1992 Some(Transmit { +1993 destination: network_path.remote, +1994 size: buf.len(), +1995 ecn: None, +1996 segment_size: None, +1997 src_ip: network_path.local_ip, +1998 }) +1999 } +2000 +2001 fn send_off_path_path_response( +2002 &mut self, +2003 now: Instant, +2004 buf: &mut Vec<u8>, +2005 path_id: PathId, +2006 ) -> Option<Transmit> { +2007 let path = self.paths.get_mut(&path_id).map(|state| &mut state.data)?; +2008 let cid_queue = self.remote_cids.get_mut(&path_id)?; +2009 let (token, network_path) = path.path_responses.pop_off_path(path.network_path)?; 2010 -2011 let frame = frame::PathResponse(token); -2012 -2013 let buf = &mut TransmitBuf::new(buf, NonZeroUsize::MIN, MIN_INITIAL_SIZE.into()); -2014 buf.start_new_datagram(); -2015 -2016 let mut builder = PacketBuilder::new(now, SpaceId::Data, path_id, cid, buf, self)?; -2017 let stats = &mut self.path_stats.for_path(path_id).frame_tx; -2018 builder.write_frame_with_log_msg(frame, stats, Some("(off-path)")); -2019 // Off-path: not tracked in congestion control. The packet is sent to a -2020 // different destination than path_id's network path. -2021 builder.pad_to(MIN_INITIAL_SIZE); -2022 builder.finish(self, now); -2023 -2024 let size = buf.len(); -2025 -2026 self.path_stats.for_path(path_id).udp_tx.on_sent(1, size); -2027 Some(Transmit { -2028 destination: network_path.remote, -2029 size, -2030 ecn: None, -2031 segment_size: None, -2032 src_ip: network_path.local_ip, -2033 }) -2034 } -2035 -2036 /// Send a nat traversal challenge (off-path) on this path if possible. -2037 /// -2038 /// This will ensure the path still has a remaining CID to use if the active one should be -2039 /// retired. -2040 fn send_nat_traversal_path_challenge( -2041 &mut self, -2042 now: Instant, -2043 buf: &mut Vec<u8>, -2044 path_id: PathId, -2045 ) -> Option<Transmit> { -2046 let remote = self -2047 .n0_nat_traversal -2048 .server_side_mut() -2049 .ok()? -2050 .next_probe_addr()?; -2051 -2052 if !self.paths.get(&path_id)?.data.validated { -2053 // Path is not usable for probing -2054 return None; -2055 } -2056 -2057 // TODO: Using the active CID here makes the paths linkable. This is a violation of -2058 // RFC9000 but something we want to accept in the short term. Eventually we aim -2059 // to fix up the supply of CIDs sufficiently so that we can keep paths unlinkable -2060 // again. -2061 let Some(cid) = self -2062 .remote_cids -2063 .get(&path_id) -2064 .map(|cid_queue| cid_queue.active()) -2065 else { -2066 trace!(%path_id, "Not sending NAT traversal probe for path with no CIDs"); -2067 return None; -2068 }; -2069 let token = self.rng.random(); -2070 -2071 let frame = frame::PathChallenge(token); -2072 -2073 let mut buf = TransmitBuf::new(buf, NonZeroUsize::MIN, MIN_INITIAL_SIZE.into()); -2074 buf.start_new_datagram(); -2075 -2076 let mut builder = PacketBuilder::new(now, SpaceId::Data, path_id, cid, &mut buf, self)?; -2077 let stats = &mut self.path_stats.for_path(path_id).frame_tx; -2078 builder.write_frame_with_log_msg(frame, stats, Some("(nat-traversal)")); -2079 // Off-path: not tracked in congestion control. The packet is sent to a -2080 // different destination than path_id's network path. -2081 builder.pad_to(MIN_INITIAL_SIZE); -2082 builder.finish(self, now); -2083 -2084 // Mark as sent after packet build succeeds. -2085 if let Ok(server_state) = self.n0_nat_traversal.server_side_mut() { -2086 server_state.mark_probe_sent((remote.ip(), remote.port())); -2087 } -2088 -2089 let path = &mut self.paths.get_mut(&path_id).expect("checked").data; -2090 let network_path = FourTuple { -2091 remote, -2092 local_ip: None, -2093 }; +2011 let cid = cid_queue +2012 .next_reserved() +2013 .unwrap_or_else(|| cid_queue.active()); +2014 // TODO(@divma): we should take a different approach when there is no fresh CID to use. +2015 // https://github.com/quinn-rs/quinn/issues/2184 +2016 +2017 let frame = frame::PathResponse(token); +2018 +2019 let buf = &mut TransmitBuf::new(buf, NonZeroUsize::MIN, MIN_INITIAL_SIZE.into()); +2020 buf.start_new_datagram(); +2021 +2022 let mut builder = PacketBuilder::new(now, SpaceId::Data, path_id, cid, buf, self)?; +2023 let stats = &mut self.path_stats.for_path(path_id).frame_tx; +2024 builder.write_frame_with_log_msg(frame, stats, Some("(off-path)")); +2025 // Off-path: not tracked in congestion control. The packet is sent to a +2026 // different destination than path_id's network path. +2027 builder.pad_to(MIN_INITIAL_SIZE); +2028 builder.finish(self, now); +2029 +2030 let size = buf.len(); +2031 +2032 self.path_stats.for_path(path_id).udp_tx.on_sent(1, size); +2033 Some(Transmit { +2034 destination: network_path.remote, +2035 size, +2036 ecn: None, +2037 segment_size: None, +2038 src_ip: network_path.local_ip, +2039 }) +2040 } +2041 +2042 /// Send a nat traversal challenge (off-path) on this path if possible. +2043 /// +2044 /// This will ensure the path still has a remaining CID to use if the active one should be +2045 /// retired. +2046 fn send_nat_traversal_path_challenge( +2047 &mut self, +2048 now: Instant, +2049 buf: &mut Vec<u8>, +2050 path_id: PathId, +2051 ) -> Option<Transmit> { +2052 let remote = self +2053 .n0_nat_traversal +2054 .server_side_mut() +2055 .ok()? +2056 .next_probe_addr()?; +2057 +2058 if !self.paths.get(&path_id)?.data.validated { +2059 // Path is not usable for probing +2060 return None; +2061 } +2062 +2063 // TODO: Using the active CID here makes the paths linkable. This is a violation of +2064 // RFC9000 but something we want to accept in the short term. Eventually we aim +2065 // to fix up the supply of CIDs sufficiently so that we can keep paths unlinkable +2066 // again. +2067 let Some(cid) = self +2068 .remote_cids +2069 .get(&path_id) +2070 .map(|cid_queue| cid_queue.active()) +2071 else { +2072 trace!(%path_id, "Not sending NAT traversal probe for path with no CIDs"); +2073 return None; +2074 }; +2075 let token = self.rng.random(); +2076 +2077 let frame = frame::PathChallenge(token); +2078 +2079 let mut buf = TransmitBuf::new(buf, NonZeroUsize::MIN, MIN_INITIAL_SIZE.into()); +2080 buf.start_new_datagram(); +2081 +2082 let mut builder = PacketBuilder::new(now, SpaceId::Data, path_id, cid, &mut buf, self)?; +2083 let stats = &mut self.path_stats.for_path(path_id).frame_tx; +2084 builder.write_frame_with_log_msg(frame, stats, Some("(nat-traversal)")); +2085 // Off-path: not tracked in congestion control. The packet is sent to a +2086 // different destination than path_id's network path. +2087 builder.pad_to(MIN_INITIAL_SIZE); +2088 builder.finish(self, now); +2089 +2090 // Mark as sent after packet build succeeds. +2091 if let Ok(server_state) = self.n0_nat_traversal.server_side_mut() { +2092 server_state.mark_probe_sent((remote.ip(), remote.port())); +2093 } 2094 -2095 path.record_path_challenge_sent(now, token, network_path); -2096 -2097 // Set retry timer for NAT traversal probes that got no PATH_RESPONSE. -2098 if let Ok(server_state) = self.n0_nat_traversal.server_side_mut() -2099 && server_state.has_pending_retries() -2100 { -2101 let initial_pto = RttEstimator::new(self.config.initial_rtt).pto_base(); -2102 self.timers.set( -2103 Timer::Conn(ConnTimer::NatTraversalProbeRetry), -2104 now + initial_pto, -2105 self.qlog.with_time(now), -2106 ); -2107 } -2108 -2109 let size = buf.len(); -2110 -2111 self.path_stats.for_path(path_id).udp_tx.on_sent(1, size); -2112 -2113 Some(Transmit { -2114 destination: remote, -2115 size, -2116 ecn: None, -2117 segment_size: None, -2118 src_ip: None, -2119 }) -2120 } -2121 -2122 /// Indicate what types of frames are ready to send for the given space. -2123 /// -2124 /// Only for on-path data. -2125 /// -2126 /// *packet_size* is the number of bytes available to build the next packet. -2127 /// *connection_close_pending* indicates whether a CONNECTION_CLOSE frame needs to be -2128 /// sent. -2129 fn space_can_send( -2130 &mut self, -2131 space_id: SpaceId, -2132 path_id: PathId, -2133 packet_size: usize, -2134 connection_close_pending: bool, -2135 ) -> SendableFrames { -2136 let space = &mut self.spaces[space_id]; -2137 let space_has_crypto = self.crypto_state.has_keys(space_id.encryption_level()); -2138 -2139 if !space_has_crypto -2140 && (space_id != SpaceId::Data -2141 || !self.crypto_state.has_keys(EncryptionLevel::ZeroRtt) -2142 || self.side.is_server()) -2143 { -2144 // Nothing to send in this space -2145 return SendableFrames::empty(); -2146 } -2147 -2148 let mut can_send = space.can_send(path_id, &self.streams); -2149 -2150 // Check for 1RTT space. -2151 if space_id == SpaceId::Data { -2152 let pn = space.for_path(path_id).peek_tx_number(); -2153 // Number of bytes available for frames if this is a 1-RTT packet. We're -2154 // guaranteed to be able to send an individual frame at least this large in the -2155 // next 1-RTT packet. This could be generalized to support every space, but it's -2156 // only needed to handle large fixed-size frames, which only exist in 1-RTT -2157 // (application datagrams). -2158 let frame_space_1rtt = -2159 packet_size.saturating_sub(self.predict_1rtt_overhead(pn, path_id)); -2160 can_send |= self.can_send_1rtt(path_id, frame_space_1rtt); -2161 } -2162 -2163 can_send.close = connection_close_pending && space_has_crypto; -2164 -2165 can_send -2166 } -2167 -2168 /// Process `ConnectionEvent`s generated by the associated `Endpoint` -2169 /// -2170 /// Will execute protocol logic upon receipt of a connection event, in turn preparing signals -2171 /// (including application `Event`s, `EndpointEvent`s and outgoing datagrams) that should be -2172 /// extracted through the relevant methods. -2173 pub fn handle_event(&mut self, event: ConnectionEvent) { -2174 use ConnectionEventInner::*; -2175 match event.0 { -2176 Datagram(DatagramConnectionEvent { -2177 now, -2178 network_path, -2179 path_id, -2180 ecn, -2181 first_decode, -2182 remaining, -2183 }) => { -2184 let span = trace_span!("pkt", %path_id); -2185 let _guard = span.enter(); -2186 -2187 if self.update_network_path_or_discard(network_path, path_id) { -2188 // A return value of true indicates we should discard this packet. -2189 return; -2190 } -2191 -2192 let was_anti_amplification_blocked = self -2193 .path(path_id) -2194 .map(|path| path.anti_amplification_blocked(1)) -2195 // We never tried to send on an non-existing (new) path so have not been -2196 // anti-amplification blocked for it previously. -2197 .unwrap_or(false); -2198 -2199 let rx = &mut self.path_stats.for_path(path_id).udp_rx; -2200 rx.datagrams += 1; -2201 rx.bytes += first_decode.len() as u64; -2202 let data_len = first_decode.len(); -2203 -2204 self.handle_decode(now, network_path, path_id, ecn, first_decode); -2205 // The current `path` might have changed inside `handle_decode` since the packet -2206 // could have triggered a migration. The packet might also belong to an unknown -2207 // path and have been rejected. Make sure the data received is accounted for the -2208 // most recent path by accessing `path` after `handle_decode`. -2209 if let Some(path) = self.path_mut(path_id) { -2210 path.inc_total_recvd(data_len as u64); -2211 } -2212 -2213 if let Some(data) = remaining { -2214 self.path_stats.for_path(path_id).udp_rx.bytes += data.len() as u64; -2215 self.handle_coalesced(now, network_path, path_id, ecn, data); -2216 } -2217 -2218 if let Some(path) = self.paths.get_mut(&path_id) { -2219 self.qlog -2220 .emit_recovery_metrics(path_id, &mut path.data, now); -2221 } -2222 -2223 if was_anti_amplification_blocked { -2224 // A prior attempt to set the loss detection timer may have failed due to -2225 // anti-amplification, so ensure it's set now. Prevents a handshake deadlock if -2226 // the server's first flight is lost. -2227 self.set_loss_detection_timer(now, path_id); -2228 } -2229 } -2230 NewIdentifiers(ids, now, cid_len, cid_lifetime) => { -2231 let path_id = ids.first().map(|issued| issued.path_id).unwrap_or_default(); -2232 debug_assert!(ids.iter().all(|issued| issued.path_id == path_id)); -2233 let cid_state = self -2234 .local_cid_state -2235 .entry(path_id) -2236 .or_insert_with(|| CidState::new(cid_len, cid_lifetime, now, 0)); -2237 cid_state.new_cids(&ids, now); -2238 -2239 ids.into_iter().rev().for_each(|frame| { -2240 self.spaces[SpaceId::Data].pending.new_cids.push(frame); -2241 }); -2242 // Always update Timer::PushNewCid -2243 self.reset_cid_retirement(now); -2244 } -2245 } -2246 } -2247 -2248 /// Updates the network path for `path_id`. -2249 /// -2250 /// Returns true if a packet coming in for this `path_id` over given `network_path` should be discarded. -2251 /// Returns false if the path was updated and the packet doesn't need to be discarded. -2252 fn update_network_path_or_discard(&mut self, network_path: FourTuple, path_id: PathId) -> bool { -2253 let remote_may_migrate = self.side.remote_may_migrate(&self.state); -2254 let local_ip_may_migrate = self.side.is_client(); -2255 // If this packet could initiate a migration and we're a client or a server that -2256 // forbids migration, drop the datagram. This could be relaxed to heuristically -2257 // permit NAT-rebinding-like migration. -2258 if let Some(known_path) = self.path_mut(path_id) { -2259 if network_path.remote != known_path.network_path.remote && !remote_may_migrate { -2260 trace!( -2261 %path_id, -2262 %network_path, -2263 %known_path.network_path, -2264 "discarding packet from unrecognized peer" -2265 ); -2266 return true; -2267 } -2268 -2269 if known_path.network_path.local_ip.is_some() -2270 && network_path.local_ip.is_some() -2271 && known_path.network_path.local_ip != network_path.local_ip -2272 && !local_ip_may_migrate -2273 { -2274 trace!( -2275 %path_id, -2276 %network_path, -2277 %known_path.network_path, -2278 "discarding packet sent to incorrect interface" -2279 ); -2280 return true; -2281 } -2282 // If the datagram indicates that we've changed our local IP, we update it. -2283 // This is alluded to in Section 5.2 of the Multipath RFC draft 18: -2284 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-18.html#name-using-multiple-paths-on-the -2285 // > Client receives the packet, recognizes a path migration, updates the source address of path 2 to 192.0.2.1. -2286 if let Some(local_ip) = network_path.local_ip { -2287 if known_path -2288 .network_path -2289 .local_ip -2290 .is_some_and(|ip| ip != local_ip) -2291 { -2292 debug!( -2293 %path_id, -2294 %network_path, -2295 %known_path.network_path, -2296 "path's local address seemingly migrated" -2297 ); -2298 } -2299 // We update the address without path validation on the client side. -2300 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-18.html#section-5.1 -2301 // > Servers observing a 4-tuple change will perform path validation (see Section 9 of [QUIC-TRANSPORT]). -2302 // This sounds like it's *only* the server endpoints that do this. -2303 // TODO(matheus23): We should still consider doing a proper migration on the client side in the future. -2304 // For now, this preserves the behavior of this code pre 4-tuple tracking. -2305 known_path.network_path.local_ip = Some(local_ip); -2306 } -2307 } -2308 false -2309 } -2310 -2311 /// Process timer expirations -2312 /// -2313 /// Executes protocol logic, potentially preparing signals (including application `Event`s, -2314 /// `EndpointEvent`s and outgoing datagrams) that should be extracted through the relevant -2315 /// methods. -2316 /// -2317 /// It is most efficient to call this immediately after the system clock reaches the latest -2318 /// `Instant` that was output by `poll_timeout`; however spurious extra calls will simply -2319 /// no-op and therefore are safe. -2320 pub fn handle_timeout(&mut self, now: Instant) { -2321 while let Some((timer, _time)) = self.timers.expire_before(now, &self.qlog) { -2322 // TODO(@divma): remove `at` when the unicorn is born -2323 trace!(?timer, at=?now, "timeout"); -2324 match timer { -2325 Timer::Conn(timer) => match timer { -2326 ConnTimer::Close => { -2327 self.state.move_to_drained(None); -2328 // move_to_drained checks that we weren't in drained before. -2329 // Adding events to endpoint_events is only legal if `Drained` was never queued before. -2330 self.endpoint_events.push_back(EndpointEventInner::Drained); -2331 } -2332 ConnTimer::Idle => { -2333 self.kill(ConnectionError::TimedOut); -2334 } -2335 ConnTimer::KeepAlive => { -2336 trace!("sending keep-alive"); -2337 self.ping(); -2338 } -2339 ConnTimer::KeyDiscard => { -2340 self.crypto_state.discard_temporary_keys(); -2341 } -2342 ConnTimer::PushNewCid => { -2343 while let Some((path_id, when)) = self.next_cid_retirement() { -2344 if when > now { -2345 break; -2346 } -2347 match self.local_cid_state.get_mut(&path_id) { -2348 None => error!(%path_id, "No local CID state for path"), -2349 Some(cid_state) => { -2350 // Update `retire_prior_to` field in NEW_CONNECTION_ID frame -2351 let num_new_cid = cid_state.on_cid_timeout().into(); -2352 if !self.state.is_closed() { -2353 trace!( -2354 "push a new CID to peer RETIRE_PRIOR_TO field {}", -2355 cid_state.retire_prior_to() -2356 ); -2357 self.endpoint_events.push_back( -2358 EndpointEventInner::NeedIdentifiers( -2359 path_id, -2360 now, -2361 num_new_cid, -2362 ), -2363 ); -2364 } -2365 } -2366 } -2367 } -2368 } -2369 ConnTimer::NoAvailablePath => { -2370 // Grace period expired: all paths were abandoned and no new path -2371 // was opened. Close the connection. There are no paths left to -2372 // send CONNECTION_CLOSE on, so this is a silent close. -2373 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-21.html#section-3.4-8 -2374 if self.state.is_closed() || self.state.is_drained() { -2375 // Connection already closing/drained (e.g. application called -2376 // close() before the grace timer fired). Nothing to do. -2377 error!("no viable path timer fired, but connection already closing"); -2378 } else { -2379 trace!("no viable path grace period expired, closing connection"); -2380 let err = TransportError::NO_VIABLE_PATH( -2381 "last path abandoned, no new path opened", -2382 ); -2383 self.close_common(); -2384 self.set_close_timer(now); -2385 self.connection_close_pending = true; -2386 self.state.move_to_closed(err); -2387 } -2388 } -2389 ConnTimer::NatTraversalProbeRetry => { -2390 if let Ok(server_state) = self.n0_nat_traversal.server_side_mut() -2391 && server_state.queue_retries() -2392 { -2393 trace!("off-path probe retry timer fired, re-queued probes"); -2394 } -2395 } -2396 }, -2397 Timer::PerPath(path_id, timer) => { -2398 let span = trace_span!("per-path timer fired", %path_id, ?timer); -2399 let _guard = span.enter(); -2400 match timer { -2401 PathTimer::PathIdle => { -2402 if let Err(err) = -2403 self.close_path_inner(now, path_id, PathAbandonReason::TimedOut) -2404 { -2405 warn!(?err, "failed closing path"); -2406 } -2407 } -2408 -2409 PathTimer::PathKeepAlive => { -2410 trace!("sending keep-alive on path"); -2411 self.ping_path(path_id).ok(); -2412 } -2413 PathTimer::LossDetection => { -2414 self.on_loss_detection_timeout(now, path_id); -2415 self.qlog.emit_recovery_metrics( -2416 path_id, -2417 &mut self.paths.get_mut(&path_id).unwrap().data, -2418 now, -2419 ); -2420 } -2421 PathTimer::PathValidationFailed => { -2422 let Some(path) = self.paths.get_mut(&path_id) else { -2423 continue; -2424 }; -2425 self.timers.stop( -2426 Timer::PerPath(path_id, PathTimer::PathChallengeLost), -2427 self.qlog.with_time(now), -2428 ); -2429 debug!("path migration validation failed"); -2430 if let Some((_, prev)) = path.prev.take() { -2431 path.data = prev; -2432 } -2433 path.data.reset_on_path_challenges(); -2434 } -2435 PathTimer::PathChallengeLost => { -2436 let Some(path) = self.paths.get_mut(&path_id) else { -2437 continue; -2438 }; -2439 trace!("path challenge deemed lost"); -2440 path.data.pending_on_path_challenge = true; -2441 } -2442 PathTimer::PathOpenFailed => { -2443 let Some(path) = self.paths.get_mut(&path_id) else { -2444 continue; -2445 }; -2446 path.data.reset_on_path_challenges(); -2447 self.timers.stop( -2448 Timer::PerPath(path_id, PathTimer::PathChallengeLost), -2449 self.qlog.with_time(now), -2450 ); -2451 debug!("new path validation failed"); -2452 if let Err(err) = self.close_path_inner( -2453 now, -2454 path_id, -2455 PathAbandonReason::ValidationFailed, -2456 ) { -2457 warn!(?err, "failed closing path"); -2458 } -2459 } -2460 PathTimer::Pacing => trace!("pacing timer expired"), -2461 PathTimer::MaxAckDelay => { -2462 trace!("max ack delay reached"); -2463 // This timer is only armed in the Data space -2464 self.spaces[SpaceId::Data] -2465 .for_path(path_id) -2466 .pending_acks -2467 .on_max_ack_delay_timeout() -2468 } -2469 PathTimer::PathDrained => { -2470 // The path was abandoned and 3*PTO has expired since. Clean up all -2471 // remaining state and install stateless reset token. -2472 self.timers.stop_per_path(path_id, self.qlog.with_time(now)); -2473 if let Some(local_cid_state) = self.local_cid_state.remove(&path_id) { -2474 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events. All timers should be cleared in drained connections. -2475 let (min_seq, max_seq) = local_cid_state.active_seq(); -2476 for seq in min_seq..=max_seq { -2477 self.endpoint_events.push_back( -2478 EndpointEventInner::RetireConnectionId( -2479 now, path_id, seq, false, -2480 ), -2481 ); -2482 } -2483 } -2484 self.discard_path(path_id, now); -2485 } -2486 } -2487 } -2488 } -2489 } -2490 } -2491 -2492 /// Close a connection immediately -2493 /// -2494 /// This does not ensure delivery of outstanding data. It is the application's responsibility to -2495 /// call this only when all important communications have been completed, e.g. by calling -2496 /// [`SendStream::finish`] on outstanding streams and waiting for the corresponding -2497 /// [`StreamEvent::Finished`] event. -2498 /// -2499 /// If [`Streams::send_streams`] returns 0, all outstanding stream data has been -2500 /// delivered. There may still be data from the peer that has not been received. -2501 /// -2502 /// [`StreamEvent::Finished`]: crate::StreamEvent::Finished -2503 pub fn close(&mut self, now: Instant, error_code: VarInt, reason: Bytes) { -2504 self.close_inner( -2505 now, -2506 Close::Application(frame::ApplicationClose { error_code, reason }), -2507 ) -2508 } -2509 -2510 /// Close the connection immediately, initiated by an API call. -2511 /// -2512 /// This will not produce a [`ConnectionLost`] event propagated by the -2513 /// [`Connection::poll`] call, because the API call already propagated the error to the -2514 /// user. -2515 /// -2516 /// Not to be used when entering immediate close due to an internal state change based -2517 /// on an event. See [`State::move_to_closed_local`] for details. -2518 /// -2519 /// This initiates immediate close from -2520 /// <https://www.rfc-editor.org/rfc/rfc9000.html#section-10.2>, moving to the closed -2521 /// state. -2522 /// -2523 /// [`ConnectionLost`]: crate::Event::ConnectionLost -2524 /// [`Connection::poll`]: super::Connection::poll -2525 fn close_inner(&mut self, now: Instant, reason: Close) { -2526 let was_closed = self.state.is_closed(); -2527 if !was_closed { -2528 self.close_common(); -2529 self.set_close_timer(now); -2530 self.connection_close_pending = true; -2531 self.state.move_to_closed_local(reason); -2532 } -2533 } -2534 -2535 /// Control datagrams -2536 pub fn datagrams(&mut self) -> Datagrams<'_> { -2537 Datagrams { conn: self } -2538 } -2539 -2540 /// Returns connection statistics -2541 pub fn stats(&mut self) -> ConnectionStats { -2542 let mut stats = self.partial_stats.clone(); -2543 -2544 for path_stats in self.path_stats.iter_stats() { -2545 // Self::path_stats() computes the path rtt, cwnd and current_mtu on access -2546 // because they are not simple counters. When computing the connection stats we -2547 // can skip that effort since those fields are not used in the `impl -2548 // Add<PathStats> for ConnectionStats`. -2549 stats += *path_stats; -2550 } -2551 -2552 stats -2553 } -2554 -2555 /// Returns path statistics -2556 pub fn path_stats(&mut self, path_id: PathId) -> Option<PathStats> { -2557 let path = self.paths.get(&path_id)?; -2558 let stats = self.path_stats.for_path(path_id); -2559 stats.rtt = path.data.rtt.get(); -2560 stats.cwnd = path.data.congestion.window(); -2561 stats.current_mtu = path.data.mtud.current_mtu(); -2562 Some(*stats) -2563 } -2564 -2565 /// Ping the remote endpoint -2566 /// -2567 /// Causes an ACK-eliciting packet to be transmitted on the connection. -2568 pub fn ping(&mut self) { -2569 // TODO(flub): This is very brute-force: it pings *all* the paths. Instead it would -2570 // be nice if we could only send a single packet for this. -2571 for path_data in self.spaces[self.highest_space].number_spaces.values_mut() { -2572 path_data.ping_pending = true; -2573 } -2574 } -2575 -2576 /// Ping the remote endpoint over a specific path -2577 /// -2578 /// Causes an ACK-eliciting packet to be transmitted on the path. -2579 pub fn ping_path(&mut self, path: PathId) -> Result<(), ClosedPath> { -2580 let path_data = self.spaces[self.highest_space] -2581 .number_spaces -2582 .get_mut(&path) -2583 .ok_or(ClosedPath { _private: () })?; -2584 path_data.ping_pending = true; -2585 Ok(()) -2586 } -2587 -2588 /// Update traffic keys spontaneously -2589 /// -2590 /// This can be useful for testing key updates, as they otherwise only happen infrequently. -2591 pub fn force_key_update(&mut self) { -2592 if !self.state.is_established() { -2593 debug!("ignoring forced key update in illegal state"); -2594 return; -2595 } -2596 if self.crypto_state.prev_crypto.is_some() { -2597 // We already just updated, or are currently updating, the keys. Concurrent key updates -2598 // are illegal. -2599 debug!("ignoring redundant forced key update"); +2095 let path = &mut self.paths.get_mut(&path_id).expect("checked").data; +2096 let network_path = FourTuple { +2097 remote, +2098 local_ip: None, +2099 }; +2100 +2101 path.record_path_challenge_sent(now, token, network_path); +2102 +2103 // Set retry timer for NAT traversal probes that got no PATH_RESPONSE. +2104 if let Ok(server_state) = self.n0_nat_traversal.server_side_mut() +2105 && server_state.has_pending_retries() +2106 { +2107 let initial_pto = RttEstimator::new(self.config.initial_rtt).pto_base(); +2108 self.timers.set( +2109 Timer::Conn(ConnTimer::NatTraversalProbeRetry), +2110 now + initial_pto, +2111 self.qlog.with_time(now), +2112 ); +2113 } +2114 +2115 let size = buf.len(); +2116 +2117 self.path_stats.for_path(path_id).udp_tx.on_sent(1, size); +2118 +2119 Some(Transmit { +2120 destination: remote, +2121 size, +2122 ecn: None, +2123 segment_size: None, +2124 src_ip: None, +2125 }) +2126 } +2127 +2128 /// Indicate what types of frames are ready to send for the given space. +2129 /// +2130 /// Only for on-path data. +2131 /// +2132 /// *packet_size* is the number of bytes available to build the next packet. +2133 /// *connection_close_pending* indicates whether a CONNECTION_CLOSE frame needs to be +2134 /// sent. +2135 fn space_can_send( +2136 &mut self, +2137 space_id: SpaceId, +2138 path_id: PathId, +2139 packet_size: usize, +2140 connection_close_pending: bool, +2141 ) -> SendableFrames { +2142 let space = &mut self.spaces[space_id]; +2143 let space_has_crypto = self.crypto_state.has_keys(space_id.encryption_level()); +2144 +2145 if !space_has_crypto +2146 && (space_id != SpaceId::Data +2147 || !self.crypto_state.has_keys(EncryptionLevel::ZeroRtt) +2148 || self.side.is_server()) +2149 { +2150 // Nothing to send in this space +2151 return SendableFrames::empty(); +2152 } +2153 +2154 let mut can_send = space.can_send(path_id, &self.streams); +2155 +2156 // Check for 1RTT space. +2157 if space_id == SpaceId::Data { +2158 let pn = space.for_path(path_id).peek_tx_number(); +2159 // Number of bytes available for frames if this is a 1-RTT packet. We're +2160 // guaranteed to be able to send an individual frame at least this large in the +2161 // next 1-RTT packet. This could be generalized to support every space, but it's +2162 // only needed to handle large fixed-size frames, which only exist in 1-RTT +2163 // (application datagrams). +2164 let frame_space_1rtt = +2165 packet_size.saturating_sub(self.predict_1rtt_overhead(pn, path_id)); +2166 can_send |= self.can_send_1rtt(path_id, frame_space_1rtt); +2167 } +2168 +2169 can_send.close = connection_close_pending && space_has_crypto; +2170 +2171 can_send +2172 } +2173 +2174 /// Process `ConnectionEvent`s generated by the associated `Endpoint` +2175 /// +2176 /// Will execute protocol logic upon receipt of a connection event, in turn preparing signals +2177 /// (including application `Event`s, `EndpointEvent`s and outgoing datagrams) that should be +2178 /// extracted through the relevant methods. +2179 pub fn handle_event(&mut self, event: ConnectionEvent) { +2180 use ConnectionEventInner::*; +2181 match event.0 { +2182 Datagram(DatagramConnectionEvent { +2183 now, +2184 network_path, +2185 path_id, +2186 ecn, +2187 first_decode, +2188 remaining, +2189 }) => { +2190 let span = trace_span!("pkt", %path_id); +2191 let _guard = span.enter(); +2192 +2193 if self.update_network_path_or_discard(network_path, path_id) { +2194 // A return value of true indicates we should discard this packet. +2195 return; +2196 } +2197 +2198 let was_anti_amplification_blocked = self +2199 .path(path_id) +2200 .map(|path| path.anti_amplification_blocked(1)) +2201 // We never tried to send on an non-existing (new) path so have not been +2202 // anti-amplification blocked for it previously. +2203 .unwrap_or(false); +2204 +2205 let rx = &mut self.path_stats.for_path(path_id).udp_rx; +2206 rx.datagrams += 1; +2207 rx.bytes += first_decode.len() as u64; +2208 let data_len = first_decode.len(); +2209 +2210 self.handle_decode(now, network_path, path_id, ecn, first_decode); +2211 // The current `path` might have changed inside `handle_decode` since the packet +2212 // could have triggered a migration. The packet might also belong to an unknown +2213 // path and have been rejected. Make sure the data received is accounted for the +2214 // most recent path by accessing `path` after `handle_decode`. +2215 if let Some(path) = self.path_mut(path_id) { +2216 path.inc_total_recvd(data_len as u64); +2217 } +2218 +2219 if let Some(data) = remaining { +2220 self.path_stats.for_path(path_id).udp_rx.bytes += data.len() as u64; +2221 self.handle_coalesced(now, network_path, path_id, ecn, data); +2222 } +2223 +2224 if let Some(path) = self.paths.get_mut(&path_id) { +2225 self.qlog +2226 .emit_recovery_metrics(path_id, &mut path.data, now); +2227 } +2228 +2229 if was_anti_amplification_blocked { +2230 // A prior attempt to set the loss detection timer may have failed due to +2231 // anti-amplification, so ensure it's set now. Prevents a handshake deadlock if +2232 // the server's first flight is lost. +2233 self.set_loss_detection_timer(now, path_id); +2234 } +2235 } +2236 NewIdentifiers(ids, now, cid_len, cid_lifetime) => { +2237 let path_id = ids.first().map(|issued| issued.path_id).unwrap_or_default(); +2238 debug_assert!(ids.iter().all(|issued| issued.path_id == path_id)); +2239 let cid_state = self +2240 .local_cid_state +2241 .entry(path_id) +2242 .or_insert_with(|| CidState::new(cid_len, cid_lifetime, now, 0)); +2243 cid_state.new_cids(&ids, now); +2244 +2245 ids.into_iter().rev().for_each(|frame| { +2246 self.spaces[SpaceId::Data].pending.new_cids.push(frame); +2247 }); +2248 // Always update Timer::PushNewCid +2249 self.reset_cid_retirement(now); +2250 } +2251 } +2252 } +2253 +2254 /// Updates the network path for `path_id`. +2255 /// +2256 /// Returns true if a packet coming in for this `path_id` over given `network_path` should be discarded. +2257 /// Returns false if the path was updated and the packet doesn't need to be discarded. +2258 fn update_network_path_or_discard(&mut self, network_path: FourTuple, path_id: PathId) -> bool { +2259 let remote_may_migrate = self.side.remote_may_migrate(&self.state); +2260 let local_ip_may_migrate = self.side.is_client(); +2261 // If this packet could initiate a migration and we're a client or a server that +2262 // forbids migration, drop the datagram. This could be relaxed to heuristically +2263 // permit NAT-rebinding-like migration. +2264 if let Some(known_path) = self.path_mut(path_id) { +2265 if network_path.remote != known_path.network_path.remote && !remote_may_migrate { +2266 trace!( +2267 %path_id, +2268 %network_path, +2269 %known_path.network_path, +2270 "discarding packet from unrecognized peer" +2271 ); +2272 return true; +2273 } +2274 +2275 if known_path.network_path.local_ip.is_some() +2276 && network_path.local_ip.is_some() +2277 && known_path.network_path.local_ip != network_path.local_ip +2278 && !local_ip_may_migrate +2279 { +2280 trace!( +2281 %path_id, +2282 %network_path, +2283 %known_path.network_path, +2284 "discarding packet sent to incorrect interface" +2285 ); +2286 return true; +2287 } +2288 // If the datagram indicates that we've changed our local IP, we update it. +2289 // This is alluded to in Section 5.2 of the Multipath RFC draft 18: +2290 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-18.html#name-using-multiple-paths-on-the +2291 // > Client receives the packet, recognizes a path migration, updates the source address of path 2 to 192.0.2.1. +2292 if let Some(local_ip) = network_path.local_ip { +2293 if known_path +2294 .network_path +2295 .local_ip +2296 .is_some_and(|ip| ip != local_ip) +2297 { +2298 debug!( +2299 %path_id, +2300 %network_path, +2301 %known_path.network_path, +2302 "path's local address seemingly migrated" +2303 ); +2304 } +2305 // We update the address without path validation on the client side. +2306 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-18.html#section-5.1 +2307 // > Servers observing a 4-tuple change will perform path validation (see Section 9 of [QUIC-TRANSPORT]). +2308 // This sounds like it's *only* the server endpoints that do this. +2309 // TODO(matheus23): We should still consider doing a proper migration on the client side in the future. +2310 // For now, this preserves the behavior of this code pre 4-tuple tracking. +2311 known_path.network_path.local_ip = Some(local_ip); +2312 } +2313 } +2314 false +2315 } +2316 +2317 /// Process timer expirations +2318 /// +2319 /// Executes protocol logic, potentially preparing signals (including application `Event`s, +2320 /// `EndpointEvent`s and outgoing datagrams) that should be extracted through the relevant +2321 /// methods. +2322 /// +2323 /// It is most efficient to call this immediately after the system clock reaches the latest +2324 /// `Instant` that was output by `poll_timeout`; however spurious extra calls will simply +2325 /// no-op and therefore are safe. +2326 pub fn handle_timeout(&mut self, now: Instant) { +2327 while let Some((timer, _time)) = self.timers.expire_before(now, &self.qlog) { +2328 // TODO(@divma): remove `at` when the unicorn is born +2329 trace!(?timer, at=?now, "timeout"); +2330 match timer { +2331 Timer::Conn(timer) => match timer { +2332 ConnTimer::Close => { +2333 self.state.move_to_drained(None); +2334 // move_to_drained checks that we weren't in drained before. +2335 // Adding events to endpoint_events is only legal if `Drained` was never queued before. +2336 self.endpoint_events.push_back(EndpointEventInner::Drained); +2337 } +2338 ConnTimer::Idle => { +2339 self.kill(ConnectionError::TimedOut); +2340 } +2341 ConnTimer::KeepAlive => { +2342 trace!("sending keep-alive"); +2343 self.ping(); +2344 } +2345 ConnTimer::KeyDiscard => { +2346 self.crypto_state.discard_temporary_keys(); +2347 } +2348 ConnTimer::PushNewCid => { +2349 while let Some((path_id, when)) = self.next_cid_retirement() { +2350 if when > now { +2351 break; +2352 } +2353 match self.local_cid_state.get_mut(&path_id) { +2354 None => error!(%path_id, "No local CID state for path"), +2355 Some(cid_state) => { +2356 // Update `retire_prior_to` field in NEW_CONNECTION_ID frame +2357 let num_new_cid = cid_state.on_cid_timeout().into(); +2358 if !self.state.is_closed() { +2359 trace!( +2360 "push a new CID to peer RETIRE_PRIOR_TO field {}", +2361 cid_state.retire_prior_to() +2362 ); +2363 self.endpoint_events.push_back( +2364 EndpointEventInner::NeedIdentifiers( +2365 path_id, +2366 now, +2367 num_new_cid, +2368 ), +2369 ); +2370 } +2371 } +2372 } +2373 } +2374 } +2375 ConnTimer::NoAvailablePath => { +2376 // Grace period expired: all paths were abandoned and no new path +2377 // was opened. Close the connection. There are no paths left to +2378 // send CONNECTION_CLOSE on, so this is a silent close. +2379 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-21.html#section-3.4-8 +2380 if self.state.is_closed() || self.state.is_drained() { +2381 // Connection already closing/drained (e.g. application called +2382 // close() before the grace timer fired). Nothing to do. +2383 error!("no viable path timer fired, but connection already closing"); +2384 } else { +2385 trace!("no viable path grace period expired, closing connection"); +2386 let err = TransportError::NO_VIABLE_PATH( +2387 "last path abandoned, no new path opened", +2388 ); +2389 self.close_common(); +2390 self.set_close_timer(now); +2391 self.connection_close_pending = true; +2392 self.state.move_to_closed(err); +2393 } +2394 } +2395 ConnTimer::NatTraversalProbeRetry => { +2396 if let Ok(server_state) = self.n0_nat_traversal.server_side_mut() +2397 && server_state.queue_retries() +2398 { +2399 trace!("off-path probe retry timer fired, re-queued probes"); +2400 } +2401 } +2402 }, +2403 Timer::PerPath(path_id, timer) => { +2404 let span = trace_span!("per-path timer fired", %path_id, ?timer); +2405 let _guard = span.enter(); +2406 match timer { +2407 PathTimer::PathIdle => { +2408 if let Err(err) = +2409 self.close_path_inner(now, path_id, PathAbandonReason::TimedOut) +2410 { +2411 warn!(?err, "failed closing path"); +2412 } +2413 } +2414 +2415 PathTimer::PathKeepAlive => { +2416 trace!("sending keep-alive on path"); +2417 self.ping_path(path_id).ok(); +2418 } +2419 PathTimer::LossDetection => { +2420 self.on_loss_detection_timeout(now, path_id); +2421 self.qlog.emit_recovery_metrics( +2422 path_id, +2423 &mut self.paths.get_mut(&path_id).unwrap().data, +2424 now, +2425 ); +2426 } +2427 PathTimer::PathValidationFailed => { +2428 let Some(path) = self.paths.get_mut(&path_id) else { +2429 continue; +2430 }; +2431 self.timers.stop( +2432 Timer::PerPath(path_id, PathTimer::PathChallengeLost), +2433 self.qlog.with_time(now), +2434 ); +2435 debug!("path migration validation failed"); +2436 if let Some((_, prev)) = path.prev.take() { +2437 path.data = prev; +2438 } +2439 path.data.reset_on_path_challenges(); +2440 } +2441 PathTimer::PathChallengeLost => { +2442 let Some(path) = self.paths.get_mut(&path_id) else { +2443 continue; +2444 }; +2445 trace!("path challenge deemed lost"); +2446 path.data.pending_on_path_challenge = true; +2447 } +2448 PathTimer::PathOpenFailed => { +2449 let Some(path) = self.paths.get_mut(&path_id) else { +2450 continue; +2451 }; +2452 path.data.reset_on_path_challenges(); +2453 self.timers.stop( +2454 Timer::PerPath(path_id, PathTimer::PathChallengeLost), +2455 self.qlog.with_time(now), +2456 ); +2457 debug!("new path validation failed"); +2458 if let Err(err) = self.close_path_inner( +2459 now, +2460 path_id, +2461 PathAbandonReason::ValidationFailed, +2462 ) { +2463 warn!(?err, "failed closing path"); +2464 } +2465 } +2466 PathTimer::Pacing => trace!("pacing timer expired"), +2467 PathTimer::MaxAckDelay => { +2468 trace!("max ack delay reached"); +2469 // This timer is only armed in the Data space +2470 self.spaces[SpaceId::Data] +2471 .for_path(path_id) +2472 .pending_acks +2473 .on_max_ack_delay_timeout() +2474 } +2475 PathTimer::PathDrained => { +2476 // The path was abandoned and 3*PTO has expired since. Clean up all +2477 // remaining state and install stateless reset token. +2478 self.timers.stop_per_path(path_id, self.qlog.with_time(now)); +2479 if let Some(local_cid_state) = self.local_cid_state.remove(&path_id) { +2480 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events. All timers should be cleared in drained connections. +2481 let (min_seq, max_seq) = local_cid_state.active_seq(); +2482 for seq in min_seq..=max_seq { +2483 self.endpoint_events.push_back( +2484 EndpointEventInner::RetireConnectionId( +2485 now, path_id, seq, false, +2486 ), +2487 ); +2488 } +2489 } +2490 self.discard_path(path_id, now); +2491 } +2492 } +2493 } +2494 } +2495 } +2496 } +2497 +2498 /// Close a connection immediately +2499 /// +2500 /// This does not ensure delivery of outstanding data. It is the application's responsibility to +2501 /// call this only when all important communications have been completed, e.g. by calling +2502 /// [`SendStream::finish`] on outstanding streams and waiting for the corresponding +2503 /// [`StreamEvent::Finished`] event. +2504 /// +2505 /// If [`Streams::send_streams`] returns 0, all outstanding stream data has been +2506 /// delivered. There may still be data from the peer that has not been received. +2507 /// +2508 /// [`StreamEvent::Finished`]: crate::StreamEvent::Finished +2509 pub fn close(&mut self, now: Instant, error_code: VarInt, reason: Bytes) { +2510 self.close_inner( +2511 now, +2512 Close::Application(frame::ApplicationClose { error_code, reason }), +2513 ) +2514 } +2515 +2516 /// Close the connection immediately, initiated by an API call. +2517 /// +2518 /// This will not produce a [`ConnectionLost`] event propagated by the +2519 /// [`Connection::poll`] call, because the API call already propagated the error to the +2520 /// user. +2521 /// +2522 /// Not to be used when entering immediate close due to an internal state change based +2523 /// on an event. See [`State::move_to_closed_local`] for details. +2524 /// +2525 /// This initiates immediate close from +2526 /// <https://www.rfc-editor.org/rfc/rfc9000.html#section-10.2>, moving to the closed +2527 /// state. +2528 /// +2529 /// [`ConnectionLost`]: crate::Event::ConnectionLost +2530 /// [`Connection::poll`]: super::Connection::poll +2531 fn close_inner(&mut self, now: Instant, reason: Close) { +2532 let was_closed = self.state.is_closed(); +2533 if !was_closed { +2534 self.close_common(); +2535 self.set_close_timer(now); +2536 self.connection_close_pending = true; +2537 self.state.move_to_closed_local(reason); +2538 } +2539 } +2540 +2541 /// Control datagrams +2542 pub fn datagrams(&mut self) -> Datagrams<'_> { +2543 Datagrams { conn: self } +2544 } +2545 +2546 /// Returns connection statistics +2547 pub fn stats(&mut self) -> ConnectionStats { +2548 let mut stats = self.partial_stats.clone(); +2549 +2550 for path_stats in self.path_stats.iter_stats() { +2551 // Self::path_stats() computes the path rtt, cwnd and current_mtu on access +2552 // because they are not simple counters. When computing the connection stats we +2553 // can skip that effort since those fields are not used in the `impl +2554 // Add<PathStats> for ConnectionStats`. +2555 stats += *path_stats; +2556 } +2557 +2558 stats +2559 } +2560 +2561 /// Returns path statistics +2562 pub fn path_stats(&mut self, path_id: PathId) -> Option<PathStats> { +2563 let path = self.paths.get(&path_id)?; +2564 let stats = self.path_stats.for_path(path_id); +2565 stats.rtt = path.data.rtt.get(); +2566 stats.cwnd = path.data.congestion.window(); +2567 stats.current_mtu = path.data.mtud.current_mtu(); +2568 Some(*stats) +2569 } +2570 +2571 /// Ping the remote endpoint +2572 /// +2573 /// Causes an ACK-eliciting packet to be transmitted on the connection. +2574 pub fn ping(&mut self) { +2575 // TODO(flub): This is very brute-force: it pings *all* the paths. Instead it would +2576 // be nice if we could only send a single packet for this. +2577 for path_data in self.spaces[self.highest_space].number_spaces.values_mut() { +2578 path_data.ping_pending = true; +2579 } +2580 } +2581 +2582 /// Ping the remote endpoint over a specific path +2583 /// +2584 /// Causes an ACK-eliciting packet to be transmitted on the path. +2585 pub fn ping_path(&mut self, path: PathId) -> Result<(), ClosedPath> { +2586 let path_data = self.spaces[self.highest_space] +2587 .number_spaces +2588 .get_mut(&path) +2589 .ok_or(ClosedPath { _private: () })?; +2590 path_data.ping_pending = true; +2591 Ok(()) +2592 } +2593 +2594 /// Update traffic keys spontaneously +2595 /// +2596 /// This can be useful for testing key updates, as they otherwise only happen infrequently. +2597 pub fn force_key_update(&mut self) { +2598 if !self.state.is_established() { +2599 debug!("ignoring forced key update in illegal state"); 2600 return; 2601 } -2602 self.crypto_state.update_keys(None, false); -2603 } -2604 -2605 /// Get a session reference -2606 pub fn crypto_session(&self) -> &dyn crypto::Session { -2607 self.crypto_state.session.as_ref() -2608 } -2609 -2610 /// Whether the connection is in the process of being established -2611 /// -2612 /// If this returns `false`, the connection may be either established or closed, -2613 /// signaled by the emission of a `Connected` or `ConnectionLost` message respectively. -2614 /// -2615 /// For an established connection this essentially means the handshake is **completed**, -2616 /// but not necessarily yet confirmed. -2617 pub fn is_handshaking(&self) -> bool { -2618 self.state.is_handshake() -2619 } -2620 -2621 /// Whether the connection is closed -2622 /// -2623 /// Closed connections cannot transport any further data. A connection becomes closed when -2624 /// either peer application intentionally closes it, or when either transport layer detects an -2625 /// error such as a time-out or certificate validation failure. -2626 /// -2627 /// A `ConnectionLost` event is emitted with details when the connection becomes closed. -2628 pub fn is_closed(&self) -> bool { -2629 self.state.is_closed() -2630 } -2631 -2632 /// Whether there is no longer any need to keep the connection around -2633 /// -2634 /// Closed connections become drained after a brief timeout to absorb any remaining in-flight -2635 /// packets from the peer. All drained connections have been closed. -2636 pub fn is_drained(&self) -> bool { -2637 self.state.is_drained() -2638 } -2639 -2640 /// For clients, if the peer accepted the 0-RTT data packets -2641 /// -2642 /// The value is meaningless until after the handshake completes. -2643 pub fn accepted_0rtt(&self) -> bool { -2644 self.crypto_state.accepted_0rtt -2645 } -2646 -2647 /// Whether 0-RTT is/was possible during the handshake -2648 pub fn has_0rtt(&self) -> bool { -2649 self.crypto_state.zero_rtt_enabled -2650 } -2651 -2652 /// Whether there are any pending retransmits -2653 pub fn has_pending_retransmits(&self) -> bool { -2654 !self.spaces[SpaceId::Data].pending.is_empty(&self.streams) -2655 } -2656 -2657 /// Look up whether we're the client or server of this Connection -2658 pub fn side(&self) -> Side { -2659 self.side.side() -2660 } -2661 -2662 /// Get the address observed by the remote over the given path -2663 pub fn path_observed_address(&self, path_id: PathId) -> Result<Option<SocketAddr>, ClosedPath> { -2664 self.path(path_id) -2665 .map(|path_data| { -2666 path_data -2667 .last_observed_addr_report -2668 .as_ref() -2669 .map(|observed| observed.socket_addr()) -2670 }) -2671 .ok_or(ClosedPath { _private: () }) -2672 } -2673 -2674 /// Current best estimate of this connection's latency (round-trip-time) -2675 pub fn rtt(&self, path_id: PathId) -> Option<Duration> { -2676 self.path(path_id).map(|d| d.rtt.get()) -2677 } -2678 -2679 /// Current state of this connection's congestion controller, for debugging purposes -2680 pub fn congestion_state(&self, path_id: PathId) -> Option<&dyn Controller> { -2681 self.path(path_id).map(|d| d.congestion.as_ref()) -2682 } -2683 -2684 /// Modify the number of remotely initiated streams that may be concurrently open -2685 /// -2686 /// No streams may be opened by the peer unless fewer than `count` are already open. Large -2687 /// `count`s increase both minimum and worst-case memory consumption. -2688 pub fn set_max_concurrent_streams(&mut self, dir: Dir, count: VarInt) { -2689 self.streams.set_max_concurrent(dir, count); -2690 // If the limit was reduced, then a flow control update previously deemed insignificant may -2691 // now be significant. -2692 let pending = &mut self.spaces[SpaceId::Data].pending; -2693 self.streams.queue_max_stream_id(pending); -2694 } -2695 -2696 /// Modify the number of open paths allowed when multipath is enabled -2697 /// -2698 /// When reducing the number of concurrent paths this will only affect delaying sending -2699 /// new MAX_PATH_ID frames until fewer than this number of paths are possible. To -2700 /// actively reduce paths they must be closed using [`Connection::close_path`], which -2701 /// can also be used to close not-yet-opened paths. -2702 /// -2703 /// If multipath is not negotiated (see the [`TransportConfig`]) this can not enable -2704 /// multipath and will fail. -2705 pub fn set_max_concurrent_paths( -2706 &mut self, -2707 now: Instant, -2708 count: NonZeroU32, -2709 ) -> Result<(), MultipathNotNegotiated> { -2710 if !self.is_multipath_negotiated() { -2711 return Err(MultipathNotNegotiated { _private: () }); -2712 } -2713 self.max_concurrent_paths = count; -2714 -2715 let in_use_count = self -2716 .local_max_path_id -2717 .next() -2718 .saturating_sub(self.abandoned_paths.len() as u32) -2719 .as_u32(); -2720 let extra_needed = count.get().saturating_sub(in_use_count); -2721 let new_max_path_id = self.local_max_path_id.saturating_add(extra_needed); -2722 -2723 self.set_max_path_id(now, new_max_path_id); -2724 -2725 Ok(()) -2726 } -2727 -2728 /// If needed, issues a new MAX_PATH_ID frame and new CIDs for any newly allowed paths -2729 fn set_max_path_id(&mut self, now: Instant, max_path_id: PathId) { -2730 if max_path_id <= self.local_max_path_id { -2731 return; -2732 } +2602 if self.crypto_state.prev_crypto.is_some() { +2603 // We already just updated, or are currently updating, the keys. Concurrent key updates +2604 // are illegal. +2605 debug!("ignoring redundant forced key update"); +2606 return; +2607 } +2608 self.crypto_state.update_keys(None, false); +2609 } +2610 +2611 /// Get a session reference +2612 pub fn crypto_session(&self) -> &dyn crypto::Session { +2613 self.crypto_state.session.as_ref() +2614 } +2615 +2616 /// Whether the connection is in the process of being established +2617 /// +2618 /// If this returns `false`, the connection may be either established or closed, +2619 /// signaled by the emission of a `Connected` or `ConnectionLost` message respectively. +2620 /// +2621 /// For an established connection this essentially means the handshake is **completed**, +2622 /// but not necessarily yet confirmed. +2623 pub fn is_handshaking(&self) -> bool { +2624 self.state.is_handshake() +2625 } +2626 +2627 /// Whether the connection is closed +2628 /// +2629 /// Closed connections cannot transport any further data. A connection becomes closed when +2630 /// either peer application intentionally closes it, or when either transport layer detects an +2631 /// error such as a time-out or certificate validation failure. +2632 /// +2633 /// A `ConnectionLost` event is emitted with details when the connection becomes closed. +2634 pub fn is_closed(&self) -> bool { +2635 self.state.is_closed() +2636 } +2637 +2638 /// Whether there is no longer any need to keep the connection around +2639 /// +2640 /// Closed connections become drained after a brief timeout to absorb any remaining in-flight +2641 /// packets from the peer. All drained connections have been closed. +2642 pub fn is_drained(&self) -> bool { +2643 self.state.is_drained() +2644 } +2645 +2646 /// For clients, if the peer accepted the 0-RTT data packets +2647 /// +2648 /// The value is meaningless until after the handshake completes. +2649 pub fn accepted_0rtt(&self) -> bool { +2650 self.crypto_state.accepted_0rtt +2651 } +2652 +2653 /// Whether 0-RTT is/was possible during the handshake +2654 pub fn has_0rtt(&self) -> bool { +2655 self.crypto_state.zero_rtt_enabled +2656 } +2657 +2658 /// Whether there are any pending retransmits +2659 pub fn has_pending_retransmits(&self) -> bool { +2660 !self.spaces[SpaceId::Data].pending.is_empty(&self.streams) +2661 } +2662 +2663 /// Look up whether we're the client or server of this Connection +2664 pub fn side(&self) -> Side { +2665 self.side.side() +2666 } +2667 +2668 /// Get the address observed by the remote over the given path +2669 pub fn path_observed_address(&self, path_id: PathId) -> Result<Option<SocketAddr>, ClosedPath> { +2670 self.path(path_id) +2671 .map(|path_data| { +2672 path_data +2673 .last_observed_addr_report +2674 .as_ref() +2675 .map(|observed| observed.socket_addr()) +2676 }) +2677 .ok_or(ClosedPath { _private: () }) +2678 } +2679 +2680 /// Current best estimate of this connection's latency (round-trip-time) +2681 pub fn rtt(&self, path_id: PathId) -> Option<Duration> { +2682 self.path(path_id).map(|d| d.rtt.get()) +2683 } +2684 +2685 /// Current state of this connection's congestion controller, for debugging purposes +2686 pub fn congestion_state(&self, path_id: PathId) -> Option<&dyn Controller> { +2687 self.path(path_id).map(|d| d.congestion.as_ref()) +2688 } +2689 +2690 /// Modify the number of remotely initiated streams that may be concurrently open +2691 /// +2692 /// No streams may be opened by the peer unless fewer than `count` are already open. Large +2693 /// `count`s increase both minimum and worst-case memory consumption. +2694 pub fn set_max_concurrent_streams(&mut self, dir: Dir, count: VarInt) { +2695 self.streams.set_max_concurrent(dir, count); +2696 // If the limit was reduced, then a flow control update previously deemed insignificant may +2697 // now be significant. +2698 let pending = &mut self.spaces[SpaceId::Data].pending; +2699 self.streams.queue_max_stream_id(pending); +2700 } +2701 +2702 /// Modify the number of open paths allowed when multipath is enabled +2703 /// +2704 /// When reducing the number of concurrent paths this will only affect delaying sending +2705 /// new MAX_PATH_ID frames until fewer than this number of paths are possible. To +2706 /// actively reduce paths they must be closed using [`Connection::close_path`], which +2707 /// can also be used to close not-yet-opened paths. +2708 /// +2709 /// If multipath is not negotiated (see the [`TransportConfig`]) this can not enable +2710 /// multipath and will fail. +2711 pub fn set_max_concurrent_paths( +2712 &mut self, +2713 now: Instant, +2714 count: NonZeroU32, +2715 ) -> Result<(), MultipathNotNegotiated> { +2716 if !self.is_multipath_negotiated() { +2717 return Err(MultipathNotNegotiated { _private: () }); +2718 } +2719 self.max_concurrent_paths = count; +2720 +2721 let in_use_count = self +2722 .local_max_path_id +2723 .next() +2724 .saturating_sub(self.abandoned_paths.len() as u32) +2725 .as_u32(); +2726 let extra_needed = count.get().saturating_sub(in_use_count); +2727 let new_max_path_id = self.local_max_path_id.saturating_add(extra_needed); +2728 +2729 self.set_max_path_id(now, new_max_path_id); +2730 +2731 Ok(()) +2732 } 2733 -2734 self.local_max_path_id = max_path_id; -2735 self.spaces[SpaceId::Data].pending.max_path_id = true; -2736 -2737 self.issue_first_path_cids(now); -2738 } +2734 /// If needed, issues a new MAX_PATH_ID frame and new CIDs for any newly allowed paths +2735 fn set_max_path_id(&mut self, now: Instant, max_path_id: PathId) { +2736 if max_path_id <= self.local_max_path_id { +2737 return; +2738 } 2739 -2740 /// Current number of remotely initiated streams that may be concurrently open -2741 /// -2742 /// If the target for this limit is reduced using [`set_max_concurrent_streams`](Self::set_max_concurrent_streams), -2743 /// it will not change immediately, even if fewer streams are open. Instead, it will -2744 /// decrement by one for each time a remotely initiated stream of matching directionality is closed. -2745 pub fn max_concurrent_streams(&self, dir: Dir) -> u64 { -2746 self.streams.max_concurrent(dir) -2747 } -2748 -2749 /// See [`TransportConfig::send_window()`] -2750 pub fn set_send_window(&mut self, send_window: u64) { -2751 self.streams.set_send_window(send_window); -2752 } -2753 -2754 /// See [`TransportConfig::receive_window()`] -2755 pub fn set_receive_window(&mut self, receive_window: VarInt) { -2756 if self.streams.set_receive_window(receive_window) { -2757 self.spaces[SpaceId::Data].pending.max_data = true; -2758 } -2759 } -2760 -2761 /// Whether the Multipath for QUIC extension is enabled. -2762 /// -2763 /// Multipath is only enabled after the handshake is completed and if it was enabled by both -2764 /// peers. -2765 pub fn is_multipath_negotiated(&self) -> bool { -2766 !self.is_handshaking() -2767 && self.config.max_concurrent_multipath_paths.is_some() -2768 && self.peer_params.initial_max_path_id.is_some() -2769 } -2770 -2771 fn on_ack_received( -2772 &mut self, -2773 now: Instant, -2774 space: SpaceId, -2775 ack: frame::Ack, -2776 ) -> Result<(), TransportError> { -2777 // All ACKs are referencing path 0 -2778 let path = PathId::ZERO; -2779 self.inner_on_ack_received(now, space, path, ack) -2780 } -2781 -2782 fn on_path_ack_received( -2783 &mut self, -2784 now: Instant, -2785 space: SpaceId, -2786 path_ack: frame::PathAck, -2787 ) -> Result<(), TransportError> { -2788 let (ack, path) = path_ack.into_ack(); -2789 self.inner_on_ack_received(now, space, path, ack) -2790 } -2791 -2792 /// Handles an ACK frame acknowledging packets sent on *path*. -2793 fn inner_on_ack_received( -2794 &mut self, -2795 now: Instant, -2796 space: SpaceId, -2797 path: PathId, -2798 ack: frame::Ack, -2799 ) -> Result<(), TransportError> { -2800 if !self.spaces[space].number_spaces.contains_key(&path) -2801 && self.abandoned_paths.contains(&path) -2802 { -2803 // See also -2804 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-21.html#section-3.4.3-3 -2805 // > When an endpoint finally deletes all state associated with the path [...] -2806 // > PATH_ACK frames received with an abandoned path ID are silently ignored, -2807 // > as specified in Section 4. -2808 trace!("silently ignoring PATH_ACK on discarded path"); -2809 return Ok(()); -2810 } -2811 if ack.largest >= self.spaces[space].for_path(path).next_packet_number { -2812 return Err(TransportError::PROTOCOL_VIOLATION("unsent packet acked")); -2813 } -2814 let new_largest = { -2815 let space = &mut self.spaces[space].for_path(path); -2816 if space.largest_acked_packet.is_none_or(|pn| ack.largest > pn) { -2817 space.largest_acked_packet = Some(ack.largest); -2818 if let Some(info) = space.sent_packets.get(ack.largest) { -2819 // This should always succeed, but a misbehaving peer might ACK a packet we -2820 // haven't sent. At worst, that will result in us spuriously reducing the -2821 // congestion window. -2822 space.largest_acked_packet_sent = info.time_sent; -2823 } -2824 true -2825 } else { -2826 false -2827 } -2828 }; -2829 -2830 if self.detect_spurious_loss(&ack, space, path) { -2831 self.path_data_mut(path) -2832 .congestion -2833 .on_spurious_congestion_event(); -2834 } +2740 self.local_max_path_id = max_path_id; +2741 self.spaces[SpaceId::Data].pending.max_path_id = true; +2742 +2743 self.issue_first_path_cids(now); +2744 } +2745 +2746 /// Current number of remotely initiated streams that may be concurrently open +2747 /// +2748 /// If the target for this limit is reduced using [`set_max_concurrent_streams`](Self::set_max_concurrent_streams), +2749 /// it will not change immediately, even if fewer streams are open. Instead, it will +2750 /// decrement by one for each time a remotely initiated stream of matching directionality is closed. +2751 pub fn max_concurrent_streams(&self, dir: Dir) -> u64 { +2752 self.streams.max_concurrent(dir) +2753 } +2754 +2755 /// See [`TransportConfig::send_window()`] +2756 pub fn set_send_window(&mut self, send_window: u64) { +2757 self.streams.set_send_window(send_window); +2758 } +2759 +2760 /// See [`TransportConfig::receive_window()`] +2761 pub fn set_receive_window(&mut self, receive_window: VarInt) { +2762 if self.streams.set_receive_window(receive_window) { +2763 self.spaces[SpaceId::Data].pending.max_data = true; +2764 } +2765 } +2766 +2767 /// Whether the Multipath for QUIC extension is enabled. +2768 /// +2769 /// Multipath is only enabled after the handshake is completed and if it was enabled by both +2770 /// peers. +2771 pub fn is_multipath_negotiated(&self) -> bool { +2772 !self.is_handshaking() +2773 && self.config.max_concurrent_multipath_paths.is_some() +2774 && self.peer_params.initial_max_path_id.is_some() +2775 } +2776 +2777 fn on_ack_received( +2778 &mut self, +2779 now: Instant, +2780 space: SpaceId, +2781 ack: frame::Ack, +2782 ) -> Result<(), TransportError> { +2783 // All ACKs are referencing path 0 +2784 let path = PathId::ZERO; +2785 self.inner_on_ack_received(now, space, path, ack) +2786 } +2787 +2788 fn on_path_ack_received( +2789 &mut self, +2790 now: Instant, +2791 space: SpaceId, +2792 path_ack: frame::PathAck, +2793 ) -> Result<(), TransportError> { +2794 let (ack, path) = path_ack.into_ack(); +2795 self.inner_on_ack_received(now, space, path, ack) +2796 } +2797 +2798 /// Handles an ACK frame acknowledging packets sent on *path*. +2799 fn inner_on_ack_received( +2800 &mut self, +2801 now: Instant, +2802 space: SpaceId, +2803 path: PathId, +2804 ack: frame::Ack, +2805 ) -> Result<(), TransportError> { +2806 if !self.spaces[space].number_spaces.contains_key(&path) +2807 && self.abandoned_paths.contains(&path) +2808 { +2809 // See also +2810 // https://www.ietf.org/archive/id/draft-ietf-quic-multipath-21.html#section-3.4.3-3 +2811 // > When an endpoint finally deletes all state associated with the path [...] +2812 // > PATH_ACK frames received with an abandoned path ID are silently ignored, +2813 // > as specified in Section 4. +2814 trace!("silently ignoring PATH_ACK on discarded path"); +2815 return Ok(()); +2816 } +2817 if ack.largest >= self.spaces[space].for_path(path).next_packet_number { +2818 return Err(TransportError::PROTOCOL_VIOLATION("unsent packet acked")); +2819 } +2820 let new_largest = { +2821 let space = &mut self.spaces[space].for_path(path); +2822 if space.largest_acked_packet.is_none_or(|pn| ack.largest > pn) { +2823 space.largest_acked_packet = Some(ack.largest); +2824 if let Some(info) = space.sent_packets.get(ack.largest) { +2825 // This should always succeed, but a misbehaving peer might ACK a packet we +2826 // haven't sent. At worst, that will result in us spuriously reducing the +2827 // congestion window. +2828 space.largest_acked_packet_sent = info.time_sent; +2829 } +2830 true +2831 } else { +2832 false +2833 } +2834 }; 2835 -2836 // Avoid DoS from unreasonably huge ack ranges by filtering out just the new acks. -2837 let mut newly_acked = ArrayRangeSet::new(); -2838 for range in ack.iter() { -2839 self.spaces[space].for_path(path).check_ack(range.clone())?; -2840 for (pn, _) in self.spaces[space] -2841 .for_path(path) -2842 .sent_packets -2843 .iter_range(range) -2844 { -2845 newly_acked.insert_one(pn); -2846 } -2847 } -2848 -2849 if newly_acked.is_empty() { -2850 return Ok(()); -2851 } -2852 -2853 let mut ack_eliciting_acked = false; -2854 for packet in newly_acked.elts() { -2855 if let Some(info) = self.spaces[space].for_path(path).take(packet) { -2856 for (acked_path_id, acked_pn) in info.largest_acked.iter() { -2857 // Assume ACKs for all packets below the largest acknowledged in -2858 // `packet` have been received. This can cause the peer to spuriously -2859 // retransmit if some of our earlier ACKs were lost, but allows for -2860 // simpler state tracking. See discussion at -2861 // https://www.rfc-editor.org/rfc/rfc9000.html#name-limiting-ranges-by-tracking -2862 if let Some(pns) = self.spaces[space].path_space_mut(*acked_path_id) { -2863 pns.pending_acks.subtract_below(*acked_pn); -2864 } -2865 } -2866 ack_eliciting_acked |= info.ack_eliciting; -2867 -2868 // Notify MTU discovery that a packet was acked, because it might be an MTU probe -2869 let path_data = self.path_data_mut(path); -2870 let mtu_updated = path_data.mtud.on_acked(space.kind(), packet, info.size); -2871 if mtu_updated { -2872 path_data -2873 .congestion -2874 .on_mtu_update(path_data.mtud.current_mtu()); -2875 } -2876 -2877 // Notify ack frequency that a packet was acked, because it might contain an ACK_FREQUENCY frame -2878 self.ack_frequency.on_acked(path, packet); -2879 -2880 self.on_packet_acked(now, path, info); -2881 } -2882 } -2883 -2884 let largest_ackd = self.spaces[space].for_path(path).largest_acked_packet; -2885 let path_data = self.path_data_mut(path); -2886 let app_limited = path_data.app_limited; -2887 let in_flight = path_data.in_flight.bytes; -2888 -2889 path_data -2890 .congestion -2891 .on_end_acks(now, in_flight, app_limited, largest_ackd); -2892 -2893 if new_largest && ack_eliciting_acked { -2894 let ack_delay = if space != SpaceId::Data { -2895 Duration::from_micros(0) -2896 } else { -2897 cmp::min( -2898 self.ack_frequency.peer_max_ack_delay, -2899 Duration::from_micros(ack.delay << self.peer_params.ack_delay_exponent.0), -2900 ) -2901 }; -2902 let rtt = now.saturating_duration_since( -2903 self.spaces[space].for_path(path).largest_acked_packet_sent, -2904 ); -2905 -2906 let next_pn = self.spaces[space].for_path(path).next_packet_number; -2907 let path_data = self.path_data_mut(path); -2908 // TODO(@divma): should be a method of path, should be contained in a single place -2909 path_data.rtt.update(ack_delay, rtt); -2910 if path_data.first_packet_after_rtt_sample.is_none() { -2911 path_data.first_packet_after_rtt_sample = Some((space.kind(), next_pn)); -2912 } -2913 } -2914 -2915 // Must be called before crypto/pto_count are clobbered -2916 self.detect_lost_packets(now, space, path, true); -2917 -2918 // If the peer did not complete the handshake address validation the ACK could be -2919 // spoofed, e.g. in the Initial space. Setting the pto_count back to 0 removes the -2920 // exponential backoff from the PTO timer and would result in too many tail-loss -2921 // probes being sent. -2922 if self.peer_completed_handshake_address_validation() { -2923 self.path_data_mut(path).pto_count = 0; -2924 } -2925 -2926 // Explicit congestion notification -2927 // TODO(@divma): this code is a good example of logic that should be contained in a single -2928 // place but it's split between the path data and the packet number space data, we should -2929 // find a way to make this work without two lookups -2930 if self.path_data(path).sending_ecn { -2931 if let Some(ecn) = ack.ecn { -2932 // We only examine ECN counters from ACKs that we are certain we received in transmit -2933 // order, allowing us to compute an increase in ECN counts to compare against the number -2934 // of newly acked packets that remains well-defined in the presence of arbitrary packet -2935 // reordering. -2936 if new_largest { -2937 let sent = self.spaces[space].for_path(path).largest_acked_packet_sent; -2938 self.process_ecn(now, space, path, newly_acked.len() as u64, ecn, sent); -2939 } -2940 } else { -2941 // We always start out sending ECN, so any ack that doesn't acknowledge it disables it. -2942 debug!("ECN not acknowledged by peer"); -2943 self.path_data_mut(path).sending_ecn = false; -2944 } -2945 } -2946 -2947 self.set_loss_detection_timer(now, path); -2948 Ok(()) -2949 } -2950 -2951 fn detect_spurious_loss(&mut self, ack: &frame::Ack, space: SpaceId, path: PathId) -> bool { -2952 let lost_packets = &mut self.spaces[space].for_path(path).lost_packets; -2953 -2954 if lost_packets.is_empty() { -2955 return false; -2956 } -2957 -2958 for range in ack.iter() { -2959 let spurious_losses: Vec<u64> = lost_packets -2960 .iter_range(range.clone()) -2961 .map(|(pn, _info)| pn) -2962 .collect(); +2836 if self.detect_spurious_loss(&ack, space, path) { +2837 self.path_data_mut(path) +2838 .congestion +2839 .on_spurious_congestion_event(); +2840 } +2841 +2842 // Avoid DoS from unreasonably huge ack ranges by filtering out just the new acks. +2843 let mut newly_acked = ArrayRangeSet::new(); +2844 for range in ack.iter() { +2845 self.spaces[space].for_path(path).check_ack(range.clone())?; +2846 for (pn, _) in self.spaces[space] +2847 .for_path(path) +2848 .sent_packets +2849 .iter_range(range) +2850 { +2851 newly_acked.insert_one(pn); +2852 } +2853 } +2854 +2855 if newly_acked.is_empty() { +2856 return Ok(()); +2857 } +2858 +2859 let mut ack_eliciting_acked = false; +2860 for packet in newly_acked.elts() { +2861 if let Some(info) = self.spaces[space].for_path(path).take(packet) { +2862 for (acked_path_id, acked_pn) in info.largest_acked.iter() { +2863 // Assume ACKs for all packets below the largest acknowledged in +2864 // `packet` have been received. This can cause the peer to spuriously +2865 // retransmit if some of our earlier ACKs were lost, but allows for +2866 // simpler state tracking. See discussion at +2867 // https://www.rfc-editor.org/rfc/rfc9000.html#name-limiting-ranges-by-tracking +2868 if let Some(pns) = self.spaces[space].path_space_mut(*acked_path_id) { +2869 pns.pending_acks.subtract_below(*acked_pn); +2870 } +2871 } +2872 ack_eliciting_acked |= info.ack_eliciting; +2873 +2874 // Notify MTU discovery that a packet was acked, because it might be an MTU probe +2875 let path_data = self.path_data_mut(path); +2876 let mtu_updated = path_data.mtud.on_acked(space.kind(), packet, info.size); +2877 if mtu_updated { +2878 path_data +2879 .congestion +2880 .on_mtu_update(path_data.mtud.current_mtu()); +2881 } +2882 +2883 // Notify ack frequency that a packet was acked, because it might contain an ACK_FREQUENCY frame +2884 self.ack_frequency.on_acked(path, packet); +2885 +2886 self.on_packet_acked(now, path, info); +2887 } +2888 } +2889 +2890 let largest_ackd = self.spaces[space].for_path(path).largest_acked_packet; +2891 let path_data = self.path_data_mut(path); +2892 let app_limited = path_data.app_limited; +2893 let in_flight = path_data.in_flight.bytes; +2894 +2895 path_data +2896 .congestion +2897 .on_end_acks(now, in_flight, app_limited, largest_ackd); +2898 +2899 if new_largest && ack_eliciting_acked { +2900 let ack_delay = if space != SpaceId::Data { +2901 Duration::from_micros(0) +2902 } else { +2903 cmp::min( +2904 self.ack_frequency.peer_max_ack_delay, +2905 Duration::from_micros(ack.delay << self.peer_params.ack_delay_exponent.0), +2906 ) +2907 }; +2908 let rtt = now.saturating_duration_since( +2909 self.spaces[space].for_path(path).largest_acked_packet_sent, +2910 ); +2911 +2912 let next_pn = self.spaces[space].for_path(path).next_packet_number; +2913 let path_data = self.path_data_mut(path); +2914 // TODO(@divma): should be a method of path, should be contained in a single place +2915 path_data.rtt.update(ack_delay, rtt); +2916 if path_data.first_packet_after_rtt_sample.is_none() { +2917 path_data.first_packet_after_rtt_sample = Some((space.kind(), next_pn)); +2918 } +2919 } +2920 +2921 // Must be called before crypto/pto_count are clobbered +2922 self.detect_lost_packets(now, space, path, true); +2923 +2924 // If the peer did not complete the handshake address validation the ACK could be +2925 // spoofed, e.g. in the Initial space. Setting the pto_count back to 0 removes the +2926 // exponential backoff from the PTO timer and would result in too many tail-loss +2927 // probes being sent. +2928 if self.peer_completed_handshake_address_validation() { +2929 self.path_data_mut(path).pto_count = 0; +2930 } +2931 +2932 // Explicit congestion notification +2933 // TODO(@divma): this code is a good example of logic that should be contained in a single +2934 // place but it's split between the path data and the packet number space data, we should +2935 // find a way to make this work without two lookups +2936 if self.path_data(path).sending_ecn { +2937 if let Some(ecn) = ack.ecn { +2938 // We only examine ECN counters from ACKs that we are certain we received in transmit +2939 // order, allowing us to compute an increase in ECN counts to compare against the number +2940 // of newly acked packets that remains well-defined in the presence of arbitrary packet +2941 // reordering. +2942 if new_largest { +2943 let sent = self.spaces[space].for_path(path).largest_acked_packet_sent; +2944 self.process_ecn(now, space, path, newly_acked.len() as u64, ecn, sent); +2945 } +2946 } else { +2947 // We always start out sending ECN, so any ack that doesn't acknowledge it disables it. +2948 debug!("ECN not acknowledged by peer"); +2949 self.path_data_mut(path).sending_ecn = false; +2950 } +2951 } +2952 +2953 self.set_loss_detection_timer(now, path); +2954 Ok(()) +2955 } +2956 +2957 fn detect_spurious_loss(&mut self, ack: &frame::Ack, space: SpaceId, path: PathId) -> bool { +2958 let lost_packets = &mut self.spaces[space].for_path(path).lost_packets; +2959 +2960 if lost_packets.is_empty() { +2961 return false; +2962 } 2963 -2964 for pn in spurious_losses { -2965 lost_packets.remove(pn); -2966 } -2967 } -2968 -2969 // If this ACK frame acknowledged all deemed lost packets, -2970 // then we have raised a spurious congestion event in the past. -2971 // We cannot conclude when there are remaining packets, -2972 // but future ACK frames might indicate a spurious loss detection. -2973 lost_packets.is_empty() -2974 } -2975 -2976 /// Drain lost packets that we reasonably think will never arrive -2977 /// -2978 /// The current criterion is copied from `msquic`: -2979 /// discard packets that were sent earlier than 2 probe timeouts ago. -2980 fn drain_lost_packets(&mut self, now: Instant, space: SpaceId, path: PathId) { -2981 let two_pto = 2 * self.path_data(path).rtt.pto_base(); -2982 -2983 let lost_packets = &mut self.spaces[space].for_path(path).lost_packets; -2984 lost_packets.retain(|_pn, info| now.saturating_duration_since(info.time_sent) <= two_pto); -2985 } -2986 -2987 /// Process a new ECN block from an in-order ACK -2988 fn process_ecn( -2989 &mut self, -2990 now: Instant, -2991 space: SpaceId, -2992 path: PathId, -2993 newly_acked: u64, -2994 ecn: frame::EcnCounts, -2995 largest_sent_time: Instant, -2996 ) { -2997 match self.spaces[space] -2998 .for_path(path) -2999 .detect_ecn(newly_acked, ecn) -3000 { -3001 Err(e) => { -3002 debug!("halting ECN due to verification failure: {}", e); -3003 -3004 self.path_data_mut(path).sending_ecn = false; -3005 // Wipe out the existing value because it might be garbage and could interfere with -3006 // future attempts to use ECN on new paths. -3007 self.spaces[space].for_path(path).ecn_feedback = frame::EcnCounts::ZERO; -3008 } -3009 Ok(false) => {} -3010 Ok(true) => { -3011 self.path_stats.for_path(path).congestion_events += 1; -3012 self.path_data_mut(path).congestion.on_congestion_event( -3013 now, -3014 largest_sent_time, -3015 false, -3016 true, -3017 0, -3018 ); -3019 } -3020 } -3021 } -3022 -3023 // Not timing-aware, so it's safe to call this for inferred acks, such as arise from -3024 // high-latency handshakes -3025 fn on_packet_acked(&mut self, now: Instant, path_id: PathId, info: SentPacket) { -3026 let path = self.path_data_mut(path_id); -3027 let app_limited = path.app_limited; -3028 path.remove_in_flight(&info); -3029 if info.ack_eliciting && info.path_generation == path.generation() { -3030 // Only pass ACKs to the congestion controller if it belongs to this exact -3031 // generation of the path. Otherwise we might be feeding ACKs from the previous -3032 // 4-tuple into our congestion controller. -3033 let rtt = path.rtt; -3034 path.congestion -3035 .on_ack(now, info.time_sent, info.size.into(), app_limited, &rtt); -3036 } -3037 -3038 // Update state for confirmed delivery of frames -3039 if let Some(retransmits) = info.retransmits.get() { -3040 for (id, _) in retransmits.reset_stream.iter() { -3041 self.streams.reset_acked(*id); -3042 } -3043 } -3044 -3045 for frame in info.stream_frames { -3046 self.streams.received_ack_of(frame); -3047 } -3048 } -3049 -3050 fn set_key_discard_timer(&mut self, now: Instant, space: SpaceKind) { -3051 let start = if self.crypto_state.has_keys(EncryptionLevel::ZeroRtt) { -3052 now -3053 } else { -3054 self.crypto_state -3055 .prev_crypto -3056 .as_ref() -3057 .expect("no previous keys") -3058 .end_packet -3059 .as_ref() -3060 .expect("update not acknowledged yet") -3061 .1 -3062 }; -3063 -3064 // QUIC-MULTIPATH § 2.5 Key Phase Update Process: use largest PTO of all paths. -3065 self.timers.set( -3066 Timer::Conn(ConnTimer::KeyDiscard), -3067 start + self.max_pto_for_space(space) * 3, -3068 self.qlog.with_time(now), -3069 ); -3070 } -3071 -3072 /// Handle a [`PathTimer::LossDetection`] timeout. -3073 /// -3074 /// This timer expires for two reasons: -3075 /// - An ACK-eliciting packet we sent should be considered lost. -3076 /// - The PTO may have expired and a tail-loss probe needs to be scheduled. -3077 /// -3078 /// The former needs us to schedule re-transmission of the lost data. +2964 for range in ack.iter() { +2965 let spurious_losses: Vec<u64> = lost_packets +2966 .iter_range(range.clone()) +2967 .map(|(pn, _info)| pn) +2968 .collect(); +2969 +2970 for pn in spurious_losses { +2971 lost_packets.remove(pn); +2972 } +2973 } +2974 +2975 // If this ACK frame acknowledged all deemed lost packets, +2976 // then we have raised a spurious congestion event in the past. +2977 // We cannot conclude when there are remaining packets, +2978 // but future ACK frames might indicate a spurious loss detection. +2979 lost_packets.is_empty() +2980 } +2981 +2982 /// Drain lost packets that we reasonably think will never arrive +2983 /// +2984 /// The current criterion is copied from `msquic`: +2985 /// discard packets that were sent earlier than 2 probe timeouts ago. +2986 fn drain_lost_packets(&mut self, now: Instant, space: SpaceId, path: PathId) { +2987 let two_pto = 2 * self.path_data(path).rtt.pto_base(); +2988 +2989 let lost_packets = &mut self.spaces[space].for_path(path).lost_packets; +2990 lost_packets.retain(|_pn, info| now.saturating_duration_since(info.time_sent) <= two_pto); +2991 } +2992 +2993 /// Process a new ECN block from an in-order ACK +2994 fn process_ecn( +2995 &mut self, +2996 now: Instant, +2997 space: SpaceId, +2998 path: PathId, +2999 newly_acked: u64, +3000 ecn: frame::EcnCounts, +3001 largest_sent_time: Instant, +3002 ) { +3003 match self.spaces[space] +3004 .for_path(path) +3005 .detect_ecn(newly_acked, ecn) +3006 { +3007 Err(e) => { +3008 debug!("halting ECN due to verification failure: {}", e); +3009 +3010 self.path_data_mut(path).sending_ecn = false; +3011 // Wipe out the existing value because it might be garbage and could interfere with +3012 // future attempts to use ECN on new paths. +3013 self.spaces[space].for_path(path).ecn_feedback = frame::EcnCounts::ZERO; +3014 } +3015 Ok(false) => {} +3016 Ok(true) => { +3017 self.path_stats.for_path(path).congestion_events += 1; +3018 self.path_data_mut(path).congestion.on_congestion_event( +3019 now, +3020 largest_sent_time, +3021 false, +3022 true, +3023 0, +3024 ); +3025 } +3026 } +3027 } +3028 +3029 // Not timing-aware, so it's safe to call this for inferred acks, such as arise from +3030 // high-latency handshakes +3031 fn on_packet_acked(&mut self, now: Instant, path_id: PathId, info: SentPacket) { +3032 let path = self.path_data_mut(path_id); +3033 let app_limited = path.app_limited; +3034 path.remove_in_flight(&info); +3035 if info.ack_eliciting && info.path_generation == path.generation() { +3036 // Only pass ACKs to the congestion controller if it belongs to this exact +3037 // generation of the path. Otherwise we might be feeding ACKs from the previous +3038 // 4-tuple into our congestion controller. +3039 let rtt = path.rtt; +3040 path.congestion +3041 .on_ack(now, info.time_sent, info.size.into(), app_limited, &rtt); +3042 } +3043 +3044 // Update state for confirmed delivery of frames +3045 if let Some(retransmits) = info.retransmits.get() { +3046 for (id, _) in retransmits.reset_stream.iter() { +3047 self.streams.reset_acked(*id); +3048 } +3049 } +3050 +3051 for frame in info.stream_frames { +3052 self.streams.received_ack_of(frame); +3053 } +3054 } +3055 +3056 fn set_key_discard_timer(&mut self, now: Instant, space: SpaceKind) { +3057 let start = if self.crypto_state.has_keys(EncryptionLevel::ZeroRtt) { +3058 now +3059 } else { +3060 self.crypto_state +3061 .prev_crypto +3062 .as_ref() +3063 .expect("no previous keys") +3064 .end_packet +3065 .as_ref() +3066 .expect("update not acknowledged yet") +3067 .1 +3068 }; +3069 +3070 // QUIC-MULTIPATH § 2.5 Key Phase Update Process: use largest PTO of all paths. +3071 self.timers.set( +3072 Timer::Conn(ConnTimer::KeyDiscard), +3073 start + self.max_pto_for_space(space) * 3, +3074 self.qlog.with_time(now), +3075 ); +3076 } +3077 +3078 /// Handle a [`PathTimer::LossDetection`] timeout. 3079 /// -3080 /// The latter means we have not received an ACK for an ack-eliciting packet we sent -3081 /// within the PTO time-window. We need to schedule a tail-loss probe, an ack-eliciting -3082 /// packet, to try and elicit new acknowledgements. These new acknowledgements will -3083 /// indicate whether the previously sent packets were lost or not. -3084 fn on_loss_detection_timeout(&mut self, now: Instant, path_id: PathId) { -3085 if let Some((_, pn_space)) = self.loss_time_and_space(path_id) { -3086 // Time threshold loss Detection -3087 self.detect_lost_packets(now, pn_space, path_id, false); -3088 self.set_loss_detection_timer(now, path_id); -3089 return; -3090 } -3091 -3092 let Some((_, space)) = self.pto_time_and_space(now, path_id) else { -3093 error!(%path_id, "PTO expired while unset"); -3094 return; -3095 }; -3096 trace!( -3097 in_flight = self.path_data(path_id).in_flight.bytes, -3098 count = self.path_data(path_id).pto_count, -3099 ?space, -3100 %path_id, -3101 "PTO fired" -3102 ); -3103 -3104 let count = match self.path_data(path_id).in_flight.ack_eliciting { -3105 // A PTO when we're not expecting any ACKs must be due to handshake -3106 // anti-amplification deadlock prevention. -3107 0 => { -3108 debug_assert!(!self.peer_completed_handshake_address_validation()); -3109 1 -3110 } -3111 // Conventional loss probe -3112 _ => 2, -3113 }; -3114 let pns = self.spaces[space].for_path(path_id); -3115 pns.loss_probes = pns.loss_probes.saturating_add(count); -3116 let path_data = self.path_data_mut(path_id); -3117 path_data.pto_count = path_data.pto_count.saturating_add(1); -3118 self.set_loss_detection_timer(now, path_id); -3119 } -3120 -3121 /// Detect any lost packets -3122 /// -3123 /// There are two cases in which we detects lost packets: -3124 /// -3125 /// - We received an ACK packet. -3126 /// - The [`PathTimer::LossDetection`] timer expired. So there is an un-acknowledged packet -3127 /// that was followed by an acknowledged packet. The loss timer for this -3128 /// un-acknowledged packet expired and we need to detect that packet as lost. -3129 /// -3130 /// Packets are lost if they are both (See RFC9002 §6.1): -3131 /// -3132 /// - Unacknowledged, in flight and sent prior to an acknowledged packet. -3133 /// - Old enough by either: -3134 /// - Having a packet number [`TransportConfig::packet_threshold`] lower then the last -3135 /// acknowledged packet. -3136 /// - Being sent [`TransportConfig::time_threshold`] * RTT in the past. -3137 fn detect_lost_packets( -3138 &mut self, -3139 now: Instant, -3140 pn_space: SpaceId, -3141 path_id: PathId, -3142 due_to_ack: bool, -3143 ) { -3144 let mut lost_packets = Vec::<u64>::new(); -3145 let mut lost_mtu_probe = None; -3146 let mut in_persistent_congestion = false; -3147 let mut size_of_lost_packets = 0u64; -3148 self.spaces[pn_space].for_path(path_id).loss_time = None; -3149 -3150 // Find all the lost packets, populating all variables initialised above. -3151 -3152 let path = self.path_data(path_id); -3153 let in_flight_mtu_probe = path.mtud.in_flight_mtu_probe(); -3154 let loss_delay = path -3155 .rtt -3156 .conservative() -3157 .mul_f32(self.config.time_threshold) -3158 .max(TIMER_GRANULARITY); -3159 let first_packet_after_rtt_sample = path.first_packet_after_rtt_sample; -3160 -3161 let largest_acked_packet = self.spaces[pn_space] -3162 .for_path(path_id) -3163 .largest_acked_packet -3164 .expect("detect_lost_packets only to be called if path received at least one ACK"); -3165 let packet_threshold = self.config.packet_threshold as u64; +3080 /// This timer expires for two reasons: +3081 /// - An ACK-eliciting packet we sent should be considered lost. +3082 /// - The PTO may have expired and a tail-loss probe needs to be scheduled. +3083 /// +3084 /// The former needs us to schedule re-transmission of the lost data. +3085 /// +3086 /// The latter means we have not received an ACK for an ack-eliciting packet we sent +3087 /// within the PTO time-window. We need to schedule a tail-loss probe, an ack-eliciting +3088 /// packet, to try and elicit new acknowledgements. These new acknowledgements will +3089 /// indicate whether the previously sent packets were lost or not. +3090 fn on_loss_detection_timeout(&mut self, now: Instant, path_id: PathId) { +3091 if let Some((_, pn_space)) = self.loss_time_and_space(path_id) { +3092 // Time threshold loss Detection +3093 self.detect_lost_packets(now, pn_space, path_id, false); +3094 self.set_loss_detection_timer(now, path_id); +3095 return; +3096 } +3097 +3098 let Some((_, space)) = self.pto_time_and_space(now, path_id) else { +3099 error!(%path_id, "PTO expired while unset"); +3100 return; +3101 }; +3102 trace!( +3103 in_flight = self.path_data(path_id).in_flight.bytes, +3104 count = self.path_data(path_id).pto_count, +3105 ?space, +3106 %path_id, +3107 "PTO fired" +3108 ); +3109 +3110 let count = match self.path_data(path_id).in_flight.ack_eliciting { +3111 // A PTO when we're not expecting any ACKs must be due to handshake +3112 // anti-amplification deadlock prevention. +3113 0 => { +3114 debug_assert!(!self.peer_completed_handshake_address_validation()); +3115 1 +3116 } +3117 // Conventional loss probe +3118 _ => 2, +3119 }; +3120 let pns = self.spaces[space].for_path(path_id); +3121 pns.loss_probes = pns.loss_probes.saturating_add(count); +3122 let path_data = self.path_data_mut(path_id); +3123 path_data.pto_count = path_data.pto_count.saturating_add(1); +3124 self.set_loss_detection_timer(now, path_id); +3125 } +3126 +3127 /// Detect any lost packets +3128 /// +3129 /// There are two cases in which we detects lost packets: +3130 /// +3131 /// - We received an ACK packet. +3132 /// - The [`PathTimer::LossDetection`] timer expired. So there is an un-acknowledged packet +3133 /// that was followed by an acknowledged packet. The loss timer for this +3134 /// un-acknowledged packet expired and we need to detect that packet as lost. +3135 /// +3136 /// Packets are lost if they are both (See RFC9002 §6.1): +3137 /// +3138 /// - Unacknowledged, in flight and sent prior to an acknowledged packet. +3139 /// - Old enough by either: +3140 /// - Having a packet number [`TransportConfig::packet_threshold`] lower then the last +3141 /// acknowledged packet. +3142 /// - Being sent [`TransportConfig::time_threshold`] * RTT in the past. +3143 fn detect_lost_packets( +3144 &mut self, +3145 now: Instant, +3146 pn_space: SpaceId, +3147 path_id: PathId, +3148 due_to_ack: bool, +3149 ) { +3150 let mut lost_packets = Vec::<u64>::new(); +3151 let mut lost_mtu_probe = None; +3152 let mut in_persistent_congestion = false; +3153 let mut size_of_lost_packets = 0u64; +3154 self.spaces[pn_space].for_path(path_id).loss_time = None; +3155 +3156 // Find all the lost packets, populating all variables initialised above. +3157 +3158 let path = self.path_data(path_id); +3159 let in_flight_mtu_probe = path.mtud.in_flight_mtu_probe(); +3160 let loss_delay = path +3161 .rtt +3162 .conservative() +3163 .mul_f32(self.config.time_threshold) +3164 .max(TIMER_GRANULARITY); +3165 let first_packet_after_rtt_sample = path.first_packet_after_rtt_sample; 3166 -3167 // InPersistentCongestion: Determine if all packets in the time period before the newest -3168 // lost packet, including the edges, are marked lost. PTO computation must always -3169 // include max ACK delay, i.e. operate as if in Data space (see RFC9001 §7.6.1). -3170 let congestion_period = self -3171 .pto(SpaceKind::Data, path_id) -3172 .saturating_mul(self.config.persistent_congestion_threshold); -3173 let mut persistent_congestion_start: Option<Instant> = None; -3174 let mut prev_packet = None; -3175 let space = self.spaces[pn_space].for_path(path_id); -3176 -3177 for (packet, info) in space.sent_packets.iter_range(0..largest_acked_packet) { -3178 if prev_packet != Some(packet.wrapping_sub(1)) { -3179 // An intervening packet was acknowledged -3180 persistent_congestion_start = None; -3181 } +3167 let largest_acked_packet = self.spaces[pn_space] +3168 .for_path(path_id) +3169 .largest_acked_packet +3170 .expect("detect_lost_packets only to be called if path received at least one ACK"); +3171 let packet_threshold = self.config.packet_threshold as u64; +3172 +3173 // InPersistentCongestion: Determine if all packets in the time period before the newest +3174 // lost packet, including the edges, are marked lost. PTO computation must always +3175 // include max ACK delay, i.e. operate as if in Data space (see RFC9001 §7.6.1). +3176 let congestion_period = self +3177 .pto(SpaceKind::Data, path_id) +3178 .saturating_mul(self.config.persistent_congestion_threshold); +3179 let mut persistent_congestion_start: Option<Instant> = None; +3180 let mut prev_packet = None; +3181 let space = self.spaces[pn_space].for_path(path_id); 3182 -3183 // Packets sent before now - loss_delay are deemed lost. -3184 // However, we avoid subtraction as it can panic and there's no -3185 // saturating equivalent of this subtraction operation with a Duration. -3186 let packet_too_old = now.saturating_duration_since(info.time_sent) >= loss_delay; -3187 if packet_too_old || largest_acked_packet >= packet + packet_threshold { -3188 // The packet should be declared lost. -3189 if Some(packet) == in_flight_mtu_probe { -3190 // Lost MTU probes are not included in `lost_packets`, because they -3191 // should not trigger a congestion control response -3192 lost_mtu_probe = in_flight_mtu_probe; -3193 } else { -3194 lost_packets.push(packet); -3195 size_of_lost_packets += info.size as u64; -3196 if info.ack_eliciting && due_to_ack { -3197 match persistent_congestion_start { -3198 // Two ACK-eliciting packets lost more than -3199 // congestion_period apart, with no ACKed packets in between -3200 Some(start) if info.time_sent - start > congestion_period => { -3201 in_persistent_congestion = true; -3202 } -3203 // Persistent congestion must start after the first RTT sample -3204 None if first_packet_after_rtt_sample -3205 .is_some_and(|x| x < (pn_space.kind(), packet)) => -3206 { -3207 persistent_congestion_start = Some(info.time_sent); +3183 for (packet, info) in space.sent_packets.iter_range(0..largest_acked_packet) { +3184 if prev_packet != Some(packet.wrapping_sub(1)) { +3185 // An intervening packet was acknowledged +3186 persistent_congestion_start = None; +3187 } +3188 +3189 // Packets sent before now - loss_delay are deemed lost. +3190 // However, we avoid subtraction as it can panic and there's no +3191 // saturating equivalent of this subtraction operation with a Duration. +3192 let packet_too_old = now.saturating_duration_since(info.time_sent) >= loss_delay; +3193 if packet_too_old || largest_acked_packet >= packet + packet_threshold { +3194 // The packet should be declared lost. +3195 if Some(packet) == in_flight_mtu_probe { +3196 // Lost MTU probes are not included in `lost_packets`, because they +3197 // should not trigger a congestion control response +3198 lost_mtu_probe = in_flight_mtu_probe; +3199 } else { +3200 lost_packets.push(packet); +3201 size_of_lost_packets += info.size as u64; +3202 if info.ack_eliciting && due_to_ack { +3203 match persistent_congestion_start { +3204 // Two ACK-eliciting packets lost more than +3205 // congestion_period apart, with no ACKed packets in between +3206 Some(start) if info.time_sent - start > congestion_period => { +3207 in_persistent_congestion = true; 3208 } -3209 _ => {} -3210 } -3211 } -3212 } -3213 } else { -3214 // The packet should not yet be declared lost. -3215 if space.loss_time.is_none() { -3216 // Since we iterate in order the lowest packet number's loss time will -3217 // always be the earliest. -3218 space.loss_time = Some(info.time_sent + loss_delay); -3219 } -3220 persistent_congestion_start = None; -3221 } -3222 -3223 prev_packet = Some(packet); -3224 } -3225 -3226 self.handle_lost_packets( -3227 pn_space, -3228 path_id, -3229 now, -3230 lost_packets, -3231 lost_mtu_probe, -3232 loss_delay, -3233 in_persistent_congestion, -3234 size_of_lost_packets, -3235 ); -3236 } -3237 -3238 /// Drops the path state, declaring any remaining in-flight packets as lost -3239 fn discard_path(&mut self, path_id: PathId, now: Instant) { -3240 trace!(%path_id, "dropping path state"); -3241 let path = self.path_data(path_id); -3242 let in_flight_mtu_probe = path.mtud.in_flight_mtu_probe(); +3209 // Persistent congestion must start after the first RTT sample +3210 None if first_packet_after_rtt_sample +3211 .is_some_and(|x| x < (pn_space.kind(), packet)) => +3212 { +3213 persistent_congestion_start = Some(info.time_sent); +3214 } +3215 _ => {} +3216 } +3217 } +3218 } +3219 } else { +3220 // The packet should not yet be declared lost. +3221 if space.loss_time.is_none() { +3222 // Since we iterate in order the lowest packet number's loss time will +3223 // always be the earliest. +3224 space.loss_time = Some(info.time_sent + loss_delay); +3225 } +3226 persistent_congestion_start = None; +3227 } +3228 +3229 prev_packet = Some(packet); +3230 } +3231 +3232 self.handle_lost_packets( +3233 pn_space, +3234 path_id, +3235 now, +3236 lost_packets, +3237 lost_mtu_probe, +3238 loss_delay, +3239 in_persistent_congestion, +3240 size_of_lost_packets, +3241 ); +3242 } 3243 -3244 let mut size_of_lost_packets = 0u64; // add to path_stats.lost_bytes; -3245 let lost_pns: Vec<_> = self.spaces[SpaceId::Data] -3246 .for_path(path_id) -3247 .sent_packets -3248 .iter() -3249 .filter(|(pn, _info)| Some(*pn) != in_flight_mtu_probe) -3250 .map(|(pn, info)| { -3251 size_of_lost_packets += info.size as u64; -3252 pn -3253 }) -3254 .collect(); -3255 -3256 if !lost_pns.is_empty() { -3257 trace!( -3258 %path_id, -3259 count = lost_pns.len(), -3260 lost_bytes = size_of_lost_packets, -3261 "packets lost on path abandon" -3262 ); -3263 self.handle_lost_packets( -3264 SpaceId::Data, -3265 path_id, -3266 now, -3267 lost_pns, -3268 in_flight_mtu_probe, -3269 Duration::ZERO, -3270 false, -3271 size_of_lost_packets, -3272 ); -3273 } -3274 // Before removing the path, we fetch the final path stats via `Self::path_stats`. -3275 // This updates some values for the last time. -3276 let path_stats = self.path_stats.discard(&path_id); -3277 self.partial_stats += path_stats; -3278 self.paths.remove(&path_id); -3279 self.spaces[SpaceId::Data].number_spaces.remove(&path_id); -3280 -3281 self.events.push_back( -3282 PathEvent::Discarded { -3283 id: path_id, -3284 path_stats: Box::new(path_stats), -3285 } -3286 .into(), -3287 ); -3288 } -3289 -3290 fn handle_lost_packets( -3291 &mut self, -3292 pn_space: SpaceId, -3293 path_id: PathId, -3294 now: Instant, -3295 lost_packets: Vec<u64>, -3296 lost_mtu_probe: Option<u64>, -3297 loss_delay: Duration, -3298 in_persistent_congestion: bool, -3299 size_of_lost_packets: u64, -3300 ) { -3301 debug_assert!(lost_packets.is_sorted(), "lost_packets must be sorted"); -3302 -3303 self.drain_lost_packets(now, pn_space, path_id); -3304 -3305 // OnPacketsLost -3306 if let Some(largest_lost) = lost_packets.last().cloned() { -3307 let old_bytes_in_flight = self.path_data_mut(path_id).in_flight.bytes; -3308 let largest_lost_sent = self.spaces[pn_space] -3309 .for_path(path_id) -3310 .sent_packets -3311 .get(largest_lost) -3312 .unwrap() -3313 .time_sent; -3314 let path_stats = self.path_stats.for_path(path_id); -3315 path_stats.lost_packets += lost_packets.len() as u64; -3316 path_stats.lost_bytes += size_of_lost_packets; -3317 trace!( -3318 %path_id, -3319 count = lost_packets.len(), -3320 lost_bytes = size_of_lost_packets, -3321 "packets lost", -3322 ); -3323 -3324 for &packet in &lost_packets { -3325 let Some(info) = self.spaces[pn_space].for_path(path_id).take(packet) else { -3326 continue; -3327 }; -3328 self.qlog -3329 .emit_packet_lost(packet, &info, loss_delay, pn_space.kind(), now); -3330 self.paths -3331 .get_mut(&path_id) -3332 .unwrap() -3333 .remove_in_flight(&info); -3334 -3335 for frame in info.stream_frames { -3336 self.streams.retransmit(frame); -3337 } -3338 self.spaces[pn_space].pending |= info.retransmits; -3339 self.path_data_mut(path_id) -3340 .mtud -3341 .on_non_probe_lost(packet, info.size); -3342 -3343 self.spaces[pn_space].for_path(path_id).lost_packets.insert( -3344 packet, -3345 LostPacket { -3346 time_sent: info.time_sent, -3347 }, -3348 ); -3349 } -3350 -3351 let path = self.path_data_mut(path_id); -3352 if path.mtud.black_hole_detected(now) { -3353 path.congestion.on_mtu_update(path.mtud.current_mtu()); -3354 if let Some(max_datagram_size) = self.datagrams().max_size() -3355 && self.datagrams.drop_oversized(max_datagram_size) -3356 && self.datagrams.send_blocked -3357 { -3358 self.datagrams.send_blocked = false; -3359 self.events.push_back(Event::DatagramsUnblocked); -3360 } -3361 self.path_stats.for_path(path_id).black_holes_detected += 1; -3362 } -3363 -3364 // Don't apply congestion penalty for lost ack-only packets -3365 let lost_ack_eliciting = -3366 old_bytes_in_flight != self.path_data_mut(path_id).in_flight.bytes; -3367 -3368 if lost_ack_eliciting { -3369 self.path_stats.for_path(path_id).congestion_events += 1; -3370 self.path_data_mut(path_id).congestion.on_congestion_event( -3371 now, -3372 largest_lost_sent, -3373 in_persistent_congestion, -3374 false, -3375 size_of_lost_packets, -3376 ); -3377 } -3378 } -3379 -3380 // Handle a lost MTU probe -3381 if let Some(packet) = lost_mtu_probe { -3382 let info = self.spaces[SpaceId::Data] -3383 .for_path(path_id) -3384 .take(packet) -3385 .unwrap(); // safe: lost_mtu_probe is omitted from lost_packets, and -3386 // therefore must not have been removed yet -3387 self.paths -3388 .get_mut(&path_id) -3389 .unwrap() -3390 .remove_in_flight(&info); -3391 self.path_data_mut(path_id).mtud.on_probe_lost(); -3392 self.path_stats.for_path(path_id).lost_plpmtud_probes += 1; -3393 } -3394 } -3395 -3396 /// Returns the earliest time packets should be declared lost for all spaces on a path. -3397 /// -3398 /// If a path has an acknowledged packet with any prior un-acknowledged packets, the -3399 /// earliest un-acknowledged packet can be declared lost after a timeout has elapsed. -3400 /// The time returned is when this packet should be declared lost. -3401 fn loss_time_and_space(&self, path_id: PathId) -> Option<(Instant, SpaceId)> { -3402 SpaceId::iter() -3403 .filter_map(|id| { -3404 self.spaces[id] -3405 .number_spaces -3406 .get(&path_id) -3407 .and_then(|pns| pns.loss_time) -3408 .map(|time| (time, id)) -3409 }) -3410 .min_by_key(|&(time, _)| time) -3411 } -3412 -3413 /// Returns the earliest next PTO should fire for all spaces on a path. -3414 /// -3415 /// This needs to be fully deterministic because it is also used to determine the PTO -3416 /// that fired, not just to set the next timer. So if it fired in the past it needs to -3417 /// return the time from the past at which it fired. -3418 /// -3419 /// This is the next time a tail-loss probe should be sent. -3420 fn pto_time_and_space(&mut self, now: Instant, path_id: PathId) -> Option<(Instant, SpaceId)> { -3421 let path = self.path(path_id)?; -3422 let pto_count = path.pto_count; -3423 -3424 // Cap the maximum interval between two tail-loss probes. -3425 let max_interval = if path.rtt.get() > SLOW_RTT_THRESHOLD { -3426 // For slow links we want to increase the interval beyond 2s. -3427 (path.rtt.get() * 3) / 2 -3428 } else if let Some(idle) = path.idle_timeout.or(self.idle_timeout) -3429 && idle <= MIN_IDLE_FOR_FAST_PTO -3430 { -3431 // If the idle timeout is relatively low, cap at 1s so we get plenty of retries -3432 // before the idle timeout fires. -3433 MAX_PTO_FAST_INTERVAL -3434 } else { -3435 // Otherwise cap to 2s. -3436 MAX_PTO_INTERVAL -3437 }; -3438 -3439 if path_id == PathId::ZERO -3440 && path.in_flight.ack_eliciting == 0 -3441 && !self.peer_completed_handshake_address_validation() -3442 { -3443 // Address Validation during Connection Establishment: -3444 // https://www.rfc-editor.org/rfc/rfc9000.html#section-8.1. To prevent a -3445 // deadlock if an Initial or Handshake packet from the server is lost and the -3446 // server can not send more due to its anti-amplification limit the client must -3447 // send another packet on PTO. -3448 let space = match self.highest_space { -3449 SpaceKind::Handshake => SpaceId::Handshake, -3450 _ => SpaceId::Initial, -3451 }; -3452 -3453 let backoff = 2u32.pow(path.pto_count.min(MAX_BACKOFF_EXPONENT)); -3454 let duration = path.rtt.pto_base() * backoff; -3455 let duration = duration.min(max_interval); -3456 return Some((now + duration, space)); -3457 } +3244 /// Drops the path state, declaring any remaining in-flight packets as lost +3245 fn discard_path(&mut self, path_id: PathId, now: Instant) { +3246 trace!(%path_id, "dropping path state"); +3247 let path = self.path_data(path_id); +3248 let in_flight_mtu_probe = path.mtud.in_flight_mtu_probe(); +3249 +3250 let mut size_of_lost_packets = 0u64; // add to path_stats.lost_bytes; +3251 let lost_pns: Vec<_> = self.spaces[SpaceId::Data] +3252 .for_path(path_id) +3253 .sent_packets +3254 .iter() +3255 .filter(|(pn, _info)| Some(*pn) != in_flight_mtu_probe) +3256 .map(|(pn, info)| { +3257 size_of_lost_packets += info.size as u64; +3258 pn +3259 }) +3260 .collect(); +3261 +3262 if !lost_pns.is_empty() { +3263 trace!( +3264 %path_id, +3265 count = lost_pns.len(), +3266 lost_bytes = size_of_lost_packets, +3267 "packets lost on path abandon" +3268 ); +3269 self.handle_lost_packets( +3270 SpaceId::Data, +3271 path_id, +3272 now, +3273 lost_pns, +3274 in_flight_mtu_probe, +3275 Duration::ZERO, +3276 false, +3277 size_of_lost_packets, +3278 ); +3279 } +3280 // Before removing the path, we fetch the final path stats via `Self::path_stats`. +3281 // This updates some values for the last time. +3282 let path_stats = self.path_stats.discard(&path_id); +3283 self.partial_stats += path_stats; +3284 self.paths.remove(&path_id); +3285 self.spaces[SpaceId::Data].number_spaces.remove(&path_id); +3286 +3287 self.events.push_back( +3288 PathEvent::Discarded { +3289 id: path_id, +3290 path_stats: Box::new(path_stats), +3291 } +3292 .into(), +3293 ); +3294 } +3295 +3296 fn handle_lost_packets( +3297 &mut self, +3298 pn_space: SpaceId, +3299 path_id: PathId, +3300 now: Instant, +3301 lost_packets: Vec<u64>, +3302 lost_mtu_probe: Option<u64>, +3303 loss_delay: Duration, +3304 in_persistent_congestion: bool, +3305 size_of_lost_packets: u64, +3306 ) { +3307 debug_assert!(lost_packets.is_sorted(), "lost_packets must be sorted"); +3308 +3309 self.drain_lost_packets(now, pn_space, path_id); +3310 +3311 // OnPacketsLost +3312 if let Some(largest_lost) = lost_packets.last().cloned() { +3313 let old_bytes_in_flight = self.path_data_mut(path_id).in_flight.bytes; +3314 let largest_lost_sent = self.spaces[pn_space] +3315 .for_path(path_id) +3316 .sent_packets +3317 .get(largest_lost) +3318 .unwrap() +3319 .time_sent; +3320 let path_stats = self.path_stats.for_path(path_id); +3321 path_stats.lost_packets += lost_packets.len() as u64; +3322 path_stats.lost_bytes += size_of_lost_packets; +3323 trace!( +3324 %path_id, +3325 count = lost_packets.len(), +3326 lost_bytes = size_of_lost_packets, +3327 "packets lost", +3328 ); +3329 +3330 for &packet in &lost_packets { +3331 let Some(info) = self.spaces[pn_space].for_path(path_id).take(packet) else { +3332 continue; +3333 }; +3334 self.qlog +3335 .emit_packet_lost(packet, &info, loss_delay, pn_space.kind(), now); +3336 self.paths +3337 .get_mut(&path_id) +3338 .unwrap() +3339 .remove_in_flight(&info); +3340 +3341 for frame in info.stream_frames { +3342 self.streams.retransmit(frame); +3343 } +3344 self.spaces[pn_space].pending |= info.retransmits; +3345 self.path_data_mut(path_id) +3346 .mtud +3347 .on_non_probe_lost(packet, info.size); +3348 +3349 self.spaces[pn_space].for_path(path_id).lost_packets.insert( +3350 packet, +3351 LostPacket { +3352 time_sent: info.time_sent, +3353 }, +3354 ); +3355 } +3356 +3357 let path = self.path_data_mut(path_id); +3358 if path.mtud.black_hole_detected(now) { +3359 path.congestion.on_mtu_update(path.mtud.current_mtu()); +3360 if let Some(max_datagram_size) = self.datagrams().max_size() +3361 && self.datagrams.drop_oversized(max_datagram_size) +3362 && self.datagrams.send_blocked +3363 { +3364 self.datagrams.send_blocked = false; +3365 self.events.push_back(Event::DatagramsUnblocked); +3366 } +3367 self.path_stats.for_path(path_id).black_holes_detected += 1; +3368 } +3369 +3370 // Don't apply congestion penalty for lost ack-only packets +3371 let lost_ack_eliciting = +3372 old_bytes_in_flight != self.path_data_mut(path_id).in_flight.bytes; +3373 +3374 if lost_ack_eliciting { +3375 self.path_stats.for_path(path_id).congestion_events += 1; +3376 self.path_data_mut(path_id).congestion.on_congestion_event( +3377 now, +3378 largest_lost_sent, +3379 in_persistent_congestion, +3380 false, +3381 size_of_lost_packets, +3382 ); +3383 } +3384 } +3385 +3386 // Handle a lost MTU probe +3387 if let Some(packet) = lost_mtu_probe { +3388 let info = self.spaces[SpaceId::Data] +3389 .for_path(path_id) +3390 .take(packet) +3391 .unwrap(); // safe: lost_mtu_probe is omitted from lost_packets, and +3392 // therefore must not have been removed yet +3393 self.paths +3394 .get_mut(&path_id) +3395 .unwrap() +3396 .remove_in_flight(&info); +3397 self.path_data_mut(path_id).mtud.on_probe_lost(); +3398 self.path_stats.for_path(path_id).lost_plpmtud_probes += 1; +3399 } +3400 } +3401 +3402 /// Returns the earliest time packets should be declared lost for all spaces on a path. +3403 /// +3404 /// If a path has an acknowledged packet with any prior un-acknowledged packets, the +3405 /// earliest un-acknowledged packet can be declared lost after a timeout has elapsed. +3406 /// The time returned is when this packet should be declared lost. +3407 fn loss_time_and_space(&self, path_id: PathId) -> Option<(Instant, SpaceId)> { +3408 SpaceId::iter() +3409 .filter_map(|id| { +3410 self.spaces[id] +3411 .number_spaces +3412 .get(&path_id) +3413 .and_then(|pns| pns.loss_time) +3414 .map(|time| (time, id)) +3415 }) +3416 .min_by_key(|&(time, _)| time) +3417 } +3418 +3419 /// Returns the earliest next PTO should fire for all spaces on a path. +3420 /// +3421 /// This needs to be fully deterministic because it is also used to determine the PTO +3422 /// that fired, not just to set the next timer. So if it fired in the past it needs to +3423 /// return the time from the past at which it fired. +3424 /// +3425 /// This is the next time a tail-loss probe should be sent. +3426 fn pto_time_and_space(&mut self, now: Instant, path_id: PathId) -> Option<(Instant, SpaceId)> { +3427 let path = self.path(path_id)?; +3428 let pto_count = path.pto_count; +3429 +3430 // Cap the maximum interval between two tail-loss probes. +3431 let max_interval = if path.rtt.get() > SLOW_RTT_THRESHOLD { +3432 // For slow links we want to increase the interval beyond 2s. +3433 (path.rtt.get() * 3) / 2 +3434 } else if let Some(idle) = path.idle_timeout.or(self.idle_timeout) +3435 && idle <= MIN_IDLE_FOR_FAST_PTO +3436 { +3437 // If the idle timeout is relatively low, cap at 1s so we get plenty of retries +3438 // before the idle timeout fires. +3439 MAX_PTO_FAST_INTERVAL +3440 } else { +3441 // Otherwise cap to 2s. +3442 MAX_PTO_INTERVAL +3443 }; +3444 +3445 if path_id == PathId::ZERO +3446 && path.in_flight.ack_eliciting == 0 +3447 && !self.peer_completed_handshake_address_validation() +3448 { +3449 // Address Validation during Connection Establishment: +3450 // https://www.rfc-editor.org/rfc/rfc9000.html#section-8.1. To prevent a +3451 // deadlock if an Initial or Handshake packet from the server is lost and the +3452 // server can not send more due to its anti-amplification limit the client must +3453 // send another packet on PTO. +3454 let space = match self.highest_space { +3455 SpaceKind::Handshake => SpaceId::Handshake, +3456 _ => SpaceId::Initial, +3457 }; 3458 -3459 let mut result = None; -3460 for space in SpaceId::iter() { -3461 let Some(pns) = self.spaces[space].number_spaces.get(&path_id) else { -3462 continue; -3463 }; +3459 let backoff = 2u32.pow(path.pto_count.min(MAX_BACKOFF_EXPONENT)); +3460 let duration = path.rtt.pto_base() * backoff; +3461 let duration = duration.min(max_interval); +3462 return Some((now + duration, space)); +3463 } 3464 -3465 if space == SpaceId::Data && !self.is_handshake_confirmed() { -3466 // https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.1-7: -3467 // An endpoint MUST NOT set its PTO timer for the Application Data packet -3468 // number space until the handshake is confirmed. -3469 continue; -3470 } -3471 -3472 if !pns.has_in_flight() { -3473 continue; -3474 } -3475 -3476 // Compute the PTO duration for this space, we want to cap the maximum interval -3477 // between two tail-loss probes so to not do a simple exponential backoff but -3478 // rather iterate through the probes to compute the capped increment for an -3479 // exponential backoff at each step. -3480 let duration = { -3481 let max_ack_delay = if space == SpaceId::Data { -3482 self.ack_frequency.max_ack_delay_for_pto() -3483 } else { -3484 Duration::ZERO -3485 }; -3486 let pto_base = path.rtt.pto_base() + max_ack_delay; -3487 let mut duration = pto_base; -3488 for i in 1..=pto_count { -3489 let exponential_duration = pto_base * 2u32.pow(i.min(MAX_BACKOFF_EXPONENT)); -3490 let max_duration = duration + max_interval; -3491 duration = exponential_duration.min(max_duration); -3492 } -3493 duration -3494 }; -3495 -3496 let Some(last_ack_eliciting) = pns.time_of_last_ack_eliciting_packet else { -3497 continue; -3498 }; -3499 // Base the deadline on when the last probe was sent, so the PTO -3500 // doesn't fire before the response has had time to arrive. -3501 let pto = last_ack_eliciting + duration; -3502 if result.is_none_or(|(earliest_pto, _)| pto < earliest_pto) { -3503 if path.anti_amplification_blocked(1) { -3504 // Nothing would be able to be sent. -3505 continue; -3506 } -3507 if path.in_flight.ack_eliciting == 0 { -3508 // Nothing ack-eliciting, no PTO to arm/fire. -3509 continue; -3510 } -3511 result = Some((pto, space)); -3512 } -3513 } -3514 result -3515 } -3516 -3517 /// Whether the peer validated our address in the connection handshake. -3518 fn peer_completed_handshake_address_validation(&self) -> bool { -3519 if self.side.is_server() || self.state.is_closed() { -3520 return true; -3521 } -3522 // The server is guaranteed to have validated our address if any of our handshake or -3523 // 1-RTT packets are acknowledged or we've seen HANDSHAKE_DONE and discarded -3524 // handshake keys. -3525 self.spaces[SpaceId::Handshake] -3526 .path_space(PathId::ZERO) -3527 .and_then(|pns| pns.largest_acked_packet) -3528 .is_some() -3529 || self.spaces[SpaceId::Data] -3530 .path_space(PathId::ZERO) -3531 .and_then(|pns| pns.largest_acked_packet) -3532 .is_some() -3533 || (self.crypto_state.has_keys(EncryptionLevel::OneRtt) -3534 && !self.crypto_state.has_keys(EncryptionLevel::Handshake)) -3535 } -3536 -3537 /// Resets the the [`PathTimer::LossDetection`] timer to the next instant it may be needed -3538 /// -3539 /// The timer must fire if either: -3540 /// - An ack-eliciting packet we sent needs to be declared lost. -3541 /// - A tail-loss probe needs to be sent. -3542 /// -3543 /// See [`Connection::on_loss_detection_timeout`] for details. -3544 fn set_loss_detection_timer(&mut self, now: Instant, path_id: PathId) { -3545 if self.state.is_closed() { -3546 // No loss detection takes place on closed connections, and `close_common` already -3547 // stopped time timer. Ensure we don't restart it inadvertently, e.g. in response to a -3548 // reordered packet being handled by state-insensitive code. -3549 return; -3550 } -3551 -3552 if let Some((loss_time, _)) = self.loss_time_and_space(path_id) { -3553 // Time threshold loss detection. -3554 self.timers.set( -3555 Timer::PerPath(path_id, PathTimer::LossDetection), -3556 loss_time, -3557 self.qlog.with_time(now), -3558 ); -3559 return; -3560 } -3561 -3562 // Determine which PN space to arm PTO for. -3563 // We can only send tail-loss probes on paths that aren't abandoned yet. -3564 if !self.abandoned_paths.contains(&path_id) -3565 && let Some((timeout, _)) = self.pto_time_and_space(now, path_id) -3566 { -3567 self.timers.set( -3568 Timer::PerPath(path_id, PathTimer::LossDetection), -3569 timeout, -3570 self.qlog.with_time(now), -3571 ); -3572 } else { -3573 self.timers.stop( +3465 let mut result = None; +3466 for space in SpaceId::iter() { +3467 let Some(pns) = self.spaces[space].number_spaces.get(&path_id) else { +3468 continue; +3469 }; +3470 +3471 if space == SpaceId::Data && !self.is_handshake_confirmed() { +3472 // https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.1-7: +3473 // An endpoint MUST NOT set its PTO timer for the Application Data packet +3474 // number space until the handshake is confirmed. +3475 continue; +3476 } +3477 +3478 if !pns.has_in_flight() { +3479 continue; +3480 } +3481 +3482 // Compute the PTO duration for this space, we want to cap the maximum interval +3483 // between two tail-loss probes so to not do a simple exponential backoff but +3484 // rather iterate through the probes to compute the capped increment for an +3485 // exponential backoff at each step. +3486 let duration = { +3487 let max_ack_delay = if space == SpaceId::Data { +3488 self.ack_frequency.max_ack_delay_for_pto() +3489 } else { +3490 Duration::ZERO +3491 }; +3492 let pto_base = path.rtt.pto_base() + max_ack_delay; +3493 let mut duration = pto_base; +3494 for i in 1..=pto_count { +3495 let exponential_duration = pto_base * 2u32.pow(i.min(MAX_BACKOFF_EXPONENT)); +3496 let max_duration = duration + max_interval; +3497 duration = exponential_duration.min(max_duration); +3498 } +3499 duration +3500 }; +3501 +3502 let Some(last_ack_eliciting) = pns.time_of_last_ack_eliciting_packet else { +3503 continue; +3504 }; +3505 // Base the deadline on when the last probe was sent, so the PTO +3506 // doesn't fire before the response has had time to arrive. +3507 let pto = last_ack_eliciting + duration; +3508 if result.is_none_or(|(earliest_pto, _)| pto < earliest_pto) { +3509 if path.anti_amplification_blocked(1) { +3510 // Nothing would be able to be sent. +3511 continue; +3512 } +3513 if path.in_flight.ack_eliciting == 0 { +3514 // Nothing ack-eliciting, no PTO to arm/fire. +3515 continue; +3516 } +3517 result = Some((pto, space)); +3518 } +3519 } +3520 result +3521 } +3522 +3523 /// Whether the peer validated our address in the connection handshake. +3524 fn peer_completed_handshake_address_validation(&self) -> bool { +3525 if self.side.is_server() || self.state.is_closed() { +3526 return true; +3527 } +3528 // The server is guaranteed to have validated our address if any of our handshake or +3529 // 1-RTT packets are acknowledged or we've seen HANDSHAKE_DONE and discarded +3530 // handshake keys. +3531 self.spaces[SpaceId::Handshake] +3532 .path_space(PathId::ZERO) +3533 .and_then(|pns| pns.largest_acked_packet) +3534 .is_some() +3535 || self.spaces[SpaceId::Data] +3536 .path_space(PathId::ZERO) +3537 .and_then(|pns| pns.largest_acked_packet) +3538 .is_some() +3539 || (self.crypto_state.has_keys(EncryptionLevel::OneRtt) +3540 && !self.crypto_state.has_keys(EncryptionLevel::Handshake)) +3541 } +3542 +3543 /// Resets the the [`PathTimer::LossDetection`] timer to the next instant it may be needed +3544 /// +3545 /// The timer must fire if either: +3546 /// - An ack-eliciting packet we sent needs to be declared lost. +3547 /// - A tail-loss probe needs to be sent. +3548 /// +3549 /// See [`Connection::on_loss_detection_timeout`] for details. +3550 fn set_loss_detection_timer(&mut self, now: Instant, path_id: PathId) { +3551 if self.state.is_closed() { +3552 // No loss detection takes place on closed connections, and `close_common` already +3553 // stopped time timer. Ensure we don't restart it inadvertently, e.g. in response to a +3554 // reordered packet being handled by state-insensitive code. +3555 return; +3556 } +3557 +3558 if let Some((loss_time, _)) = self.loss_time_and_space(path_id) { +3559 // Time threshold loss detection. +3560 self.timers.set( +3561 Timer::PerPath(path_id, PathTimer::LossDetection), +3562 loss_time, +3563 self.qlog.with_time(now), +3564 ); +3565 return; +3566 } +3567 +3568 // Determine which PN space to arm PTO for. +3569 // We can only send tail-loss probes on paths that aren't abandoned yet. +3570 if !self.abandoned_paths.contains(&path_id) +3571 && let Some((timeout, _)) = self.pto_time_and_space(now, path_id) +3572 { +3573 self.timers.set( 3574 Timer::PerPath(path_id, PathTimer::LossDetection), -3575 self.qlog.with_time(now), -3576 ); -3577 } -3578 } -3579 -3580 /// The maximum probe timeout across all paths -3581 /// -3582 /// See [`Connection::pto`] -3583 fn max_pto_for_space(&self, space: SpaceKind) -> Duration { -3584 self.paths -3585 .keys() -3586 .map(|path_id| self.pto(space, *path_id)) -3587 .max() -3588 .unwrap_or_else(|| { -3589 // No paths remain (e.g. last path was abandoned and the NoAvailablePath grace timer -3590 // fired before any new path was opened). Fall back to a PTO derived from the -3591 // configured initial RTT, matching RFC 9002 §6.2.2 initial values. -3592 let rtt = self.config.initial_rtt; -3593 let max_ack_delay = match space { -3594 SpaceKind::Initial | SpaceKind::Handshake => Duration::ZERO, -3595 SpaceKind::Data => self.ack_frequency.max_ack_delay_for_pto(), -3596 }; -3597 rtt + cmp::max(4 * (rtt / 2), TIMER_GRANULARITY) + max_ack_delay -3598 }) -3599 } -3600 -3601 /// Probe Timeout -3602 /// -3603 /// The PTO is logically the time in which you'd expect to receive an acknowledgement -3604 /// for a packet. So approximately RTT + max_ack_delay. -3605 fn pto(&self, space: SpaceKind, path_id: PathId) -> Duration { -3606 let max_ack_delay = match space { -3607 SpaceKind::Initial | SpaceKind::Handshake => Duration::ZERO, -3608 SpaceKind::Data => self.ack_frequency.max_ack_delay_for_pto(), -3609 }; -3610 self.path_data(path_id).rtt.pto_base() + max_ack_delay -3611 } -3612 -3613 fn on_packet_authenticated( -3614 &mut self, -3615 now: Instant, -3616 space_id: SpaceKind, -3617 path_id: PathId, -3618 ecn: Option<EcnCodepoint>, -3619 packet_number: Option<u64>, -3620 spin: bool, -3621 is_1rtt: bool, -3622 remote: &FourTuple, -3623 ) { -3624 // During the handshake we already have discarded packets that do not match the path -3625 // remote. So any off-path packet here is either a probing packet or a -3626 // migration. Handling probing packets here means that the path's idle timeout will -3627 // be reset and will delay detecting the path as idle. However tail-loss probes -3628 // would still not get acknowledged if the path was broken so eventually the path -3629 // would still become idle. -3630 let is_on_path = *remote == self.path_data(path_id).network_path; -3631 -3632 self.total_authed_packets += 1; -3633 self.reset_keep_alive(path_id, now); -3634 self.reset_idle_timeout(now, space_id, path_id); -3635 self.path_data_mut(path_id).permit_idle_reset = true; -3636 -3637 // Do not process ECN for off-path packets. If this is a migration we'll get ECN -3638 // back once we've migrated. -3639 if is_on_path { -3640 self.receiving_ecn |= ecn.is_some(); -3641 if let Some(x) = ecn { -3642 let space = &mut self.spaces[space_id]; -3643 space.for_path(path_id).ecn_counters += x; -3644 -3645 if x.is_ce() { -3646 space -3647 .for_path(path_id) -3648 .pending_acks -3649 .set_immediate_ack_required(); -3650 } -3651 } -3652 } -3653 -3654 let Some(packet_number) = packet_number else { -3655 return; -3656 }; -3657 match &self.side { -3658 ConnectionSide::Client { .. } => { -3659 // If we received a handshake packet that authenticated, then we're talking to -3660 // the real server. From now on we should no longer allow the server to migrate -3661 // its address. -3662 if space_id == SpaceKind::Handshake -3663 && let Some(hs) = self.state.as_handshake_mut() -3664 { -3665 hs.allow_server_migration = false; -3666 } -3667 } -3668 ConnectionSide::Server { .. } => { -3669 if self.crypto_state.has_keys(EncryptionLevel::Initial) -3670 && space_id == SpaceKind::Handshake -3671 { -3672 // A server stops sending and processing Initial packets when it receives its first Handshake packet. -3673 self.discard_space(now, SpaceKind::Initial); -3674 } -3675 if self.crypto_state.has_keys(EncryptionLevel::ZeroRtt) && is_1rtt { -3676 // Discard 0-RTT keys soon after receiving a 1-RTT packet -3677 self.set_key_discard_timer(now, space_id) -3678 } -3679 } -3680 } -3681 let space = self.spaces[space_id].for_path(path_id); -3682 -3683 space.pending_acks.insert_one(packet_number, now); -3684 if packet_number >= space.largest_received_packet_number.unwrap_or_default() { -3685 space.largest_received_packet_number = Some(packet_number); -3686 -3687 // Update outgoing spin bit for on-path packets, inverting iff we're the client -3688 if is_on_path { -3689 self.spin = self.side.is_client() ^ spin; -3690 } -3691 } -3692 } -3693 -3694 /// Resets the idle timeout timers -3695 /// -3696 /// Without multipath there is only the connection-wide idle timeout. When multipath is -3697 /// enabled there is an additional per-path idle timeout. -3698 fn reset_idle_timeout(&mut self, now: Instant, space: SpaceKind, path_id: PathId) { -3699 // First reset the global idle timeout. -3700 if let Some(timeout) = self.idle_timeout { -3701 if self.state.is_closed() { -3702 self.timers -3703 .stop(Timer::Conn(ConnTimer::Idle), self.qlog.with_time(now)); -3704 } else { -3705 let dt = cmp::max(timeout, 3 * self.max_pto_for_space(space)); -3706 self.timers.set( -3707 Timer::Conn(ConnTimer::Idle), -3708 now + dt, -3709 self.qlog.with_time(now), -3710 ); -3711 } -3712 } -3713 -3714 // Now handle the per-path state -3715 if let Some(timeout) = self.path_data(path_id).idle_timeout { -3716 if self.state.is_closed() { -3717 self.timers.stop( -3718 Timer::PerPath(path_id, PathTimer::PathIdle), -3719 self.qlog.with_time(now), -3720 ); -3721 } else { -3722 let dt = cmp::max(timeout, 3 * self.pto(space, path_id)); -3723 self.timers.set( +3575 timeout, +3576 self.qlog.with_time(now), +3577 ); +3578 } else { +3579 self.timers.stop( +3580 Timer::PerPath(path_id, PathTimer::LossDetection), +3581 self.qlog.with_time(now), +3582 ); +3583 } +3584 } +3585 +3586 /// The maximum probe timeout across all paths +3587 /// +3588 /// See [`Connection::pto`] +3589 fn max_pto_for_space(&self, space: SpaceKind) -> Duration { +3590 self.paths +3591 .keys() +3592 .map(|path_id| self.pto(space, *path_id)) +3593 .max() +3594 .unwrap_or_else(|| { +3595 // No paths remain (e.g. last path was abandoned and the NoAvailablePath grace timer +3596 // fired before any new path was opened). Fall back to a PTO derived from the +3597 // configured initial RTT, matching RFC 9002 §6.2.2 initial values. +3598 let rtt = self.config.initial_rtt; +3599 let max_ack_delay = match space { +3600 SpaceKind::Initial | SpaceKind::Handshake => Duration::ZERO, +3601 SpaceKind::Data => self.ack_frequency.max_ack_delay_for_pto(), +3602 }; +3603 rtt + cmp::max(4 * (rtt / 2), TIMER_GRANULARITY) + max_ack_delay +3604 }) +3605 } +3606 +3607 /// Probe Timeout +3608 /// +3609 /// The PTO is logically the time in which you'd expect to receive an acknowledgement +3610 /// for a packet. So approximately RTT + max_ack_delay. +3611 fn pto(&self, space: SpaceKind, path_id: PathId) -> Duration { +3612 let max_ack_delay = match space { +3613 SpaceKind::Initial | SpaceKind::Handshake => Duration::ZERO, +3614 SpaceKind::Data => self.ack_frequency.max_ack_delay_for_pto(), +3615 }; +3616 self.path_data(path_id).rtt.pto_base() + max_ack_delay +3617 } +3618 +3619 fn on_packet_authenticated( +3620 &mut self, +3621 now: Instant, +3622 space_id: SpaceKind, +3623 path_id: PathId, +3624 ecn: Option<EcnCodepoint>, +3625 packet_number: Option<u64>, +3626 spin: bool, +3627 is_1rtt: bool, +3628 remote: &FourTuple, +3629 ) { +3630 // During the handshake we already have discarded packets that do not match the path +3631 // remote. So any off-path packet here is either a probing packet or a +3632 // migration. Handling probing packets here means that the path's idle timeout will +3633 // be reset and will delay detecting the path as idle. However tail-loss probes +3634 // would still not get acknowledged if the path was broken so eventually the path +3635 // would still become idle. +3636 let is_on_path = *remote == self.path_data(path_id).network_path; +3637 +3638 self.total_authed_packets += 1; +3639 self.reset_keep_alive(path_id, now); +3640 self.reset_idle_timeout(now, space_id, path_id); +3641 self.path_data_mut(path_id).permit_idle_reset = true; +3642 +3643 // Do not process ECN for off-path packets. If this is a migration we'll get ECN +3644 // back once we've migrated. +3645 if is_on_path { +3646 self.receiving_ecn |= ecn.is_some(); +3647 if let Some(x) = ecn { +3648 let space = &mut self.spaces[space_id]; +3649 space.for_path(path_id).ecn_counters += x; +3650 +3651 if x.is_ce() { +3652 space +3653 .for_path(path_id) +3654 .pending_acks +3655 .set_immediate_ack_required(); +3656 } +3657 } +3658 } +3659 +3660 let Some(packet_number) = packet_number else { +3661 return; +3662 }; +3663 match &self.side { +3664 ConnectionSide::Client { .. } => { +3665 // If we received a handshake packet that authenticated, then we're talking to +3666 // the real server. From now on we should no longer allow the server to migrate +3667 // its address. +3668 if space_id == SpaceKind::Handshake +3669 && let Some(hs) = self.state.as_handshake_mut() +3670 { +3671 hs.allow_server_migration = false; +3672 } +3673 } +3674 ConnectionSide::Server { .. } => { +3675 if self.crypto_state.has_keys(EncryptionLevel::Initial) +3676 && space_id == SpaceKind::Handshake +3677 { +3678 // A server stops sending and processing Initial packets when it receives its first Handshake packet. +3679 self.discard_space(now, SpaceKind::Initial); +3680 } +3681 if self.crypto_state.has_keys(EncryptionLevel::ZeroRtt) && is_1rtt { +3682 // Discard 0-RTT keys soon after receiving a 1-RTT packet +3683 self.set_key_discard_timer(now, space_id) +3684 } +3685 } +3686 } +3687 let space = self.spaces[space_id].for_path(path_id); +3688 +3689 space.pending_acks.insert_one(packet_number, now); +3690 if packet_number >= space.largest_received_packet_number.unwrap_or_default() { +3691 space.largest_received_packet_number = Some(packet_number); +3692 +3693 // Update outgoing spin bit for on-path packets, inverting iff we're the client +3694 if is_on_path { +3695 self.spin = self.side.is_client() ^ spin; +3696 } +3697 } +3698 } +3699 +3700 /// Resets the idle timeout timers +3701 /// +3702 /// Without multipath there is only the connection-wide idle timeout. When multipath is +3703 /// enabled there is an additional per-path idle timeout. +3704 fn reset_idle_timeout(&mut self, now: Instant, space: SpaceKind, path_id: PathId) { +3705 // First reset the global idle timeout. +3706 if let Some(timeout) = self.idle_timeout { +3707 if self.state.is_closed() { +3708 self.timers +3709 .stop(Timer::Conn(ConnTimer::Idle), self.qlog.with_time(now)); +3710 } else { +3711 let dt = cmp::max(timeout, 3 * self.max_pto_for_space(space)); +3712 self.timers.set( +3713 Timer::Conn(ConnTimer::Idle), +3714 now + dt, +3715 self.qlog.with_time(now), +3716 ); +3717 } +3718 } +3719 +3720 // Now handle the per-path state +3721 if let Some(timeout) = self.path_data(path_id).idle_timeout { +3722 if self.state.is_closed() { +3723 self.timers.stop( 3724 Timer::PerPath(path_id, PathTimer::PathIdle), -3725 now + dt, -3726 self.qlog.with_time(now), -3727 ); -3728 } -3729 } -3730 } -3731 -3732 /// Resets both the [`ConnTimer::KeepAlive`] and [`PathTimer::PathKeepAlive`] timers -3733 fn reset_keep_alive(&mut self, path_id: PathId, now: Instant) { -3734 if !self.state.is_established() { -3735 return; -3736 } +3725 self.qlog.with_time(now), +3726 ); +3727 } else { +3728 let dt = cmp::max(timeout, 3 * self.pto(space, path_id)); +3729 self.timers.set( +3730 Timer::PerPath(path_id, PathTimer::PathIdle), +3731 now + dt, +3732 self.qlog.with_time(now), +3733 ); +3734 } +3735 } +3736 } 3737 -3738 if let Some(interval) = self.config.keep_alive_interval { -3739 self.timers.set( -3740 Timer::Conn(ConnTimer::KeepAlive), -3741 now + interval, -3742 self.qlog.with_time(now), -3743 ); -3744 } -3745 -3746 if let Some(interval) = self.path_data(path_id).keep_alive { -3747 self.timers.set( -3748 Timer::PerPath(path_id, PathTimer::PathKeepAlive), -3749 now + interval, -3750 self.qlog.with_time(now), -3751 ); -3752 } -3753 } -3754 -3755 /// Sets the timer for when a previously issued CID should be retired next -3756 fn reset_cid_retirement(&mut self, now: Instant) { -3757 if let Some((_path, t)) = self.next_cid_retirement() { -3758 self.timers.set( -3759 Timer::Conn(ConnTimer::PushNewCid), -3760 t, -3761 self.qlog.with_time(now), -3762 ); -3763 } -3764 } -3765 -3766 /// The next time when a previously issued CID should be retired -3767 fn next_cid_retirement(&self) -> Option<(PathId, Instant)> { -3768 self.local_cid_state -3769 .iter() -3770 .filter_map(|(path_id, cid_state)| cid_state.next_timeout().map(|t| (*path_id, t))) -3771 .min_by_key(|(_path_id, timeout)| *timeout) -3772 } -3773 -3774 /// Handle the already-decrypted first packet from the client -3775 /// -3776 /// Decrypting the first packet in the `Endpoint` allows stateless packet handling to be more -3777 /// efficient. -3778 pub(crate) fn handle_first_packet( -3779 &mut self, -3780 now: Instant, -3781 network_path: FourTuple, -3782 ecn: Option<EcnCodepoint>, -3783 packet_number: u64, -3784 packet: InitialPacket, -3785 remaining: Option<BytesMut>, -3786 ) -> Result<(), ConnectionError> { -3787 let span = trace_span!("first recv"); -3788 let _guard = span.enter(); -3789 debug_assert!(self.side.is_server()); -3790 let len = packet.header_data.len() + packet.payload.len(); -3791 let path_id = PathId::ZERO; -3792 self.path_data_mut(path_id).total_recvd = len as u64; -3793 -3794 if let Some(hs) = self.state.as_handshake_mut() { -3795 hs.expected_token = packet.header.token.clone(); -3796 } else { -3797 unreachable!("first packet must be delivered in Handshake state"); -3798 } +3738 /// Resets both the [`ConnTimer::KeepAlive`] and [`PathTimer::PathKeepAlive`] timers +3739 fn reset_keep_alive(&mut self, path_id: PathId, now: Instant) { +3740 if !self.state.is_established() { +3741 return; +3742 } +3743 +3744 if let Some(interval) = self.config.keep_alive_interval { +3745 self.timers.set( +3746 Timer::Conn(ConnTimer::KeepAlive), +3747 now + interval, +3748 self.qlog.with_time(now), +3749 ); +3750 } +3751 +3752 if let Some(interval) = self.path_data(path_id).keep_alive { +3753 self.timers.set( +3754 Timer::PerPath(path_id, PathTimer::PathKeepAlive), +3755 now + interval, +3756 self.qlog.with_time(now), +3757 ); +3758 } +3759 } +3760 +3761 /// Sets the timer for when a previously issued CID should be retired next +3762 fn reset_cid_retirement(&mut self, now: Instant) { +3763 if let Some((_path, t)) = self.next_cid_retirement() { +3764 self.timers.set( +3765 Timer::Conn(ConnTimer::PushNewCid), +3766 t, +3767 self.qlog.with_time(now), +3768 ); +3769 } +3770 } +3771 +3772 /// The next time when a previously issued CID should be retired +3773 fn next_cid_retirement(&self) -> Option<(PathId, Instant)> { +3774 self.local_cid_state +3775 .iter() +3776 .filter_map(|(path_id, cid_state)| cid_state.next_timeout().map(|t| (*path_id, t))) +3777 .min_by_key(|(_path_id, timeout)| *timeout) +3778 } +3779 +3780 /// Handle the already-decrypted first packet from the client +3781 /// +3782 /// Decrypting the first packet in the `Endpoint` allows stateless packet handling to be more +3783 /// efficient. +3784 pub(crate) fn handle_first_packet( +3785 &mut self, +3786 now: Instant, +3787 network_path: FourTuple, +3788 ecn: Option<EcnCodepoint>, +3789 packet_number: u64, +3790 packet: InitialPacket, +3791 remaining: Option<BytesMut>, +3792 ) -> Result<(), ConnectionError> { +3793 let span = trace_span!("first recv"); +3794 let _guard = span.enter(); +3795 debug_assert!(self.side.is_server()); +3796 let len = packet.header_data.len() + packet.payload.len(); +3797 let path_id = PathId::ZERO; +3798 self.path_data_mut(path_id).total_recvd = len as u64; 3799 -3800 // The first packet is always on PathId::ZERO -3801 self.on_packet_authenticated( -3802 now, -3803 SpaceKind::Initial, -3804 path_id, -3805 ecn, -3806 Some(packet_number), -3807 false, -3808 false, -3809 &network_path, -3810 ); -3811 -3812 let packet: Packet = packet.into(); -3813 -3814 let mut qlog = QlogRecvPacket::new(len); -3815 qlog.header(&packet.header, Some(packet_number), path_id); -3816 -3817 self.process_decrypted_packet( -3818 now, -3819 network_path, -3820 path_id, -3821 Some(packet_number), -3822 packet, -3823 &mut qlog, -3824 )?; -3825 self.qlog.emit_packet_received(qlog, now); -3826 if let Some(data) = remaining { -3827 self.handle_coalesced(now, network_path, path_id, ecn, data); -3828 } -3829 -3830 self.qlog.emit_recovery_metrics( -3831 path_id, -3832 &mut self.paths.get_mut(&path_id).unwrap().data, -3833 now, -3834 ); +3800 if let Some(hs) = self.state.as_handshake_mut() { +3801 hs.expected_token = packet.header.token.clone(); +3802 } else { +3803 unreachable!("first packet must be delivered in Handshake state"); +3804 } +3805 +3806 // The first packet is always on PathId::ZERO +3807 self.on_packet_authenticated( +3808 now, +3809 SpaceKind::Initial, +3810 path_id, +3811 ecn, +3812 Some(packet_number), +3813 false, +3814 false, +3815 &network_path, +3816 ); +3817 +3818 let packet: Packet = packet.into(); +3819 +3820 let mut qlog = QlogRecvPacket::new(len); +3821 qlog.header(&packet.header, Some(packet_number), path_id); +3822 +3823 self.process_decrypted_packet( +3824 now, +3825 network_path, +3826 path_id, +3827 Some(packet_number), +3828 packet, +3829 &mut qlog, +3830 )?; +3831 self.qlog.emit_packet_received(qlog, now); +3832 if let Some(data) = remaining { +3833 self.handle_coalesced(now, network_path, path_id, ecn, data); +3834 } 3835 -3836 Ok(()) -3837 } -3838 -3839 fn init_0rtt(&mut self, now: Instant) { -3840 let Some((header, packet)) = self.crypto_state.session.early_crypto() else { -3841 return; -3842 }; -3843 if self.side.is_client() { -3844 match self.crypto_state.session.transport_parameters() { -3845 Ok(params) => { -3846 let params = params -3847 .expect("crypto layer didn't supply transport parameters with ticket"); -3848 // Certain values must not be cached -3849 let params = TransportParameters { -3850 initial_src_cid: None, -3851 original_dst_cid: None, -3852 preferred_address: None, -3853 retry_src_cid: None, -3854 stateless_reset_token: None, -3855 min_ack_delay: None, -3856 ack_delay_exponent: TransportParameters::default().ack_delay_exponent, -3857 max_ack_delay: TransportParameters::default().max_ack_delay, -3858 initial_max_path_id: None, -3859 ..params -3860 }; -3861 self.set_peer_params(params); -3862 self.qlog.emit_peer_transport_params_restored(self, now); -3863 } -3864 Err(e) => { -3865 error!("session ticket has malformed transport parameters: {}", e); -3866 return; -3867 } -3868 } -3869 } -3870 trace!("0-RTT enabled"); -3871 self.crypto_state.enable_zero_rtt(header, packet); -3872 } -3873 -3874 fn read_crypto( -3875 &mut self, -3876 space: SpaceId, -3877 crypto: &frame::Crypto, -3878 payload_len: usize, -3879 ) -> Result<(), TransportError> { -3880 let expected = if !self.state.is_handshake() { -3881 SpaceId::Data -3882 } else if self.highest_space == SpaceKind::Initial { -3883 SpaceId::Initial -3884 } else { -3885 // On the server, self.highest_space can be Data after receiving the client's first -3886 // flight, but we expect Handshake CRYPTO until the handshake is complete. -3887 SpaceId::Handshake -3888 }; -3889 // We can't decrypt Handshake packets when highest_space is Initial, CRYPTO frames in 0-RTT -3890 // packets are illegal, and we don't process 1-RTT packets until the handshake is -3891 // complete. Therefore, we will never see CRYPTO data from a later-than-expected space. -3892 debug_assert!(space <= expected, "received out-of-order CRYPTO data"); -3893 -3894 let end = crypto.offset + crypto.data.len() as u64; -3895 if space < expected -3896 && end -3897 > self.crypto_state.spaces[space.kind()] -3898 .crypto_stream -3899 .bytes_read() -3900 { -3901 warn!( -3902 "received new {:?} CRYPTO data when expecting {:?}", -3903 space, expected -3904 ); -3905 return Err(TransportError::PROTOCOL_VIOLATION( -3906 "new data at unexpected encryption level", -3907 )); -3908 } -3909 -3910 let crypto_space = &mut self.crypto_state.spaces[space.kind()]; -3911 let max = end.saturating_sub(crypto_space.crypto_stream.bytes_read()); -3912 if max > self.config.crypto_buffer_size as u64 { -3913 return Err(TransportError::CRYPTO_BUFFER_EXCEEDED("")); +3836 self.qlog.emit_recovery_metrics( +3837 path_id, +3838 &mut self.paths.get_mut(&path_id).unwrap().data, +3839 now, +3840 ); +3841 +3842 Ok(()) +3843 } +3844 +3845 fn init_0rtt(&mut self, now: Instant) { +3846 let Some((header, packet)) = self.crypto_state.session.early_crypto() else { +3847 return; +3848 }; +3849 if self.side.is_client() { +3850 match self.crypto_state.session.transport_parameters() { +3851 Ok(params) => { +3852 let params = params +3853 .expect("crypto layer didn't supply transport parameters with ticket"); +3854 // Certain values must not be cached +3855 let params = TransportParameters { +3856 initial_src_cid: None, +3857 original_dst_cid: None, +3858 preferred_address: None, +3859 retry_src_cid: None, +3860 stateless_reset_token: None, +3861 min_ack_delay: None, +3862 ack_delay_exponent: TransportParameters::default().ack_delay_exponent, +3863 max_ack_delay: TransportParameters::default().max_ack_delay, +3864 initial_max_path_id: None, +3865 ..params +3866 }; +3867 self.set_peer_params(params); +3868 self.qlog.emit_peer_transport_params_restored(self, now); +3869 } +3870 Err(e) => { +3871 error!("session ticket has malformed transport parameters: {}", e); +3872 return; +3873 } +3874 } +3875 } +3876 trace!("0-RTT enabled"); +3877 self.crypto_state.enable_zero_rtt(header, packet); +3878 } +3879 +3880 fn read_crypto( +3881 &mut self, +3882 space: SpaceId, +3883 crypto: &frame::Crypto, +3884 payload_len: usize, +3885 ) -> Result<(), TransportError> { +3886 let expected = if !self.state.is_handshake() { +3887 SpaceId::Data +3888 } else if self.highest_space == SpaceKind::Initial { +3889 SpaceId::Initial +3890 } else { +3891 // On the server, self.highest_space can be Data after receiving the client's first +3892 // flight, but we expect Handshake CRYPTO until the handshake is complete. +3893 SpaceId::Handshake +3894 }; +3895 // We can't decrypt Handshake packets when highest_space is Initial, CRYPTO frames in 0-RTT +3896 // packets are illegal, and we don't process 1-RTT packets until the handshake is +3897 // complete. Therefore, we will never see CRYPTO data from a later-than-expected space. +3898 debug_assert!(space <= expected, "received out-of-order CRYPTO data"); +3899 +3900 let end = crypto.offset + crypto.data.len() as u64; +3901 if space < expected +3902 && end +3903 > self.crypto_state.spaces[space.kind()] +3904 .crypto_stream +3905 .bytes_read() +3906 { +3907 warn!( +3908 "received new {:?} CRYPTO data when expecting {:?}", +3909 space, expected +3910 ); +3911 return Err(TransportError::PROTOCOL_VIOLATION( +3912 "new data at unexpected encryption level", +3913 )); 3914 } 3915 -3916 crypto_space -3917 .crypto_stream -3918 .insert(crypto.offset, crypto.data.clone(), payload_len); -3919 while let Some(chunk) = crypto_space.crypto_stream.read(usize::MAX, true) { -3920 trace!("consumed {} CRYPTO bytes", chunk.bytes.len()); -3921 if self.crypto_state.session.read_handshake(&chunk.bytes)? { -3922 self.events.push_back(Event::HandshakeDataReady); -3923 } -3924 } -3925 -3926 Ok(()) -3927 } -3928 -3929 fn write_crypto(&mut self) { -3930 loop { -3931 let space = self.highest_space; -3932 let mut outgoing = Vec::new(); -3933 if let Some(crypto) = self.crypto_state.session.write_handshake(&mut outgoing) { -3934 match space { -3935 SpaceKind::Initial => { -3936 self.upgrade_crypto(SpaceKind::Handshake, crypto); -3937 } -3938 SpaceKind::Handshake => { -3939 self.upgrade_crypto(SpaceKind::Data, crypto); -3940 } -3941 SpaceKind::Data => unreachable!("got updated secrets during 1-RTT"), -3942 } -3943 } -3944 if outgoing.is_empty() { -3945 if space == self.highest_space { -3946 break; -3947 } else { -3948 // Keys updated, check for more data to send -3949 continue; -3950 } -3951 } -3952 let offset = self.crypto_state.spaces[space].crypto_offset; -3953 let outgoing = Bytes::from(outgoing); -3954 if let Some(hs) = self.state.as_handshake_mut() -3955 && space == SpaceKind::Initial -3956 && offset == 0 -3957 && self.side.is_client() -3958 { -3959 hs.client_hello = Some(outgoing.clone()); -3960 } -3961 self.crypto_state.spaces[space].crypto_offset += outgoing.len() as u64; -3962 trace!("wrote {} {:?} CRYPTO bytes", outgoing.len(), space); -3963 self.spaces[space].pending.crypto.push_back(frame::Crypto { -3964 offset, -3965 data: outgoing, -3966 }); -3967 } -3968 } -3969 -3970 /// Switch to stronger cryptography during handshake -3971 fn upgrade_crypto(&mut self, space: SpaceKind, crypto: Keys) { -3972 debug_assert!( -3973 !self.crypto_state.has_keys(space.encryption_level()), -3974 "already reached packet space {space:?}" -3975 ); -3976 trace!("{:?} keys ready", space); -3977 if space == SpaceKind::Data { -3978 // Precompute the first key update -3979 self.crypto_state.next_crypto = Some( -3980 self.crypto_state -3981 .session -3982 .next_1rtt_keys() -3983 .expect("handshake should be complete"), -3984 ); -3985 } -3986 -3987 self.crypto_state.spaces[space].keys = Some(crypto); -3988 debug_assert!(space > self.highest_space); -3989 self.highest_space = space; -3990 if space == SpaceKind::Data && self.side.is_client() { -3991 // Discard 0-RTT keys because 1-RTT keys are available. -3992 self.crypto_state.discard_zero_rtt(); -3993 } -3994 } -3995 -3996 fn discard_space(&mut self, now: Instant, space: SpaceKind) { -3997 debug_assert!(space != SpaceKind::Data); -3998 trace!("discarding {:?} keys", space); -3999 if space == SpaceKind::Initial { -4000 // No longer needed -4001 if let ConnectionSide::Client { token, .. } = &mut self.side { -4002 *token = Bytes::new(); -4003 } -4004 } -4005 self.crypto_state.spaces[space].keys = None; -4006 let space = &mut self.spaces[space]; -4007 let pns = space.for_path(PathId::ZERO); -4008 pns.time_of_last_ack_eliciting_packet = None; -4009 pns.loss_time = None; -4010 pns.loss_probes = 0; -4011 let sent_packets = mem::take(&mut pns.sent_packets); -4012 let path = self.paths.get_mut(&PathId::ZERO).unwrap(); -4013 for (_, packet) in sent_packets.into_iter() { -4014 path.data.remove_in_flight(&packet); -4015 } -4016 -4017 self.set_loss_detection_timer(now, PathId::ZERO) -4018 } -4019 -4020 fn handle_coalesced( -4021 &mut self, -4022 now: Instant, -4023 network_path: FourTuple, -4024 path_id: PathId, -4025 ecn: Option<EcnCodepoint>, -4026 data: BytesMut, -4027 ) { -4028 self.path_data_mut(path_id) -4029 .inc_total_recvd(data.len() as u64); -4030 let mut remaining = Some(data); -4031 let cid_len = self -4032 .local_cid_state -4033 .values() -4034 .map(|cid_state| cid_state.cid_len()) -4035 .next() -4036 .expect("one cid_state must exist"); -4037 while let Some(data) = remaining { -4038 match PartialDecode::new( -4039 data, -4040 &FixedLengthConnectionIdParser::new(cid_len), -4041 &[self.version], -4042 self.endpoint_config.grease_quic_bit, -4043 ) { -4044 Ok((partial_decode, rest)) => { -4045 remaining = rest; -4046 self.handle_decode(now, network_path, path_id, ecn, partial_decode); -4047 } -4048 Err(e) => { -4049 trace!("malformed header: {}", e); -4050 return; -4051 } -4052 } -4053 } -4054 } -4055 -4056 fn handle_decode( -4057 &mut self, -4058 now: Instant, -4059 network_path: FourTuple, -4060 path_id: PathId, -4061 ecn: Option<EcnCodepoint>, -4062 partial_decode: PartialDecode, -4063 ) { -4064 let qlog = QlogRecvPacket::new(partial_decode.len()); -4065 if let Some(decoded) = self -4066 .crypto_state -4067 .unprotect_header(partial_decode, self.peer_params.stateless_reset_token) -4068 { -4069 self.handle_packet( -4070 now, -4071 network_path, -4072 path_id, -4073 ecn, -4074 decoded.packet, -4075 decoded.stateless_reset, -4076 qlog, -4077 ); -4078 } -4079 } -4080 -4081 fn handle_packet( -4082 &mut self, -4083 now: Instant, -4084 network_path: FourTuple, -4085 path_id: PathId, -4086 ecn: Option<EcnCodepoint>, -4087 packet: Option<Packet>, -4088 stateless_reset: bool, -4089 mut qlog: QlogRecvPacket, -4090 ) { -4091 self.path_stats.for_path(path_id).udp_rx.ios += 1; -4092 -4093 if let Some(ref packet) = packet { -4094 trace!( -4095 "got {:?} packet ({} bytes) from {} using id {}", -4096 packet.header.space(), -4097 packet.payload.len() + packet.header_data.len(), -4098 network_path, -4099 packet.header.dst_cid(), -4100 ); -4101 } -4102 -4103 if self.is_handshaking() { -4104 if path_id != PathId::ZERO { -4105 debug!(%network_path, %path_id, "discarding multipath packet during handshake"); -4106 return; -4107 } -4108 if network_path != self.path_data_mut(path_id).network_path { -4109 if let Some(hs) = self.state.as_handshake() { -4110 if hs.allow_server_migration { -4111 trace!(%network_path, prev = %self.path_data(path_id).network_path, "server migrated to new remote"); -4112 self.path_data_mut(path_id).network_path = network_path; -4113 self.qlog.emit_tuple_assigned(path_id, network_path, now); -4114 } else { -4115 debug!("discarding packet with unexpected remote during handshake"); -4116 return; -4117 } -4118 } else { -4119 debug!("discarding packet with unexpected remote during handshake"); -4120 return; -4121 } -4122 } -4123 } -4124 -4125 let was_closed = self.state.is_closed(); -4126 let was_drained = self.state.is_drained(); -4127 -4128 let decrypted = match packet { -4129 None => Err(None), -4130 Some(mut packet) => self -4131 .decrypt_packet(now, path_id, &mut packet) -4132 .map(move |number| (packet, number)), -4133 }; -4134 let result = match decrypted { -4135 _ if stateless_reset => { -4136 debug!("got stateless reset"); -4137 Err(ConnectionError::Reset) -4138 } -4139 Err(Some(e)) => { -4140 warn!("illegal packet: {}", e); -4141 Err(e.into()) -4142 } -4143 Err(None) => { -4144 debug!("failed to authenticate packet"); -4145 self.authentication_failures += 1; -4146 let integrity_limit = self -4147 .crypto_state -4148 .integrity_limit(self.highest_space) -4149 .unwrap(); -4150 if self.authentication_failures > integrity_limit { -4151 Err(TransportError::AEAD_LIMIT_REACHED("integrity limit violated").into()) -4152 } else { -4153 return; -4154 } -4155 } -4156 Ok((packet, number)) => { -4157 qlog.header(&packet.header, number, path_id); -4158 let span = match number { -4159 Some(pn) => trace_span!("recv", space = ?packet.header.space(), pn), -4160 None => trace_span!("recv", space = ?packet.header.space()), -4161 }; -4162 let _guard = span.enter(); -4163 -4164 let dedup = self.spaces[packet.header.space()] -4165 .path_space_mut(path_id) -4166 .map(|pns| &mut pns.dedup); -4167 if number.zip(dedup).is_some_and(|(n, d)| d.insert(n)) { -4168 debug!("discarding possible duplicate packet"); -4169 self.qlog.emit_packet_received(qlog, now); -4170 return; -4171 } else if self.state.is_handshake() && packet.header.is_short() { -4172 // TODO: SHOULD buffer these to improve reordering tolerance. -4173 trace!("dropping short packet during handshake"); -4174 self.qlog.emit_packet_received(qlog, now); -4175 return; -4176 } else { -4177 if let Header::Initial(InitialHeader { ref token, .. }) = packet.header -4178 && let Some(hs) = self.state.as_handshake() -4179 && self.side.is_server() -4180 && token != &hs.expected_token -4181 { -4182 // Clients must send the same retry token in every Initial. Initial -4183 // packets can be spoofed, so we discard rather than killing the -4184 // connection. -4185 warn!("discarding Initial with invalid retry token"); -4186 self.qlog.emit_packet_received(qlog, now); -4187 return; -4188 } -4189 -4190 if !self.state.is_closed() { -4191 let spin = match packet.header { -4192 Header::Short { spin, .. } => spin, -4193 _ => false, -4194 }; +3916 let crypto_space = &mut self.crypto_state.spaces[space.kind()]; +3917 let max = end.saturating_sub(crypto_space.crypto_stream.bytes_read()); +3918 if max > self.config.crypto_buffer_size as u64 { +3919 return Err(TransportError::CRYPTO_BUFFER_EXCEEDED("")); +3920 } +3921 +3922 crypto_space +3923 .crypto_stream +3924 .insert(crypto.offset, crypto.data.clone(), payload_len); +3925 while let Some(chunk) = crypto_space.crypto_stream.read(usize::MAX, true) { +3926 trace!("consumed {} CRYPTO bytes", chunk.bytes.len()); +3927 if self.crypto_state.session.read_handshake(&chunk.bytes)? { +3928 self.events.push_back(Event::HandshakeDataReady); +3929 } +3930 } +3931 +3932 Ok(()) +3933 } +3934 +3935 fn write_crypto(&mut self) { +3936 loop { +3937 let space = self.highest_space; +3938 let mut outgoing = Vec::new(); +3939 if let Some(crypto) = self.crypto_state.session.write_handshake(&mut outgoing) { +3940 match space { +3941 SpaceKind::Initial => { +3942 self.upgrade_crypto(SpaceKind::Handshake, crypto); +3943 } +3944 SpaceKind::Handshake => { +3945 self.upgrade_crypto(SpaceKind::Data, crypto); +3946 } +3947 SpaceKind::Data => unreachable!("got updated secrets during 1-RTT"), +3948 } +3949 } +3950 if outgoing.is_empty() { +3951 if space == self.highest_space { +3952 break; +3953 } else { +3954 // Keys updated, check for more data to send +3955 continue; +3956 } +3957 } +3958 let offset = self.crypto_state.spaces[space].crypto_offset; +3959 let outgoing = Bytes::from(outgoing); +3960 if let Some(hs) = self.state.as_handshake_mut() +3961 && space == SpaceKind::Initial +3962 && offset == 0 +3963 && self.side.is_client() +3964 { +3965 hs.client_hello = Some(outgoing.clone()); +3966 } +3967 self.crypto_state.spaces[space].crypto_offset += outgoing.len() as u64; +3968 trace!("wrote {} {:?} CRYPTO bytes", outgoing.len(), space); +3969 self.spaces[space].pending.crypto.push_back(frame::Crypto { +3970 offset, +3971 data: outgoing, +3972 }); +3973 } +3974 } +3975 +3976 /// Switch to stronger cryptography during handshake +3977 fn upgrade_crypto(&mut self, space: SpaceKind, crypto: Keys) { +3978 debug_assert!( +3979 !self.crypto_state.has_keys(space.encryption_level()), +3980 "already reached packet space {space:?}" +3981 ); +3982 trace!("{:?} keys ready", space); +3983 if space == SpaceKind::Data { +3984 // Precompute the first key update +3985 self.crypto_state.next_crypto = Some( +3986 self.crypto_state +3987 .session +3988 .next_1rtt_keys() +3989 .expect("handshake should be complete"), +3990 ); +3991 } +3992 +3993 self.crypto_state.spaces[space].keys = Some(crypto); +3994 debug_assert!(space > self.highest_space); +3995 self.highest_space = space; +3996 if space == SpaceKind::Data && self.side.is_client() { +3997 // Discard 0-RTT keys because 1-RTT keys are available. +3998 self.crypto_state.discard_zero_rtt(); +3999 } +4000 } +4001 +4002 fn discard_space(&mut self, now: Instant, space: SpaceKind) { +4003 debug_assert!(space != SpaceKind::Data); +4004 trace!("discarding {:?} keys", space); +4005 if space == SpaceKind::Initial { +4006 // No longer needed +4007 if let ConnectionSide::Client { token, .. } = &mut self.side { +4008 *token = Bytes::new(); +4009 } +4010 } +4011 self.crypto_state.spaces[space].keys = None; +4012 let space = &mut self.spaces[space]; +4013 let pns = space.for_path(PathId::ZERO); +4014 pns.time_of_last_ack_eliciting_packet = None; +4015 pns.loss_time = None; +4016 pns.loss_probes = 0; +4017 let sent_packets = mem::take(&mut pns.sent_packets); +4018 let path = self.paths.get_mut(&PathId::ZERO).unwrap(); +4019 for (_, packet) in sent_packets.into_iter() { +4020 path.data.remove_in_flight(&packet); +4021 } +4022 +4023 self.set_loss_detection_timer(now, PathId::ZERO) +4024 } +4025 +4026 fn handle_coalesced( +4027 &mut self, +4028 now: Instant, +4029 network_path: FourTuple, +4030 path_id: PathId, +4031 ecn: Option<EcnCodepoint>, +4032 data: BytesMut, +4033 ) { +4034 self.path_data_mut(path_id) +4035 .inc_total_recvd(data.len() as u64); +4036 let mut remaining = Some(data); +4037 let cid_len = self +4038 .local_cid_state +4039 .values() +4040 .map(|cid_state| cid_state.cid_len()) +4041 .next() +4042 .expect("one cid_state must exist"); +4043 while let Some(data) = remaining { +4044 match PartialDecode::new( +4045 data, +4046 &FixedLengthConnectionIdParser::new(cid_len), +4047 &[self.version], +4048 self.endpoint_config.grease_quic_bit, +4049 ) { +4050 Ok((partial_decode, rest)) => { +4051 remaining = rest; +4052 self.handle_decode(now, network_path, path_id, ecn, partial_decode); +4053 } +4054 Err(e) => { +4055 trace!("malformed header: {}", e); +4056 return; +4057 } +4058 } +4059 } +4060 } +4061 +4062 fn handle_decode( +4063 &mut self, +4064 now: Instant, +4065 network_path: FourTuple, +4066 path_id: PathId, +4067 ecn: Option<EcnCodepoint>, +4068 partial_decode: PartialDecode, +4069 ) { +4070 let qlog = QlogRecvPacket::new(partial_decode.len()); +4071 if let Some(decoded) = self +4072 .crypto_state +4073 .unprotect_header(partial_decode, self.peer_params.stateless_reset_token) +4074 { +4075 self.handle_packet( +4076 now, +4077 network_path, +4078 path_id, +4079 ecn, +4080 decoded.packet, +4081 decoded.stateless_reset, +4082 qlog, +4083 ); +4084 } +4085 } +4086 +4087 fn handle_packet( +4088 &mut self, +4089 now: Instant, +4090 network_path: FourTuple, +4091 path_id: PathId, +4092 ecn: Option<EcnCodepoint>, +4093 packet: Option<Packet>, +4094 stateless_reset: bool, +4095 mut qlog: QlogRecvPacket, +4096 ) { +4097 self.path_stats.for_path(path_id).udp_rx.ios += 1; +4098 +4099 if let Some(ref packet) = packet { +4100 trace!( +4101 "got {:?} packet ({} bytes) from {} using id {}", +4102 packet.header.space(), +4103 packet.payload.len() + packet.header_data.len(), +4104 network_path, +4105 packet.header.dst_cid(), +4106 ); +4107 } +4108 +4109 if self.is_handshaking() { +4110 if path_id != PathId::ZERO { +4111 debug!(%network_path, %path_id, "discarding multipath packet during handshake"); +4112 return; +4113 } +4114 if network_path != self.path_data_mut(path_id).network_path { +4115 if let Some(hs) = self.state.as_handshake() { +4116 if hs.allow_server_migration { +4117 trace!(%network_path, prev = %self.path_data(path_id).network_path, "server migrated to new remote"); +4118 self.path_data_mut(path_id).network_path = network_path; +4119 self.qlog.emit_tuple_assigned(path_id, network_path, now); +4120 } else { +4121 debug!("discarding packet with unexpected remote during handshake"); +4122 return; +4123 } +4124 } else { +4125 debug!("discarding packet with unexpected remote during handshake"); +4126 return; +4127 } +4128 } +4129 } +4130 +4131 let was_closed = self.state.is_closed(); +4132 let was_drained = self.state.is_drained(); +4133 +4134 let decrypted = match packet { +4135 None => Err(None), +4136 Some(mut packet) => self +4137 .decrypt_packet(now, path_id, &mut packet) +4138 .map(move |number| (packet, number)), +4139 }; +4140 let result = match decrypted { +4141 _ if stateless_reset => { +4142 debug!("got stateless reset"); +4143 Err(ConnectionError::Reset) +4144 } +4145 Err(Some(e)) => { +4146 warn!("illegal packet: {}", e); +4147 Err(e.into()) +4148 } +4149 Err(None) => { +4150 debug!("failed to authenticate packet"); +4151 self.authentication_failures += 1; +4152 let integrity_limit = self +4153 .crypto_state +4154 .integrity_limit(self.highest_space) +4155 .unwrap(); +4156 if self.authentication_failures > integrity_limit { +4157 Err(TransportError::AEAD_LIMIT_REACHED("integrity limit violated").into()) +4158 } else { +4159 return; +4160 } +4161 } +4162 Ok((packet, number)) => { +4163 qlog.header(&packet.header, number, path_id); +4164 let span = match number { +4165 Some(pn) => trace_span!("recv", space = ?packet.header.space(), pn), +4166 None => trace_span!("recv", space = ?packet.header.space()), +4167 }; +4168 let _guard = span.enter(); +4169 +4170 let dedup = self.spaces[packet.header.space()] +4171 .path_space_mut(path_id) +4172 .map(|pns| &mut pns.dedup); +4173 if number.zip(dedup).is_some_and(|(n, d)| d.insert(n)) { +4174 debug!("discarding possible duplicate packet"); +4175 self.qlog.emit_packet_received(qlog, now); +4176 return; +4177 } else if self.state.is_handshake() && packet.header.is_short() { +4178 // TODO: SHOULD buffer these to improve reordering tolerance. +4179 trace!("dropping short packet during handshake"); +4180 self.qlog.emit_packet_received(qlog, now); +4181 return; +4182 } else { +4183 if let Header::Initial(InitialHeader { ref token, .. }) = packet.header +4184 && let Some(hs) = self.state.as_handshake() +4185 && self.side.is_server() +4186 && token != &hs.expected_token +4187 { +4188 // Clients must send the same retry token in every Initial. Initial +4189 // packets can be spoofed, so we discard rather than killing the +4190 // connection. +4191 warn!("discarding Initial with invalid retry token"); +4192 self.qlog.emit_packet_received(qlog, now); +4193 return; +4194 } 4195 -4196 if self.side().is_server() && !self.abandoned_paths.contains(&path_id) { -4197 // Only the client is allowed to open paths -4198 self.ensure_path(path_id, network_path, now, number); -4199 } -4200 if self.paths.contains_key(&path_id) { -4201 self.on_packet_authenticated( -4202 now, -4203 packet.header.space(), -4204 path_id, -4205 ecn, -4206 number, -4207 spin, -4208 packet.header.is_1rtt(), -4209 &network_path, -4210 ); -4211 } -4212 } -4213 -4214 let res = self.process_decrypted_packet( -4215 now, -4216 network_path, -4217 path_id, -4218 number, -4219 packet, -4220 &mut qlog, -4221 ); -4222 -4223 self.qlog.emit_packet_received(qlog, now); -4224 res -4225 } -4226 } -4227 }; +4196 if !self.state.is_closed() { +4197 let spin = match packet.header { +4198 Header::Short { spin, .. } => spin, +4199 _ => false, +4200 }; +4201 +4202 if self.side().is_server() && !self.abandoned_paths.contains(&path_id) { +4203 // Only the client is allowed to open paths +4204 self.ensure_path(path_id, network_path, now, number); +4205 } +4206 if self.paths.contains_key(&path_id) { +4207 self.on_packet_authenticated( +4208 now, +4209 packet.header.space(), +4210 path_id, +4211 ecn, +4212 number, +4213 spin, +4214 packet.header.is_1rtt(), +4215 &network_path, +4216 ); +4217 } +4218 } +4219 +4220 let res = self.process_decrypted_packet( +4221 now, +4222 network_path, +4223 path_id, +4224 number, +4225 packet, +4226 &mut qlog, +4227 ); 4228 -4229 // State transitions for error cases -4230 if let Err(conn_err) = result { -4231 match conn_err { -4232 ConnectionError::ApplicationClosed(reason) => self.state.move_to_closed(reason), -4233 ConnectionError::ConnectionClosed(reason) => self.state.move_to_closed(reason), -4234 ConnectionError::Reset -4235 | ConnectionError::TransportError(TransportError { -4236 code: TransportErrorCode::AEAD_LIMIT_REACHED, -4237 .. -4238 }) => { -4239 self.state.move_to_drained(Some(conn_err)); -4240 } -4241 ConnectionError::TimedOut => { -4242 unreachable!("timeouts aren't generated by packet processing"); -4243 } -4244 ConnectionError::TransportError(err) => { -4245 debug!("closing connection due to transport error: {}", err); -4246 self.state.move_to_closed(err); -4247 } -4248 ConnectionError::VersionMismatch => { -4249 self.state.move_to_draining(Some(conn_err)); -4250 } -4251 ConnectionError::LocallyClosed => { -4252 unreachable!("LocallyClosed isn't generated by packet processing"); +4229 self.qlog.emit_packet_received(qlog, now); +4230 res +4231 } +4232 } +4233 }; +4234 +4235 // State transitions for error cases +4236 if let Err(conn_err) = result { +4237 match conn_err { +4238 ConnectionError::ApplicationClosed(reason) => self.state.move_to_closed(reason), +4239 ConnectionError::ConnectionClosed(reason) => self.state.move_to_closed(reason), +4240 ConnectionError::Reset +4241 | ConnectionError::TransportError(TransportError { +4242 code: TransportErrorCode::AEAD_LIMIT_REACHED, +4243 .. +4244 }) => { +4245 self.state.move_to_drained(Some(conn_err)); +4246 } +4247 ConnectionError::TimedOut => { +4248 unreachable!("timeouts aren't generated by packet processing"); +4249 } +4250 ConnectionError::TransportError(err) => { +4251 debug!("closing connection due to transport error: {}", err); +4252 self.state.move_to_closed(err); 4253 } -4254 ConnectionError::CidsExhausted => { -4255 unreachable!("CidsExhausted isn't generated by packet processing"); +4254 ConnectionError::VersionMismatch => { +4255 self.state.move_to_draining(Some(conn_err)); 4256 } -4257 }; -4258 } -4259 -4260 if !was_closed && self.state.is_closed() { -4261 self.close_common(); -4262 if !self.state.is_drained() { -4263 self.set_close_timer(now); -4264 } -4265 } -4266 if !was_drained && self.state.is_drained() { -4267 self.endpoint_events.push_back(EndpointEventInner::Drained); -4268 // Close timer may have been started previously, e.g. if we sent a close and got a -4269 // stateless reset in response -4270 self.timers -4271 .stop(Timer::Conn(ConnTimer::Close), self.qlog.with_time(now)); -4272 } -4273 -4274 // Transmit CONNECTION_CLOSE if necessary. -4275 // -4276 // If we received a valid packet and we are in the closed state we should respond -4277 // with a CONNECTION_CLOSE frame. -4278 // TODO: This SHOULD be rate-limited according to §10.2.1 of QUIC-TRANSPORT, but -4279 // that does not yet happen. This is triggered by each received packet. -4280 if matches!(self.state.as_type(), StateType::Closed) { -4281 // From https://www.rfc-editor.org/rfc/rfc9000.html#section-10.2.1-7 -4282 // -4283 // While in the closing state we must either: -4284 // - discard packets coming from an un-validated remote OR -4285 // - ensure we do not send more than 3 times the received data -4286 // -4287 // Doing the 2nd would mean we would be able to send CONNECTION_CLOSE to a peer -4288 // who was (involuntary) migrated just at the time we initiated immediate -4289 // close. It is a lot more work though. So while we would like to do this for -4290 // now we only do 1. -4291 // -4292 // Another shortcoming of the current implementation is that when we have a -4293 // previous PathData which is validated and the remote matches that path, we -4294 // should schedule CONNECTION_CLOSE on that path. However currently we can not -4295 // schedule such a packet. We should also fix this some day. This makes us -4296 // vulnerable to an attacker faking a migration at the right time and then we'd -4297 // be unable to send the CONNECTION_CLOSE to the real remote. -4298 if self -4299 .paths -4300 .get(&path_id) -4301 .map(|p| p.data.validated && p.data.network_path == network_path) -4302 .unwrap_or(false) -4303 { -4304 self.connection_close_pending = true; -4305 } -4306 } -4307 } -4308 -4309 fn process_decrypted_packet( -4310 &mut self, -4311 now: Instant, -4312 network_path: FourTuple, -4313 path_id: PathId, -4314 number: Option<u64>, -4315 packet: Packet, -4316 qlog: &mut QlogRecvPacket, -4317 ) -> Result<(), ConnectionError> { -4318 if !self.paths.contains_key(&path_id) { -4319 // There is a chance this is a server side, first (for this path) packet, which would -4320 // be a protocol violation. It's more likely, however, that this is a packet of a -4321 // pruned path -4322 trace!(%path_id, ?number, "discarding packet for unknown path"); -4323 return Ok(()); -4324 } -4325 let state = match self.state.as_type() { -4326 StateType::Established => { -4327 match packet.header.space() { -4328 SpaceKind::Data => self.process_payload( -4329 now, -4330 network_path, -4331 path_id, -4332 number.unwrap(), -4333 packet, -4334 qlog, -4335 )?, -4336 _ if packet.header.has_frames() => { -4337 self.process_early_payload(now, path_id, packet, qlog)? -4338 } -4339 _ => { -4340 trace!("discarding unexpected pre-handshake packet"); -4341 } -4342 } -4343 return Ok(()); -4344 } -4345 StateType::Closed => { -4346 for result in frame::Iter::new(packet.payload.freeze())? { -4347 let frame = match result { -4348 Ok(frame) => frame, -4349 Err(err) => { -4350 debug!("frame decoding error: {err:?}"); -4351 continue; -4352 } -4353 }; -4354 qlog.frame(&frame); -4355 -4356 if let Frame::Padding = frame { -4357 continue; -4358 }; -4359 -4360 self.path_stats -4361 .for_path(path_id) -4362 .frame_rx -4363 .record(frame.ty()); -4364 -4365 if let Frame::Close(_error) = frame { -4366 self.state.move_to_draining(None); -4367 break; -4368 } -4369 } -4370 return Ok(()); -4371 } -4372 StateType::Draining | StateType::Drained => return Ok(()), -4373 StateType::Handshake => self.state.as_handshake_mut().expect("checked"), -4374 }; -4375 -4376 match packet.header { -4377 Header::Retry { -4378 src_cid: remote_cid, -4379 .. -4380 } => { -4381 debug_assert_eq!(path_id, PathId::ZERO); -4382 if self.side.is_server() { -4383 return Err(TransportError::PROTOCOL_VIOLATION("client sent Retry").into()); -4384 } -4385 -4386 let is_valid_retry = self -4387 .remote_cids -4388 .get(&path_id) -4389 .map(|cids| cids.active()) -4390 .map(|orig_dst_cid| { -4391 self.crypto_state.session.is_valid_retry( -4392 orig_dst_cid, -4393 &packet.header_data, -4394 &packet.payload, -4395 ) -4396 }) -4397 .unwrap_or_default(); -4398 if self.total_authed_packets > 1 -4399 || packet.payload.len() <= 16 // token + 16 byte tag -4400 || !is_valid_retry -4401 { -4402 trace!("discarding invalid Retry"); -4403 // - After the client has received and processed an Initial or Retry -4404 // packet from the server, it MUST discard any subsequent Retry -4405 // packets that it receives. -4406 // - A client MUST discard a Retry packet with a zero-length Retry Token -4407 // field. -4408 // - Clients MUST discard Retry packets that have a Retry Integrity Tag -4409 // that cannot be validated -4410 return Ok(()); -4411 } -4412 -4413 trace!("retrying with CID {}", remote_cid); -4414 let client_hello = state.client_hello.take().unwrap(); -4415 self.retry_src_cid = Some(remote_cid); -4416 self.remote_cids -4417 .get_mut(&path_id) -4418 .expect("PathId::ZERO not yet abandoned, is_valid_retry would have been false") -4419 .update_initial_cid(remote_cid); -4420 self.remote_handshake_cid = remote_cid; -4421 -4422 let space = &mut self.spaces[SpaceId::Initial]; -4423 if let Some(info) = space.for_path(PathId::ZERO).take(0) { -4424 self.on_packet_acked(now, PathId::ZERO, info); -4425 }; -4426 -4427 self.discard_space(now, SpaceKind::Initial); // Make sure we clean up after -4428 // any retransmitted Initials -4429 let crypto_space = &mut self.crypto_state.spaces[SpaceKind::Initial]; -4430 crypto_space.keys = Some( -4431 self.crypto_state -4432 .session -4433 .initial_keys(remote_cid, self.side.side()), -4434 ); -4435 crypto_space.crypto_offset = client_hello.len() as u64; -4436 -4437 let next_pn = self.spaces[SpaceId::Initial] -4438 .for_path(path_id) -4439 .next_packet_number; -4440 self.spaces[SpaceId::Initial] = { -4441 let mut space = PacketSpace::new(now, SpaceId::Initial, &mut self.rng); -4442 space.for_path(path_id).next_packet_number = next_pn; -4443 space.pending.crypto.push_back(frame::Crypto { -4444 offset: 0, -4445 data: client_hello, -4446 }); -4447 space -4448 }; -4449 -4450 // Retransmit all 0-RTT data -4451 let zero_rtt = mem::take( -4452 &mut self.spaces[SpaceId::Data] -4453 .for_path(PathId::ZERO) -4454 .sent_packets, -4455 ); -4456 for (_, info) in zero_rtt.into_iter() { -4457 self.paths -4458 .get_mut(&PathId::ZERO) -4459 .unwrap() -4460 .remove_in_flight(&info); -4461 self.spaces[SpaceId::Data].pending |= info.retransmits; -4462 } -4463 self.streams.retransmit_all_for_0rtt(); -4464 -4465 let token_len = packet.payload.len() - 16; -4466 let ConnectionSide::Client { ref mut token, .. } = self.side else { -4467 unreachable!("we already short-circuited if we're server"); -4468 }; -4469 *token = packet.payload.freeze().split_to(token_len); +4257 ConnectionError::LocallyClosed => { +4258 unreachable!("LocallyClosed isn't generated by packet processing"); +4259 } +4260 ConnectionError::CidsExhausted => { +4261 unreachable!("CidsExhausted isn't generated by packet processing"); +4262 } +4263 }; +4264 } +4265 +4266 if !was_closed && self.state.is_closed() { +4267 self.close_common(); +4268 if !self.state.is_drained() { +4269 self.set_close_timer(now); +4270 } +4271 } +4272 if !was_drained && self.state.is_drained() { +4273 self.endpoint_events.push_back(EndpointEventInner::Drained); +4274 // Close timer may have been started previously, e.g. if we sent a close and got a +4275 // stateless reset in response +4276 self.timers +4277 .stop(Timer::Conn(ConnTimer::Close), self.qlog.with_time(now)); +4278 } +4279 +4280 // Transmit CONNECTION_CLOSE if necessary. +4281 // +4282 // If we received a valid packet and we are in the closed state we should respond +4283 // with a CONNECTION_CLOSE frame. +4284 // TODO: This SHOULD be rate-limited according to §10.2.1 of QUIC-TRANSPORT, but +4285 // that does not yet happen. This is triggered by each received packet. +4286 if matches!(self.state.as_type(), StateType::Closed) { +4287 // From https://www.rfc-editor.org/rfc/rfc9000.html#section-10.2.1-7 +4288 // +4289 // While in the closing state we must either: +4290 // - discard packets coming from an un-validated remote OR +4291 // - ensure we do not send more than 3 times the received data +4292 // +4293 // Doing the 2nd would mean we would be able to send CONNECTION_CLOSE to a peer +4294 // who was (involuntary) migrated just at the time we initiated immediate +4295 // close. It is a lot more work though. So while we would like to do this for +4296 // now we only do 1. +4297 // +4298 // Another shortcoming of the current implementation is that when we have a +4299 // previous PathData which is validated and the remote matches that path, we +4300 // should schedule CONNECTION_CLOSE on that path. However currently we can not +4301 // schedule such a packet. We should also fix this some day. This makes us +4302 // vulnerable to an attacker faking a migration at the right time and then we'd +4303 // be unable to send the CONNECTION_CLOSE to the real remote. +4304 if self +4305 .paths +4306 .get(&path_id) +4307 .map(|p| p.data.validated && p.data.network_path == network_path) +4308 .unwrap_or(false) +4309 { +4310 self.connection_close_pending = true; +4311 } +4312 } +4313 } +4314 +4315 fn process_decrypted_packet( +4316 &mut self, +4317 now: Instant, +4318 network_path: FourTuple, +4319 path_id: PathId, +4320 number: Option<u64>, +4321 packet: Packet, +4322 qlog: &mut QlogRecvPacket, +4323 ) -> Result<(), ConnectionError> { +4324 if !self.paths.contains_key(&path_id) { +4325 // There is a chance this is a server side, first (for this path) packet, which would +4326 // be a protocol violation. It's more likely, however, that this is a packet of a +4327 // pruned path +4328 trace!(%path_id, ?number, "discarding packet for unknown path"); +4329 return Ok(()); +4330 } +4331 let state = match self.state.as_type() { +4332 StateType::Established => { +4333 match packet.header.space() { +4334 SpaceKind::Data => self.process_payload( +4335 now, +4336 network_path, +4337 path_id, +4338 number.unwrap(), +4339 packet, +4340 qlog, +4341 )?, +4342 _ if packet.header.has_frames() => { +4343 self.process_early_payload(now, path_id, packet, qlog)? +4344 } +4345 _ => { +4346 trace!("discarding unexpected pre-handshake packet"); +4347 } +4348 } +4349 return Ok(()); +4350 } +4351 StateType::Closed => { +4352 for result in frame::Iter::new(packet.payload.freeze())? { +4353 let frame = match result { +4354 Ok(frame) => frame, +4355 Err(err) => { +4356 debug!("frame decoding error: {err:?}"); +4357 continue; +4358 } +4359 }; +4360 qlog.frame(&frame); +4361 +4362 if let Frame::Padding = frame { +4363 continue; +4364 }; +4365 +4366 self.path_stats +4367 .for_path(path_id) +4368 .frame_rx +4369 .record(frame.ty()); +4370 +4371 if let Frame::Close(_error) = frame { +4372 self.state.move_to_draining(None); +4373 break; +4374 } +4375 } +4376 return Ok(()); +4377 } +4378 StateType::Draining | StateType::Drained => return Ok(()), +4379 StateType::Handshake => self.state.as_handshake_mut().expect("checked"), +4380 }; +4381 +4382 match packet.header { +4383 Header::Retry { +4384 src_cid: remote_cid, +4385 .. +4386 } => { +4387 debug_assert_eq!(path_id, PathId::ZERO); +4388 if self.side.is_server() { +4389 return Err(TransportError::PROTOCOL_VIOLATION("client sent Retry").into()); +4390 } +4391 +4392 let is_valid_retry = self +4393 .remote_cids +4394 .get(&path_id) +4395 .map(|cids| cids.active()) +4396 .map(|orig_dst_cid| { +4397 self.crypto_state.session.is_valid_retry( +4398 orig_dst_cid, +4399 &packet.header_data, +4400 &packet.payload, +4401 ) +4402 }) +4403 .unwrap_or_default(); +4404 if self.total_authed_packets > 1 +4405 || packet.payload.len() <= 16 // token + 16 byte tag +4406 || !is_valid_retry +4407 { +4408 trace!("discarding invalid Retry"); +4409 // - After the client has received and processed an Initial or Retry +4410 // packet from the server, it MUST discard any subsequent Retry +4411 // packets that it receives. +4412 // - A client MUST discard a Retry packet with a zero-length Retry Token +4413 // field. +4414 // - Clients MUST discard Retry packets that have a Retry Integrity Tag +4415 // that cannot be validated +4416 return Ok(()); +4417 } +4418 +4419 trace!("retrying with CID {}", remote_cid); +4420 let client_hello = state.client_hello.take().unwrap(); +4421 self.retry_src_cid = Some(remote_cid); +4422 self.remote_cids +4423 .get_mut(&path_id) +4424 .expect("PathId::ZERO not yet abandoned, is_valid_retry would have been false") +4425 .update_initial_cid(remote_cid); +4426 self.remote_handshake_cid = remote_cid; +4427 +4428 let space = &mut self.spaces[SpaceId::Initial]; +4429 if let Some(info) = space.for_path(PathId::ZERO).take(0) { +4430 self.on_packet_acked(now, PathId::ZERO, info); +4431 }; +4432 +4433 self.discard_space(now, SpaceKind::Initial); // Make sure we clean up after +4434 // any retransmitted Initials +4435 let crypto_space = &mut self.crypto_state.spaces[SpaceKind::Initial]; +4436 crypto_space.keys = Some( +4437 self.crypto_state +4438 .session +4439 .initial_keys(remote_cid, self.side.side()), +4440 ); +4441 crypto_space.crypto_offset = client_hello.len() as u64; +4442 +4443 let next_pn = self.spaces[SpaceId::Initial] +4444 .for_path(path_id) +4445 .next_packet_number; +4446 self.spaces[SpaceId::Initial] = { +4447 let mut space = PacketSpace::new(now, SpaceId::Initial, &mut self.rng); +4448 space.for_path(path_id).next_packet_number = next_pn; +4449 space.pending.crypto.push_back(frame::Crypto { +4450 offset: 0, +4451 data: client_hello, +4452 }); +4453 space +4454 }; +4455 +4456 // Retransmit all 0-RTT data +4457 let zero_rtt = mem::take( +4458 &mut self.spaces[SpaceId::Data] +4459 .for_path(PathId::ZERO) +4460 .sent_packets, +4461 ); +4462 for (_, info) in zero_rtt.into_iter() { +4463 self.paths +4464 .get_mut(&PathId::ZERO) +4465 .unwrap() +4466 .remove_in_flight(&info); +4467 self.spaces[SpaceId::Data].pending |= info.retransmits; +4468 } +4469 self.streams.retransmit_all_for_0rtt(); 4470 -4471 self.state = State::handshake(state::Handshake { -4472 expected_token: Bytes::new(), -4473 remote_cid_set: false, -4474 client_hello: None, -4475 allow_server_migration: true, -4476 }); -4477 Ok(()) -4478 } -4479 Header::Long { -4480 ty: LongType::Handshake, -4481 src_cid: remote_cid, -4482 dst_cid: local_cid, -4483 .. -4484 } => { -4485 debug_assert_eq!(path_id, PathId::ZERO); -4486 if remote_cid != self.remote_handshake_cid { -4487 debug!( -4488 "discarding packet with mismatched remote CID: {} != {}", -4489 self.remote_handshake_cid, remote_cid -4490 ); -4491 return Ok(()); -4492 } -4493 self.on_path_validated(path_id); -4494 -4495 self.process_early_payload(now, path_id, packet, qlog)?; -4496 if self.state.is_closed() { +4471 let token_len = packet.payload.len() - 16; +4472 let ConnectionSide::Client { ref mut token, .. } = self.side else { +4473 unreachable!("we already short-circuited if we're server"); +4474 }; +4475 *token = packet.payload.freeze().split_to(token_len); +4476 +4477 self.state = State::handshake(state::Handshake { +4478 expected_token: Bytes::new(), +4479 remote_cid_set: false, +4480 client_hello: None, +4481 allow_server_migration: true, +4482 }); +4483 Ok(()) +4484 } +4485 Header::Long { +4486 ty: LongType::Handshake, +4487 src_cid: remote_cid, +4488 dst_cid: local_cid, +4489 .. +4490 } => { +4491 debug_assert_eq!(path_id, PathId::ZERO); +4492 if remote_cid != self.remote_handshake_cid { +4493 debug!( +4494 "discarding packet with mismatched remote CID: {} != {}", +4495 self.remote_handshake_cid, remote_cid +4496 ); 4497 return Ok(()); 4498 } -4499 -4500 if self.crypto_state.session.is_handshaking() { -4501 trace!("handshake ongoing"); -4502 return Ok(()); -4503 } -4504 -4505 if self.side.is_client() { -4506 // Client-only because server params were set from the client's Initial -4507 let params = self -4508 .crypto_state -4509 .session -4510 .transport_parameters()? -4511 .ok_or_else(|| { -4512 TransportError::new( -4513 TransportErrorCode::crypto(0x6d), -4514 "transport parameters missing".to_owned(), -4515 ) -4516 })?; -4517 -4518 if self.has_0rtt() { -4519 if !self.crypto_state.session.early_data_accepted().unwrap() { -4520 debug_assert!(self.side.is_client()); -4521 debug!("0-RTT rejected"); -4522 self.crypto_state.accepted_0rtt = false; -4523 self.streams.zero_rtt_rejected(); -4524 -4525 // Discard already-queued frames -4526 self.spaces[SpaceId::Data].pending = Retransmits::default(); -4527 -4528 // Discard 0-RTT packets -4529 let sent_packets = mem::take( -4530 &mut self.spaces[SpaceId::Data].for_path(path_id).sent_packets, -4531 ); -4532 for (_, packet) in sent_packets.into_iter() { -4533 self.paths -4534 .get_mut(&path_id) -4535 .unwrap() -4536 .remove_in_flight(&packet); -4537 } -4538 } else { -4539 self.crypto_state.accepted_0rtt = true; -4540 params.validate_resumption_from(&self.peer_params)?; -4541 } -4542 } -4543 if let Some(token) = params.stateless_reset_token { -4544 let remote = self.path_data(path_id).network_path.remote; -4545 debug_assert!(!self.state.is_drained()); // requirement for endpoint events, checked above -4546 self.endpoint_events -4547 .push_back(EndpointEventInner::ResetToken(path_id, remote, token)); +4499 self.on_path_validated(path_id); +4500 +4501 self.process_early_payload(now, path_id, packet, qlog)?; +4502 if self.state.is_closed() { +4503 return Ok(()); +4504 } +4505 +4506 if self.crypto_state.session.is_handshaking() { +4507 trace!("handshake ongoing"); +4508 return Ok(()); +4509 } +4510 +4511 if self.side.is_client() { +4512 // Client-only because server params were set from the client's Initial +4513 let params = self +4514 .crypto_state +4515 .session +4516 .transport_parameters()? +4517 .ok_or_else(|| { +4518 TransportError::new( +4519 TransportErrorCode::crypto(0x6d), +4520 "transport parameters missing".to_owned(), +4521 ) +4522 })?; +4523 +4524 if self.has_0rtt() { +4525 if !self.crypto_state.session.early_data_accepted().unwrap() { +4526 debug_assert!(self.side.is_client()); +4527 debug!("0-RTT rejected"); +4528 self.crypto_state.accepted_0rtt = false; +4529 self.streams.zero_rtt_rejected(); +4530 +4531 // Discard already-queued frames +4532 self.spaces[SpaceId::Data].pending = Retransmits::default(); +4533 +4534 // Discard 0-RTT packets +4535 let sent_packets = mem::take( +4536 &mut self.spaces[SpaceId::Data].for_path(path_id).sent_packets, +4537 ); +4538 for (_, packet) in sent_packets.into_iter() { +4539 self.paths +4540 .get_mut(&path_id) +4541 .unwrap() +4542 .remove_in_flight(&packet); +4543 } +4544 } else { +4545 self.crypto_state.accepted_0rtt = true; +4546 params.validate_resumption_from(&self.peer_params)?; +4547 } 4548 } -4549 self.handle_peer_params(params, local_cid, remote_cid, now)?; -4550 self.issue_first_cids(now); -4551 } else { -4552 // Server-only -4553 self.spaces[SpaceId::Data].pending.handshake_done = true; -4554 self.discard_space(now, SpaceKind::Handshake); -4555 self.events.push_back(Event::HandshakeConfirmed); -4556 trace!("handshake confirmed"); -4557 } -4558 -4559 self.events.push_back(Event::Connected); -4560 self.state.move_to_established(); -4561 trace!("established"); -4562 -4563 // Multipath can only be enabled after the state has reached Established. -4564 // So this can not happen any earlier. -4565 self.issue_first_path_cids(now); -4566 Ok(()) -4567 } -4568 Header::Initial(InitialHeader { -4569 src_cid: remote_cid, -4570 dst_cid: local_cid, -4571 .. -4572 }) => { -4573 debug_assert_eq!(path_id, PathId::ZERO); -4574 if !state.remote_cid_set { -4575 trace!("switching remote CID to {}", remote_cid); -4576 let mut state = state.clone(); -4577 self.remote_cids -4578 .get_mut(&path_id) -4579 .expect("PathId::ZERO not yet abandoned") -4580 .update_initial_cid(remote_cid); -4581 self.remote_handshake_cid = remote_cid; -4582 self.original_remote_cid = remote_cid; -4583 state.remote_cid_set = true; -4584 self.state.move_to_handshake(state); -4585 } else if remote_cid != self.remote_handshake_cid { -4586 debug!( -4587 "discarding packet with mismatched remote CID: {} != {}", -4588 self.remote_handshake_cid, remote_cid -4589 ); -4590 return Ok(()); -4591 } -4592 -4593 let starting_space = self.highest_space; -4594 self.process_early_payload(now, path_id, packet, qlog)?; -4595 -4596 if self.side.is_server() -4597 && starting_space == SpaceKind::Initial -4598 && self.highest_space != SpaceKind::Initial -4599 { -4600 let params = self -4601 .crypto_state -4602 .session -4603 .transport_parameters()? -4604 .ok_or_else(|| { -4605 TransportError::new( -4606 TransportErrorCode::crypto(0x6d), -4607 "transport parameters missing".to_owned(), -4608 ) -4609 })?; -4610 self.handle_peer_params(params, local_cid, remote_cid, now)?; -4611 self.issue_first_cids(now); -4612 self.init_0rtt(now); -4613 } -4614 Ok(()) -4615 } -4616 Header::Long { -4617 ty: LongType::ZeroRtt, -4618 .. -4619 } => { -4620 self.process_payload(now, network_path, path_id, number.unwrap(), packet, qlog)?; -4621 Ok(()) -4622 } -4623 Header::VersionNegotiate { .. } => { -4624 if self.total_authed_packets > 1 { -4625 return Ok(()); -4626 } -4627 let supported = packet -4628 .payload -4629 .chunks(4) -4630 .any(|x| match <[u8; 4]>::try_from(x) { -4631 Ok(version) => self.version == u32::from_be_bytes(version), -4632 Err(_) => false, -4633 }); -4634 if supported { -4635 return Ok(()); -4636 } -4637 debug!("remote doesn't support our version"); -4638 Err(ConnectionError::VersionMismatch) -4639 } -4640 Header::Short { .. } => unreachable!( -4641 "short packets received during handshake are discarded in handle_packet" -4642 ), -4643 } -4644 } -4645 -4646 /// Process an Initial or Handshake packet payload -4647 fn process_early_payload( -4648 &mut self, -4649 now: Instant, -4650 path_id: PathId, -4651 packet: Packet, -4652 #[allow(unused)] qlog: &mut QlogRecvPacket, -4653 ) -> Result<(), TransportError> { -4654 debug_assert_ne!(packet.header.space(), SpaceKind::Data); -4655 debug_assert_eq!(path_id, PathId::ZERO); -4656 let payload_len = packet.payload.len(); -4657 let mut ack_eliciting = false; -4658 for result in frame::Iter::new(packet.payload.freeze())? { -4659 let frame = result?; -4660 qlog.frame(&frame); -4661 let span = match frame { -4662 Frame::Padding => continue, -4663 _ => Some(trace_span!("frame", ty = %frame.ty(), path = tracing::field::Empty)), -4664 }; -4665 -4666 self.path_stats -4667 .for_path(path_id) -4668 .frame_rx -4669 .record(frame.ty()); -4670 -4671 let _guard = span.as_ref().map(|x| x.enter()); -4672 ack_eliciting |= frame.is_ack_eliciting(); -4673 -4674 // Process frames -4675 if frame.is_1rtt() && packet.header.space() != SpaceKind::Data { -4676 return Err(TransportError::PROTOCOL_VIOLATION( -4677 "illegal frame type in handshake", -4678 )); -4679 } -4680 -4681 match frame { -4682 Frame::Padding | Frame::Ping => {} -4683 Frame::Crypto(frame) => { -4684 self.read_crypto(packet.header.space().into(), &frame, payload_len)?; -4685 } -4686 Frame::Ack(ack) => { -4687 self.on_ack_received(now, packet.header.space().into(), ack)?; -4688 } -4689 Frame::PathAck(ack) => { -4690 span.as_ref() -4691 .map(|span| span.record("path", tracing::field::display(&ack.path_id))); -4692 self.on_path_ack_received(now, packet.header.space().into(), ack)?; -4693 } -4694 Frame::Close(reason) => { -4695 self.state.move_to_draining(Some(reason.into())); -4696 return Ok(()); -4697 } -4698 _ => { -4699 let mut err = -4700 TransportError::PROTOCOL_VIOLATION("illegal frame type in handshake"); -4701 err.frame = frame::MaybeFrame::Known(frame.ty()); -4702 return Err(err); +4549 if let Some(token) = params.stateless_reset_token { +4550 let remote = self.path_data(path_id).network_path.remote; +4551 debug_assert!(!self.state.is_drained()); // requirement for endpoint events, checked above +4552 self.endpoint_events +4553 .push_back(EndpointEventInner::ResetToken(path_id, remote, token)); +4554 } +4555 self.handle_peer_params(params, local_cid, remote_cid, now)?; +4556 self.issue_first_cids(now); +4557 } else { +4558 // Server-only +4559 self.spaces[SpaceId::Data].pending.handshake_done = true; +4560 self.discard_space(now, SpaceKind::Handshake); +4561 self.events.push_back(Event::HandshakeConfirmed); +4562 trace!("handshake confirmed"); +4563 } +4564 +4565 self.events.push_back(Event::Connected); +4566 self.state.move_to_established(); +4567 trace!("established"); +4568 +4569 // Multipath can only be enabled after the state has reached Established. +4570 // So this can not happen any earlier. +4571 self.issue_first_path_cids(now); +4572 Ok(()) +4573 } +4574 Header::Initial(InitialHeader { +4575 src_cid: remote_cid, +4576 dst_cid: local_cid, +4577 .. +4578 }) => { +4579 debug_assert_eq!(path_id, PathId::ZERO); +4580 if !state.remote_cid_set { +4581 trace!("switching remote CID to {}", remote_cid); +4582 let mut state = state.clone(); +4583 self.remote_cids +4584 .get_mut(&path_id) +4585 .expect("PathId::ZERO not yet abandoned") +4586 .update_initial_cid(remote_cid); +4587 self.remote_handshake_cid = remote_cid; +4588 self.original_remote_cid = remote_cid; +4589 state.remote_cid_set = true; +4590 self.state.move_to_handshake(state); +4591 } else if remote_cid != self.remote_handshake_cid { +4592 debug!( +4593 "discarding packet with mismatched remote CID: {} != {}", +4594 self.remote_handshake_cid, remote_cid +4595 ); +4596 return Ok(()); +4597 } +4598 +4599 let starting_space = self.highest_space; +4600 self.process_early_payload(now, path_id, packet, qlog)?; +4601 +4602 if self.side.is_server() +4603 && starting_space == SpaceKind::Initial +4604 && self.highest_space != SpaceKind::Initial +4605 { +4606 let params = self +4607 .crypto_state +4608 .session +4609 .transport_parameters()? +4610 .ok_or_else(|| { +4611 TransportError::new( +4612 TransportErrorCode::crypto(0x6d), +4613 "transport parameters missing".to_owned(), +4614 ) +4615 })?; +4616 self.handle_peer_params(params, local_cid, remote_cid, now)?; +4617 self.issue_first_cids(now); +4618 self.init_0rtt(now); +4619 } +4620 Ok(()) +4621 } +4622 Header::Long { +4623 ty: LongType::ZeroRtt, +4624 .. +4625 } => { +4626 self.process_payload(now, network_path, path_id, number.unwrap(), packet, qlog)?; +4627 Ok(()) +4628 } +4629 Header::VersionNegotiate { .. } => { +4630 if self.total_authed_packets > 1 { +4631 return Ok(()); +4632 } +4633 let supported = packet +4634 .payload +4635 .chunks(4) +4636 .any(|x| match <[u8; 4]>::try_from(x) { +4637 Ok(version) => self.version == u32::from_be_bytes(version), +4638 Err(_) => false, +4639 }); +4640 if supported { +4641 return Ok(()); +4642 } +4643 debug!("remote doesn't support our version"); +4644 Err(ConnectionError::VersionMismatch) +4645 } +4646 Header::Short { .. } => unreachable!( +4647 "short packets received during handshake are discarded in handle_packet" +4648 ), +4649 } +4650 } +4651 +4652 /// Process an Initial or Handshake packet payload +4653 fn process_early_payload( +4654 &mut self, +4655 now: Instant, +4656 path_id: PathId, +4657 packet: Packet, +4658 #[allow(unused)] qlog: &mut QlogRecvPacket, +4659 ) -> Result<(), TransportError> { +4660 debug_assert_ne!(packet.header.space(), SpaceKind::Data); +4661 debug_assert_eq!(path_id, PathId::ZERO); +4662 let payload_len = packet.payload.len(); +4663 let mut ack_eliciting = false; +4664 for result in frame::Iter::new(packet.payload.freeze())? { +4665 let frame = result?; +4666 qlog.frame(&frame); +4667 let span = match frame { +4668 Frame::Padding => continue, +4669 _ => Some(trace_span!("frame", ty = %frame.ty(), path = tracing::field::Empty)), +4670 }; +4671 +4672 self.path_stats +4673 .for_path(path_id) +4674 .frame_rx +4675 .record(frame.ty()); +4676 +4677 let _guard = span.as_ref().map(|x| x.enter()); +4678 ack_eliciting |= frame.is_ack_eliciting(); +4679 +4680 // Process frames +4681 if frame.is_1rtt() && packet.header.space() != SpaceKind::Data { +4682 return Err(TransportError::PROTOCOL_VIOLATION( +4683 "illegal frame type in handshake", +4684 )); +4685 } +4686 +4687 match frame { +4688 Frame::Padding | Frame::Ping => {} +4689 Frame::Crypto(frame) => { +4690 self.read_crypto(packet.header.space().into(), &frame, payload_len)?; +4691 } +4692 Frame::Ack(ack) => { +4693 self.on_ack_received(now, packet.header.space().into(), ack)?; +4694 } +4695 Frame::PathAck(ack) => { +4696 span.as_ref() +4697 .map(|span| span.record("path", tracing::field::display(&ack.path_id))); +4698 self.on_path_ack_received(now, packet.header.space().into(), ack)?; +4699 } +4700 Frame::Close(reason) => { +4701 self.state.move_to_draining(Some(reason.into())); +4702 return Ok(()); 4703 } -4704 } -4705 } -4706 -4707 if ack_eliciting { -4708 // In the initial and handshake spaces, ACKs must be sent immediately -4709 self.spaces[packet.header.space()] -4710 .for_path(path_id) -4711 .pending_acks -4712 .set_immediate_ack_required(); -4713 } -4714 -4715 self.write_crypto(); -4716 Ok(()) -4717 } -4718 -4719 /// Processes the packet payload, always in the data space. -4720 fn process_payload( -4721 &mut self, -4722 now: Instant, -4723 network_path: FourTuple, -4724 path_id: PathId, -4725 number: u64, -4726 packet: Packet, -4727 #[allow(unused)] qlog: &mut QlogRecvPacket, -4728 ) -> Result<(), TransportError> { -4729 let is_multipath_negotiated = self.is_multipath_negotiated(); -4730 let payload = packet.payload.freeze(); -4731 let mut is_probing_packet = true; -4732 let mut close = None; -4733 let payload_len = payload.len(); -4734 let mut ack_eliciting = false; -4735 // if this packet triggers a path migration and includes a observed address frame, it's -4736 // stored here -4737 let mut migration_observed_addr = None; -4738 for result in frame::Iter::new(payload)? { -4739 let frame = result?; -4740 qlog.frame(&frame); -4741 let span = match frame { -4742 Frame::Padding => continue, -4743 _ => trace_span!("frame", ty = %frame.ty(), path = tracing::field::Empty), -4744 }; -4745 -4746 self.path_stats -4747 .for_path(path_id) -4748 .frame_rx -4749 .record(frame.ty()); -4750 // Crypto, Stream and Datagram frames are special cased in order no pollute -4751 // the log with payload data -4752 match &frame { -4753 Frame::Crypto(f) => { -4754 trace!(offset = f.offset, len = f.data.len(), "got frame CRYPTO"); -4755 } -4756 Frame::Stream(f) => { -4757 trace!(id = %f.id, offset = f.offset, len = f.data.len(), fin = f.fin, "got frame STREAM"); -4758 } -4759 Frame::Datagram(f) => { -4760 trace!(len = f.data.len(), "got frame DATAGRAM"); +4704 _ => { +4705 let mut err = +4706 TransportError::PROTOCOL_VIOLATION("illegal frame type in handshake"); +4707 err.frame = frame::MaybeFrame::Known(frame.ty()); +4708 return Err(err); +4709 } +4710 } +4711 } +4712 +4713 if ack_eliciting { +4714 // In the initial and handshake spaces, ACKs must be sent immediately +4715 self.spaces[packet.header.space()] +4716 .for_path(path_id) +4717 .pending_acks +4718 .set_immediate_ack_required(); +4719 } +4720 +4721 self.write_crypto(); +4722 Ok(()) +4723 } +4724 +4725 /// Processes the packet payload, always in the data space. +4726 fn process_payload( +4727 &mut self, +4728 now: Instant, +4729 network_path: FourTuple, +4730 path_id: PathId, +4731 number: u64, +4732 packet: Packet, +4733 #[allow(unused)] qlog: &mut QlogRecvPacket, +4734 ) -> Result<(), TransportError> { +4735 let is_multipath_negotiated = self.is_multipath_negotiated(); +4736 let payload = packet.payload.freeze(); +4737 let mut is_probing_packet = true; +4738 let mut close = None; +4739 let payload_len = payload.len(); +4740 let mut ack_eliciting = false; +4741 // if this packet triggers a path migration and includes a observed address frame, it's +4742 // stored here +4743 let mut migration_observed_addr = None; +4744 for result in frame::Iter::new(payload)? { +4745 let frame = result?; +4746 qlog.frame(&frame); +4747 let span = match frame { +4748 Frame::Padding => continue, +4749 _ => trace_span!("frame", ty = %frame.ty(), path = tracing::field::Empty), +4750 }; +4751 +4752 self.path_stats +4753 .for_path(path_id) +4754 .frame_rx +4755 .record(frame.ty()); +4756 // Crypto, Stream and Datagram frames are special cased in order no pollute +4757 // the log with payload data +4758 match &frame { +4759 Frame::Crypto(f) => { +4760 trace!(offset = f.offset, len = f.data.len(), "got frame CRYPTO"); 4761 } -4762 f => { -4763 trace!("got frame {f}"); +4762 Frame::Stream(f) => { +4763 trace!(id = %f.id, offset = f.offset, len = f.data.len(), fin = f.fin, "got frame STREAM"); 4764 } -4765 } -4766 -4767 let _guard = span.enter(); -4768 if packet.header.is_0rtt() { -4769 match frame { -4770 Frame::Crypto(_) | Frame::Close(Close::Application(_)) => { -4771 return Err(TransportError::PROTOCOL_VIOLATION( -4772 "illegal frame type in 0-RTT", -4773 )); -4774 } -4775 _ => { -4776 if frame.is_1rtt() { -4777 return Err(TransportError::PROTOCOL_VIOLATION( -4778 "illegal frame type in 0-RTT", -4779 )); -4780 } -4781 } -4782 } -4783 } -4784 ack_eliciting |= frame.is_ack_eliciting(); -4785 -4786 // Check whether this could be a probing packet -4787 match frame { -4788 Frame::Padding -4789 | Frame::PathChallenge(_) -4790 | Frame::PathResponse(_) -4791 | Frame::NewConnectionId(_) -4792 | Frame::ObservedAddr(_) => {} -4793 _ => { -4794 is_probing_packet = false; -4795 } -4796 } -4797 -4798 match frame { -4799 Frame::Crypto(frame) => { -4800 self.read_crypto(SpaceId::Data, &frame, payload_len)?; +4765 Frame::Datagram(f) => { +4766 trace!(len = f.data.len(), "got frame DATAGRAM"); +4767 } +4768 f => { +4769 trace!("got frame {f}"); +4770 } +4771 } +4772 +4773 let _guard = span.enter(); +4774 if packet.header.is_0rtt() { +4775 match frame { +4776 Frame::Crypto(_) | Frame::Close(Close::Application(_)) => { +4777 return Err(TransportError::PROTOCOL_VIOLATION( +4778 "illegal frame type in 0-RTT", +4779 )); +4780 } +4781 _ => { +4782 if frame.is_1rtt() { +4783 return Err(TransportError::PROTOCOL_VIOLATION( +4784 "illegal frame type in 0-RTT", +4785 )); +4786 } +4787 } +4788 } +4789 } +4790 ack_eliciting |= frame.is_ack_eliciting(); +4791 +4792 // Check whether this could be a probing packet +4793 match frame { +4794 Frame::Padding +4795 | Frame::PathChallenge(_) +4796 | Frame::PathResponse(_) +4797 | Frame::NewConnectionId(_) +4798 | Frame::ObservedAddr(_) => {} +4799 _ => { +4800 is_probing_packet = false; 4801 } -4802 Frame::Stream(frame) => { -4803 if self.streams.received(frame, payload_len)?.should_transmit() { -4804 self.spaces[SpaceId::Data].pending.max_data = true; -4805 } -4806 } -4807 Frame::Ack(ack) => { -4808 self.on_ack_received(now, SpaceId::Data, ack)?; -4809 } -4810 Frame::PathAck(ack) => { -4811 span.record("path", tracing::field::display(&ack.path_id)); -4812 self.on_path_ack_received(now, SpaceId::Data, ack)?; -4813 } -4814 Frame::Padding | Frame::Ping => {} -4815 Frame::Close(reason) => { -4816 close = Some(reason); -4817 } -4818 Frame::PathChallenge(challenge) => { -4819 let path = &mut self -4820 .path_mut(path_id) -4821 .expect("payload is processed only after the path becomes known"); -4822 path.path_responses.push(number, challenge.0, network_path); -4823 // At this point, update_network_path_or_discard was already called, so -4824 // we don't need to be lenient about `local_ip` possibly mis-matching. -4825 if network_path == path.network_path { -4826 // PATH_CHALLENGE on active path, possible off-path packet forwarding -4827 // attack. Send a non-probing packet to recover the active path. -4828 // TODO(flub): No longer true! We now path_challege also to validate -4829 // the path if the path is new, without an RFC9000-style -4830 // migration involved. This means we add in an extra -4831 // IMMEDIATE_ACK on some challenges. It isn't really wrong to do -4832 // so, but it still is something untidy. We should instead -4833 // suppress this when we know the remote is still validating the -4834 // path. -4835 match self.peer_supports_ack_frequency() { -4836 true => self.immediate_ack(path_id), -4837 false => { -4838 self.ping_path(path_id).ok(); -4839 } -4840 } -4841 } -4842 } -4843 Frame::PathResponse(response) => { -4844 let path = self -4845 .paths -4846 .get_mut(&path_id) -4847 .expect("payload is processed only after the path becomes known"); -4848 -4849 use PathTimer::*; -4850 use paths::OnPathResponseReceived::*; -4851 match path -4852 .data -4853 .on_path_response_received(now, response.0, network_path) -4854 { -4855 OnPath { was_open } => { -4856 let qlog = self.qlog.with_time(now); -4857 -4858 self.timers -4859 .stop(Timer::PerPath(path_id, PathValidationFailed), qlog.clone()); -4860 self.timers -4861 .stop(Timer::PerPath(path_id, PathOpenFailed), qlog.clone()); -4862 -4863 let next_challenge = path -4864 .data -4865 .earliest_on_path_expiring_challenge() -4866 .map(|time| time + self.ack_frequency.max_ack_delay_for_pto()); -4867 self.timers.set_or_stop( -4868 Timer::PerPath(path_id, PathChallengeLost), -4869 next_challenge, -4870 qlog, -4871 ); -4872 -4873 if !was_open { -4874 if is_multipath_negotiated { -4875 self.events -4876 .push_back(Event::Path(PathEvent::Opened { id: path_id })); -4877 } -4878 if let Some(observed) = path.data.last_observed_addr_report.as_ref() -4879 { -4880 self.events.push_back(Event::Path(PathEvent::ObservedAddr { -4881 id: path_id, -4882 addr: observed.socket_addr(), -4883 })); -4884 } -4885 } -4886 if let Some((_, ref mut prev)) = path.prev { -4887 prev.reset_on_path_challenges(); -4888 } -4889 } -4890 OffPath => { -4891 debug!(%response, "Valid response to off-path PATH_CHALLENGE"); -4892 } -4893 Ignored { -4894 sent_on, -4895 current_path, -4896 } => { -4897 debug!(%sent_on, %current_path, %response, "ignoring valid PATH_RESPONSE") +4802 } +4803 +4804 match frame { +4805 Frame::Crypto(frame) => { +4806 self.read_crypto(SpaceId::Data, &frame, payload_len)?; +4807 } +4808 Frame::Stream(frame) => { +4809 if self.streams.received(frame, payload_len)?.should_transmit() { +4810 self.spaces[SpaceId::Data].pending.max_data = true; +4811 } +4812 } +4813 Frame::Ack(ack) => { +4814 self.on_ack_received(now, SpaceId::Data, ack)?; +4815 } +4816 Frame::PathAck(ack) => { +4817 span.record("path", tracing::field::display(&ack.path_id)); +4818 self.on_path_ack_received(now, SpaceId::Data, ack)?; +4819 } +4820 Frame::Padding | Frame::Ping => {} +4821 Frame::Close(reason) => { +4822 close = Some(reason); +4823 } +4824 Frame::PathChallenge(challenge) => { +4825 let path = &mut self +4826 .path_mut(path_id) +4827 .expect("payload is processed only after the path becomes known"); +4828 path.path_responses.push(number, challenge.0, network_path); +4829 // At this point, update_network_path_or_discard was already called, so +4830 // we don't need to be lenient about `local_ip` possibly mis-matching. +4831 if network_path == path.network_path { +4832 // PATH_CHALLENGE on active path, possible off-path packet forwarding +4833 // attack. Send a non-probing packet to recover the active path. +4834 // TODO(flub): No longer true! We now path_challege also to validate +4835 // the path if the path is new, without an RFC9000-style +4836 // migration involved. This means we add in an extra +4837 // IMMEDIATE_ACK on some challenges. It isn't really wrong to do +4838 // so, but it still is something untidy. We should instead +4839 // suppress this when we know the remote is still validating the +4840 // path. +4841 match self.peer_supports_ack_frequency() { +4842 true => self.immediate_ack(path_id), +4843 false => { +4844 self.ping_path(path_id).ok(); +4845 } +4846 } +4847 } +4848 } +4849 Frame::PathResponse(response) => { +4850 let path = self +4851 .paths +4852 .get_mut(&path_id) +4853 .expect("payload is processed only after the path becomes known"); +4854 +4855 use PathTimer::*; +4856 use paths::OnPathResponseReceived::*; +4857 match path +4858 .data +4859 .on_path_response_received(now, response.0, network_path) +4860 { +4861 OnPath { was_open } => { +4862 let qlog = self.qlog.with_time(now); +4863 +4864 self.timers +4865 .stop(Timer::PerPath(path_id, PathValidationFailed), qlog.clone()); +4866 self.timers +4867 .stop(Timer::PerPath(path_id, PathOpenFailed), qlog.clone()); +4868 +4869 let next_challenge = path +4870 .data +4871 .earliest_on_path_expiring_challenge() +4872 .map(|time| time + self.ack_frequency.max_ack_delay_for_pto()); +4873 self.timers.set_or_stop( +4874 Timer::PerPath(path_id, PathChallengeLost), +4875 next_challenge, +4876 qlog, +4877 ); +4878 +4879 if !was_open { +4880 if is_multipath_negotiated { +4881 self.events +4882 .push_back(Event::Path(PathEvent::Opened { id: path_id })); +4883 } +4884 if let Some(observed) = path.data.last_observed_addr_report.as_ref() +4885 { +4886 self.events.push_back(Event::Path(PathEvent::ObservedAddr { +4887 id: path_id, +4888 addr: observed.socket_addr(), +4889 })); +4890 } +4891 } +4892 if let Some((_, ref mut prev)) = path.prev { +4893 prev.reset_on_path_challenges(); +4894 } +4895 } +4896 OffPath => { +4897 debug!(%response, "Valid response to off-path PATH_CHALLENGE"); 4898 } -4899 Unknown => debug!(%response, "ignoring invalid PATH_RESPONSE"), -4900 } -4901 } -4902 Frame::MaxData(frame::MaxData(bytes)) => { -4903 self.streams.received_max_data(bytes); -4904 } -4905 Frame::MaxStreamData(frame::MaxStreamData { id, offset }) => { -4906 self.streams.received_max_stream_data(id, offset)?; +4899 Ignored { +4900 sent_on, +4901 current_path, +4902 } => { +4903 debug!(%sent_on, %current_path, %response, "ignoring valid PATH_RESPONSE") +4904 } +4905 Unknown => debug!(%response, "ignoring invalid PATH_RESPONSE"), +4906 } 4907 } -4908 Frame::MaxStreams(frame::MaxStreams { dir, count }) => { -4909 self.streams.received_max_streams(dir, count)?; +4908 Frame::MaxData(frame::MaxData(bytes)) => { +4909 self.streams.received_max_data(bytes); 4910 } -4911 Frame::ResetStream(frame) => { -4912 if self.streams.received_reset(frame)?.should_transmit() { -4913 self.spaces[SpaceId::Data].pending.max_data = true; -4914 } -4915 } -4916 Frame::DataBlocked(DataBlocked(offset)) => { -4917 debug!(offset, "peer claims to be blocked at connection level"); -4918 } -4919 Frame::StreamDataBlocked(StreamDataBlocked { id, offset }) => { -4920 if id.initiator() == self.side.side() && id.dir() == Dir::Uni { -4921 debug!("got STREAM_DATA_BLOCKED on send-only {}", id); -4922 return Err(TransportError::STREAM_STATE_ERROR( -4923 "STREAM_DATA_BLOCKED on send-only stream", -4924 )); -4925 } -4926 debug!( -4927 stream = %id, -4928 offset, "peer claims to be blocked at stream level" -4929 ); -4930 } -4931 Frame::StreamsBlocked(StreamsBlocked { dir, limit }) => { -4932 if limit > MAX_STREAM_COUNT { -4933 return Err(TransportError::FRAME_ENCODING_ERROR( -4934 "unrepresentable stream limit", -4935 )); -4936 } -4937 debug!( -4938 "peer claims to be blocked opening more than {} {} streams", -4939 limit, dir -4940 ); -4941 } -4942 Frame::StopSending(frame::StopSending { id, error_code }) => { -4943 if id.initiator() != self.side.side() { -4944 if id.dir() == Dir::Uni { -4945 debug!("got STOP_SENDING on recv-only {}", id); -4946 return Err(TransportError::STREAM_STATE_ERROR( -4947 "STOP_SENDING on recv-only stream", -4948 )); -4949 } -4950 } else if self.streams.is_local_unopened(id) { -4951 return Err(TransportError::STREAM_STATE_ERROR( -4952 "STOP_SENDING on unopened stream", -4953 )); -4954 } -4955 self.streams.received_stop_sending(id, error_code); -4956 } -4957 Frame::RetireConnectionId(frame::RetireConnectionId { path_id, sequence }) => { -4958 if let Some(ref path_id) = path_id { -4959 span.record("path", tracing::field::display(&path_id)); +4911 Frame::MaxStreamData(frame::MaxStreamData { id, offset }) => { +4912 self.streams.received_max_stream_data(id, offset)?; +4913 } +4914 Frame::MaxStreams(frame::MaxStreams { dir, count }) => { +4915 self.streams.received_max_streams(dir, count)?; +4916 } +4917 Frame::ResetStream(frame) => { +4918 if self.streams.received_reset(frame)?.should_transmit() { +4919 self.spaces[SpaceId::Data].pending.max_data = true; +4920 } +4921 } +4922 Frame::DataBlocked(DataBlocked(offset)) => { +4923 debug!(offset, "peer claims to be blocked at connection level"); +4924 } +4925 Frame::StreamDataBlocked(StreamDataBlocked { id, offset }) => { +4926 if id.initiator() == self.side.side() && id.dir() == Dir::Uni { +4927 debug!("got STREAM_DATA_BLOCKED on send-only {}", id); +4928 return Err(TransportError::STREAM_STATE_ERROR( +4929 "STREAM_DATA_BLOCKED on send-only stream", +4930 )); +4931 } +4932 debug!( +4933 stream = %id, +4934 offset, "peer claims to be blocked at stream level" +4935 ); +4936 } +4937 Frame::StreamsBlocked(StreamsBlocked { dir, limit }) => { +4938 if limit > MAX_STREAM_COUNT { +4939 return Err(TransportError::FRAME_ENCODING_ERROR( +4940 "unrepresentable stream limit", +4941 )); +4942 } +4943 debug!( +4944 "peer claims to be blocked opening more than {} {} streams", +4945 limit, dir +4946 ); +4947 } +4948 Frame::StopSending(frame::StopSending { id, error_code }) => { +4949 if id.initiator() != self.side.side() { +4950 if id.dir() == Dir::Uni { +4951 debug!("got STOP_SENDING on recv-only {}", id); +4952 return Err(TransportError::STREAM_STATE_ERROR( +4953 "STOP_SENDING on recv-only stream", +4954 )); +4955 } +4956 } else if self.streams.is_local_unopened(id) { +4957 return Err(TransportError::STREAM_STATE_ERROR( +4958 "STOP_SENDING on unopened stream", +4959 )); 4960 } -4961 let path_id = path_id.unwrap_or_default(); -4962 match self.local_cid_state.get_mut(&path_id) { -4963 None => error!(?path_id, "RETIRE_CONNECTION_ID for unknown path"), -4964 Some(cid_state) => { -4965 let allow_more_cids = cid_state -4966 .on_cid_retirement(sequence, self.peer_params.issue_cids_limit())?; -4967 -4968 // If the path has closed, we do not issue more CIDs for this path -4969 // For details see https://www.ietf.org/archive/id/draft-ietf-quic-multipath-17.html#section-3.2.2 -4970 // > an endpoint SHOULD provide new connection IDs for that path, if still open, using PATH_NEW_CONNECTION_ID frames. -4971 let has_path = !self.abandoned_paths.contains(&path_id); -4972 let allow_more_cids = allow_more_cids && has_path; +4961 self.streams.received_stop_sending(id, error_code); +4962 } +4963 Frame::RetireConnectionId(frame::RetireConnectionId { path_id, sequence }) => { +4964 if let Some(ref path_id) = path_id { +4965 span.record("path", tracing::field::display(&path_id)); +4966 } +4967 let path_id = path_id.unwrap_or_default(); +4968 match self.local_cid_state.get_mut(&path_id) { +4969 None => error!(?path_id, "RETIRE_CONNECTION_ID for unknown path"), +4970 Some(cid_state) => { +4971 let allow_more_cids = cid_state +4972 .on_cid_retirement(sequence, self.peer_params.issue_cids_limit())?; 4973 -4974 debug_assert!(!self.state.is_drained()); // required for adding endpoint events, process_payload is never called for drained connections -4975 self.endpoint_events -4976 .push_back(EndpointEventInner::RetireConnectionId( -4977 now, -4978 path_id, -4979 sequence, -4980 allow_more_cids, -4981 )); -4982 } -4983 } -4984 } -4985 Frame::NewConnectionId(frame) => { -4986 let path_id = if let Some(path_id) = frame.path_id { -4987 if !self.is_multipath_negotiated() { -4988 return Err(TransportError::PROTOCOL_VIOLATION( -4989 "received PATH_NEW_CONNECTION_ID frame when multipath was not negotiated", -4990 )); -4991 } -4992 if path_id > self.local_max_path_id { -4993 return Err(TransportError::PROTOCOL_VIOLATION( -4994 "PATH_NEW_CONNECTION_ID contains path_id exceeding current max", -4995 )); -4996 } -4997 path_id -4998 } else { -4999 PathId::ZERO -5000 }; -5001 -5002 if let Some(ref path_id) = frame.path_id { -5003 span.record("path", tracing::field::display(&path_id)); -5004 } -5005 -5006 if self.abandoned_paths.contains(&path_id) { -5007 trace!("ignoring issued CID for abandoned path"); -5008 continue; -5009 } -5010 let remote_cids = self -5011 .remote_cids -5012 .entry(path_id) -5013 .or_insert_with(|| CidQueue::new(frame.id)); -5014 if remote_cids.active().is_empty() { -5015 return Err(TransportError::PROTOCOL_VIOLATION( -5016 "NEW_CONNECTION_ID when CIDs aren't in use", -5017 )); -5018 } -5019 if frame.retire_prior_to > frame.sequence { -5020 return Err(TransportError::PROTOCOL_VIOLATION( -5021 "NEW_CONNECTION_ID retiring unissued CIDs", -5022 )); -5023 } -5024 -5025 use crate::cid_queue::InsertError; -5026 match remote_cids.insert(frame) { -5027 Ok(None) if self.path(path_id).is_none() => { -5028 // if this gives us CIDs to open a new path and a nat traversal attempt -5029 // is underway we could try to probe a pending remote -5030 self.continue_nat_traversal_round(now); -5031 } -5032 Ok(None) => {} -5033 Ok(Some((retired, reset_token))) => { -5034 let pending_retired = -5035 &mut self.spaces[SpaceId::Data].pending.retire_cids; -5036 /// Ensure `pending_retired` cannot grow without bound. Limit is -5037 /// somewhat arbitrary but very permissive. -5038 const MAX_PENDING_RETIRED_CIDS: u64 = CidQueue::LEN as u64 * 10; -5039 // We don't bother counting in-flight frames because those are bounded -5040 // by congestion control. -5041 if (pending_retired.len() as u64) -5042 .saturating_add(retired.end.saturating_sub(retired.start)) -5043 > MAX_PENDING_RETIRED_CIDS -5044 { -5045 return Err(TransportError::CONNECTION_ID_LIMIT_ERROR( -5046 "queued too many retired CIDs", -5047 )); -5048 } -5049 pending_retired.extend(retired.map(|seq| (path_id, seq))); -5050 self.set_reset_token(path_id, network_path.remote, reset_token); -5051 } -5052 Err(InsertError::ExceedsLimit) => { -5053 return Err(TransportError::CONNECTION_ID_LIMIT_ERROR("")); -5054 } -5055 Err(InsertError::Retired) => { -5056 trace!("discarding already-retired"); -5057 // RETIRE_CONNECTION_ID might not have been previously sent if e.g. a -5058 // range of connection IDs larger than the active connection ID limit -5059 // was retired all at once via retire_prior_to. -5060 self.spaces[SpaceId::Data] -5061 .pending -5062 .retire_cids -5063 .push((path_id, frame.sequence)); -5064 continue; -5065 } -5066 }; -5067 -5068 if self.side.is_server() -5069 && path_id == PathId::ZERO -5070 && self -5071 .remote_cids -5072 .get(&PathId::ZERO) -5073 .map(|cids| cids.active_seq() == 0) -5074 .unwrap_or_default() -5075 { -5076 // We're a server still using the initial remote CID for the client, so -5077 // let's switch immediately to enable clientside stateless resets. -5078 self.update_remote_cid(PathId::ZERO); -5079 } -5080 } -5081 Frame::NewToken(NewToken { token }) => { -5082 let ConnectionSide::Client { -5083 token_store, -5084 server_name, -5085 .. -5086 } = &self.side -5087 else { -5088 return Err(TransportError::PROTOCOL_VIOLATION("client sent NEW_TOKEN")); -5089 }; -5090 if token.is_empty() { -5091 return Err(TransportError::FRAME_ENCODING_ERROR("empty token")); -5092 } -5093 trace!("got new token"); -5094 token_store.insert(server_name, token); -5095 } -5096 Frame::Datagram(datagram) => { -5097 if self -5098 .datagrams -5099 .received(datagram, &self.config.datagram_receive_buffer_size)? -5100 { -5101 self.events.push_back(Event::DatagramReceived); -5102 } -5103 } -5104 Frame::AckFrequency(ack_frequency) => { -5105 // This frame can only be sent in the Data space -5106 -5107 if !self.ack_frequency.ack_frequency_received(&ack_frequency)? { -5108 // The AckFrequency frame is stale (we have already received a more -5109 // recent one) -5110 continue; -5111 } +4974 // If the path has closed, we do not issue more CIDs for this path +4975 // For details see https://www.ietf.org/archive/id/draft-ietf-quic-multipath-17.html#section-3.2.2 +4976 // > an endpoint SHOULD provide new connection IDs for that path, if still open, using PATH_NEW_CONNECTION_ID frames. +4977 let has_path = !self.abandoned_paths.contains(&path_id); +4978 let allow_more_cids = allow_more_cids && has_path; +4979 +4980 debug_assert!(!self.state.is_drained()); // required for adding endpoint events, process_payload is never called for drained connections +4981 self.endpoint_events +4982 .push_back(EndpointEventInner::RetireConnectionId( +4983 now, +4984 path_id, +4985 sequence, +4986 allow_more_cids, +4987 )); +4988 } +4989 } +4990 } +4991 Frame::NewConnectionId(frame) => { +4992 let path_id = if let Some(path_id) = frame.path_id { +4993 if !self.is_multipath_negotiated() { +4994 return Err(TransportError::PROTOCOL_VIOLATION( +4995 "received PATH_NEW_CONNECTION_ID frame when multipath was not negotiated", +4996 )); +4997 } +4998 if path_id > self.local_max_path_id { +4999 return Err(TransportError::PROTOCOL_VIOLATION( +5000 "PATH_NEW_CONNECTION_ID contains path_id exceeding current max", +5001 )); +5002 } +5003 path_id +5004 } else { +5005 PathId::ZERO +5006 }; +5007 +5008 if let Some(ref path_id) = frame.path_id { +5009 span.record("path", tracing::field::display(&path_id)); +5010 } +5011 +5012 if self.abandoned_paths.contains(&path_id) { +5013 trace!("ignoring issued CID for abandoned path"); +5014 continue; +5015 } +5016 let remote_cids = self +5017 .remote_cids +5018 .entry(path_id) +5019 .or_insert_with(|| CidQueue::new(frame.id)); +5020 if remote_cids.active().is_empty() { +5021 return Err(TransportError::PROTOCOL_VIOLATION( +5022 "NEW_CONNECTION_ID when CIDs aren't in use", +5023 )); +5024 } +5025 if frame.retire_prior_to > frame.sequence { +5026 return Err(TransportError::PROTOCOL_VIOLATION( +5027 "NEW_CONNECTION_ID retiring unissued CIDs", +5028 )); +5029 } +5030 +5031 use crate::cid_queue::InsertError; +5032 match remote_cids.insert(frame) { +5033 Ok(None) if self.path(path_id).is_none() => { +5034 // if this gives us CIDs to open a new path and a nat traversal attempt +5035 // is underway we could try to probe a pending remote +5036 self.continue_nat_traversal_round(now); +5037 } +5038 Ok(None) => {} +5039 Ok(Some((retired, reset_token))) => { +5040 let pending_retired = +5041 &mut self.spaces[SpaceId::Data].pending.retire_cids; +5042 /// Ensure `pending_retired` cannot grow without bound. Limit is +5043 /// somewhat arbitrary but very permissive. +5044 const MAX_PENDING_RETIRED_CIDS: u64 = CidQueue::LEN as u64 * 10; +5045 // We don't bother counting in-flight frames because those are bounded +5046 // by congestion control. +5047 if (pending_retired.len() as u64) +5048 .saturating_add(retired.end.saturating_sub(retired.start)) +5049 > MAX_PENDING_RETIRED_CIDS +5050 { +5051 return Err(TransportError::CONNECTION_ID_LIMIT_ERROR( +5052 "queued too many retired CIDs", +5053 )); +5054 } +5055 pending_retired.extend(retired.map(|seq| (path_id, seq))); +5056 self.set_reset_token(path_id, network_path.remote, reset_token); +5057 } +5058 Err(InsertError::ExceedsLimit) => { +5059 return Err(TransportError::CONNECTION_ID_LIMIT_ERROR("")); +5060 } +5061 Err(InsertError::Retired) => { +5062 trace!("discarding already-retired"); +5063 // RETIRE_CONNECTION_ID might not have been previously sent if e.g. a +5064 // range of connection IDs larger than the active connection ID limit +5065 // was retired all at once via retire_prior_to. +5066 self.spaces[SpaceId::Data] +5067 .pending +5068 .retire_cids +5069 .push((path_id, frame.sequence)); +5070 continue; +5071 } +5072 }; +5073 +5074 if self.side.is_server() +5075 && path_id == PathId::ZERO +5076 && self +5077 .remote_cids +5078 .get(&PathId::ZERO) +5079 .map(|cids| cids.active_seq() == 0) +5080 .unwrap_or_default() +5081 { +5082 // We're a server still using the initial remote CID for the client, so +5083 // let's switch immediately to enable clientside stateless resets. +5084 self.update_remote_cid(PathId::ZERO); +5085 } +5086 } +5087 Frame::NewToken(NewToken { token }) => { +5088 let ConnectionSide::Client { +5089 token_store, +5090 server_name, +5091 .. +5092 } = &self.side +5093 else { +5094 return Err(TransportError::PROTOCOL_VIOLATION("client sent NEW_TOKEN")); +5095 }; +5096 if token.is_empty() { +5097 return Err(TransportError::FRAME_ENCODING_ERROR("empty token")); +5098 } +5099 trace!("got new token"); +5100 token_store.insert(server_name, token); +5101 } +5102 Frame::Datagram(datagram) => { +5103 if self +5104 .datagrams +5105 .received(datagram, &self.config.datagram_receive_buffer_size)? +5106 { +5107 self.events.push_back(Event::DatagramReceived); +5108 } +5109 } +5110 Frame::AckFrequency(ack_frequency) => { +5111 // This frame can only be sent in the Data space 5112 -5113 // Update the params for all of our paths -5114 for (path_id, space) in self.spaces[SpaceId::Data].number_spaces.iter_mut() { -5115 space.pending_acks.set_ack_frequency_params(&ack_frequency); -5116 -5117 // Our `max_ack_delay` has been updated, so we may need to adjust -5118 // its associated timeout. -5119 // Packets received on abandoned paths are always acknowledged immediately. -5120 if !self.abandoned_paths.contains(path_id) -5121 && let Some(timeout) = space -5122 .pending_acks -5123 .max_ack_delay_timeout(self.ack_frequency.max_ack_delay) -5124 { -5125 self.timers.set( -5126 Timer::PerPath(*path_id, PathTimer::MaxAckDelay), -5127 timeout, -5128 self.qlog.with_time(now), -5129 ); -5130 } -5131 } -5132 } -5133 Frame::ImmediateAck => { -5134 // This frame can only be sent in the Data space -5135 for pns in self.spaces[SpaceId::Data].iter_paths_mut() { -5136 pns.pending_acks.set_immediate_ack_required(); +5113 if !self.ack_frequency.ack_frequency_received(&ack_frequency)? { +5114 // The AckFrequency frame is stale (we have already received a more +5115 // recent one) +5116 continue; +5117 } +5118 +5119 // Update the params for all of our paths +5120 for (path_id, space) in self.spaces[SpaceId::Data].number_spaces.iter_mut() { +5121 space.pending_acks.set_ack_frequency_params(&ack_frequency); +5122 +5123 // Our `max_ack_delay` has been updated, so we may need to adjust +5124 // its associated timeout. +5125 // Packets received on abandoned paths are always acknowledged immediately. +5126 if !self.abandoned_paths.contains(path_id) +5127 && let Some(timeout) = space +5128 .pending_acks +5129 .max_ack_delay_timeout(self.ack_frequency.max_ack_delay) +5130 { +5131 self.timers.set( +5132 Timer::PerPath(*path_id, PathTimer::MaxAckDelay), +5133 timeout, +5134 self.qlog.with_time(now), +5135 ); +5136 } 5137 } 5138 } -5139 Frame::HandshakeDone => { -5140 if self.side.is_server() { -5141 return Err(TransportError::PROTOCOL_VIOLATION( -5142 "client sent HANDSHAKE_DONE", -5143 )); -5144 } -5145 if self.crypto_state.has_keys(EncryptionLevel::Handshake) { -5146 self.discard_space(now, SpaceKind::Handshake); -5147 self.events.push_back(Event::HandshakeConfirmed); -5148 trace!("handshake confirmed"); -5149 } -5150 } -5151 Frame::ObservedAddr(observed) => { -5152 // check if params allows the peer to send report and this node to receive it -5153 trace!(seq_no = %observed.seq_no, ip = %observed.ip, port = observed.port); -5154 if !self -5155 .peer_params -5156 .address_discovery_role -5157 .should_report(&self.config.address_discovery_role) -5158 { -5159 return Err(TransportError::PROTOCOL_VIOLATION( -5160 "received OBSERVED_ADDRESS frame when not negotiated", -5161 )); -5162 } -5163 // must only be sent in data space -5164 if packet.header.space() != SpaceKind::Data { +5139 Frame::ImmediateAck => { +5140 // This frame can only be sent in the Data space +5141 for pns in self.spaces[SpaceId::Data].iter_paths_mut() { +5142 pns.pending_acks.set_immediate_ack_required(); +5143 } +5144 } +5145 Frame::HandshakeDone => { +5146 if self.side.is_server() { +5147 return Err(TransportError::PROTOCOL_VIOLATION( +5148 "client sent HANDSHAKE_DONE", +5149 )); +5150 } +5151 if self.crypto_state.has_keys(EncryptionLevel::Handshake) { +5152 self.discard_space(now, SpaceKind::Handshake); +5153 self.events.push_back(Event::HandshakeConfirmed); +5154 trace!("handshake confirmed"); +5155 } +5156 } +5157 Frame::ObservedAddr(observed) => { +5158 // check if params allows the peer to send report and this node to receive it +5159 trace!(seq_no = %observed.seq_no, ip = %observed.ip, port = observed.port); +5160 if !self +5161 .peer_params +5162 .address_discovery_role +5163 .should_report(&self.config.address_discovery_role) +5164 { 5165 return Err(TransportError::PROTOCOL_VIOLATION( -5166 "OBSERVED_ADDRESS frame outside data space", +5166 "received OBSERVED_ADDRESS frame when not negotiated", 5167 )); 5168 } -5169 -5170 let path = self.path_data_mut(path_id); -5171 if network_path == path.network_path { -5172 if let Some(updated) = path.update_observed_addr_report(observed) -5173 && path.open_status == paths::OpenStatus::Informed -5174 { -5175 self.events.push_back(Event::Path(PathEvent::ObservedAddr { -5176 id: path_id, -5177 addr: updated, -5178 })); -5179 // otherwise the event is reported when the path is deemed open -5180 } -5181 } else { -5182 // include in migration -5183 migration_observed_addr = Some(observed) -5184 } -5185 } -5186 Frame::PathAbandon(frame::PathAbandon { -5187 path_id, -5188 error_code, -5189 }) => { -5190 span.record("path", tracing::field::display(&path_id)); -5191 match self.close_path_inner( -5192 now, -5193 path_id, -5194 PathAbandonReason::RemoteAbandoned { -5195 error_code: error_code.into(), -5196 }, -5197 ) { -5198 Ok(()) => { -5199 trace!("peer abandoned path"); -5200 } -5201 Err(ClosePathError::ClosedPath) => { -5202 trace!("peer abandoned already closed path"); -5203 } -5204 Err(ClosePathError::MultipathNotNegotiated) => { -5205 return Err(TransportError::PROTOCOL_VIOLATION( -5206 "received PATH_ABANDON frame when multipath was not negotiated", -5207 )); -5208 } -5209 Err(ClosePathError::LastOpenPath) => { -5210 // Not reachable: close_path_inner allows remote abandons -5211 // for the last path. But handle gracefully just in case. -5212 error!( -5213 "peer abandoned last path but close_path_inner returned LastOpenPath" -5214 ); -5215 } -5216 }; -5217 -5218 // Start draining the path if it still exists and hasn't started draining yet. -5219 if let Some(path) = self.paths.get_mut(&path_id) -5220 && !mem::replace(&mut path.data.draining, true) -5221 { -5222 let ack_delay = self.ack_frequency.max_ack_delay_for_pto(); -5223 let pto = path.data.rtt.pto_base() + ack_delay; -5224 self.timers.set( -5225 Timer::PerPath(path_id, PathTimer::PathDrained), -5226 now + 3 * pto, -5227 self.qlog.with_time(now), -5228 ); -5229 -5230 self.set_max_path_id(now, self.local_max_path_id.saturating_add(1u8)); -5231 } -5232 } -5233 Frame::PathStatusAvailable(info) => { -5234 span.record("path", tracing::field::display(&info.path_id)); -5235 if self.is_multipath_negotiated() { -5236 self.on_path_status( -5237 info.path_id, -5238 PathStatus::Available, -5239 info.status_seq_no, -5240 ); -5241 } else { -5242 return Err(TransportError::PROTOCOL_VIOLATION( -5243 "received PATH_STATUS_AVAILABLE frame when multipath was not negotiated", -5244 )); -5245 } -5246 } -5247 Frame::PathStatusBackup(info) => { -5248 span.record("path", tracing::field::display(&info.path_id)); -5249 if self.is_multipath_negotiated() { -5250 self.on_path_status(info.path_id, PathStatus::Backup, info.status_seq_no); -5251 } else { -5252 return Err(TransportError::PROTOCOL_VIOLATION( -5253 "received PATH_STATUS_BACKUP frame when multipath was not negotiated", -5254 )); -5255 } -5256 } -5257 Frame::MaxPathId(frame::MaxPathId(path_id)) => { -5258 span.record("path", tracing::field::display(&path_id)); -5259 if !self.is_multipath_negotiated() { -5260 return Err(TransportError::PROTOCOL_VIOLATION( -5261 "received MAX_PATH_ID frame when multipath was not negotiated", -5262 )); -5263 } -5264 // frames that do not increase the path id are ignored -5265 if path_id > self.remote_max_path_id { -5266 self.remote_max_path_id = path_id; -5267 self.issue_first_path_cids(now); -5268 while let Some(true) = self.continue_nat_traversal_round(now) {} +5169 // must only be sent in data space +5170 if packet.header.space() != SpaceKind::Data { +5171 return Err(TransportError::PROTOCOL_VIOLATION( +5172 "OBSERVED_ADDRESS frame outside data space", +5173 )); +5174 } +5175 +5176 let path = self.path_data_mut(path_id); +5177 if network_path == path.network_path { +5178 if let Some(updated) = path.update_observed_addr_report(observed) +5179 && path.open_status == paths::OpenStatus::Informed +5180 { +5181 self.events.push_back(Event::Path(PathEvent::ObservedAddr { +5182 id: path_id, +5183 addr: updated, +5184 })); +5185 // otherwise the event is reported when the path is deemed open +5186 } +5187 } else { +5188 // include in migration +5189 migration_observed_addr = Some(observed) +5190 } +5191 } +5192 Frame::PathAbandon(frame::PathAbandon { +5193 path_id, +5194 error_code, +5195 }) => { +5196 span.record("path", tracing::field::display(&path_id)); +5197 match self.close_path_inner( +5198 now, +5199 path_id, +5200 PathAbandonReason::RemoteAbandoned { +5201 error_code: error_code.into(), +5202 }, +5203 ) { +5204 Ok(()) => { +5205 trace!("peer abandoned path"); +5206 } +5207 Err(ClosePathError::ClosedPath) => { +5208 trace!("peer abandoned already closed path"); +5209 } +5210 Err(ClosePathError::MultipathNotNegotiated) => { +5211 return Err(TransportError::PROTOCOL_VIOLATION( +5212 "received PATH_ABANDON frame when multipath was not negotiated", +5213 )); +5214 } +5215 Err(ClosePathError::LastOpenPath) => { +5216 // Not reachable: close_path_inner allows remote abandons +5217 // for the last path. But handle gracefully just in case. +5218 error!( +5219 "peer abandoned last path but close_path_inner returned LastOpenPath" +5220 ); +5221 } +5222 }; +5223 +5224 // Start draining the path if it still exists and hasn't started draining yet. +5225 if let Some(path) = self.paths.get_mut(&path_id) +5226 && !mem::replace(&mut path.data.draining, true) +5227 { +5228 let ack_delay = self.ack_frequency.max_ack_delay_for_pto(); +5229 let pto = path.data.rtt.pto_base() + ack_delay; +5230 self.timers.set( +5231 Timer::PerPath(path_id, PathTimer::PathDrained), +5232 now + 3 * pto, +5233 self.qlog.with_time(now), +5234 ); +5235 +5236 self.set_max_path_id(now, self.local_max_path_id.saturating_add(1u8)); +5237 } +5238 } +5239 Frame::PathStatusAvailable(info) => { +5240 span.record("path", tracing::field::display(&info.path_id)); +5241 if self.is_multipath_negotiated() { +5242 self.on_path_status( +5243 info.path_id, +5244 PathStatus::Available, +5245 info.status_seq_no, +5246 ); +5247 } else { +5248 return Err(TransportError::PROTOCOL_VIOLATION( +5249 "received PATH_STATUS_AVAILABLE frame when multipath was not negotiated", +5250 )); +5251 } +5252 } +5253 Frame::PathStatusBackup(info) => { +5254 span.record("path", tracing::field::display(&info.path_id)); +5255 if self.is_multipath_negotiated() { +5256 self.on_path_status(info.path_id, PathStatus::Backup, info.status_seq_no); +5257 } else { +5258 return Err(TransportError::PROTOCOL_VIOLATION( +5259 "received PATH_STATUS_BACKUP frame when multipath was not negotiated", +5260 )); +5261 } +5262 } +5263 Frame::MaxPathId(frame::MaxPathId(path_id)) => { +5264 span.record("path", tracing::field::display(&path_id)); +5265 if !self.is_multipath_negotiated() { +5266 return Err(TransportError::PROTOCOL_VIOLATION( +5267 "received MAX_PATH_ID frame when multipath was not negotiated", +5268 )); 5269 } -5270 } -5271 Frame::PathsBlocked(frame::PathsBlocked(max_path_id)) => { -5272 // Receipt of a value of Maximum Path Identifier or Path Identifier that is higher than the local maximum value MUST -5273 // be treated as a connection error of type PROTOCOL_VIOLATION. -5274 // Ref <https://www.ietf.org/archive/id/draft-ietf-quic-multipath-14.html#name-paths_blocked-and-path_cids> -5275 if self.is_multipath_negotiated() { -5276 if max_path_id > self.local_max_path_id { -5277 return Err(TransportError::PROTOCOL_VIOLATION( -5278 "PATHS_BLOCKED maximum path identifier was larger than local maximum", -5279 )); -5280 } -5281 debug!("received PATHS_BLOCKED({:?})", max_path_id); -5282 // TODO(@divma): ensure max concurrent paths -5283 } else { -5284 return Err(TransportError::PROTOCOL_VIOLATION( -5285 "received PATHS_BLOCKED frame when not multipath was not negotiated", -5286 )); -5287 } -5288 } -5289 Frame::PathCidsBlocked(frame::PathCidsBlocked { path_id, next_seq }) => { -5290 // Nothing to do. This is recorded in the frame stats, but otherwise we -5291 // always issue all CIDs we're allowed to issue, so either this is an -5292 // impatient peer or a bug on our side. -5293 -5294 // Receipt of a value of Maximum Path Identifier or Path Identifier that is higher than the local maximum value MUST -5295 // be treated as a connection error of type PROTOCOL_VIOLATION. -5296 // Ref <https://www.ietf.org/archive/id/draft-ietf-quic-multipath-14.html#name-paths_blocked-and-path_cids> -5297 if self.is_multipath_negotiated() { -5298 if path_id > self.local_max_path_id { -5299 return Err(TransportError::PROTOCOL_VIOLATION( -5300 "PATH_CIDS_BLOCKED path identifier was larger than local maximum", -5301 )); -5302 } -5303 if next_seq.0 -5304 > self -5305 .local_cid_state -5306 .get(&path_id) -5307 .map(|cid_state| cid_state.active_seq().1 + 1) -5308 .unwrap_or_default() -5309 { -5310 return Err(TransportError::PROTOCOL_VIOLATION( -5311 "PATH_CIDS_BLOCKED next sequence number larger than in local state", -5312 )); -5313 } -5314 debug!(%path_id, %next_seq, "received PATH_CIDS_BLOCKED"); -5315 } else { -5316 return Err(TransportError::PROTOCOL_VIOLATION( -5317 "received PATH_CIDS_BLOCKED frame when not multipath was not negotiated", -5318 )); -5319 } -5320 } -5321 Frame::AddAddress(addr) => { -5322 let client_state = match self.n0_nat_traversal.client_side_mut() { -5323 Ok(state) => state, -5324 Err(err) => { -5325 return Err(TransportError::PROTOCOL_VIOLATION(format!( -5326 "Nat traversal(ADD_ADDRESS): {err}" -5327 ))); -5328 } -5329 }; -5330 -5331 if !client_state.check_remote_address(&addr) { -5332 // if the address is not valid we flag it, but update anyway -5333 warn!(?addr, "server sent illegal ADD_ADDRESS frame"); -5334 } -5335 -5336 match client_state.add_remote_address(addr) { -5337 Ok(maybe_added) => { -5338 if let Some(added) = maybe_added { -5339 self.events.push_back(Event::NatTraversal( -5340 n0_nat_traversal::Event::AddressAdded(added), -5341 )); -5342 } -5343 } -5344 Err(e) => { -5345 warn!(%e, "failed to add remote address") -5346 } -5347 } -5348 } -5349 Frame::RemoveAddress(addr) => { -5350 let client_state = match self.n0_nat_traversal.client_side_mut() { -5351 Ok(state) => state, -5352 Err(err) => { -5353 return Err(TransportError::PROTOCOL_VIOLATION(format!( -5354 "Nat traversal(REMOVE_ADDRESS): {err}" -5355 ))); -5356 } -5357 }; -5358 if let Some(removed_addr) = client_state.remove_remote_address(addr) { -5359 self.events.push_back(Event::NatTraversal( -5360 n0_nat_traversal::Event::AddressRemoved(removed_addr), -5361 )); -5362 } -5363 } -5364 Frame::ReachOut(reach_out) => { -5365 let ipv6 = self.is_ipv6(); -5366 let server_state = match self.n0_nat_traversal.server_side_mut() { -5367 Ok(state) => state, -5368 Err(err) => { -5369 return Err(TransportError::PROTOCOL_VIOLATION(format!( -5370 "Nat traversal(REACH_OUT): {err}" -5371 ))); -5372 } -5373 }; -5374 -5375 let round_before = server_state.current_round(); -5376 -5377 if let Err(err) = server_state.handle_reach_out(reach_out, ipv6) { -5378 return Err(TransportError::PROTOCOL_VIOLATION(format!( -5379 "Nat traversal(REACH_OUT): {err}" -5380 ))); -5381 } +5270 // frames that do not increase the path id are ignored +5271 if path_id > self.remote_max_path_id { +5272 self.remote_max_path_id = path_id; +5273 self.issue_first_path_cids(now); +5274 while let Some(true) = self.continue_nat_traversal_round(now) {} +5275 } +5276 } +5277 Frame::PathsBlocked(frame::PathsBlocked(max_path_id)) => { +5278 // Receipt of a value of Maximum Path Identifier or Path Identifier that is higher than the local maximum value MUST +5279 // be treated as a connection error of type PROTOCOL_VIOLATION. +5280 // Ref <https://www.ietf.org/archive/id/draft-ietf-quic-multipath-14.html#name-paths_blocked-and-path_cids> +5281 if self.is_multipath_negotiated() { +5282 if max_path_id > self.local_max_path_id { +5283 return Err(TransportError::PROTOCOL_VIOLATION( +5284 "PATHS_BLOCKED maximum path identifier was larger than local maximum", +5285 )); +5286 } +5287 debug!("received PATHS_BLOCKED({:?})", max_path_id); +5288 // TODO(@divma): ensure max concurrent paths +5289 } else { +5290 return Err(TransportError::PROTOCOL_VIOLATION( +5291 "received PATHS_BLOCKED frame when not multipath was not negotiated", +5292 )); +5293 } +5294 } +5295 Frame::PathCidsBlocked(frame::PathCidsBlocked { path_id, next_seq }) => { +5296 // Nothing to do. This is recorded in the frame stats, but otherwise we +5297 // always issue all CIDs we're allowed to issue, so either this is an +5298 // impatient peer or a bug on our side. +5299 +5300 // Receipt of a value of Maximum Path Identifier or Path Identifier that is higher than the local maximum value MUST +5301 // be treated as a connection error of type PROTOCOL_VIOLATION. +5302 // Ref <https://www.ietf.org/archive/id/draft-ietf-quic-multipath-14.html#name-paths_blocked-and-path_cids> +5303 if self.is_multipath_negotiated() { +5304 if path_id > self.local_max_path_id { +5305 return Err(TransportError::PROTOCOL_VIOLATION( +5306 "PATH_CIDS_BLOCKED path identifier was larger than local maximum", +5307 )); +5308 } +5309 if next_seq.0 +5310 > self +5311 .local_cid_state +5312 .get(&path_id) +5313 .map(|cid_state| cid_state.active_seq().1 + 1) +5314 .unwrap_or_default() +5315 { +5316 return Err(TransportError::PROTOCOL_VIOLATION( +5317 "PATH_CIDS_BLOCKED next sequence number larger than in local state", +5318 )); +5319 } +5320 debug!(%path_id, %next_seq, "received PATH_CIDS_BLOCKED"); +5321 } else { +5322 return Err(TransportError::PROTOCOL_VIOLATION( +5323 "received PATH_CIDS_BLOCKED frame when not multipath was not negotiated", +5324 )); +5325 } +5326 } +5327 Frame::AddAddress(addr) => { +5328 let client_state = match self.n0_nat_traversal.client_side_mut() { +5329 Ok(state) => state, +5330 Err(err) => { +5331 return Err(TransportError::PROTOCOL_VIOLATION(format!( +5332 "Nat traversal(ADD_ADDRESS): {err}" +5333 ))); +5334 } +5335 }; +5336 +5337 if !client_state.check_remote_address(&addr) { +5338 // if the address is not valid we flag it, but update anyway +5339 warn!(?addr, "server sent illegal ADD_ADDRESS frame"); +5340 } +5341 +5342 match client_state.add_remote_address(addr) { +5343 Ok(maybe_added) => { +5344 if let Some(added) = maybe_added { +5345 self.events.push_back(Event::NatTraversal( +5346 n0_nat_traversal::Event::AddressAdded(added), +5347 )); +5348 } +5349 } +5350 Err(e) => { +5351 warn!(%e, "failed to add remote address") +5352 } +5353 } +5354 } +5355 Frame::RemoveAddress(addr) => { +5356 let client_state = match self.n0_nat_traversal.client_side_mut() { +5357 Ok(state) => state, +5358 Err(err) => { +5359 return Err(TransportError::PROTOCOL_VIOLATION(format!( +5360 "Nat traversal(REMOVE_ADDRESS): {err}" +5361 ))); +5362 } +5363 }; +5364 if let Some(removed_addr) = client_state.remove_remote_address(addr) { +5365 self.events.push_back(Event::NatTraversal( +5366 n0_nat_traversal::Event::AddressRemoved(removed_addr), +5367 )); +5368 } +5369 } +5370 Frame::ReachOut(reach_out) => { +5371 let ipv6 = self.is_ipv6(); +5372 let server_state = match self.n0_nat_traversal.server_side_mut() { +5373 Ok(state) => state, +5374 Err(err) => { +5375 return Err(TransportError::PROTOCOL_VIOLATION(format!( +5376 "Nat traversal(REACH_OUT): {err}" +5377 ))); +5378 } +5379 }; +5380 +5381 let round_before = server_state.current_round(); 5382 -5383 // Only clean up if handle_reach_out actually advanced the round -5384 // (it may silently ignore frames for old rounds or unsupported IP families). -5385 let round_advanced = server_state.current_round() > round_before; -5386 if round_advanced { -5387 self.timers.stop( -5388 Timer::Conn(ConnTimer::NatTraversalProbeRetry), -5389 self.qlog.with_time(now), -5390 ); -5391 -5392 let path = &mut self.paths.get_mut(&path_id).expect("known path").data; -5393 if path.has_off_path_challenges() { -5394 trace!( -5395 "clearing stale off-path challenges for new NAT traversal round" -5396 ); -5397 path.clear_off_path_challenges(); -5398 -5399 if let Some(remote_cids) = self.remote_cids.get_mut(&path_id) -5400 && let Some((reset_token, retired)) = remote_cids.next() -5401 { -5402 self.spaces[SpaceId::Data] -5403 .pending -5404 .retire_cids -5405 .extend(retired.map(|seq| (path_id, seq))); -5406 let remote = self -5407 .paths -5408 .get(&path_id) -5409 .expect("known path") -5410 .data -5411 .network_path -5412 .remote; -5413 self.set_reset_token(path_id, remote, reset_token); -5414 } -5415 } -5416 } -5417 } -5418 } -5419 } -5420 -5421 let space = self.spaces[SpaceId::Data].for_path(path_id); -5422 if space -5423 .pending_acks -5424 .packet_received(now, number, ack_eliciting, &space.dedup) -5425 { -5426 if self.abandoned_paths.contains(&path_id) { -5427 // § 3.4.3 QUIC-MULTIPATH: promptly send ACKs for packets received from -5428 // abandoned paths. -5429 space.pending_acks.set_immediate_ack_required(); -5430 } else { -5431 self.timers.set( -5432 Timer::PerPath(path_id, PathTimer::MaxAckDelay), -5433 now + self.ack_frequency.max_ack_delay, -5434 self.qlog.with_time(now), -5435 ); -5436 } -5437 } -5438 -5439 // Issue stream ID credit due to ACKs of outgoing finish/resets and incoming finish/resets -5440 // on stopped streams. Incoming finishes/resets on open streams are not handled here as they -5441 // are only freed, and hence only issue credit, once the application has been notified -5442 // during a read on the stream. -5443 let pending = &mut self.spaces[SpaceId::Data].pending; -5444 self.streams.queue_max_stream_id(pending); -5445 -5446 if let Some(reason) = close { -5447 self.state.move_to_draining(Some(reason.into())); -5448 self.connection_close_pending = true; -5449 } -5450 -5451 if Some(number) -5452 == self.spaces[SpaceId::Data] -5453 .for_path(path_id) -5454 .largest_received_packet_number -5455 && !is_probing_packet -5456 && network_path != self.path_data(path_id).network_path -5457 { -5458 let ConnectionSide::Server { ref server_config } = self.side else { -5459 panic!("packets from unknown remote should be dropped by clients"); -5460 }; -5461 debug_assert!( -5462 server_config.migration, -5463 "migration-initiating packets should have been dropped immediately" -5464 ); -5465 self.migrate(path_id, now, network_path, migration_observed_addr); -5466 // Break linkability, if possible -5467 self.update_remote_cid(path_id); -5468 self.spin = false; -5469 } -5470 -5471 Ok(()) -5472 } -5473 -5474 fn migrate( -5475 &mut self, -5476 path_id: PathId, -5477 now: Instant, -5478 network_path: FourTuple, -5479 observed_addr: Option<ObservedAddr>, -5480 ) { -5481 trace!(%network_path, %path_id, "migration initiated"); -5482 self.path_generation_counter = self.path_generation_counter.wrapping_add(1); -5483 // TODO(@divma): conditions for path migration in multipath are very specific, check them -5484 // again to prevent path migrations that should actually create a new path -5485 -5486 // Reset rtt/congestion state for new path unless it looks like a NAT rebinding. -5487 // Note that the congestion window will not grow until validation terminates. Helps mitigate -5488 // amplification attacks performed by spoofing source addresses. -5489 let prev_pto = self.pto(SpaceKind::Data, path_id); -5490 let path = self.paths.get_mut(&path_id).expect("known path"); -5491 let mut new_path_data = if network_path.remote.is_ipv4() -5492 && network_path.remote.ip() == path.data.network_path.remote.ip() -5493 { -5494 PathData::from_previous(network_path, &path.data, self.path_generation_counter, now) -5495 } else { -5496 let peer_max_udp_payload_size = -5497 u16::try_from(self.peer_params.max_udp_payload_size.into_inner()) -5498 .unwrap_or(u16::MAX); -5499 PathData::new( -5500 network_path, -5501 self.allow_mtud, -5502 Some(peer_max_udp_payload_size), -5503 self.path_generation_counter, -5504 now, -5505 &self.config, -5506 ) -5507 }; -5508 new_path_data.last_observed_addr_report = path.data.last_observed_addr_report.clone(); -5509 if let Some(report) = observed_addr -5510 && let Some(updated) = new_path_data.update_observed_addr_report(report) -5511 { -5512 tracing::info!("adding observed addr event from migration"); -5513 self.events.push_back(Event::Path(PathEvent::ObservedAddr { -5514 id: path_id, -5515 addr: updated, -5516 })); -5517 } -5518 new_path_data.pending_on_path_challenge = true; -5519 -5520 let mut prev_path_data = mem::replace(&mut path.data, new_path_data); -5521 -5522 // Only store this as previous path if it was validated. For all we know there could -5523 // already be a previous path stored which might have been validated in the past, -5524 // which is more valuable than one that's not yet validated. -5525 // -5526 // With multipath it is possible that there are no remote CIDs for the path ID -5527 // yet. In this case we would never have sent on this path yet and would not be able -5528 // to send a PATH_CHALLENGE either, which is currently a fire-and-forget affair -5529 // anyway. So don't store such a path either. -5530 if !prev_path_data.validated -5531 && let Some(cid) = self.remote_cids.get(&path_id).map(CidQueue::active) -5532 { -5533 prev_path_data.pending_on_path_challenge = true; -5534 // We haven't updated the remote CID yet, this captures the remote CID we were using on -5535 // the previous path. -5536 path.prev = Some((cid, prev_path_data)); -5537 } -5538 -5539 // We need to re-assign the correct remote to this path in qlog -5540 self.qlog.emit_tuple_assigned(path_id, network_path, now); -5541 -5542 self.timers.set( -5543 Timer::PerPath(path_id, PathTimer::PathValidationFailed), -5544 now + 3 * cmp::max(self.pto(SpaceKind::Data, path_id), prev_pto), -5545 self.qlog.with_time(now), -5546 ); -5547 } -5548 -5549 /// Handle a change in the local address, i.e. an active migration -5550 /// -5551 /// In the general (non-multipath) case, paths will perform a RFC9000 migration and be pinged -5552 /// for a liveness check. This is the behaviour of a path assumed to be recoverable, even if -5553 /// this is not the case. -5554 /// -5555 /// Clients in a connection in which multipath has been negotiated should migrate paths to new -5556 /// [`PathId`]s. For paths that are known to be non-recoverable can be migrated to a new -5557 /// [`PathId`] by closing the current path, and opening a new one to the same remote. Treating -5558 /// paths as non recoverable when necessary accelerates connectivity re-establishment, or might -5559 /// allow it altogether. +5383 if let Err(err) = server_state.handle_reach_out(reach_out, ipv6) { +5384 return Err(TransportError::PROTOCOL_VIOLATION(format!( +5385 "Nat traversal(REACH_OUT): {err}" +5386 ))); +5387 } +5388 +5389 // Only clean up if handle_reach_out actually advanced the round +5390 // (it may silently ignore frames for old rounds or unsupported IP families). +5391 let round_advanced = server_state.current_round() > round_before; +5392 if round_advanced { +5393 self.timers.stop( +5394 Timer::Conn(ConnTimer::NatTraversalProbeRetry), +5395 self.qlog.with_time(now), +5396 ); +5397 +5398 let path = &mut self.paths.get_mut(&path_id).expect("known path").data; +5399 if path.has_off_path_challenges() { +5400 trace!( +5401 "clearing stale off-path challenges for new NAT traversal round" +5402 ); +5403 path.clear_off_path_challenges(); +5404 +5405 if let Some(remote_cids) = self.remote_cids.get_mut(&path_id) +5406 && let Some((reset_token, retired)) = remote_cids.next() +5407 { +5408 self.spaces[SpaceId::Data] +5409 .pending +5410 .retire_cids +5411 .extend(retired.map(|seq| (path_id, seq))); +5412 let remote = self +5413 .paths +5414 .get(&path_id) +5415 .expect("known path") +5416 .data +5417 .network_path +5418 .remote; +5419 self.set_reset_token(path_id, remote, reset_token); +5420 } +5421 } +5422 } +5423 } +5424 } +5425 } +5426 +5427 let space = self.spaces[SpaceId::Data].for_path(path_id); +5428 if space +5429 .pending_acks +5430 .packet_received(now, number, ack_eliciting, &space.dedup) +5431 { +5432 if self.abandoned_paths.contains(&path_id) { +5433 // § 3.4.3 QUIC-MULTIPATH: promptly send ACKs for packets received from +5434 // abandoned paths. +5435 space.pending_acks.set_immediate_ack_required(); +5436 } else { +5437 self.timers.set( +5438 Timer::PerPath(path_id, PathTimer::MaxAckDelay), +5439 now + self.ack_frequency.max_ack_delay, +5440 self.qlog.with_time(now), +5441 ); +5442 } +5443 } +5444 +5445 // Issue stream ID credit due to ACKs of outgoing finish/resets and incoming finish/resets +5446 // on stopped streams. Incoming finishes/resets on open streams are not handled here as they +5447 // are only freed, and hence only issue credit, once the application has been notified +5448 // during a read on the stream. +5449 let pending = &mut self.spaces[SpaceId::Data].pending; +5450 self.streams.queue_max_stream_id(pending); +5451 +5452 if let Some(reason) = close { +5453 self.state.move_to_draining(Some(reason.into())); +5454 self.connection_close_pending = true; +5455 } +5456 +5457 if Some(number) +5458 == self.spaces[SpaceId::Data] +5459 .for_path(path_id) +5460 .largest_received_packet_number +5461 && !is_probing_packet +5462 && network_path != self.path_data(path_id).network_path +5463 { +5464 let ConnectionSide::Server { ref server_config } = self.side else { +5465 panic!("packets from unknown remote should be dropped by clients"); +5466 }; +5467 debug_assert!( +5468 server_config.migration, +5469 "migration-initiating packets should have been dropped immediately" +5470 ); +5471 self.migrate(path_id, now, network_path, migration_observed_addr); +5472 // Break linkability, if possible +5473 self.update_remote_cid(path_id); +5474 self.spin = false; +5475 } +5476 +5477 Ok(()) +5478 } +5479 +5480 fn migrate( +5481 &mut self, +5482 path_id: PathId, +5483 now: Instant, +5484 network_path: FourTuple, +5485 observed_addr: Option<ObservedAddr>, +5486 ) { +5487 trace!(%network_path, %path_id, "migration initiated"); +5488 self.path_generation_counter = self.path_generation_counter.wrapping_add(1); +5489 // TODO(@divma): conditions for path migration in multipath are very specific, check them +5490 // again to prevent path migrations that should actually create a new path +5491 +5492 // Reset rtt/congestion state for new path unless it looks like a NAT rebinding. +5493 // Note that the congestion window will not grow until validation terminates. Helps mitigate +5494 // amplification attacks performed by spoofing source addresses. +5495 let prev_pto = self.pto(SpaceKind::Data, path_id); +5496 let path = self.paths.get_mut(&path_id).expect("known path"); +5497 let mut new_path_data = if network_path.remote.is_ipv4() +5498 && network_path.remote.ip() == path.data.network_path.remote.ip() +5499 { +5500 PathData::from_previous(network_path, &path.data, self.path_generation_counter, now) +5501 } else { +5502 let peer_max_udp_payload_size = +5503 u16::try_from(self.peer_params.max_udp_payload_size.into_inner()) +5504 .unwrap_or(u16::MAX); +5505 PathData::new( +5506 network_path, +5507 self.allow_mtud, +5508 Some(peer_max_udp_payload_size), +5509 self.path_generation_counter, +5510 now, +5511 &self.config, +5512 ) +5513 }; +5514 new_path_data.last_observed_addr_report = path.data.last_observed_addr_report.clone(); +5515 if let Some(report) = observed_addr +5516 && let Some(updated) = new_path_data.update_observed_addr_report(report) +5517 { +5518 tracing::info!("adding observed addr event from migration"); +5519 self.events.push_back(Event::Path(PathEvent::ObservedAddr { +5520 id: path_id, +5521 addr: updated, +5522 })); +5523 } +5524 new_path_data.pending_on_path_challenge = true; +5525 +5526 let mut prev_path_data = mem::replace(&mut path.data, new_path_data); +5527 +5528 // Only store this as previous path if it was validated. For all we know there could +5529 // already be a previous path stored which might have been validated in the past, +5530 // which is more valuable than one that's not yet validated. +5531 // +5532 // With multipath it is possible that there are no remote CIDs for the path ID +5533 // yet. In this case we would never have sent on this path yet and would not be able +5534 // to send a PATH_CHALLENGE either, which is currently a fire-and-forget affair +5535 // anyway. So don't store such a path either. +5536 if !prev_path_data.validated +5537 && let Some(cid) = self.remote_cids.get(&path_id).map(CidQueue::active) +5538 { +5539 prev_path_data.pending_on_path_challenge = true; +5540 // We haven't updated the remote CID yet, this captures the remote CID we were using on +5541 // the previous path. +5542 path.prev = Some((cid, prev_path_data)); +5543 } +5544 +5545 // We need to re-assign the correct remote to this path in qlog +5546 self.qlog.emit_tuple_assigned(path_id, network_path, now); +5547 +5548 self.timers.set( +5549 Timer::PerPath(path_id, PathTimer::PathValidationFailed), +5550 now + 3 * cmp::max(self.pto(SpaceKind::Data, path_id), prev_pto), +5551 self.qlog.with_time(now), +5552 ); +5553 } +5554 +5555 /// Handle a change in the local address, i.e. an active migration +5556 /// +5557 /// In the general (non-multipath) case, paths will perform a RFC9000 migration and be pinged +5558 /// for a liveness check. This is the behaviour of a path assumed to be recoverable, even if +5559 /// this is not the case. 5560 /// -5561 /// The optional `hint` allows callers to indicate when paths are non-recoverable and should be -5562 /// migrated to new a [`PathId`]. -5563 // NOTE: only clients are allowed to migrate, but generally dealing with RFC9000 migrations is -5564 // lacking <https://github.com/n0-computer/noq/issues/364> -5565 pub fn handle_network_change(&mut self, hint: Option<&dyn NetworkChangeHint>, now: Instant) { -5566 debug!("network changed"); -5567 if self.state.is_drained() { -5568 return; -5569 } -5570 if self.highest_space < SpaceKind::Data { -5571 for path in self.paths.values_mut() { -5572 // Clear the local address for it to be obtained from the socket again. -5573 path.data.network_path.local_ip = None; -5574 } -5575 -5576 self.update_remote_cid(PathId::ZERO); -5577 self.ping(); -5578 -5579 return; -5580 } +5561 /// Clients in a connection in which multipath has been negotiated should migrate paths to new +5562 /// [`PathId`]s. For paths that are known to be non-recoverable can be migrated to a new +5563 /// [`PathId`] by closing the current path, and opening a new one to the same remote. Treating +5564 /// paths as non recoverable when necessary accelerates connectivity re-establishment, or might +5565 /// allow it altogether. +5566 /// +5567 /// The optional `hint` allows callers to indicate when paths are non-recoverable and should be +5568 /// migrated to new a [`PathId`]. +5569 // NOTE: only clients are allowed to migrate, but generally dealing with RFC9000 migrations is +5570 // lacking <https://github.com/n0-computer/noq/issues/364> +5571 pub fn handle_network_change(&mut self, hint: Option<&dyn NetworkChangeHint>, now: Instant) { +5572 debug!("network changed"); +5573 if self.state.is_drained() { +5574 return; +5575 } +5576 if self.highest_space < SpaceKind::Data { +5577 for path in self.paths.values_mut() { +5578 // Clear the local address for it to be obtained from the socket again. +5579 path.data.network_path.local_ip = None; +5580 } 5581 -5582 // Paths that can't recover so a new path should be open instead. If multipath is not -5583 // negotiated, this will be empty. -5584 let mut non_recoverable_paths = Vec::default(); -5585 let mut recoverable_paths = Vec::default(); -5586 let mut open_paths = 0; +5582 self.update_remote_cid(PathId::ZERO); +5583 self.ping(); +5584 +5585 return; +5586 } 5587 -5588 let is_multipath_negotiated = self.is_multipath_negotiated(); -5589 let is_client = self.side().is_client(); -5590 let immediate_ack_allowed = self.peer_supports_ack_frequency(); -5591 -5592 for (path_id, path) in self.paths.iter_mut() { -5593 if self.abandoned_paths.contains(path_id) { -5594 continue; -5595 } -5596 open_paths += 1; +5588 // Paths that can't recover so a new path should be open instead. If multipath is not +5589 // negotiated, this will be empty. +5590 let mut non_recoverable_paths = Vec::default(); +5591 let mut recoverable_paths = Vec::default(); +5592 let mut open_paths = 0; +5593 +5594 let is_multipath_negotiated = self.is_multipath_negotiated(); +5595 let is_client = self.side().is_client(); +5596 let immediate_ack_allowed = self.peer_supports_ack_frequency(); 5597 -5598 // Read the network path BEFORE clearing local_ip, so the hint can -5599 // check which interface the path was using. -5600 let network_path = path.data.network_path; -5601 -5602 // Clear the local address for it to be obtained from the socket again. This applies to -5603 // all paths, regardless of being considered recoverable or not -5604 path.data.network_path.local_ip = None; -5605 let remote = network_path.remote; -5606 -5607 // Without multipath, the connection tries to recover the single path, whereas with -5608 // multipath, even in a single-path scenario, we attempt to migrate the path to a new -5609 // PathId. -5610 let attempt_to_recover = if is_multipath_negotiated { -5611 if is_client { -5612 hint.map(|h| h.is_path_recoverable(*path_id, network_path)) -5613 .unwrap_or(false) -5614 } else { -5615 // Servers should have stable addresses so this scenario is generally discouraged. -5616 // There is no way to prevent this, so the best hope is to attempt to recover the -5617 // path -5618 true -5619 } -5620 } else { -5621 // In the non multipath case, we try to recover the single active path -5622 true -5623 }; -5624 -5625 if attempt_to_recover { -5626 recoverable_paths.push((*path_id, remote)); -5627 } else { -5628 non_recoverable_paths.push((*path_id, remote, path.data.local_status())) -5629 } -5630 } -5631 -5632 /* NON RECOVERABLE PATHS */ -5633 // This are handled first, so that in case the treatment intended for these fails, we can -5634 // go the recoverable route instead. -5635 -5636 // Decide if we need to close first or open first in the multipath case. -5637 // - Opening first has a higher risk of getting limited by the negotiated MAX_PATH_ID. -5638 // - Closing first risks this being the only open path. -5639 // We prefer closing paths first unless we identify this is the last open path. -5640 let open_first = open_paths == non_recoverable_paths.len(); +5598 for (path_id, path) in self.paths.iter_mut() { +5599 if self.abandoned_paths.contains(path_id) { +5600 continue; +5601 } +5602 open_paths += 1; +5603 +5604 // Read the network path BEFORE clearing local_ip, so the hint can +5605 // check which interface the path was using. +5606 let network_path = path.data.network_path; +5607 +5608 // Clear the local address for it to be obtained from the socket again. This applies to +5609 // all paths, regardless of being considered recoverable or not +5610 path.data.network_path.local_ip = None; +5611 let remote = network_path.remote; +5612 +5613 // Without multipath, the connection tries to recover the single path, whereas with +5614 // multipath, even in a single-path scenario, we attempt to migrate the path to a new +5615 // PathId. +5616 let attempt_to_recover = if is_multipath_negotiated { +5617 if is_client { +5618 hint.map(|h| h.is_path_recoverable(*path_id, network_path)) +5619 .unwrap_or(false) +5620 } else { +5621 // Servers should have stable addresses so this scenario is generally discouraged. +5622 // There is no way to prevent this, so the best hope is to attempt to recover the +5623 // path +5624 true +5625 } +5626 } else { +5627 // In the non multipath case, we try to recover the single active path +5628 true +5629 }; +5630 +5631 if attempt_to_recover { +5632 recoverable_paths.push((*path_id, remote)); +5633 } else { +5634 non_recoverable_paths.push((*path_id, remote, path.data.local_status())) +5635 } +5636 } +5637 +5638 /* NON RECOVERABLE PATHS */ +5639 // This are handled first, so that in case the treatment intended for these fails, we can +5640 // go the recoverable route instead. 5641 -5642 for (path_id, remote, status) in non_recoverable_paths.into_iter() { -5643 let network_path = FourTuple { -5644 remote, -5645 local_ip: None, /* allow the local ip to be discovered */ -5646 }; +5642 // Decide if we need to close first or open first in the multipath case. +5643 // - Opening first has a higher risk of getting limited by the negotiated MAX_PATH_ID. +5644 // - Closing first risks this being the only open path. +5645 // We prefer closing paths first unless we identify this is the last open path. +5646 let open_first = open_paths == non_recoverable_paths.len(); 5647 -5648 if open_first && let Err(e) = self.open_path(network_path, status, now) { -5649 debug!(%e,"Failed to open new path for network change"); -5650 // if this fails, let the path try to recover itself -5651 recoverable_paths.push((path_id, remote)); -5652 continue; -5653 } -5654 -5655 if let Err(e) = -5656 self.close_path_inner(now, path_id, PathAbandonReason::UnusableAfterNetworkChange) -5657 { -5658 debug!(%e,"Failed to close unrecoverable path after network change"); -5659 recoverable_paths.push((path_id, remote)); -5660 continue; -5661 } -5662 -5663 if !open_first && let Err(e) = self.open_path(network_path, status, now) { -5664 // Path has already been closed if we got here. Since the path was not recoverable, -5665 // this might be desirable in any case, because other paths exist (!open_first) and -5666 // this was is considered non recoverable -5667 debug!(%e,"Failed to open new path for network change"); -5668 } -5669 } -5670 -5671 /* RECOVERABLE PATHS */ -5672 -5673 for (path_id, remote) in recoverable_paths.into_iter() { -5674 // Schedule a Ping for a liveness check. -5675 if let Some(path_space) = self.spaces[SpaceId::Data].number_spaces.get_mut(&path_id) { -5676 path_space.ping_pending = true; -5677 -5678 if immediate_ack_allowed { -5679 path_space.immediate_ack_pending = true; -5680 } -5681 } -5682 -5683 // Reset PTO backoff so retransmits resume promptly. Congestion controller and -5684 // RTT are intentionally preserved for recoverable paths. We explicitly allow -5685 // this reset also during the handshake, so do not check -5686 // Self::peer_competed_handshake_address_validation. -5687 if let Some(path) = self.paths.get_mut(&path_id) { -5688 path.data.pto_count = 0; -5689 } -5690 self.set_loss_detection_timer(now, path_id); -5691 -5692 let Some((reset_token, retired)) = -5693 self.remote_cids.get_mut(&path_id).and_then(CidQueue::next) -5694 else { -5695 continue; -5696 }; +5648 for (path_id, remote, status) in non_recoverable_paths.into_iter() { +5649 let network_path = FourTuple { +5650 remote, +5651 local_ip: None, /* allow the local ip to be discovered */ +5652 }; +5653 +5654 if open_first && let Err(e) = self.open_path(network_path, status, now) { +5655 debug!(%e,"Failed to open new path for network change"); +5656 // if this fails, let the path try to recover itself +5657 recoverable_paths.push((path_id, remote)); +5658 continue; +5659 } +5660 +5661 if let Err(e) = +5662 self.close_path_inner(now, path_id, PathAbandonReason::UnusableAfterNetworkChange) +5663 { +5664 debug!(%e,"Failed to close unrecoverable path after network change"); +5665 recoverable_paths.push((path_id, remote)); +5666 continue; +5667 } +5668 +5669 if !open_first && let Err(e) = self.open_path(network_path, status, now) { +5670 // Path has already been closed if we got here. Since the path was not recoverable, +5671 // this might be desirable in any case, because other paths exist (!open_first) and +5672 // this was is considered non recoverable +5673 debug!(%e,"Failed to open new path for network change"); +5674 } +5675 } +5676 +5677 /* RECOVERABLE PATHS */ +5678 +5679 for (path_id, remote) in recoverable_paths.into_iter() { +5680 // Schedule a Ping for a liveness check. +5681 if let Some(path_space) = self.spaces[SpaceId::Data].number_spaces.get_mut(&path_id) { +5682 path_space.ping_pending = true; +5683 +5684 if immediate_ack_allowed { +5685 path_space.immediate_ack_pending = true; +5686 } +5687 } +5688 +5689 // Reset PTO backoff so retransmits resume promptly. Congestion controller and +5690 // RTT are intentionally preserved for recoverable paths. We explicitly allow +5691 // this reset also during the handshake, so do not check +5692 // Self::peer_competed_handshake_address_validation. +5693 if let Some(path) = self.paths.get_mut(&path_id) { +5694 path.data.pto_count = 0; +5695 } +5696 self.set_loss_detection_timer(now, path_id); 5697 -5698 // Retire the current remote CID and any CIDs we had to skip. -5699 self.spaces[SpaceId::Data] -5700 .pending -5701 .retire_cids -5702 .extend(retired.map(|seq| (path_id, seq))); +5698 let Some((reset_token, retired)) = +5699 self.remote_cids.get_mut(&path_id).and_then(CidQueue::next) +5700 else { +5701 continue; +5702 }; 5703 -5704 debug_assert!(!self.state.is_drained()); // required for endpoint_events, checked above -5705 self.endpoint_events -5706 .push_back(EndpointEventInner::ResetToken(path_id, remote, reset_token)); -5707 } -5708 } +5704 // Retire the current remote CID and any CIDs we had to skip. +5705 self.spaces[SpaceId::Data] +5706 .pending +5707 .retire_cids +5708 .extend(retired.map(|seq| (path_id, seq))); 5709 -5710 /// Switch to a previously unused remote connection ID, if possible -5711 fn update_remote_cid(&mut self, path_id: PathId) { -5712 let Some((reset_token, retired)) = self -5713 .remote_cids -5714 .get_mut(&path_id) -5715 .and_then(|cids| cids.next()) -5716 else { -5717 return; -5718 }; -5719 -5720 // Retire the current remote CID and any CIDs we had to skip. -5721 self.spaces[SpaceId::Data] -5722 .pending -5723 .retire_cids -5724 .extend(retired.map(|seq| (path_id, seq))); -5725 let remote = self.path_data(path_id).network_path.remote; -5726 self.set_reset_token(path_id, remote, reset_token); -5727 } -5728 -5729 /// Sends this reset token to the endpoint -5730 /// -5731 /// The endpoint needs to know the reset tokens issued by the peer, so that if the peer -5732 /// sends a reset token it knows to route it to this connection. See RFC 9000 section -5733 /// 10.3. Stateless Reset. -5734 /// -5735 /// Reset tokens are different for each path, the endpoint identifies paths by peer -5736 /// socket address however, not by path ID. -5737 fn set_reset_token(&mut self, path_id: PathId, remote: SocketAddr, reset_token: ResetToken) { -5738 debug_assert!(!self.state.is_drained()); // required for endpoint events, set_reset_token is never called for drained connections -5739 self.endpoint_events -5740 .push_back(EndpointEventInner::ResetToken(path_id, remote, reset_token)); -5741 -5742 // During the handshake the server sends a reset token in the transport -5743 // parameters. When we are the client and we receive the reset token during the -5744 // handshake we want this to affect our peer transport parameters. -5745 // TODO(flub): Pretty sure this is pointless, the entire params is overwritten -5746 // shortly after this was called. And then the params don't have this anymore. -5747 if path_id == PathId::ZERO { -5748 self.peer_params.stateless_reset_token = Some(reset_token); -5749 } -5750 } -5751 -5752 /// Issue an initial set of connection IDs to the peer upon connection -5753 fn issue_first_cids(&mut self, now: Instant) { -5754 if self -5755 .local_cid_state -5756 .get(&PathId::ZERO) -5757 .expect("PathId::ZERO exists when the connection is created") -5758 .cid_len() -5759 == 0 -5760 { -5761 return; -5762 } -5763 -5764 // Subtract 1 to account for the CID we supplied while handshaking -5765 let mut n = self.peer_params.issue_cids_limit() - 1; -5766 if let ConnectionSide::Server { server_config } = &self.side -5767 && server_config.has_preferred_address() -5768 { -5769 // We also sent a CID in the transport parameters -5770 n -= 1; -5771 } -5772 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events -5773 self.endpoint_events -5774 .push_back(EndpointEventInner::NeedIdentifiers(PathId::ZERO, now, n)); -5775 } -5776 -5777 /// Issues an initial set of CIDs for paths that have not yet had any CIDs issued -5778 /// -5779 /// Later CIDs are issued when CIDs expire or are retired by the peer. -5780 fn issue_first_path_cids(&mut self, now: Instant) { -5781 if let Some(max_path_id) = self.max_path_id() { -5782 let mut path_id = self.max_path_id_with_cids.next(); -5783 while path_id <= max_path_id { -5784 self.endpoint_events -5785 .push_back(EndpointEventInner::NeedIdentifiers( -5786 path_id, -5787 now, -5788 self.peer_params.issue_cids_limit(), -5789 )); -5790 path_id = path_id.next(); -5791 } -5792 self.max_path_id_with_cids = max_path_id; -5793 } -5794 } -5795 -5796 /// Populates a packet with frames -5797 /// -5798 /// This tries to fit as many frames as possible into the packet. -5799 /// -5800 /// *path_exclusive_only* means to only build frames which can only be sent on this -5801 /// *path. This is used in multipath for backup paths while there is still an active -5802 /// *path. -5803 fn populate_packet<'a, 'b>( -5804 &mut self, -5805 now: Instant, -5806 space_id: SpaceId, -5807 path_id: PathId, -5808 scheduling_info: &PathSchedulingInfo, -5809 builder: &mut PacketBuilder<'a, 'b>, -5810 ) { -5811 let is_multipath_negotiated = self.is_multipath_negotiated(); -5812 let space_has_keys = self.crypto_state.has_keys(space_id.encryption_level()); -5813 let is_0rtt = space_id == SpaceId::Data && !space_has_keys; -5814 let stats = &mut self.path_stats.for_path(path_id).frame_tx; -5815 let space = &mut self.spaces[space_id]; -5816 let path = &mut self.paths.get_mut(&path_id).expect("known path").data; -5817 space -5818 .for_path(path_id) -5819 .pending_acks -5820 .maybe_ack_non_eliciting(); -5821 -5822 // HANDSHAKE_DONE -5823 if !is_0rtt -5824 && !scheduling_info.is_abandoned -5825 && scheduling_info.may_send_data -5826 && mem::replace(&mut space.pending.handshake_done, false) -5827 { -5828 builder.write_frame(frame::HandshakeDone, stats); -5829 } -5830 -5831 // PING -5832 if !scheduling_info.is_abandoned -5833 && mem::replace(&mut space.for_path(path_id).ping_pending, false) -5834 { -5835 builder.write_frame(frame::Ping, stats); -5836 } -5837 -5838 // IMMEDIATE_ACK -5839 if !scheduling_info.is_abandoned -5840 && mem::replace(&mut space.for_path(path_id).immediate_ack_pending, false) -5841 { -5842 debug_assert_eq!( -5843 space_id, -5844 SpaceId::Data, -5845 "immediate acks must be sent in the data space" -5846 ); -5847 builder.write_frame(frame::ImmediateAck, stats); -5848 } -5849 -5850 // ACK -5851 if !scheduling_info.is_abandoned && scheduling_info.may_send_data { -5852 for path_id in space -5853 .number_spaces -5854 .iter_mut() -5855 .filter(|(_, pns)| pns.pending_acks.can_send()) -5856 .map(|(&path_id, _)| path_id) -5857 .collect::<Vec<_>>() -5858 { -5859 Self::populate_acks( -5860 now, -5861 self.receiving_ecn, -5862 path_id, -5863 space_id, -5864 space, -5865 is_multipath_negotiated, -5866 builder, -5867 stats, -5868 space_has_keys, -5869 ); -5870 } -5871 } -5872 -5873 // ACK_FREQUENCY -5874 if !scheduling_info.is_abandoned -5875 && scheduling_info.may_send_data -5876 && mem::replace(&mut space.pending.ack_frequency, false) -5877 { -5878 let sequence_number = self.ack_frequency.next_sequence_number(); -5879 -5880 // Safe to unwrap because this is always provided when ACK frequency is enabled -5881 let config = self.config.ack_frequency_config.as_ref().unwrap(); -5882 -5883 // Ensure the delay is within bounds to avoid a PROTOCOL_VIOLATION error -5884 let max_ack_delay = self.ack_frequency.candidate_max_ack_delay( -5885 path.rtt.get(), -5886 config, -5887 &self.peer_params, -5888 ); -5889 -5890 let frame = frame::AckFrequency { -5891 sequence: sequence_number, -5892 ack_eliciting_threshold: config.ack_eliciting_threshold, -5893 request_max_ack_delay: max_ack_delay.as_micros().try_into().unwrap_or(VarInt::MAX), -5894 reordering_threshold: config.reordering_threshold, -5895 }; -5896 builder.write_frame(frame, stats); -5897 -5898 self.ack_frequency -5899 .ack_frequency_sent(path_id, builder.packet_number, max_ack_delay); -5900 } -5901 -5902 // PATH_CHALLENGE -5903 if !scheduling_info.is_abandoned -5904 && space_id == SpaceId::Data -5905 && path.pending_on_path_challenge -5906 && !self.state.is_closed() -5907 && builder.frame_space_remaining() > frame::PathChallenge::SIZE_BOUND -5908 // we don't want to send new challenges if we are already closing -5909 { -5910 path.pending_on_path_challenge = false; -5911 -5912 let token = self.rng.random(); -5913 path.record_path_challenge_sent(now, token, path.network_path); -5914 // Generate a new challenge every time we send a new PATH_CHALLENGE -5915 let challenge = frame::PathChallenge(token); -5916 builder.write_frame(challenge, stats); -5917 builder.require_padding(); -5918 let pto = self.ack_frequency.max_ack_delay_for_pto() + path.rtt.pto_base(); -5919 if path.open_status == paths::OpenStatus::Pending { -5920 path.open_status = paths::OpenStatus::Sent; -5921 self.timers.set( -5922 Timer::PerPath(path_id, PathTimer::PathOpenFailed), -5923 now + 3 * pto, -5924 self.qlog.with_time(now), -5925 ); -5926 } -5927 -5928 self.timers.set( -5929 Timer::PerPath(path_id, PathTimer::PathChallengeLost), -5930 now + pto, -5931 self.qlog.with_time(now), -5932 ); +5710 debug_assert!(!self.state.is_drained()); // required for endpoint_events, checked above +5711 self.endpoint_events +5712 .push_back(EndpointEventInner::ResetToken(path_id, remote, reset_token)); +5713 } +5714 } +5715 +5716 /// Switch to a previously unused remote connection ID, if possible +5717 fn update_remote_cid(&mut self, path_id: PathId) { +5718 let Some((reset_token, retired)) = self +5719 .remote_cids +5720 .get_mut(&path_id) +5721 .and_then(|cids| cids.next()) +5722 else { +5723 return; +5724 }; +5725 +5726 // Retire the current remote CID and any CIDs we had to skip. +5727 self.spaces[SpaceId::Data] +5728 .pending +5729 .retire_cids +5730 .extend(retired.map(|seq| (path_id, seq))); +5731 let remote = self.path_data(path_id).network_path.remote; +5732 self.set_reset_token(path_id, remote, reset_token); +5733 } +5734 +5735 /// Sends this reset token to the endpoint +5736 /// +5737 /// The endpoint needs to know the reset tokens issued by the peer, so that if the peer +5738 /// sends a reset token it knows to route it to this connection. See RFC 9000 section +5739 /// 10.3. Stateless Reset. +5740 /// +5741 /// Reset tokens are different for each path, the endpoint identifies paths by peer +5742 /// socket address however, not by path ID. +5743 fn set_reset_token(&mut self, path_id: PathId, remote: SocketAddr, reset_token: ResetToken) { +5744 debug_assert!(!self.state.is_drained()); // required for endpoint events, set_reset_token is never called for drained connections +5745 self.endpoint_events +5746 .push_back(EndpointEventInner::ResetToken(path_id, remote, reset_token)); +5747 +5748 // During the handshake the server sends a reset token in the transport +5749 // parameters. When we are the client and we receive the reset token during the +5750 // handshake we want this to affect our peer transport parameters. +5751 // TODO(flub): Pretty sure this is pointless, the entire params is overwritten +5752 // shortly after this was called. And then the params don't have this anymore. +5753 if path_id == PathId::ZERO { +5754 self.peer_params.stateless_reset_token = Some(reset_token); +5755 } +5756 } +5757 +5758 /// Issue an initial set of connection IDs to the peer upon connection +5759 fn issue_first_cids(&mut self, now: Instant) { +5760 if self +5761 .local_cid_state +5762 .get(&PathId::ZERO) +5763 .expect("PathId::ZERO exists when the connection is created") +5764 .cid_len() +5765 == 0 +5766 { +5767 return; +5768 } +5769 +5770 // Subtract 1 to account for the CID we supplied while handshaking +5771 let mut n = self.peer_params.issue_cids_limit() - 1; +5772 if let ConnectionSide::Server { server_config } = &self.side +5773 && server_config.has_preferred_address() +5774 { +5775 // We also sent a CID in the transport parameters +5776 n -= 1; +5777 } +5778 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events +5779 self.endpoint_events +5780 .push_back(EndpointEventInner::NeedIdentifiers(PathId::ZERO, now, n)); +5781 } +5782 +5783 /// Issues an initial set of CIDs for paths that have not yet had any CIDs issued +5784 /// +5785 /// Later CIDs are issued when CIDs expire or are retired by the peer. +5786 fn issue_first_path_cids(&mut self, now: Instant) { +5787 if let Some(max_path_id) = self.max_path_id() { +5788 let mut path_id = self.max_path_id_with_cids.next(); +5789 while path_id <= max_path_id { +5790 self.endpoint_events +5791 .push_back(EndpointEventInner::NeedIdentifiers( +5792 path_id, +5793 now, +5794 self.peer_params.issue_cids_limit(), +5795 )); +5796 path_id = path_id.next(); +5797 } +5798 self.max_path_id_with_cids = max_path_id; +5799 } +5800 } +5801 +5802 /// Populates a packet with frames +5803 /// +5804 /// This tries to fit as many frames as possible into the packet. +5805 /// +5806 /// *path_exclusive_only* means to only build frames which can only be sent on this +5807 /// *path. This is used in multipath for backup paths while there is still an active +5808 /// *path. +5809 fn populate_packet<'a, 'b>( +5810 &mut self, +5811 now: Instant, +5812 space_id: SpaceId, +5813 path_id: PathId, +5814 scheduling_info: &PathSchedulingInfo, +5815 builder: &mut PacketBuilder<'a, 'b>, +5816 ) { +5817 let is_multipath_negotiated = self.is_multipath_negotiated(); +5818 let space_has_keys = self.crypto_state.has_keys(space_id.encryption_level()); +5819 let is_0rtt = space_id == SpaceId::Data && !space_has_keys; +5820 let stats = &mut self.path_stats.for_path(path_id).frame_tx; +5821 let space = &mut self.spaces[space_id]; +5822 let path = &mut self.paths.get_mut(&path_id).expect("known path").data; +5823 space +5824 .for_path(path_id) +5825 .pending_acks +5826 .maybe_ack_non_eliciting(); +5827 +5828 // HANDSHAKE_DONE +5829 if !is_0rtt +5830 && !scheduling_info.is_abandoned +5831 && scheduling_info.may_send_data +5832 && mem::replace(&mut space.pending.handshake_done, false) +5833 { +5834 builder.write_frame(frame::HandshakeDone, stats); +5835 } +5836 +5837 // PING +5838 if !scheduling_info.is_abandoned +5839 && mem::replace(&mut space.for_path(path_id).ping_pending, false) +5840 { +5841 builder.write_frame(frame::Ping, stats); +5842 } +5843 +5844 // IMMEDIATE_ACK +5845 if !scheduling_info.is_abandoned +5846 && mem::replace(&mut space.for_path(path_id).immediate_ack_pending, false) +5847 { +5848 debug_assert_eq!( +5849 space_id, +5850 SpaceId::Data, +5851 "immediate acks must be sent in the data space" +5852 ); +5853 builder.write_frame(frame::ImmediateAck, stats); +5854 } +5855 +5856 // ACK +5857 if !scheduling_info.is_abandoned && scheduling_info.may_send_data { +5858 for path_id in space +5859 .number_spaces +5860 .iter_mut() +5861 .filter(|(_, pns)| pns.pending_acks.can_send()) +5862 .map(|(&path_id, _)| path_id) +5863 .collect::<Vec<_>>() +5864 { +5865 Self::populate_acks( +5866 now, +5867 self.receiving_ecn, +5868 path_id, +5869 space_id, +5870 space, +5871 is_multipath_negotiated, +5872 builder, +5873 stats, +5874 space_has_keys, +5875 ); +5876 } +5877 } +5878 +5879 // ACK_FREQUENCY +5880 if !scheduling_info.is_abandoned +5881 && scheduling_info.may_send_data +5882 && mem::replace(&mut space.pending.ack_frequency, false) +5883 { +5884 let sequence_number = self.ack_frequency.next_sequence_number(); +5885 +5886 // Safe to unwrap because this is always provided when ACK frequency is enabled +5887 let config = self.config.ack_frequency_config.as_ref().unwrap(); +5888 +5889 // Ensure the delay is within bounds to avoid a PROTOCOL_VIOLATION error +5890 let max_ack_delay = self.ack_frequency.candidate_max_ack_delay( +5891 path.rtt.get(), +5892 config, +5893 &self.peer_params, +5894 ); +5895 +5896 let frame = frame::AckFrequency { +5897 sequence: sequence_number, +5898 ack_eliciting_threshold: config.ack_eliciting_threshold, +5899 request_max_ack_delay: max_ack_delay.as_micros().try_into().unwrap_or(VarInt::MAX), +5900 reordering_threshold: config.reordering_threshold, +5901 }; +5902 builder.write_frame(frame, stats); +5903 +5904 self.ack_frequency +5905 .ack_frequency_sent(path_id, builder.packet_number, max_ack_delay); +5906 } +5907 +5908 // PATH_CHALLENGE +5909 if !scheduling_info.is_abandoned +5910 && space_id == SpaceId::Data +5911 && path.pending_on_path_challenge +5912 && !self.state.is_closed() +5913 && builder.frame_space_remaining() > frame::PathChallenge::SIZE_BOUND +5914 // we don't want to send new challenges if we are already closing +5915 { +5916 path.pending_on_path_challenge = false; +5917 +5918 let token = self.rng.random(); +5919 path.record_path_challenge_sent(now, token, path.network_path); +5920 // Generate a new challenge every time we send a new PATH_CHALLENGE +5921 let challenge = frame::PathChallenge(token); +5922 builder.write_frame(challenge, stats); +5923 builder.require_padding(); +5924 let pto = self.ack_frequency.max_ack_delay_for_pto() + path.rtt.pto_base(); +5925 if path.open_status == paths::OpenStatus::Pending { +5926 path.open_status = paths::OpenStatus::Sent; +5927 self.timers.set( +5928 Timer::PerPath(path_id, PathTimer::PathOpenFailed), +5929 now + 3 * pto, +5930 self.qlog.with_time(now), +5931 ); +5932 } 5933 -5934 if is_multipath_negotiated && !path.validated && path.pending_on_path_challenge { -5935 // queue informing the path status along with the challenge -5936 space.pending.path_status.insert(path_id); -5937 } -5938 -5939 // Always include an OBSERVED_ADDR frame with a PATH_CHALLENGE, regardless -5940 // of whether one has already been sent on this path. -5941 if space_id == SpaceId::Data -5942 && self -5943 .config -5944 .address_discovery_role -5945 .should_report(&self.peer_params.address_discovery_role) -5946 { -5947 let frame = frame::ObservedAddr::new( -5948 path.network_path.remote, -5949 self.next_observed_addr_seq_no, -5950 ); -5951 if builder.frame_space_remaining() > frame.size() { -5952 builder.write_frame(frame, stats); -5953 -5954 self.next_observed_addr_seq_no = -5955 self.next_observed_addr_seq_no.saturating_add(1u8); -5956 path.observed_addr_sent = true; -5957 -5958 space.pending.observed_addr = false; -5959 } -5960 } -5961 } -5962 -5963 // PATH_RESPONSE -5964 if !scheduling_info.is_abandoned -5965 && space_id == SpaceId::Data -5966 && builder.frame_space_remaining() > frame::PathResponse::SIZE_BOUND -5967 && let Some(token) = path.path_responses.pop_on_path(path.network_path) -5968 { -5969 let response = frame::PathResponse(token); -5970 builder.write_frame(response, stats); -5971 builder.require_padding(); -5972 -5973 // NOTE: this is technically not required but might be useful to ride the -5974 // request/response nature of path challenges to refresh an observation -5975 // Since PATH_RESPONSE is a probing frame, this is allowed by the spec. -5976 if space_id == SpaceId::Data -5977 && self -5978 .config -5979 .address_discovery_role -5980 .should_report(&self.peer_params.address_discovery_role) -5981 { -5982 let frame = frame::ObservedAddr::new( -5983 path.network_path.remote, -5984 self.next_observed_addr_seq_no, -5985 ); -5986 if builder.frame_space_remaining() > frame.size() { -5987 builder.write_frame(frame, stats); -5988 -5989 self.next_observed_addr_seq_no = -5990 self.next_observed_addr_seq_no.saturating_add(1u8); -5991 path.observed_addr_sent = true; -5992 -5993 space.pending.observed_addr = false; -5994 } -5995 } -5996 } -5997 -5998 // REACH_OUT -5999 if !scheduling_info.is_abandoned -6000 && scheduling_info.may_send_data -6001 && let Some((round, addresses)) = space.pending.reach_out.as_mut() -6002 { -6003 while let Some(local_addr) = addresses.iter().next().copied() { -6004 let local_addr = addresses.take(&local_addr).expect("found from iter"); -6005 let reach_out = frame::ReachOut::new(*round, local_addr); -6006 if builder.frame_space_remaining() > reach_out.size() { -6007 builder.write_frame(reach_out, stats); -6008 } else { -6009 addresses.insert(local_addr); -6010 break; -6011 } -6012 } -6013 if addresses.is_empty() { -6014 space.pending.reach_out = None; -6015 } -6016 } -6017 -6018 // PATH_ABANDON -6019 if space_id == SpaceId::Data -6020 && scheduling_info.is_abandoned -6021 && scheduling_info.may_self_abandon -6022 && frame::PathAbandon::SIZE_BOUND <= builder.frame_space_remaining() -6023 && let Some(error_code) = space.pending.path_abandon.remove(&path_id) -6024 { -6025 let frame = frame::PathAbandon { -6026 path_id, -6027 error_code, -6028 }; -6029 builder.write_frame(frame, stats); -6030 -6031 // Consider remotely issued CIDs as retired now that we have sent this frame at -6032 // least once. -6033 self.remote_cids.remove(&path_id); -6034 } -6035 while space_id == SpaceId::Data -6036 && scheduling_info.may_send_data -6037 && frame::PathAbandon::SIZE_BOUND <= builder.frame_space_remaining() -6038 && let Some((abandoned_path_id, error_code)) = space.pending.path_abandon.pop_first() -6039 { -6040 let frame = frame::PathAbandon { -6041 path_id: abandoned_path_id, -6042 error_code, -6043 }; -6044 builder.write_frame(frame, stats); -6045 -6046 // Consider remotely issued CIDs as retired now that we have sent this frame at -6047 // least once. -6048 self.remote_cids.remove(&abandoned_path_id); -6049 } -6050 -6051 // OBSERVED_ADDR -6052 if !scheduling_info.is_abandoned -6053 && scheduling_info.may_send_data -6054 && space_id == SpaceId::Data -6055 && self -6056 .config -6057 .address_discovery_role -6058 .should_report(&self.peer_params.address_discovery_role) -6059 && (!path.observed_addr_sent || space.pending.observed_addr) -6060 { -6061 let frame = -6062 frame::ObservedAddr::new(path.network_path.remote, self.next_observed_addr_seq_no); -6063 if builder.frame_space_remaining() > frame.size() { -6064 builder.write_frame(frame, stats); -6065 -6066 self.next_observed_addr_seq_no = self.next_observed_addr_seq_no.saturating_add(1u8); -6067 path.observed_addr_sent = true; -6068 -6069 space.pending.observed_addr = false; -6070 } -6071 } -6072 -6073 // CRYPTO -6074 while !is_0rtt -6075 && !scheduling_info.is_abandoned -6076 && scheduling_info.may_send_data -6077 && builder.frame_space_remaining() > frame::Crypto::SIZE_BOUND -6078 { -6079 let Some(mut frame) = space.pending.crypto.pop_front() else { -6080 break; -6081 }; -6082 -6083 // Calculate the maximum amount of crypto data we can store in the buffer. -6084 // Since the offset is known, we can reserve the exact size required to encode it. -6085 // For length we reserve 2bytes which allows to encode up to 2^14, -6086 // which is more than what fits into normally sized QUIC frames. -6087 let max_crypto_data_size = builder.frame_space_remaining() -6088 - 1 // Frame Type -6089 - VarInt::size(unsafe { VarInt::from_u64_unchecked(frame.offset) }) -6090 - 2; // Maximum encoded length for frame size, given we send less than 2^14 bytes -6091 -6092 let len = frame -6093 .data -6094 .len() -6095 .min(2usize.pow(14) - 1) -6096 .min(max_crypto_data_size); +5934 self.timers.set( +5935 Timer::PerPath(path_id, PathTimer::PathChallengeLost), +5936 now + pto, +5937 self.qlog.with_time(now), +5938 ); +5939 +5940 if is_multipath_negotiated && !path.validated && path.pending_on_path_challenge { +5941 // queue informing the path status along with the challenge +5942 space.pending.path_status.insert(path_id); +5943 } +5944 +5945 // Always include an OBSERVED_ADDR frame with a PATH_CHALLENGE, regardless +5946 // of whether one has already been sent on this path. +5947 if space_id == SpaceId::Data +5948 && self +5949 .config +5950 .address_discovery_role +5951 .should_report(&self.peer_params.address_discovery_role) +5952 { +5953 let frame = frame::ObservedAddr::new( +5954 path.network_path.remote, +5955 self.next_observed_addr_seq_no, +5956 ); +5957 if builder.frame_space_remaining() > frame.size() { +5958 builder.write_frame(frame, stats); +5959 +5960 self.next_observed_addr_seq_no = +5961 self.next_observed_addr_seq_no.saturating_add(1u8); +5962 path.observed_addr_sent = true; +5963 +5964 space.pending.observed_addr = false; +5965 } +5966 } +5967 } +5968 +5969 // PATH_RESPONSE +5970 if !scheduling_info.is_abandoned +5971 && space_id == SpaceId::Data +5972 && builder.frame_space_remaining() > frame::PathResponse::SIZE_BOUND +5973 && let Some(token) = path.path_responses.pop_on_path(path.network_path) +5974 { +5975 let response = frame::PathResponse(token); +5976 builder.write_frame(response, stats); +5977 builder.require_padding(); +5978 +5979 // NOTE: this is technically not required but might be useful to ride the +5980 // request/response nature of path challenges to refresh an observation +5981 // Since PATH_RESPONSE is a probing frame, this is allowed by the spec. +5982 if space_id == SpaceId::Data +5983 && self +5984 .config +5985 .address_discovery_role +5986 .should_report(&self.peer_params.address_discovery_role) +5987 { +5988 let frame = frame::ObservedAddr::new( +5989 path.network_path.remote, +5990 self.next_observed_addr_seq_no, +5991 ); +5992 if builder.frame_space_remaining() > frame.size() { +5993 builder.write_frame(frame, stats); +5994 +5995 self.next_observed_addr_seq_no = +5996 self.next_observed_addr_seq_no.saturating_add(1u8); +5997 path.observed_addr_sent = true; +5998 +5999 space.pending.observed_addr = false; +6000 } +6001 } +6002 } +6003 +6004 // REACH_OUT +6005 if !scheduling_info.is_abandoned +6006 && scheduling_info.may_send_data +6007 && let Some((round, addresses)) = space.pending.reach_out.as_mut() +6008 { +6009 while let Some(local_addr) = addresses.iter().next().copied() { +6010 let local_addr = addresses.take(&local_addr).expect("found from iter"); +6011 let reach_out = frame::ReachOut::new(*round, local_addr); +6012 if builder.frame_space_remaining() > reach_out.size() { +6013 builder.write_frame(reach_out, stats); +6014 } else { +6015 addresses.insert(local_addr); +6016 break; +6017 } +6018 } +6019 if addresses.is_empty() { +6020 space.pending.reach_out = None; +6021 } +6022 } +6023 +6024 // PATH_ABANDON +6025 if space_id == SpaceId::Data +6026 && scheduling_info.is_abandoned +6027 && scheduling_info.may_self_abandon +6028 && frame::PathAbandon::SIZE_BOUND <= builder.frame_space_remaining() +6029 && let Some(error_code) = space.pending.path_abandon.remove(&path_id) +6030 { +6031 let frame = frame::PathAbandon { +6032 path_id, +6033 error_code, +6034 }; +6035 builder.write_frame(frame, stats); +6036 +6037 // Consider remotely issued CIDs as retired now that we have sent this frame at +6038 // least once. +6039 self.remote_cids.remove(&path_id); +6040 } +6041 while space_id == SpaceId::Data +6042 && scheduling_info.may_send_data +6043 && frame::PathAbandon::SIZE_BOUND <= builder.frame_space_remaining() +6044 && let Some((abandoned_path_id, error_code)) = space.pending.path_abandon.pop_first() +6045 { +6046 let frame = frame::PathAbandon { +6047 path_id: abandoned_path_id, +6048 error_code, +6049 }; +6050 builder.write_frame(frame, stats); +6051 +6052 // Consider remotely issued CIDs as retired now that we have sent this frame at +6053 // least once. +6054 self.remote_cids.remove(&abandoned_path_id); +6055 } +6056 +6057 // OBSERVED_ADDR +6058 if !scheduling_info.is_abandoned +6059 && scheduling_info.may_send_data +6060 && space_id == SpaceId::Data +6061 && self +6062 .config +6063 .address_discovery_role +6064 .should_report(&self.peer_params.address_discovery_role) +6065 && (!path.observed_addr_sent || space.pending.observed_addr) +6066 { +6067 let frame = +6068 frame::ObservedAddr::new(path.network_path.remote, self.next_observed_addr_seq_no); +6069 if builder.frame_space_remaining() > frame.size() { +6070 builder.write_frame(frame, stats); +6071 +6072 self.next_observed_addr_seq_no = self.next_observed_addr_seq_no.saturating_add(1u8); +6073 path.observed_addr_sent = true; +6074 +6075 space.pending.observed_addr = false; +6076 } +6077 } +6078 +6079 // CRYPTO +6080 while !is_0rtt +6081 && !scheduling_info.is_abandoned +6082 && scheduling_info.may_send_data +6083 && builder.frame_space_remaining() > frame::Crypto::SIZE_BOUND +6084 { +6085 let Some(mut frame) = space.pending.crypto.pop_front() else { +6086 break; +6087 }; +6088 +6089 // Calculate the maximum amount of crypto data we can store in the buffer. +6090 // Since the offset is known, we can reserve the exact size required to encode it. +6091 // For length we reserve 2bytes which allows to encode up to 2^14, +6092 // which is more than what fits into normally sized QUIC frames. +6093 let max_crypto_data_size = builder.frame_space_remaining() +6094 - 1 // Frame Type +6095 - VarInt::size(unsafe { VarInt::from_u64_unchecked(frame.offset) }) +6096 - 2; // Maximum encoded length for frame size, given we send less than 2^14 bytes 6097 -6098 let data = frame.data.split_to(len); -6099 let offset = frame.offset; -6100 let truncated = frame::Crypto { offset, data }; -6101 builder.write_frame(truncated, stats); -6102 -6103 if !frame.data.is_empty() { -6104 frame.offset += len as u64; -6105 space.pending.crypto.push_front(frame); -6106 } -6107 } +6098 let len = frame +6099 .data +6100 .len() +6101 .min(2usize.pow(14) - 1) +6102 .min(max_crypto_data_size); +6103 +6104 let data = frame.data.split_to(len); +6105 let offset = frame.offset; +6106 let truncated = frame::Crypto { offset, data }; +6107 builder.write_frame(truncated, stats); 6108 -6109 // PATH_STATUS_AVAILABLE & PATH_STATUS_BACKUP -6110 while space_id == SpaceId::Data -6111 && !scheduling_info.is_abandoned -6112 && scheduling_info.may_send_data -6113 && frame::PathStatusAvailable::SIZE_BOUND <= builder.frame_space_remaining() -6114 { -6115 let Some(path_id) = space.pending.path_status.pop_first() else { -6116 break; -6117 }; -6118 let Some(path) = self.paths.get(&path_id).map(|path_state| &path_state.data) else { -6119 trace!(%path_id, "discarding queued path status for unknown path"); -6120 continue; -6121 }; -6122 -6123 let seq = path.status.seq(); -6124 match path.local_status() { -6125 PathStatus::Available => { -6126 let frame = frame::PathStatusAvailable { -6127 path_id, -6128 status_seq_no: seq, -6129 }; -6130 builder.write_frame(frame, stats); -6131 } -6132 PathStatus::Backup => { -6133 let frame = frame::PathStatusBackup { -6134 path_id, -6135 status_seq_no: seq, -6136 }; -6137 builder.write_frame(frame, stats); -6138 } -6139 } -6140 } -6141 -6142 // MAX_PATH_ID -6143 if space_id == SpaceId::Data -6144 && !scheduling_info.is_abandoned -6145 && scheduling_info.may_send_data -6146 && space.pending.max_path_id -6147 && frame::MaxPathId::SIZE_BOUND <= builder.frame_space_remaining() -6148 { -6149 let frame = frame::MaxPathId(self.local_max_path_id); -6150 builder.write_frame(frame, stats); -6151 space.pending.max_path_id = false; -6152 } -6153 -6154 // PATHS_BLOCKED -6155 if space_id == SpaceId::Data -6156 && !scheduling_info.is_abandoned -6157 && scheduling_info.may_send_data -6158 && space.pending.paths_blocked -6159 && frame::PathsBlocked::SIZE_BOUND <= builder.frame_space_remaining() -6160 { -6161 let frame = frame::PathsBlocked(self.remote_max_path_id); -6162 builder.write_frame(frame, stats); -6163 space.pending.paths_blocked = false; -6164 } -6165 -6166 // PATH_CIDS_BLOCKED -6167 while space_id == SpaceId::Data -6168 && !scheduling_info.is_abandoned -6169 && scheduling_info.may_send_data -6170 && frame::PathCidsBlocked::SIZE_BOUND <= builder.frame_space_remaining() -6171 { -6172 let Some(path_id) = space.pending.path_cids_blocked.pop_first() else { -6173 break; -6174 }; -6175 let next_seq = match self.remote_cids.get(&path_id) { -6176 Some(cid_queue) => VarInt(cid_queue.active_seq() + 1), -6177 None => VarInt(0), -6178 }; -6179 let frame = frame::PathCidsBlocked { path_id, next_seq }; -6180 builder.write_frame(frame, stats); -6181 } -6182 -6183 // RESET_STREAM, STOP_SENDING, MAX_DATA, MAX_STREAM_DATA, MAX_STREAMS -6184 if space_id == SpaceId::Data -6185 && !scheduling_info.is_abandoned -6186 && scheduling_info.may_send_data -6187 { -6188 self.streams -6189 .write_control_frames(builder, &mut space.pending, stats); -6190 } -6191 -6192 // NEW_CONNECTION_ID -6193 let cid_len = self -6194 .local_cid_state -6195 .values() -6196 .map(|cid_state| cid_state.cid_len()) -6197 .max() -6198 .expect("some local CID state must exist"); -6199 let new_cid_size_bound = -6200 frame::NewConnectionId::size_bound(is_multipath_negotiated, cid_len); -6201 while !scheduling_info.is_abandoned -6202 && scheduling_info.may_send_data -6203 && builder.frame_space_remaining() > new_cid_size_bound -6204 { -6205 let Some(issued) = space.pending.new_cids.pop() else { -6206 break; -6207 }; -6208 let retire_prior_to = self -6209 .local_cid_state -6210 .get(&issued.path_id) -6211 .map(|cid_state| cid_state.retire_prior_to()) -6212 .unwrap_or_else(|| panic!("missing local CID state for path={}", issued.path_id)); -6213 -6214 let cid_path_id = match is_multipath_negotiated { -6215 true => Some(issued.path_id), -6216 false => { -6217 debug_assert_eq!(issued.path_id, PathId::ZERO); -6218 None -6219 } -6220 }; -6221 let frame = frame::NewConnectionId { -6222 path_id: cid_path_id, -6223 sequence: issued.sequence, -6224 retire_prior_to, -6225 id: issued.id, -6226 reset_token: issued.reset_token, -6227 }; -6228 builder.write_frame(frame, stats); -6229 } -6230 -6231 // RETIRE_CONNECTION_ID -6232 let retire_cid_bound = frame::RetireConnectionId::size_bound(is_multipath_negotiated); -6233 while !scheduling_info.is_abandoned -6234 && scheduling_info.may_send_data -6235 && builder.frame_space_remaining() > retire_cid_bound -6236 { -6237 let (path_id, sequence) = match space.pending.retire_cids.pop() { -6238 Some((PathId::ZERO, seq)) if !is_multipath_negotiated => (None, seq), -6239 Some((path_id, seq)) => (Some(path_id), seq), -6240 None => break, -6241 }; -6242 let frame = frame::RetireConnectionId { path_id, sequence }; -6243 builder.write_frame(frame, stats); -6244 } -6245 -6246 // DATAGRAM -6247 let mut sent_datagrams = false; -6248 while !scheduling_info.is_abandoned -6249 && scheduling_info.may_send_data -6250 && builder.frame_space_remaining() > Datagram::SIZE_BOUND -6251 && space_id == SpaceId::Data -6252 { -6253 match self.datagrams.write(builder, stats) { -6254 true => { -6255 sent_datagrams = true; -6256 } -6257 false => break, -6258 } -6259 } -6260 if self.datagrams.send_blocked && sent_datagrams { -6261 self.events.push_back(Event::DatagramsUnblocked); -6262 self.datagrams.send_blocked = false; -6263 } -6264 -6265 let path = &mut self.paths.get_mut(&path_id).expect("known path").data; -6266 -6267 // NEW_TOKEN -6268 if !scheduling_info.is_abandoned && scheduling_info.may_send_data { -6269 while let Some(network_path) = space.pending.new_tokens.pop() { -6270 debug_assert_eq!(space_id, SpaceId::Data); -6271 let ConnectionSide::Server { server_config } = &self.side else { -6272 panic!("NEW_TOKEN frames should not be enqueued by clients"); -6273 }; -6274 -6275 if !network_path.is_probably_same_path(&path.network_path) { -6276 // NEW_TOKEN frames contain tokens bound to a client's IP address, and are only -6277 // useful if used from the same IP address. Thus, we abandon enqueued NEW_TOKEN -6278 // frames upon an path change. Instead, when the new path becomes validated, -6279 // NEW_TOKEN frames may be enqueued for the new path instead. -6280 continue; -6281 } -6282 -6283 let token = Token::new( -6284 TokenPayload::Validation { -6285 ip: network_path.remote.ip(), -6286 issued: server_config.time_source.now(), -6287 }, -6288 &mut self.rng, -6289 ); -6290 let new_token = NewToken { -6291 token: token.encode(&*server_config.token_key).into(), -6292 }; -6293 -6294 if builder.frame_space_remaining() < new_token.size() { -6295 space.pending.new_tokens.push(network_path); -6296 break; -6297 } -6298 -6299 builder.write_frame(new_token, stats); -6300 builder.retransmits_mut().new_tokens.push(network_path); -6301 } -6302 } -6303 -6304 // ADD_ADDRESS -6305 while space_id == SpaceId::Data -6306 && !scheduling_info.is_abandoned -6307 && scheduling_info.may_send_data -6308 && frame::AddAddress::SIZE_BOUND <= builder.frame_space_remaining() -6309 { -6310 if let Some(added_address) = space.pending.add_address.pop_last() { -6311 builder.write_frame(added_address, stats); -6312 } else { -6313 break; -6314 } -6315 } -6316 -6317 // REMOVE_ADDRESS -6318 while space_id == SpaceId::Data -6319 && !scheduling_info.is_abandoned -6320 && scheduling_info.may_send_data -6321 && frame::RemoveAddress::SIZE_BOUND <= builder.frame_space_remaining() -6322 { -6323 if let Some(removed_address) = space.pending.remove_address.pop_last() { -6324 builder.write_frame(removed_address, stats); -6325 } else { -6326 break; -6327 } -6328 } -6329 -6330 // STREAM -6331 if !scheduling_info.is_abandoned -6332 && scheduling_info.may_send_data -6333 && space_id == SpaceId::Data -6334 { -6335 self.streams -6336 .write_stream_frames(builder, self.config.send_fairness, stats); -6337 } -6338 } -6339 -6340 /// Write pending ACKs into a buffer -6341 fn populate_acks<'a, 'b>( -6342 now: Instant, -6343 receiving_ecn: bool, -6344 path_id: PathId, -6345 space_id: SpaceId, -6346 space: &mut PacketSpace, -6347 is_multipath_negotiated: bool, -6348 builder: &mut PacketBuilder<'a, 'b>, -6349 stats: &mut FrameStats, -6350 space_has_keys: bool, -6351 ) { -6352 // 0-RTT packets must never carry acks (which would have to be of handshake packets) -6353 debug_assert!(space_has_keys, "tried to send ACK in 0-RTT"); -6354 -6355 debug_assert!( -6356 is_multipath_negotiated || path_id == PathId::ZERO, -6357 "Only PathId::ZERO allowed without multipath (have {path_id:?})" -6358 ); -6359 if is_multipath_negotiated { -6360 debug_assert!( -6361 space_id == SpaceId::Data || path_id == PathId::ZERO, -6362 "path acks must be sent in 1RTT space (have {space_id:?})" -6363 ); -6364 } -6365 -6366 let pns = space.for_path(path_id); -6367 let ranges = pns.pending_acks.ranges(); -6368 debug_assert!(!ranges.is_empty(), "can not send empty ACK range"); -6369 let ecn = if receiving_ecn { -6370 Some(&pns.ecn_counters) -6371 } else { -6372 None -6373 }; -6374 -6375 let delay_micros = pns.pending_acks.ack_delay(now).as_micros() as u64; -6376 // TODO: This should come from `TransportConfig` if that gets configurable. -6377 let ack_delay_exp = TransportParameters::default().ack_delay_exponent; -6378 let delay = delay_micros >> ack_delay_exp.into_inner(); -6379 -6380 if is_multipath_negotiated && space_id == SpaceId::Data { -6381 if !ranges.is_empty() { -6382 let frame = frame::PathAck::encoder(path_id, delay, ranges, ecn); -6383 builder.write_frame(frame, stats); -6384 } -6385 } else { -6386 builder.write_frame(frame::Ack::encoder(delay, ranges, ecn), stats); -6387 } -6388 } -6389 -6390 fn close_common(&mut self) { -6391 trace!("connection closed"); -6392 self.timers.reset(); -6393 } -6394 -6395 fn set_close_timer(&mut self, now: Instant) { -6396 // QUIC-MULTIPATH § 2.6 Connection Closure: draining for 3*PTO using the max PTO of -6397 // all paths. -6398 let pto_max = self.max_pto_for_space(self.highest_space); -6399 self.timers.set( -6400 Timer::Conn(ConnTimer::Close), -6401 now + 3 * pto_max, -6402 self.qlog.with_time(now), -6403 ); -6404 } -6405 -6406 /// Handle transport parameters received from the peer -6407 /// -6408 /// *remote_cid* and *local_cid* are the source and destination CIDs respectively of the -6409 /// *packet into which the transport parameters arrived. -6410 fn handle_peer_params( -6411 &mut self, -6412 params: TransportParameters, -6413 local_cid: ConnectionId, -6414 remote_cid: ConnectionId, -6415 now: Instant, -6416 ) -> Result<(), TransportError> { -6417 if Some(self.original_remote_cid) != params.initial_src_cid -6418 || (self.side.is_client() -6419 && (Some(self.initial_dst_cid) != params.original_dst_cid -6420 || self.retry_src_cid != params.retry_src_cid)) -6421 { -6422 return Err(TransportError::TRANSPORT_PARAMETER_ERROR( -6423 "CID authentication failure", -6424 )); -6425 } -6426 if params.initial_max_path_id.is_some() && (local_cid.is_empty() || remote_cid.is_empty()) { -6427 return Err(TransportError::PROTOCOL_VIOLATION( -6428 "multipath must not use zero-length CIDs", -6429 )); -6430 } -6431 -6432 self.set_peer_params(params); -6433 self.qlog.emit_peer_transport_params_received(self, now); -6434 -6435 Ok(()) -6436 } +6109 if !frame.data.is_empty() { +6110 frame.offset += len as u64; +6111 space.pending.crypto.push_front(frame); +6112 } +6113 } +6114 +6115 // PATH_STATUS_AVAILABLE & PATH_STATUS_BACKUP +6116 while space_id == SpaceId::Data +6117 && !scheduling_info.is_abandoned +6118 && scheduling_info.may_send_data +6119 && frame::PathStatusAvailable::SIZE_BOUND <= builder.frame_space_remaining() +6120 { +6121 let Some(path_id) = space.pending.path_status.pop_first() else { +6122 break; +6123 }; +6124 let Some(path) = self.paths.get(&path_id).map(|path_state| &path_state.data) else { +6125 trace!(%path_id, "discarding queued path status for unknown path"); +6126 continue; +6127 }; +6128 +6129 let seq = path.status.seq(); +6130 match path.local_status() { +6131 PathStatus::Available => { +6132 let frame = frame::PathStatusAvailable { +6133 path_id, +6134 status_seq_no: seq, +6135 }; +6136 builder.write_frame(frame, stats); +6137 } +6138 PathStatus::Backup => { +6139 let frame = frame::PathStatusBackup { +6140 path_id, +6141 status_seq_no: seq, +6142 }; +6143 builder.write_frame(frame, stats); +6144 } +6145 } +6146 } +6147 +6148 // MAX_PATH_ID +6149 if space_id == SpaceId::Data +6150 && !scheduling_info.is_abandoned +6151 && scheduling_info.may_send_data +6152 && space.pending.max_path_id +6153 && frame::MaxPathId::SIZE_BOUND <= builder.frame_space_remaining() +6154 { +6155 let frame = frame::MaxPathId(self.local_max_path_id); +6156 builder.write_frame(frame, stats); +6157 space.pending.max_path_id = false; +6158 } +6159 +6160 // PATHS_BLOCKED +6161 if space_id == SpaceId::Data +6162 && !scheduling_info.is_abandoned +6163 && scheduling_info.may_send_data +6164 && space.pending.paths_blocked +6165 && frame::PathsBlocked::SIZE_BOUND <= builder.frame_space_remaining() +6166 { +6167 let frame = frame::PathsBlocked(self.remote_max_path_id); +6168 builder.write_frame(frame, stats); +6169 space.pending.paths_blocked = false; +6170 } +6171 +6172 // PATH_CIDS_BLOCKED +6173 while space_id == SpaceId::Data +6174 && !scheduling_info.is_abandoned +6175 && scheduling_info.may_send_data +6176 && frame::PathCidsBlocked::SIZE_BOUND <= builder.frame_space_remaining() +6177 { +6178 let Some(path_id) = space.pending.path_cids_blocked.pop_first() else { +6179 break; +6180 }; +6181 let next_seq = match self.remote_cids.get(&path_id) { +6182 Some(cid_queue) => VarInt(cid_queue.active_seq() + 1), +6183 None => VarInt(0), +6184 }; +6185 let frame = frame::PathCidsBlocked { path_id, next_seq }; +6186 builder.write_frame(frame, stats); +6187 } +6188 +6189 // RESET_STREAM, STOP_SENDING, MAX_DATA, MAX_STREAM_DATA, MAX_STREAMS +6190 if space_id == SpaceId::Data +6191 && !scheduling_info.is_abandoned +6192 && scheduling_info.may_send_data +6193 { +6194 self.streams +6195 .write_control_frames(builder, &mut space.pending, stats); +6196 } +6197 +6198 // NEW_CONNECTION_ID +6199 let cid_len = self +6200 .local_cid_state +6201 .values() +6202 .map(|cid_state| cid_state.cid_len()) +6203 .max() +6204 .expect("some local CID state must exist"); +6205 let new_cid_size_bound = +6206 frame::NewConnectionId::size_bound(is_multipath_negotiated, cid_len); +6207 while !scheduling_info.is_abandoned +6208 && scheduling_info.may_send_data +6209 && builder.frame_space_remaining() > new_cid_size_bound +6210 { +6211 let Some(issued) = space.pending.new_cids.pop() else { +6212 break; +6213 }; +6214 let retire_prior_to = self +6215 .local_cid_state +6216 .get(&issued.path_id) +6217 .map(|cid_state| cid_state.retire_prior_to()) +6218 .unwrap_or_else(|| panic!("missing local CID state for path={}", issued.path_id)); +6219 +6220 let cid_path_id = match is_multipath_negotiated { +6221 true => Some(issued.path_id), +6222 false => { +6223 debug_assert_eq!(issued.path_id, PathId::ZERO); +6224 None +6225 } +6226 }; +6227 let frame = frame::NewConnectionId { +6228 path_id: cid_path_id, +6229 sequence: issued.sequence, +6230 retire_prior_to, +6231 id: issued.id, +6232 reset_token: issued.reset_token, +6233 }; +6234 builder.write_frame(frame, stats); +6235 } +6236 +6237 // RETIRE_CONNECTION_ID +6238 let retire_cid_bound = frame::RetireConnectionId::size_bound(is_multipath_negotiated); +6239 while !scheduling_info.is_abandoned +6240 && scheduling_info.may_send_data +6241 && builder.frame_space_remaining() > retire_cid_bound +6242 { +6243 let (path_id, sequence) = match space.pending.retire_cids.pop() { +6244 Some((PathId::ZERO, seq)) if !is_multipath_negotiated => (None, seq), +6245 Some((path_id, seq)) => (Some(path_id), seq), +6246 None => break, +6247 }; +6248 let frame = frame::RetireConnectionId { path_id, sequence }; +6249 builder.write_frame(frame, stats); +6250 } +6251 +6252 // DATAGRAM +6253 let mut sent_datagrams = false; +6254 while !scheduling_info.is_abandoned +6255 && scheduling_info.may_send_data +6256 && builder.frame_space_remaining() > Datagram::SIZE_BOUND +6257 && space_id == SpaceId::Data +6258 { +6259 match self.datagrams.write(builder, stats) { +6260 true => { +6261 sent_datagrams = true; +6262 } +6263 false => break, +6264 } +6265 } +6266 if self.datagrams.send_blocked && sent_datagrams { +6267 self.events.push_back(Event::DatagramsUnblocked); +6268 self.datagrams.send_blocked = false; +6269 } +6270 +6271 let path = &mut self.paths.get_mut(&path_id).expect("known path").data; +6272 +6273 // NEW_TOKEN +6274 if !scheduling_info.is_abandoned && scheduling_info.may_send_data { +6275 while let Some(network_path) = space.pending.new_tokens.pop() { +6276 debug_assert_eq!(space_id, SpaceId::Data); +6277 let ConnectionSide::Server { server_config } = &self.side else { +6278 panic!("NEW_TOKEN frames should not be enqueued by clients"); +6279 }; +6280 +6281 if !network_path.is_probably_same_path(&path.network_path) { +6282 // NEW_TOKEN frames contain tokens bound to a client's IP address, and are only +6283 // useful if used from the same IP address. Thus, we abandon enqueued NEW_TOKEN +6284 // frames upon an path change. Instead, when the new path becomes validated, +6285 // NEW_TOKEN frames may be enqueued for the new path instead. +6286 continue; +6287 } +6288 +6289 let token = Token::new( +6290 TokenPayload::Validation { +6291 ip: network_path.remote.ip(), +6292 issued: server_config.time_source.now(), +6293 }, +6294 &mut self.rng, +6295 ); +6296 let new_token = NewToken { +6297 token: token.encode(&*server_config.token_key).into(), +6298 }; +6299 +6300 if builder.frame_space_remaining() < new_token.size() { +6301 space.pending.new_tokens.push(network_path); +6302 break; +6303 } +6304 +6305 builder.write_frame(new_token, stats); +6306 builder.retransmits_mut().new_tokens.push(network_path); +6307 } +6308 } +6309 +6310 // ADD_ADDRESS +6311 while space_id == SpaceId::Data +6312 && !scheduling_info.is_abandoned +6313 && scheduling_info.may_send_data +6314 && frame::AddAddress::SIZE_BOUND <= builder.frame_space_remaining() +6315 { +6316 if let Some(added_address) = space.pending.add_address.pop_last() { +6317 builder.write_frame(added_address, stats); +6318 } else { +6319 break; +6320 } +6321 } +6322 +6323 // REMOVE_ADDRESS +6324 while space_id == SpaceId::Data +6325 && !scheduling_info.is_abandoned +6326 && scheduling_info.may_send_data +6327 && frame::RemoveAddress::SIZE_BOUND <= builder.frame_space_remaining() +6328 { +6329 if let Some(removed_address) = space.pending.remove_address.pop_last() { +6330 builder.write_frame(removed_address, stats); +6331 } else { +6332 break; +6333 } +6334 } +6335 +6336 // STREAM +6337 if !scheduling_info.is_abandoned +6338 && scheduling_info.may_send_data +6339 && space_id == SpaceId::Data +6340 { +6341 self.streams +6342 .write_stream_frames(builder, self.config.send_fairness, stats); +6343 } +6344 } +6345 +6346 /// Write pending ACKs into a buffer +6347 fn populate_acks<'a, 'b>( +6348 now: Instant, +6349 receiving_ecn: bool, +6350 path_id: PathId, +6351 space_id: SpaceId, +6352 space: &mut PacketSpace, +6353 is_multipath_negotiated: bool, +6354 builder: &mut PacketBuilder<'a, 'b>, +6355 stats: &mut FrameStats, +6356 space_has_keys: bool, +6357 ) { +6358 // 0-RTT packets must never carry acks (which would have to be of handshake packets) +6359 debug_assert!(space_has_keys, "tried to send ACK in 0-RTT"); +6360 +6361 debug_assert!( +6362 is_multipath_negotiated || path_id == PathId::ZERO, +6363 "Only PathId::ZERO allowed without multipath (have {path_id:?})" +6364 ); +6365 if is_multipath_negotiated { +6366 debug_assert!( +6367 space_id == SpaceId::Data || path_id == PathId::ZERO, +6368 "path acks must be sent in 1RTT space (have {space_id:?})" +6369 ); +6370 } +6371 +6372 let pns = space.for_path(path_id); +6373 let ranges = pns.pending_acks.ranges(); +6374 debug_assert!(!ranges.is_empty(), "can not send empty ACK range"); +6375 let ecn = if receiving_ecn { +6376 Some(&pns.ecn_counters) +6377 } else { +6378 None +6379 }; +6380 +6381 let delay_micros = pns.pending_acks.ack_delay(now).as_micros() as u64; +6382 // TODO: This should come from `TransportConfig` if that gets configurable. +6383 let ack_delay_exp = TransportParameters::default().ack_delay_exponent; +6384 let delay = delay_micros >> ack_delay_exp.into_inner(); +6385 +6386 if is_multipath_negotiated && space_id == SpaceId::Data { +6387 if !ranges.is_empty() { +6388 let frame = frame::PathAck::encoder(path_id, delay, ranges, ecn); +6389 builder.write_frame(frame, stats); +6390 } +6391 } else { +6392 builder.write_frame(frame::Ack::encoder(delay, ranges, ecn), stats); +6393 } +6394 } +6395 +6396 fn close_common(&mut self) { +6397 trace!("connection closed"); +6398 self.timers.reset(); +6399 } +6400 +6401 fn set_close_timer(&mut self, now: Instant) { +6402 // QUIC-MULTIPATH § 2.6 Connection Closure: draining for 3*PTO using the max PTO of +6403 // all paths. +6404 let pto_max = self.max_pto_for_space(self.highest_space); +6405 self.timers.set( +6406 Timer::Conn(ConnTimer::Close), +6407 now + 3 * pto_max, +6408 self.qlog.with_time(now), +6409 ); +6410 } +6411 +6412 /// Handle transport parameters received from the peer +6413 /// +6414 /// *remote_cid* and *local_cid* are the source and destination CIDs respectively of the +6415 /// *packet into which the transport parameters arrived. +6416 fn handle_peer_params( +6417 &mut self, +6418 params: TransportParameters, +6419 local_cid: ConnectionId, +6420 remote_cid: ConnectionId, +6421 now: Instant, +6422 ) -> Result<(), TransportError> { +6423 if Some(self.original_remote_cid) != params.initial_src_cid +6424 || (self.side.is_client() +6425 && (Some(self.initial_dst_cid) != params.original_dst_cid +6426 || self.retry_src_cid != params.retry_src_cid)) +6427 { +6428 return Err(TransportError::TRANSPORT_PARAMETER_ERROR( +6429 "CID authentication failure", +6430 )); +6431 } +6432 if params.initial_max_path_id.is_some() && (local_cid.is_empty() || remote_cid.is_empty()) { +6433 return Err(TransportError::PROTOCOL_VIOLATION( +6434 "multipath must not use zero-length CIDs", +6435 )); +6436 } 6437 -6438 fn set_peer_params(&mut self, params: TransportParameters) { -6439 self.streams.set_params(&params); -6440 self.idle_timeout = -6441 negotiate_max_idle_timeout(self.config.max_idle_timeout, Some(params.max_idle_timeout)); -6442 trace!("negotiated max idle timeout {:?}", self.idle_timeout); +6438 self.set_peer_params(params); +6439 self.qlog.emit_peer_transport_params_received(self, now); +6440 +6441 Ok(()) +6442 } 6443 -6444 if let Some(ref info) = params.preferred_address { -6445 // During the handshake PathId::ZERO exists. -6446 self.remote_cids.get_mut(&PathId::ZERO).expect("not yet abandoned").insert(frame::NewConnectionId { -6447 path_id: None, -6448 sequence: 1, -6449 id: info.connection_id, -6450 reset_token: info.stateless_reset_token, -6451 retire_prior_to: 0, -6452 }) -6453 .expect( -6454 "preferred address CID is the first received, and hence is guaranteed to be legal", -6455 ); -6456 let remote = self.path_data(PathId::ZERO).network_path.remote; -6457 self.set_reset_token(PathId::ZERO, remote, info.stateless_reset_token); -6458 } -6459 self.ack_frequency.peer_max_ack_delay = get_max_ack_delay(&params); -6460 -6461 let mut multipath_enabled = None; -6462 if let (Some(local_max_path_id), Some(remote_max_path_id)) = ( -6463 self.config.get_initial_max_path_id(), -6464 params.initial_max_path_id, -6465 ) { -6466 // multipath is enabled, register the local and remote maximums -6467 self.local_max_path_id = local_max_path_id; -6468 self.remote_max_path_id = remote_max_path_id; -6469 let initial_max_path_id = local_max_path_id.min(remote_max_path_id); -6470 debug!(%initial_max_path_id, "multipath negotiated"); -6471 multipath_enabled = Some(initial_max_path_id); -6472 } -6473 -6474 if let Some((max_locally_allowed_remote_addresses, max_remotely_allowed_remote_addresses)) = -6475 self.config -6476 .max_remote_nat_traversal_addresses -6477 .zip(params.max_remote_nat_traversal_addresses) -6478 { -6479 if let Some(max_initial_paths) = -6480 multipath_enabled.map(|path_id| path_id.saturating_add(1u8)) -6481 { -6482 let max_local_addresses = max_remotely_allowed_remote_addresses.get(); -6483 let max_remote_addresses = max_locally_allowed_remote_addresses.get(); -6484 self.n0_nat_traversal = n0_nat_traversal::State::new( -6485 max_remote_addresses, -6486 max_local_addresses, -6487 self.side(), -6488 ); -6489 debug!( -6490 %max_remote_addresses, %max_local_addresses, -6491 "n0's nat traversal negotiated" -6492 ); -6493 -6494 match self.side() { -6495 Side::Client => { -6496 if max_initial_paths.as_u32() < max_remote_addresses as u32 + 1 { -6497 // in this case the client might try to open `max_remote_addresses` new -6498 // paths, but the current multipath configuration will not allow it -6499 debug!(%max_initial_paths, %max_remote_addresses, "local client configuration might cause nat traversal issues") -6500 } else if max_local_addresses as u64 -6501 > params.active_connection_id_limit.into_inner() -6502 { -6503 // the server allows us to send at most `params.active_connection_id_limit` -6504 // but they might need at least `max_local_addresses` to effectively send -6505 // `PATH_CHALLENGE` frames to each advertised local address -6506 debug!(%max_local_addresses, remote_cid_limit=%params.active_connection_id_limit.into_inner(), "remote server configuration might cause nat traversal issues") -6507 } -6508 } -6509 Side::Server => { -6510 if (max_initial_paths.as_u32() as u64) < crate::LOCAL_CID_COUNT { -6511 debug!(%max_initial_paths, local_cid_limit=%crate::LOCAL_CID_COUNT, "local server configuration might cause nat traversal issues") -6512 } -6513 } -6514 } -6515 } else { -6516 debug!("n0 nat traversal enabled for both endpoints, but multipath is missing") -6517 } -6518 } -6519 -6520 self.peer_params = params; -6521 let peer_max_udp_payload_size = -6522 u16::try_from(self.peer_params.max_udp_payload_size.into_inner()).unwrap_or(u16::MAX); -6523 self.path_data_mut(PathId::ZERO) -6524 .mtud -6525 .on_peer_max_udp_payload_size_received(peer_max_udp_payload_size); -6526 } -6527 -6528 /// Decrypts a packet, returning the packet number on success -6529 fn decrypt_packet( -6530 &mut self, -6531 now: Instant, -6532 path_id: PathId, -6533 packet: &mut Packet, -6534 ) -> Result<Option<u64>, Option<TransportError>> { -6535 let result = self -6536 .crypto_state -6537 .decrypt_packet_body(packet, path_id, &self.spaces)?; -6538 -6539 let Some(result) = result else { -6540 return Ok(None); -6541 }; -6542 -6543 if result.outgoing_key_update_acked -6544 && let Some(prev) = self.crypto_state.prev_crypto.as_mut() -6545 { -6546 prev.end_packet = Some((result.packet_number, now)); -6547 self.set_key_discard_timer(now, packet.header.space()); -6548 } -6549 -6550 if result.incoming_key_update { -6551 trace!("key update authenticated"); -6552 self.crypto_state -6553 .update_keys(Some((result.packet_number, now)), true); -6554 self.set_key_discard_timer(now, packet.header.space()); -6555 } -6556 -6557 Ok(Some(result.packet_number)) -6558 } -6559 -6560 fn peer_supports_ack_frequency(&self) -> bool { -6561 self.peer_params.min_ack_delay.is_some() -6562 } -6563 -6564 /// Send an IMMEDIATE_ACK frame to the remote endpoint -6565 /// -6566 /// According to the spec, this will result in an error if the remote endpoint does not support -6567 /// the Acknowledgement Frequency extension -6568 pub(crate) fn immediate_ack(&mut self, path_id: PathId) { -6569 debug_assert_eq!( -6570 self.highest_space, -6571 SpaceKind::Data, -6572 "immediate ack must be written in the data space" -6573 ); -6574 self.spaces[SpaceId::Data] -6575 .for_path(path_id) -6576 .immediate_ack_pending = true; -6577 } -6578 -6579 /// Decodes a packet, returning its decrypted payload, so it can be inspected in tests -6580 #[cfg(test)] -6581 pub(crate) fn decode_packet(&self, event: &ConnectionEvent) -> Option<Vec<u8>> { -6582 let ConnectionEventInner::Datagram(DatagramConnectionEvent { -6583 path_id, -6584 first_decode, -6585 remaining, -6586 .. -6587 }) = &event.0 -6588 else { -6589 return None; -6590 }; -6591 -6592 if remaining.is_some() { -6593 panic!("Packets should never be coalesced in tests"); -6594 } -6595 -6596 let decrypted_header = self -6597 .crypto_state -6598 .unprotect_header(first_decode.clone(), self.peer_params.stateless_reset_token)?; -6599 -6600 let mut packet = decrypted_header.packet?; -6601 self.crypto_state -6602 .decrypt_packet_body(&mut packet, *path_id, &self.spaces) -6603 .ok()?; -6604 -6605 Some(packet.payload.to_vec()) -6606 } -6607 -6608 /// The number of bytes of packets containing retransmittable frames that have not been -6609 /// acknowledged or declared lost. -6610 #[cfg(test)] -6611 pub(crate) fn bytes_in_flight(&self) -> u64 { -6612 // TODO(@divma): consider including for multipath? -6613 self.path_data(PathId::ZERO).in_flight.bytes -6614 } -6615 -6616 /// Number of bytes worth of non-ack-only packets that may be sent -6617 #[cfg(test)] -6618 pub(crate) fn congestion_window(&self) -> u64 { -6619 let path = self.path_data(PathId::ZERO); -6620 path.congestion -6621 .window() -6622 .saturating_sub(path.in_flight.bytes) -6623 } -6624 -6625 /// Whether no timers but keepalive, idle, rtt, pushnewcid, and key discard are running -6626 #[cfg(test)] -6627 pub(crate) fn is_idle(&self) -> bool { -6628 let current_timers = self.timers.values(); -6629 current_timers -6630 .into_iter() -6631 .filter(|(timer, _)| { -6632 !matches!( -6633 timer, -6634 Timer::Conn(ConnTimer::KeepAlive) -6635 | Timer::PerPath(_, PathTimer::PathKeepAlive) -6636 | Timer::Conn(ConnTimer::PushNewCid) -6637 | Timer::Conn(ConnTimer::KeyDiscard) -6638 ) -6639 }) -6640 .min_by_key(|(_, time)| *time) -6641 .is_none_or(|(timer, _)| { -6642 matches!( -6643 timer, -6644 Timer::Conn(ConnTimer::Idle) | Timer::PerPath(_, PathTimer::PathIdle) -6645 ) -6646 }) -6647 } -6648 -6649 /// Whether explicit congestion notification is in use on outgoing packets. -6650 #[cfg(test)] -6651 pub(crate) fn using_ecn(&self) -> bool { -6652 self.path_data(PathId::ZERO).sending_ecn +6444 fn set_peer_params(&mut self, params: TransportParameters) { +6445 self.streams.set_params(&params); +6446 self.idle_timeout = +6447 negotiate_max_idle_timeout(self.config.max_idle_timeout, Some(params.max_idle_timeout)); +6448 trace!("negotiated max idle timeout {:?}", self.idle_timeout); +6449 +6450 if let Some(ref info) = params.preferred_address { +6451 // During the handshake PathId::ZERO exists. +6452 self.remote_cids.get_mut(&PathId::ZERO).expect("not yet abandoned").insert(frame::NewConnectionId { +6453 path_id: None, +6454 sequence: 1, +6455 id: info.connection_id, +6456 reset_token: info.stateless_reset_token, +6457 retire_prior_to: 0, +6458 }) +6459 .expect( +6460 "preferred address CID is the first received, and hence is guaranteed to be legal", +6461 ); +6462 let remote = self.path_data(PathId::ZERO).network_path.remote; +6463 self.set_reset_token(PathId::ZERO, remote, info.stateless_reset_token); +6464 } +6465 self.ack_frequency.peer_max_ack_delay = get_max_ack_delay(&params); +6466 +6467 let mut multipath_enabled = None; +6468 if let (Some(local_max_path_id), Some(remote_max_path_id)) = ( +6469 self.config.get_initial_max_path_id(), +6470 params.initial_max_path_id, +6471 ) { +6472 // multipath is enabled, register the local and remote maximums +6473 self.local_max_path_id = local_max_path_id; +6474 self.remote_max_path_id = remote_max_path_id; +6475 let initial_max_path_id = local_max_path_id.min(remote_max_path_id); +6476 debug!(%initial_max_path_id, "multipath negotiated"); +6477 multipath_enabled = Some(initial_max_path_id); +6478 } +6479 +6480 if let Some((max_locally_allowed_remote_addresses, max_remotely_allowed_remote_addresses)) = +6481 self.config +6482 .max_remote_nat_traversal_addresses +6483 .zip(params.max_remote_nat_traversal_addresses) +6484 { +6485 if let Some(max_initial_paths) = +6486 multipath_enabled.map(|path_id| path_id.saturating_add(1u8)) +6487 { +6488 let max_local_addresses = max_remotely_allowed_remote_addresses.get(); +6489 let max_remote_addresses = max_locally_allowed_remote_addresses.get(); +6490 self.n0_nat_traversal = n0_nat_traversal::State::new( +6491 max_remote_addresses, +6492 max_local_addresses, +6493 self.side(), +6494 ); +6495 debug!( +6496 %max_remote_addresses, %max_local_addresses, +6497 "n0's nat traversal negotiated" +6498 ); +6499 +6500 match self.side() { +6501 Side::Client => { +6502 if max_initial_paths.as_u32() < max_remote_addresses as u32 + 1 { +6503 // in this case the client might try to open `max_remote_addresses` new +6504 // paths, but the current multipath configuration will not allow it +6505 debug!(%max_initial_paths, %max_remote_addresses, "local client configuration might cause nat traversal issues") +6506 } else if max_local_addresses as u64 +6507 > params.active_connection_id_limit.into_inner() +6508 { +6509 // the server allows us to send at most `params.active_connection_id_limit` +6510 // but they might need at least `max_local_addresses` to effectively send +6511 // `PATH_CHALLENGE` frames to each advertised local address +6512 debug!(%max_local_addresses, remote_cid_limit=%params.active_connection_id_limit.into_inner(), "remote server configuration might cause nat traversal issues") +6513 } +6514 } +6515 Side::Server => { +6516 if (max_initial_paths.as_u32() as u64) < crate::LOCAL_CID_COUNT { +6517 debug!(%max_initial_paths, local_cid_limit=%crate::LOCAL_CID_COUNT, "local server configuration might cause nat traversal issues") +6518 } +6519 } +6520 } +6521 } else { +6522 debug!("n0 nat traversal enabled for both endpoints, but multipath is missing") +6523 } +6524 } +6525 +6526 self.peer_params = params; +6527 let peer_max_udp_payload_size = +6528 u16::try_from(self.peer_params.max_udp_payload_size.into_inner()).unwrap_or(u16::MAX); +6529 self.path_data_mut(PathId::ZERO) +6530 .mtud +6531 .on_peer_max_udp_payload_size_received(peer_max_udp_payload_size); +6532 } +6533 +6534 /// Decrypts a packet, returning the packet number on success +6535 fn decrypt_packet( +6536 &mut self, +6537 now: Instant, +6538 path_id: PathId, +6539 packet: &mut Packet, +6540 ) -> Result<Option<u64>, Option<TransportError>> { +6541 let result = self +6542 .crypto_state +6543 .decrypt_packet_body(packet, path_id, &self.spaces)?; +6544 +6545 let Some(result) = result else { +6546 return Ok(None); +6547 }; +6548 +6549 if result.outgoing_key_update_acked +6550 && let Some(prev) = self.crypto_state.prev_crypto.as_mut() +6551 { +6552 prev.end_packet = Some((result.packet_number, now)); +6553 self.set_key_discard_timer(now, packet.header.space()); +6554 } +6555 +6556 if result.incoming_key_update { +6557 trace!("key update authenticated"); +6558 self.crypto_state +6559 .update_keys(Some((result.packet_number, now)), true); +6560 self.set_key_discard_timer(now, packet.header.space()); +6561 } +6562 +6563 Ok(Some(result.packet_number)) +6564 } +6565 +6566 fn peer_supports_ack_frequency(&self) -> bool { +6567 self.peer_params.min_ack_delay.is_some() +6568 } +6569 +6570 /// Send an IMMEDIATE_ACK frame to the remote endpoint +6571 /// +6572 /// According to the spec, this will result in an error if the remote endpoint does not support +6573 /// the Acknowledgement Frequency extension +6574 pub(crate) fn immediate_ack(&mut self, path_id: PathId) { +6575 debug_assert_eq!( +6576 self.highest_space, +6577 SpaceKind::Data, +6578 "immediate ack must be written in the data space" +6579 ); +6580 self.spaces[SpaceId::Data] +6581 .for_path(path_id) +6582 .immediate_ack_pending = true; +6583 } +6584 +6585 /// Decodes a packet, returning its decrypted payload, so it can be inspected in tests +6586 #[cfg(test)] +6587 pub(crate) fn decode_packet(&self, event: &ConnectionEvent) -> Option<Vec<u8>> { +6588 let ConnectionEventInner::Datagram(DatagramConnectionEvent { +6589 path_id, +6590 first_decode, +6591 remaining, +6592 .. +6593 }) = &event.0 +6594 else { +6595 return None; +6596 }; +6597 +6598 if remaining.is_some() { +6599 panic!("Packets should never be coalesced in tests"); +6600 } +6601 +6602 let decrypted_header = self +6603 .crypto_state +6604 .unprotect_header(first_decode.clone(), self.peer_params.stateless_reset_token)?; +6605 +6606 let mut packet = decrypted_header.packet?; +6607 self.crypto_state +6608 .decrypt_packet_body(&mut packet, *path_id, &self.spaces) +6609 .ok()?; +6610 +6611 Some(packet.payload.to_vec()) +6612 } +6613 +6614 /// The number of bytes of packets containing retransmittable frames that have not been +6615 /// acknowledged or declared lost. +6616 #[cfg(test)] +6617 pub(crate) fn bytes_in_flight(&self) -> u64 { +6618 // TODO(@divma): consider including for multipath? +6619 self.path_data(PathId::ZERO).in_flight.bytes +6620 } +6621 +6622 /// Number of bytes worth of non-ack-only packets that may be sent +6623 #[cfg(test)] +6624 pub(crate) fn congestion_window(&self) -> u64 { +6625 let path = self.path_data(PathId::ZERO); +6626 path.congestion +6627 .window() +6628 .saturating_sub(path.in_flight.bytes) +6629 } +6630 +6631 /// Whether no timers but keepalive, idle, rtt, pushnewcid, and key discard are running +6632 #[cfg(test)] +6633 pub(crate) fn is_idle(&self) -> bool { +6634 let current_timers = self.timers.values(); +6635 current_timers +6636 .into_iter() +6637 .filter(|(timer, _)| { +6638 !matches!( +6639 timer, +6640 Timer::Conn(ConnTimer::KeepAlive) +6641 | Timer::PerPath(_, PathTimer::PathKeepAlive) +6642 | Timer::Conn(ConnTimer::PushNewCid) +6643 | Timer::Conn(ConnTimer::KeyDiscard) +6644 ) +6645 }) +6646 .min_by_key(|(_, time)| *time) +6647 .is_none_or(|(timer, _)| { +6648 matches!( +6649 timer, +6650 Timer::Conn(ConnTimer::Idle) | Timer::PerPath(_, PathTimer::PathIdle) +6651 ) +6652 }) 6653 } 6654 -6655 /// The number of received bytes in the current path +6655 /// Whether explicit congestion notification is in use on outgoing packets. 6656 #[cfg(test)] -6657 pub(crate) fn total_recvd(&self) -> u64 { -6658 self.path_data(PathId::ZERO).total_recvd +6657 pub(crate) fn using_ecn(&self) -> bool { +6658 self.path_data(PathId::ZERO).sending_ecn 6659 } 6660 -6661 #[cfg(test)] -6662 pub(crate) fn active_local_cid_seq(&self) -> (u64, u64) { -6663 self.local_cid_state -6664 .get(&PathId::ZERO) -6665 .unwrap() -6666 .active_seq() -6667 } -6668 -6669 #[cfg(test)] -6670 #[track_caller] -6671 pub(crate) fn active_local_path_cid_seq(&self, path_id: u32) -> (u64, u64) { -6672 self.local_cid_state -6673 .get(&PathId(path_id)) -6674 .unwrap() -6675 .active_seq() -6676 } -6677 -6678 /// Instruct the peer to replace previously issued CIDs by sending a NEW_CONNECTION_ID frame -6679 /// with updated `retire_prior_to` field set to `v` -6680 #[cfg(test)] -6681 pub(crate) fn rotate_local_cid(&mut self, v: u64, now: Instant) { -6682 let n = self -6683 .local_cid_state -6684 .get_mut(&PathId::ZERO) -6685 .unwrap() -6686 .assign_retire_seq(v); -6687 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events -6688 self.endpoint_events -6689 .push_back(EndpointEventInner::NeedIdentifiers(PathId::ZERO, now, n)); -6690 } -6691 -6692 /// Check the current active remote CID sequence for `PathId::ZERO` -6693 #[cfg(test)] -6694 pub(crate) fn active_remote_cid_seq(&self) -> u64 { -6695 self.remote_cids.get(&PathId::ZERO).unwrap().active_seq() +6661 /// The number of received bytes in the current path +6662 #[cfg(test)] +6663 pub(crate) fn total_recvd(&self) -> u64 { +6664 self.path_data(PathId::ZERO).total_recvd +6665 } +6666 +6667 #[cfg(test)] +6668 pub(crate) fn active_local_cid_seq(&self) -> (u64, u64) { +6669 self.local_cid_state +6670 .get(&PathId::ZERO) +6671 .unwrap() +6672 .active_seq() +6673 } +6674 +6675 #[cfg(test)] +6676 #[track_caller] +6677 pub(crate) fn active_local_path_cid_seq(&self, path_id: u32) -> (u64, u64) { +6678 self.local_cid_state +6679 .get(&PathId(path_id)) +6680 .unwrap() +6681 .active_seq() +6682 } +6683 +6684 /// Instruct the peer to replace previously issued CIDs by sending a NEW_CONNECTION_ID frame +6685 /// with updated `retire_prior_to` field set to `v` +6686 #[cfg(test)] +6687 pub(crate) fn rotate_local_cid(&mut self, v: u64, now: Instant) { +6688 let n = self +6689 .local_cid_state +6690 .get_mut(&PathId::ZERO) +6691 .unwrap() +6692 .assign_retire_seq(v); +6693 debug_assert!(!self.state.is_drained()); // requirement for endpoint_events +6694 self.endpoint_events +6695 .push_back(EndpointEventInner::NeedIdentifiers(PathId::ZERO, now, n)); 6696 } 6697 -6698 /// Returns the detected maximum udp payload size for the current path +6698 /// Check the current active remote CID sequence for `PathId::ZERO` 6699 #[cfg(test)] -6700 pub(crate) fn path_mtu(&self, path_id: PathId) -> u16 { -6701 self.path_data(path_id).current_mtu() +6700 pub(crate) fn active_remote_cid_seq(&self) -> u64 { +6701 self.remote_cids.get(&PathId::ZERO).unwrap().active_seq() 6702 } 6703 -6704 /// Triggers path validation on all paths +6704 /// Returns the detected maximum udp payload size for the current path 6705 #[cfg(test)] -6706 pub(crate) fn trigger_path_validation(&mut self) { -6707 for path in self.paths.values_mut() { -6708 path.data.pending_on_path_challenge = true; -6709 } -6710 } -6711 -6712 /// Simulates a protocol violation error for test purposes. -6713 #[cfg(test)] -6714 pub fn simulate_protocol_violation(&mut self, now: Instant) { -6715 if !self.state.is_closed() { -6716 self.state -6717 .move_to_closed(TransportError::PROTOCOL_VIOLATION("simulated violation")); -6718 self.close_common(); -6719 if !self.state.is_drained() { -6720 self.set_close_timer(now); -6721 } -6722 self.connection_close_pending = true; -6723 } -6724 } -6725 -6726 /// Whether we have on-path 1-RTT data to send. -6727 /// -6728 /// This checks for frames that can only be sent in the data space (1-RTT): -6729 /// - Pending PATH_CHALLENGE frames on the active and previous path if just migrated. -6730 /// - Pending PATH_RESPONSE frames. -6731 /// - Pending data to send in STREAM frames. -6732 /// - Pending DATAGRAM frames to send. +6706 pub(crate) fn path_mtu(&self, path_id: PathId) -> u16 { +6707 self.path_data(path_id).current_mtu() +6708 } +6709 +6710 /// Triggers path validation on all paths +6711 #[cfg(test)] +6712 pub(crate) fn trigger_path_validation(&mut self) { +6713 for path in self.paths.values_mut() { +6714 path.data.pending_on_path_challenge = true; +6715 } +6716 } +6717 +6718 /// Simulates a protocol violation error for test purposes. +6719 #[cfg(test)] +6720 pub fn simulate_protocol_violation(&mut self, now: Instant) { +6721 if !self.state.is_closed() { +6722 self.state +6723 .move_to_closed(TransportError::PROTOCOL_VIOLATION("simulated violation")); +6724 self.close_common(); +6725 if !self.state.is_drained() { +6726 self.set_close_timer(now); +6727 } +6728 self.connection_close_pending = true; +6729 } +6730 } +6731 +6732 /// Whether we have on-path 1-RTT data to send. 6733 /// -6734 /// See also [`PacketSpace::can_send`] which keeps track of all other frame types that -6735 /// may need to be sent. -6736 fn can_send_1rtt(&self, path_id: PathId, max_size: usize) -> SendableFrames { -6737 let space_specific = self.paths.get(&path_id).is_some_and(|path| { -6738 path.data.pending_on_path_challenge || !path.data.path_responses.is_empty() -6739 }); -6740 -6741 // Stream control frames are checked in PacketSpace::can_send, only check data here. -6742 let other = self.streams.can_send_stream_data() -6743 || self -6744 .datagrams -6745 .outgoing -6746 .front() -6747 .is_some_and(|x| x.size(true) <= max_size); -6748 -6749 // All `false` fields are set in PacketSpace::can_send. -6750 SendableFrames { -6751 acks: false, -6752 close: false, -6753 space_specific, -6754 other, -6755 } -6756 } -6757 -6758 /// Terminate the connection instantly, without sending a close packet -6759 fn kill(&mut self, reason: ConnectionError) { -6760 self.close_common(); -6761 self.state.move_to_drained(Some(reason)); -6762 // move_to_drained checks that we were never in drained before, so we -6763 // never sent a `Drained` event before (it's illegal to send more events after drained). -6764 self.endpoint_events.push_back(EndpointEventInner::Drained); -6765 } -6766 -6767 /// Storage size required for the largest packet that can be transmitted on all currently -6768 /// available paths -6769 /// -6770 /// Buffers passed to [`Connection::poll_transmit`] should be at least this large. -6771 /// -6772 /// When multipath is enabled, this value is the minimum MTU across all available paths. -6773 pub fn current_mtu(&self) -> u16 { -6774 self.paths -6775 .iter() -6776 .filter(|&(path_id, _path_state)| !self.abandoned_paths.contains(path_id)) -6777 .map(|(_path_id, path_state)| path_state.data.current_mtu()) -6778 .min() -6779 .unwrap_or(INITIAL_MTU) -6780 } -6781 -6782 /// Size of non-frame data for a 1-RTT packet -6783 /// -6784 /// Quantifies space consumed by the QUIC header and AEAD tag. All other bytes in a packet are -6785 /// frames. Changes if the length of the remote connection ID changes, which is expected to be -6786 /// rare. If `pn` is specified, may additionally change unpredictably due to variations in -6787 /// latency and packet loss. -6788 fn predict_1rtt_overhead(&mut self, pn: u64, path: PathId) -> usize { -6789 let pn_len = PacketNumber::new( -6790 pn, -6791 self.spaces[SpaceId::Data] -6792 .for_path(path) -6793 .largest_acked_packet -6794 .unwrap_or(0), -6795 ) -6796 .len(); -6797 -6798 // 1 byte for flags -6799 1 + self -6800 .remote_cids -6801 .get(&path) -6802 .map(|cids| cids.active().len()) -6803 .unwrap_or(20) // Max CID len in QUIC v1 -6804 + pn_len -6805 + self.tag_len_1rtt() -6806 } -6807 -6808 fn predict_1rtt_overhead_no_pn(&self) -> usize { -6809 let pn_len = 4; -6810 -6811 let cid_len = self -6812 .remote_cids -6813 .values() -6814 .map(|cids| cids.active().len()) -6815 .max() -6816 .unwrap_or(20); // Max CID len in QUIC v1 -6817 -6818 // 1 byte for flags -6819 1 + cid_len + pn_len + self.tag_len_1rtt() -6820 } -6821 -6822 fn tag_len_1rtt(&self) -> usize { -6823 // encryption_keys for Data space returns 1-RTT keys if available, otherwise 0-RTT keys -6824 let packet_crypto = self -6825 .crypto_state -6826 .encryption_keys(SpaceKind::Data, self.side.side()) -6827 .map(|(_header, packet, _level)| packet); -6828 // If neither Data nor 0-RTT keys are available, make a reasonable tag length guess. As of -6829 // this writing, all QUIC cipher suites use 16-byte tags. We could return `None` instead, -6830 // but that would needlessly prevent sending datagrams during 0-RTT. -6831 packet_crypto.map_or(16, |x| x.tag_len()) -6832 } -6833 -6834 /// Mark the path as validated, and enqueue NEW_TOKEN frames to be sent as appropriate -6835 fn on_path_validated(&mut self, path_id: PathId) { -6836 self.path_data_mut(path_id).validated = true; -6837 let ConnectionSide::Server { server_config } = &self.side else { -6838 return; -6839 }; -6840 let network_path = self.path_data(path_id).network_path; -6841 let new_tokens = &mut self.spaces[SpaceId::Data as usize].pending.new_tokens; -6842 new_tokens.clear(); -6843 for _ in 0..server_config.validation_token.sent { -6844 new_tokens.push(network_path); -6845 } -6846 } -6847 -6848 /// Handle new path status information: PATH_STATUS_AVAILABLE, PATH_STATUS_BACKUP -6849 fn on_path_status(&mut self, path_id: PathId, status: PathStatus, status_seq_no: VarInt) { -6850 if let Some(path) = self.paths.get_mut(&path_id) { -6851 path.data.status.remote_update(status, status_seq_no); -6852 } else { -6853 debug!("PATH_STATUS_AVAILABLE received unknown path {:?}", path_id); -6854 } -6855 self.events.push_back( -6856 PathEvent::RemoteStatus { -6857 id: path_id, -6858 status, -6859 } -6860 .into(), -6861 ); -6862 } -6863 -6864 /// Returns the maximum [`PathId`] to be used for sending in this connection. -6865 /// -6866 /// This is calculated as minimum between the local and remote's maximums when multipath is -6867 /// enabled, or `None` when disabled. -6868 /// -6869 /// For data that's received, we should use [`Self::local_max_path_id`] instead. -6870 /// The reasoning is that the remote might already have updated to its own newer -6871 /// [`Self::max_path_id`] after sending out a `MAX_PATH_ID` frame, but it got re-ordered. -6872 fn max_path_id(&self) -> Option<PathId> { -6873 if self.is_multipath_negotiated() { -6874 Some(self.remote_max_path_id.min(self.local_max_path_id)) -6875 } else { -6876 None -6877 } -6878 } -6879 -6880 /// Returns whether this connection has a socket that supports IPv6. -6881 /// -6882 /// TODO(matheus23): This is related to noq endpoint state's `ipv6` bool. We should move that info -6883 /// here instead of trying to hack around not knowing it exactly. -6884 fn is_ipv6(&self) -> bool { -6885 self.paths -6886 .values() -6887 .any(|p| p.data.network_path.remote.is_ipv6()) -6888 } -6889 -6890 /// Add addresses the local endpoint considers are reachable for nat traversal. -6891 pub fn add_nat_traversal_address( -6892 &mut self, -6893 address: SocketAddr, -6894 ) -> Result<(), n0_nat_traversal::Error> { -6895 if let Some(added) = self.n0_nat_traversal.add_local_address(address)? { -6896 self.spaces[SpaceId::Data].pending.add_address.insert(added); -6897 }; -6898 Ok(()) -6899 } -6900 -6901 /// Removes an address the endpoing no longer considers reachable for nat traversal -6902 /// -6903 /// Addresses not present in the set will be silently ignored. -6904 pub fn remove_nat_traversal_address( -6905 &mut self, -6906 address: SocketAddr, -6907 ) -> Result<(), n0_nat_traversal::Error> { -6908 if let Some(removed) = self.n0_nat_traversal.remove_local_address(address)? { -6909 self.spaces[SpaceId::Data] -6910 .pending -6911 .remove_address -6912 .insert(removed); -6913 } -6914 Ok(()) -6915 } -6916 -6917 /// Get the current local nat traversal addresses -6918 pub fn get_local_nat_traversal_addresses( -6919 &self, -6920 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { -6921 self.n0_nat_traversal.get_local_nat_traversal_addresses() -6922 } -6923 -6924 /// Get the currently advertised nat traversal addresses by the server -6925 pub fn get_remote_nat_traversal_addresses( -6926 &self, -6927 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { -6928 Ok(self -6929 .n0_nat_traversal -6930 .client_side()? -6931 .get_remote_nat_traversal_addresses()) -6932 } -6933 -6934 /// Attempts to open a path for nat traversal. -6935 /// -6936 /// On success returns the [`PathId`] and remote address of the path. -6937 fn open_nat_traversal_path( -6938 &mut self, -6939 now: Instant, -6940 ip_port: (IpAddr, u16), -6941 ) -> Result<Option<(PathId, SocketAddr)>, PathError> { -6942 let remote = ip_port.into(); -6943 // TODO(matheus23): Probe the correct 4-tuple, instead of only a remote address? -6944 // By specifying None for `local_ip`, we do two things: 1. open_path_ensure won't -6945 // generate two paths to the same remote and 2. we let the OS choose which -6946 // interface to use for sending on that path. -6947 let network_path = FourTuple { -6948 remote, -6949 local_ip: None, -6950 }; -6951 match self.open_path_ensure(network_path, PathStatus::Backup, now) { -6952 Ok((path_id, path_was_known)) => { -6953 if path_was_known { -6954 trace!(%path_id, %remote, "nat traversal: path existed for remote, revalidating"); -6955 if let Some(path) = self.paths.get_mut(&path_id) { -6956 path.data.pending_on_path_challenge = true; -6957 } -6958 } -6959 Ok(Some((path_id, remote))) -6960 } -6961 Err(e) => { -6962 debug!(%remote, %e, "nat traversal: failed to probe remote"); -6963 Err(e) -6964 } -6965 } -6966 } -6967 -6968 /// Initiates a new nat traversal round -6969 /// -6970 /// A nat traversal round involves advertising the client's local addresses in `REACH_OUT` -6971 /// frames, and initiating probing of the known remote addresses. When a new round is -6972 /// initiated, the previous one is cancelled, and paths that have not been opened are closed. -6973 /// -6974 /// Returns the server addresses that are now being probed. -6975 /// If addresses fail due to spurious errors, these might succeed later and not be returned in -6976 /// this set. -6977 pub fn initiate_nat_traversal_round( -6978 &mut self, -6979 now: Instant, -6980 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { -6981 if self.state.is_closed() { -6982 return Err(n0_nat_traversal::Error::Closed); -6983 } -6984 -6985 let ipv6 = self.is_ipv6(); -6986 let client_state = self.n0_nat_traversal.client_side_mut()?; -6987 let n0_nat_traversal::NatTraversalRound { -6988 new_round, -6989 reach_out_at, -6990 addresses_to_probe, -6991 prev_round_path_ids, -6992 } = client_state.initiate_nat_traversal_round(ipv6)?; -6993 -6994 trace!(%new_round, reach_out=reach_out_at.len(), to_probe=addresses_to_probe.len(), -6995 "initiating nat traversal round"); -6996 -6997 self.spaces[SpaceId::Data].pending.reach_out = Some((new_round, reach_out_at)); -6998 -6999 for path_id in prev_round_path_ids { -7000 let Some(path) = self.path(path_id) else { -7001 continue; -7002 }; -7003 let ip = path.network_path.remote.ip(); -7004 let port = path.network_path.remote.port(); -7005 -7006 // We only close paths that aren't validated (thus are working) that we opened -7007 // in a previous round. -7008 // And we only close paths that we don't want to probe anyways. -7009 if !addresses_to_probe -7010 .iter() -7011 .any(|(_, probe)| *probe == (ip, port)) -7012 && !path.validated -7013 && !self.abandoned_paths.contains(&path_id) -7014 { -7015 trace!(%path_id, "closing path from previous round"); -7016 let _ = -7017 self.close_path_inner(now, path_id, PathAbandonReason::NatTraversalRoundEnded); -7018 } -7019 } -7020 -7021 let mut err = None; -7022 -7023 let mut path_ids = Vec::with_capacity(addresses_to_probe.len()); -7024 let mut probed_addresses = Vec::with_capacity(addresses_to_probe.len()); -7025 -7026 for (id, address) in addresses_to_probe { -7027 match self.open_nat_traversal_path(now, address) { -7028 Ok(None) => {} -7029 Ok(Some((path_id, remote))) => { -7030 path_ids.push(path_id); -7031 probed_addresses.push(remote); -7032 } -7033 Err(e) => { -7034 self.n0_nat_traversal -7035 .client_side_mut() -7036 .expect("validated") -7037 .report_in_continuation(id, e); -7038 err.get_or_insert(e); -7039 } -7040 } -7041 } -7042 -7043 if let Some(err) = err { -7044 // We failed to probe any addresses, bail out -7045 if probed_addresses.is_empty() { -7046 return Err(n0_nat_traversal::Error::Multipath(err)); -7047 } -7048 } -7049 -7050 self.n0_nat_traversal -7051 .client_side_mut() -7052 .expect("connection side validated") -7053 .set_round_path_ids(path_ids); -7054 -7055 Ok(probed_addresses) -7056 } -7057 -7058 /// Attempts to continue a nat traversal round by trying to open paths for pending client probes. -7059 /// -7060 /// If there was nothing to do, it returns `None`. Otherwise it returns whether the path was -7061 /// successfully open. -7062 fn continue_nat_traversal_round(&mut self, now: Instant) -> Option<bool> { -7063 let ipv6 = self.is_ipv6(); -7064 let client_state = self.n0_nat_traversal.client_side_mut().ok()?; -7065 let (id, address) = client_state.continue_nat_traversal_round(ipv6)?; -7066 let open_result = self.open_nat_traversal_path(now, address); -7067 let client_state = self.n0_nat_traversal.client_side_mut().expect("validated"); -7068 match open_result { -7069 Ok(None) => Some(true), -7070 Ok(Some((path_id, _remote))) => { -7071 client_state.add_round_path_id(path_id); -7072 Some(true) -7073 } -7074 Err(e) => { -7075 client_state.report_in_continuation(id, e); -7076 Some(false) -7077 } -7078 } -7079 } -7080 -7081 /// Whether the handshake is considered **confirmed**. -7082 /// -7083 /// <https://www.rfc-editor.org/rfc/rfc9001#section-4.1.2> defines a handshake to be -7084 /// confirmed when you know the peer successfully received and successfully processed -7085 /// your TLS Finished message. -7086 /// -7087 /// Implementation-wise this is the point at which the handshake crypto keys are -7088 /// discarded. So we can use this to know if the handshake is confirmed. -7089 fn is_handshake_confirmed(&self) -> bool { -7090 !self.is_handshaking() && !self.crypto_state.has_keys(EncryptionLevel::Handshake) -7091 } -7092} -7093 -7094impl fmt::Debug for Connection { -7095 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { -7096 f.debug_struct("Connection") -7097 .field("handshake_cid", &self.handshake_cid) -7098 .finish() -7099 } -7100} -7101 -7102/// Hints when the caller identifies a network change. -7103pub trait NetworkChangeHint: std::fmt::Debug + 'static { -7104 /// Inform the connection if a path may recover after a network change. -7105 /// -7106 /// After network changes, paths may not be recoverable. In this case, waiting for the path to -7107 /// become idle may take longer than what is desirable. If [`Self::is_path_recoverable`] -7108 /// returns `false`, a multipath-enabled, client-side connection will establish a new path to -7109 /// the same remote, closing the current one, instead of migrating the path. -7110 /// -7111 /// Paths that are deemed recoverable will simply be sent a PING for a liveness check. -7112 fn is_path_recoverable(&self, path_id: PathId, network_path: FourTuple) -> bool; -7113} -7114 -7115/// Return value for [`Connection::poll_transmit_path_space`]. -7116#[derive(Debug)] -7117enum PollPathSpaceStatus { -7118 /// Nothing to send in the space, nothing was written into the [`TransmitBuf`]. -7119 NothingToSend { -7120 /// If true there was data to send but congestion control did not allow so. -7121 congestion_blocked: bool, -7122 }, -7123 /// One or more packets have been written into the [`TransmitBuf`]. -7124 WrotePacket { -7125 /// The highest packet number. -7126 last_packet_number: u64, -7127 /// Whether to pad an already started datagram in the next packet. -7128 /// -7129 /// When packets in Initial, 0-RTT or Handshake packet do not fill the entire -7130 /// datagram they may decide to coalesce with the next packet from a higher -7131 /// encryption level on the same path. But the earlier packet may require specific -7132 /// size requirements for the datagram they are sent in. -7133 /// -7134 /// If a space did not complete the datagram, they use this to request the correct -7135 /// padding in the final packet of the datagram so that the final datagram will have -7136 /// the correct size. -7137 /// -7138 /// If a space did fill an entire datagram, it leaves this to the default of -7139 /// [`PadDatagram::No`]. -7140 pad_datagram: PadDatagram, -7141 }, -7142 /// Send the contents of the transmit immediately. -7143 /// -7144 /// Packets were written and the GSO batch must end now, regardless from whether higher -7145 /// spaces still have frames to write. This is used when the last datagram written would -7146 /// require too much padding to continue a GSO batch, which would waste space on the -7147 /// wire. -7148 Send { -7149 /// The highest packet number written into the transmit. -7150 last_packet_number: u64, -7151 }, -7152} -7153 -7154/// Information used to decide what frames to schedule into which packets. -7155/// -7156/// Primarily used by [`Connection::poll_transmit_on_path`] and the functions that help -7157/// building packets for it: [`Connection::poll_transmit_path_space`] and -7158/// [`Connection::populate_packet`]. -7159#[derive(Debug, Copy, Clone)] -7160struct PathSchedulingInfo { -7161 /// Whether the path is abandoned. -7162 /// -7163 /// Note that a path that is abandoned but still has CIDs can still send a packet. After -7164 /// sending that packet the CIDs issued by the remote have to be considered retired as -7165 /// well. -7166 is_abandoned: bool, -7167 /// Whether the path may send [`SpaceKind::Data`] frames. +6734 /// This checks for frames that can only be sent in the data space (1-RTT): +6735 /// - Pending PATH_CHALLENGE frames on the active and previous path if just migrated. +6736 /// - Pending PATH_RESPONSE frames. +6737 /// - Pending data to send in STREAM frames. +6738 /// - Pending DATAGRAM frames to send. +6739 /// +6740 /// See also [`PacketSpace::can_send`] which keeps track of all other frame types that +6741 /// may need to be sent. +6742 fn can_send_1rtt(&self, path_id: PathId, max_size: usize) -> SendableFrames { +6743 let space_specific = self.paths.get(&path_id).is_some_and(|path| { +6744 path.data.pending_on_path_challenge || !path.data.path_responses.is_empty() +6745 }); +6746 +6747 // Stream control frames are checked in PacketSpace::can_send, only check data here. +6748 let other = self.streams.can_send_stream_data() +6749 || self +6750 .datagrams +6751 .outgoing +6752 .front() +6753 .is_some_and(|x| x.size(true) <= max_size); +6754 +6755 // All `false` fields are set in PacketSpace::can_send. +6756 SendableFrames { +6757 acks: false, +6758 close: false, +6759 space_specific, +6760 other, +6761 } +6762 } +6763 +6764 /// Terminate the connection instantly, without sending a close packet +6765 fn kill(&mut self, reason: ConnectionError) { +6766 self.close_common(); +6767 self.state.move_to_drained(Some(reason)); +6768 // move_to_drained checks that we were never in drained before, so we +6769 // never sent a `Drained` event before (it's illegal to send more events after drained). +6770 self.endpoint_events.push_back(EndpointEventInner::Drained); +6771 } +6772 +6773 /// Storage size required for the largest packet that can be transmitted on all currently +6774 /// available paths +6775 /// +6776 /// Buffers passed to [`Connection::poll_transmit`] should be at least this large. +6777 /// +6778 /// When multipath is enabled, this value is the minimum MTU across all available paths. +6779 pub fn current_mtu(&self) -> u16 { +6780 self.paths +6781 .iter() +6782 .filter(|&(path_id, _path_state)| !self.abandoned_paths.contains(path_id)) +6783 .map(|(_path_id, path_state)| path_state.data.current_mtu()) +6784 .min() +6785 .unwrap_or(INITIAL_MTU) +6786 } +6787 +6788 /// Size of non-frame data for a 1-RTT packet +6789 /// +6790 /// Quantifies space consumed by the QUIC header and AEAD tag. All other bytes in a packet are +6791 /// frames. Changes if the length of the remote connection ID changes, which is expected to be +6792 /// rare. If `pn` is specified, may additionally change unpredictably due to variations in +6793 /// latency and packet loss. +6794 fn predict_1rtt_overhead(&mut self, pn: u64, path: PathId) -> usize { +6795 let pn_len = PacketNumber::new( +6796 pn, +6797 self.spaces[SpaceId::Data] +6798 .for_path(path) +6799 .largest_acked_packet +6800 .unwrap_or(0), +6801 ) +6802 .len(); +6803 +6804 // 1 byte for flags +6805 1 + self +6806 .remote_cids +6807 .get(&path) +6808 .map(|cids| cids.active().len()) +6809 .unwrap_or(20) // Max CID len in QUIC v1 +6810 + pn_len +6811 + self.tag_len_1rtt() +6812 } +6813 +6814 fn predict_1rtt_overhead_no_pn(&self) -> usize { +6815 let pn_len = 4; +6816 +6817 let cid_len = self +6818 .remote_cids +6819 .values() +6820 .map(|cids| cids.active().len()) +6821 .max() +6822 .unwrap_or(20); // Max CID len in QUIC v1 +6823 +6824 // 1 byte for flags +6825 1 + cid_len + pn_len + self.tag_len_1rtt() +6826 } +6827 +6828 fn tag_len_1rtt(&self) -> usize { +6829 // encryption_keys for Data space returns 1-RTT keys if available, otherwise 0-RTT keys +6830 let packet_crypto = self +6831 .crypto_state +6832 .encryption_keys(SpaceKind::Data, self.side.side()) +6833 .map(|(_header, packet, _level)| packet); +6834 // If neither Data nor 0-RTT keys are available, make a reasonable tag length guess. As of +6835 // this writing, all QUIC cipher suites use 16-byte tags. We could return `None` instead, +6836 // but that would needlessly prevent sending datagrams during 0-RTT. +6837 packet_crypto.map_or(16, |x| x.tag_len()) +6838 } +6839 +6840 /// Mark the path as validated, and enqueue NEW_TOKEN frames to be sent as appropriate +6841 fn on_path_validated(&mut self, path_id: PathId) { +6842 self.path_data_mut(path_id).validated = true; +6843 let ConnectionSide::Server { server_config } = &self.side else { +6844 return; +6845 }; +6846 let network_path = self.path_data(path_id).network_path; +6847 let new_tokens = &mut self.spaces[SpaceId::Data as usize].pending.new_tokens; +6848 new_tokens.clear(); +6849 for _ in 0..server_config.validation_token.sent { +6850 new_tokens.push(network_path); +6851 } +6852 } +6853 +6854 /// Handle new path status information: PATH_STATUS_AVAILABLE, PATH_STATUS_BACKUP +6855 fn on_path_status(&mut self, path_id: PathId, status: PathStatus, status_seq_no: VarInt) { +6856 if let Some(path) = self.paths.get_mut(&path_id) { +6857 path.data.status.remote_update(status, status_seq_no); +6858 } else { +6859 debug!("PATH_STATUS_AVAILABLE received unknown path {:?}", path_id); +6860 } +6861 self.events.push_back( +6862 PathEvent::RemoteStatus { +6863 id: path_id, +6864 status, +6865 } +6866 .into(), +6867 ); +6868 } +6869 +6870 /// Returns the maximum [`PathId`] to be used for sending in this connection. +6871 /// +6872 /// This is calculated as minimum between the local and remote's maximums when multipath is +6873 /// enabled, or `None` when disabled. +6874 /// +6875 /// For data that's received, we should use [`Self::local_max_path_id`] instead. +6876 /// The reasoning is that the remote might already have updated to its own newer +6877 /// [`Self::max_path_id`] after sending out a `MAX_PATH_ID` frame, but it got re-ordered. +6878 fn max_path_id(&self) -> Option<PathId> { +6879 if self.is_multipath_negotiated() { +6880 Some(self.remote_max_path_id.min(self.local_max_path_id)) +6881 } else { +6882 None +6883 } +6884 } +6885 +6886 /// Returns whether this connection has a socket that supports IPv6. +6887 /// +6888 /// TODO(matheus23): This is related to noq endpoint state's `ipv6` bool. We should move that info +6889 /// here instead of trying to hack around not knowing it exactly. +6890 fn is_ipv6(&self) -> bool { +6891 self.paths +6892 .values() +6893 .any(|p| p.data.network_path.remote.is_ipv6()) +6894 } +6895 +6896 /// Add addresses the local endpoint considers are reachable for nat traversal. +6897 pub fn add_nat_traversal_address( +6898 &mut self, +6899 address: SocketAddr, +6900 ) -> Result<(), n0_nat_traversal::Error> { +6901 if let Some(added) = self.n0_nat_traversal.add_local_address(address)? { +6902 self.spaces[SpaceId::Data].pending.add_address.insert(added); +6903 }; +6904 Ok(()) +6905 } +6906 +6907 /// Removes an address the endpoing no longer considers reachable for nat traversal +6908 /// +6909 /// Addresses not present in the set will be silently ignored. +6910 pub fn remove_nat_traversal_address( +6911 &mut self, +6912 address: SocketAddr, +6913 ) -> Result<(), n0_nat_traversal::Error> { +6914 if let Some(removed) = self.n0_nat_traversal.remove_local_address(address)? { +6915 self.spaces[SpaceId::Data] +6916 .pending +6917 .remove_address +6918 .insert(removed); +6919 } +6920 Ok(()) +6921 } +6922 +6923 /// Get the current local nat traversal addresses +6924 pub fn get_local_nat_traversal_addresses( +6925 &self, +6926 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { +6927 self.n0_nat_traversal.get_local_nat_traversal_addresses() +6928 } +6929 +6930 /// Get the currently advertised nat traversal addresses by the server +6931 pub fn get_remote_nat_traversal_addresses( +6932 &self, +6933 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { +6934 Ok(self +6935 .n0_nat_traversal +6936 .client_side()? +6937 .get_remote_nat_traversal_addresses()) +6938 } +6939 +6940 /// Attempts to open a path for nat traversal. +6941 /// +6942 /// On success returns the [`PathId`] and remote address of the path. +6943 fn open_nat_traversal_path( +6944 &mut self, +6945 now: Instant, +6946 ip_port: (IpAddr, u16), +6947 ) -> Result<Option<(PathId, SocketAddr)>, PathError> { +6948 let remote = ip_port.into(); +6949 // TODO(matheus23): Probe the correct 4-tuple, instead of only a remote address? +6950 // By specifying None for `local_ip`, we do two things: 1. open_path_ensure won't +6951 // generate two paths to the same remote and 2. we let the OS choose which +6952 // interface to use for sending on that path. +6953 let network_path = FourTuple { +6954 remote, +6955 local_ip: None, +6956 }; +6957 match self.open_path_ensure(network_path, PathStatus::Backup, now) { +6958 Ok((path_id, path_was_known)) => { +6959 if path_was_known { +6960 trace!(%path_id, %remote, "nat traversal: path existed for remote, revalidating"); +6961 if let Some(path) = self.paths.get_mut(&path_id) { +6962 path.data.pending_on_path_challenge = true; +6963 } +6964 } +6965 Ok(Some((path_id, remote))) +6966 } +6967 Err(e) => { +6968 debug!(%remote, %e, "nat traversal: failed to probe remote"); +6969 Err(e) +6970 } +6971 } +6972 } +6973 +6974 /// Initiates a new nat traversal round +6975 /// +6976 /// A nat traversal round involves advertising the client's local addresses in `REACH_OUT` +6977 /// frames, and initiating probing of the known remote addresses. When a new round is +6978 /// initiated, the previous one is cancelled, and paths that have not been opened are closed. +6979 /// +6980 /// Returns the server addresses that are now being probed. +6981 /// If addresses fail due to spurious errors, these might succeed later and not be returned in +6982 /// this set. +6983 pub fn initiate_nat_traversal_round( +6984 &mut self, +6985 now: Instant, +6986 ) -> Result<Vec<SocketAddr>, n0_nat_traversal::Error> { +6987 if self.state.is_closed() { +6988 return Err(n0_nat_traversal::Error::Closed); +6989 } +6990 +6991 let ipv6 = self.is_ipv6(); +6992 let client_state = self.n0_nat_traversal.client_side_mut()?; +6993 let n0_nat_traversal::NatTraversalRound { +6994 new_round, +6995 reach_out_at, +6996 addresses_to_probe, +6997 prev_round_path_ids, +6998 } = client_state.initiate_nat_traversal_round(ipv6)?; +6999 +7000 trace!(%new_round, reach_out=reach_out_at.len(), to_probe=addresses_to_probe.len(), +7001 "initiating nat traversal round"); +7002 +7003 self.spaces[SpaceId::Data].pending.reach_out = Some((new_round, reach_out_at)); +7004 +7005 for path_id in prev_round_path_ids { +7006 let Some(path) = self.path(path_id) else { +7007 continue; +7008 }; +7009 let ip = path.network_path.remote.ip(); +7010 let port = path.network_path.remote.port(); +7011 +7012 // We only close paths that aren't validated (thus are working) that we opened +7013 // in a previous round. +7014 // And we only close paths that we don't want to probe anyways. +7015 if !addresses_to_probe +7016 .iter() +7017 .any(|(_, probe)| *probe == (ip, port)) +7018 && !path.validated +7019 && !self.abandoned_paths.contains(&path_id) +7020 { +7021 trace!(%path_id, "closing path from previous round"); +7022 let _ = +7023 self.close_path_inner(now, path_id, PathAbandonReason::NatTraversalRoundEnded); +7024 } +7025 } +7026 +7027 let mut err = None; +7028 +7029 let mut path_ids = Vec::with_capacity(addresses_to_probe.len()); +7030 let mut probed_addresses = Vec::with_capacity(addresses_to_probe.len()); +7031 +7032 for (id, address) in addresses_to_probe { +7033 match self.open_nat_traversal_path(now, address) { +7034 Ok(None) => {} +7035 Ok(Some((path_id, remote))) => { +7036 path_ids.push(path_id); +7037 probed_addresses.push(remote); +7038 } +7039 Err(e) => { +7040 self.n0_nat_traversal +7041 .client_side_mut() +7042 .expect("validated") +7043 .report_in_continuation(id, e); +7044 err.get_or_insert(e); +7045 } +7046 } +7047 } +7048 +7049 if let Some(err) = err { +7050 // We failed to probe any addresses, bail out +7051 if probed_addresses.is_empty() { +7052 return Err(n0_nat_traversal::Error::Multipath(err)); +7053 } +7054 } +7055 +7056 self.n0_nat_traversal +7057 .client_side_mut() +7058 .expect("connection side validated") +7059 .set_round_path_ids(path_ids); +7060 +7061 Ok(probed_addresses) +7062 } +7063 +7064 /// Attempts to continue a nat traversal round by trying to open paths for pending client probes. +7065 /// +7066 /// If there was nothing to do, it returns `None`. Otherwise it returns whether the path was +7067 /// successfully open. +7068 fn continue_nat_traversal_round(&mut self, now: Instant) -> Option<bool> { +7069 let ipv6 = self.is_ipv6(); +7070 let client_state = self.n0_nat_traversal.client_side_mut().ok()?; +7071 let (id, address) = client_state.continue_nat_traversal_round(ipv6)?; +7072 let open_result = self.open_nat_traversal_path(now, address); +7073 let client_state = self.n0_nat_traversal.client_side_mut().expect("validated"); +7074 match open_result { +7075 Ok(None) => Some(true), +7076 Ok(Some((path_id, _remote))) => { +7077 client_state.add_round_path_id(path_id); +7078 Some(true) +7079 } +7080 Err(e) => { +7081 client_state.report_in_continuation(id, e); +7082 Some(false) +7083 } +7084 } +7085 } +7086 +7087 /// Whether the handshake is considered **confirmed**. +7088 /// +7089 /// <https://www.rfc-editor.org/rfc/rfc9001#section-4.1.2> defines a handshake to be +7090 /// confirmed when you know the peer successfully received and successfully processed +7091 /// your TLS Finished message. +7092 /// +7093 /// Implementation-wise this is the point at which the handshake crypto keys are +7094 /// discarded. So we can use this to know if the handshake is confirmed. +7095 fn is_handshake_confirmed(&self) -> bool { +7096 !self.is_handshaking() && !self.crypto_state.has_keys(EncryptionLevel::Handshake) +7097 } +7098} +7099 +7100impl fmt::Debug for Connection { +7101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +7102 f.debug_struct("Connection") +7103 .field("handshake_cid", &self.handshake_cid) +7104 .finish() +7105 } +7106} +7107 +7108/// Hints when the caller identifies a network change. +7109pub trait NetworkChangeHint: std::fmt::Debug + 'static { +7110 /// Inform the connection if a path may recover after a network change. +7111 /// +7112 /// After network changes, paths may not be recoverable. In this case, waiting for the path to +7113 /// become idle may take longer than what is desirable. If [`Self::is_path_recoverable`] +7114 /// returns `false`, a multipath-enabled, client-side connection will establish a new path to +7115 /// the same remote, closing the current one, instead of migrating the path. +7116 /// +7117 /// Paths that are deemed recoverable will simply be sent a PING for a liveness check. +7118 fn is_path_recoverable(&self, path_id: PathId, network_path: FourTuple) -> bool; +7119} +7120 +7121/// Return value for [`Connection::poll_transmit_path_space`]. +7122#[derive(Debug)] +7123enum PollPathSpaceStatus { +7124 /// Nothing to send in the space, nothing was written into the [`TransmitBuf`]. +7125 NothingToSend { +7126 /// If true there was data to send but congestion control did not allow so. +7127 congestion_blocked: bool, +7128 }, +7129 /// One or more packets have been written into the [`TransmitBuf`]. +7130 WrotePacket { +7131 /// The highest packet number. +7132 last_packet_number: u64, +7133 /// Whether to pad an already started datagram in the next packet. +7134 /// +7135 /// When packets in Initial, 0-RTT or Handshake packet do not fill the entire +7136 /// datagram they may decide to coalesce with the next packet from a higher +7137 /// encryption level on the same path. But the earlier packet may require specific +7138 /// size requirements for the datagram they are sent in. +7139 /// +7140 /// If a space did not complete the datagram, they use this to request the correct +7141 /// padding in the final packet of the datagram so that the final datagram will have +7142 /// the correct size. +7143 /// +7144 /// If a space did fill an entire datagram, it leaves this to the default of +7145 /// [`PadDatagram::No`]. +7146 pad_datagram: PadDatagram, +7147 }, +7148 /// Send the contents of the transmit immediately. +7149 /// +7150 /// Packets were written and the GSO batch must end now, regardless from whether higher +7151 /// spaces still have frames to write. This is used when the last datagram written would +7152 /// require too much padding to continue a GSO batch, which would waste space on the +7153 /// wire. +7154 Send { +7155 /// The highest packet number written into the transmit. +7156 last_packet_number: u64, +7157 }, +7158} +7159 +7160/// Information used to decide what frames to schedule into which packets. +7161/// +7162/// Primarily used by [`Connection::poll_transmit_on_path`] and the functions that help +7163/// building packets for it: [`Connection::poll_transmit_path_space`] and +7164/// [`Connection::populate_packet`]. +7165#[derive(Debug, Copy, Clone)] +7166struct PathSchedulingInfo { +7167 /// Whether the path is abandoned. 7168 /// -7169 /// Some paths should only send frames from [`SendableFrames::space_specific`]. All other -7170 /// frames are essentially frames that can be sent on any [`SpaceKind::Data`] space. For -7171 /// those we want to respect packet scheduling rules however. -7172 /// -7173 /// Roughly speaking data frames are only sent on spaces that have CIDs, are not -7174 /// abandoned and have no *better* spaces. However see to comments where this is -7175 /// populated for the exact packet scheduling implementation. -7176 /// -7177 /// This essentially marks this paths as the best validated space ID. Except during -7178 /// the handshake in which case it does not need to be validated. Several paths could be -7179 /// equally good and all have this set to `true`, in that case packet scheduling can -7180 /// choose which path to use. Currently it chooses the lowest path that is not -7181 /// congestion blocked. +7169 /// Note that a path that is abandoned but still has CIDs can still send a packet. After +7170 /// sending that packet the CIDs issued by the remote have to be considered retired as +7171 /// well. +7172 is_abandoned: bool, +7173 /// Whether the path may send [`SpaceKind::Data`] frames. +7174 /// +7175 /// Some paths should only send frames from [`SendableFrames::space_specific`]. All other +7176 /// frames are essentially frames that can be sent on any [`SpaceKind::Data`] space. For +7177 /// those we want to respect packet scheduling rules however. +7178 /// +7179 /// Roughly speaking data frames are only sent on spaces that have CIDs, are not +7180 /// abandoned and have no *better* spaces. However see to comments where this is +7181 /// populated for the exact packet scheduling implementation. 7182 /// -7183 /// Note that once in the closed or draining states this will never be true. -7184 may_send_data: bool, -7185 /// Whether the path may send a CONNECTION_CLOSE frame. -7186 /// -7187 /// This essentially marks this path as the best validated space ID with a fallback -7188 /// to unvalidated spaces if there are no validated spaces. Like for -7189 /// [`Self::may_send_data`] other paths could be equally good. -7190 may_send_close: bool, -7191 may_self_abandon: bool, -7192} -7193 -7194#[derive(Debug, Copy, Clone, PartialEq, Eq)] -7195enum PathBlocked { -7196 No, -7197 AntiAmplification, -7198 Congestion, -7199 Pacing, -7200} -7201 -7202/// Fields of `Connection` specific to it being client-side or server-side -7203enum ConnectionSide { -7204 Client { -7205 /// Sent in every outgoing Initial packet. Always empty after Initial keys are discarded -7206 token: Bytes, -7207 token_store: Arc<dyn TokenStore>, -7208 server_name: String, -7209 }, -7210 Server { -7211 server_config: Arc<ServerConfig>, -7212 }, -7213} -7214 -7215impl ConnectionSide { -7216 fn remote_may_migrate(&self, state: &State) -> bool { -7217 match self { -7218 Self::Server { server_config } => server_config.migration, -7219 Self::Client { .. } => { -7220 if let Some(hs) = state.as_handshake() { -7221 hs.allow_server_migration -7222 } else { -7223 false -7224 } -7225 } -7226 } -7227 } -7228 -7229 fn is_client(&self) -> bool { -7230 self.side().is_client() -7231 } -7232 -7233 fn is_server(&self) -> bool { -7234 self.side().is_server() -7235 } -7236 -7237 fn side(&self) -> Side { -7238 match *self { -7239 Self::Client { .. } => Side::Client, -7240 Self::Server { .. } => Side::Server, -7241 } -7242 } -7243} -7244 -7245impl From<SideArgs> for ConnectionSide { -7246 fn from(side: SideArgs) -> Self { -7247 match side { -7248 SideArgs::Client { -7249 token_store, -7250 server_name, -7251 } => Self::Client { -7252 token: token_store.take(&server_name).unwrap_or_default(), -7253 token_store, -7254 server_name, -7255 }, -7256 SideArgs::Server { -7257 server_config, -7258 pref_addr_cid: _, -7259 path_validated: _, -7260 } => Self::Server { server_config }, -7261 } -7262 } -7263} -7264 -7265/// Parameters to `Connection::new` specific to it being client-side or server-side -7266pub(crate) enum SideArgs { -7267 Client { -7268 token_store: Arc<dyn TokenStore>, -7269 server_name: String, -7270 }, -7271 Server { -7272 server_config: Arc<ServerConfig>, -7273 pref_addr_cid: Option<ConnectionId>, -7274 path_validated: bool, -7275 }, -7276} -7277 -7278impl SideArgs { -7279 pub(crate) fn pref_addr_cid(&self) -> Option<ConnectionId> { -7280 match *self { -7281 Self::Client { .. } => None, -7282 Self::Server { pref_addr_cid, .. } => pref_addr_cid, -7283 } -7284 } -7285 -7286 pub(crate) fn path_validated(&self) -> bool { -7287 match *self { -7288 Self::Client { .. } => true, -7289 Self::Server { path_validated, .. } => path_validated, -7290 } -7291 } -7292 -7293 pub(crate) fn side(&self) -> Side { -7294 match *self { -7295 Self::Client { .. } => Side::Client, -7296 Self::Server { .. } => Side::Server, -7297 } -7298 } -7299} -7300 -7301/// Reasons why a connection might be lost -7302#[derive(Debug, Error, Clone, PartialEq, Eq)] -7303pub enum ConnectionError { -7304 /// The peer doesn't implement any supported version -7305 #[error("peer doesn't implement any supported version")] -7306 VersionMismatch, -7307 /// The peer violated the QUIC specification as understood by this implementation -7308 #[error(transparent)] -7309 TransportError(#[from] TransportError), -7310 /// The peer's QUIC stack aborted the connection automatically -7311 #[error("aborted by peer: {0}")] -7312 ConnectionClosed(frame::ConnectionClose), -7313 /// The peer closed the connection -7314 #[error("closed by peer: {0}")] -7315 ApplicationClosed(frame::ApplicationClose), -7316 /// The peer is unable to continue processing this connection, usually due to having restarted -7317 #[error("reset by peer")] -7318 Reset, -7319 /// Communication with the peer has lapsed for longer than the negotiated idle timeout -7320 /// -7321 /// If neither side is sending keep-alives, a connection will time out after a long enough idle -7322 /// period even if the peer is still reachable. See also [`TransportConfig::max_idle_timeout()`] -7323 /// and [`TransportConfig::keep_alive_interval()`]. -7324 #[error("timed out")] -7325 TimedOut, -7326 /// The local application closed the connection -7327 #[error("closed")] -7328 LocallyClosed, -7329 /// The connection could not be created because not enough of the CID space is available -7330 /// -7331 /// Try using longer connection IDs. -7332 #[error("CIDs exhausted")] -7333 CidsExhausted, -7334} -7335 -7336impl From<Close> for ConnectionError { -7337 fn from(x: Close) -> Self { -7338 match x { -7339 Close::Connection(reason) => Self::ConnectionClosed(reason), -7340 Close::Application(reason) => Self::ApplicationClosed(reason), -7341 } -7342 } -7343} -7344 -7345// For compatibility with API consumers -7346impl From<ConnectionError> for io::Error { -7347 fn from(x: ConnectionError) -> Self { -7348 use ConnectionError::*; -7349 let kind = match x { -7350 TimedOut => io::ErrorKind::TimedOut, -7351 Reset => io::ErrorKind::ConnectionReset, -7352 ApplicationClosed(_) | ConnectionClosed(_) => io::ErrorKind::ConnectionAborted, -7353 TransportError(_) | VersionMismatch | LocallyClosed | CidsExhausted => { -7354 io::ErrorKind::Other -7355 } -7356 }; -7357 Self::new(kind, x) -7358 } -7359} -7360 -7361/// Errors that might trigger a path being closed -7362// TODO(@divma): maybe needs to be reworked based on what we want to do with the public API -7363#[derive(Debug, Error, PartialEq, Eq, Clone, Copy)] -7364pub enum PathError { -7365 /// The extension was not negotiated with the peer -7366 #[error("multipath extension not negotiated")] -7367 MultipathNotNegotiated, -7368 /// Paths can only be opened client-side -7369 #[error("the server side may not open a path")] -7370 ServerSideNotAllowed, -7371 /// Current limits do not allow us to open more paths -7372 #[error("maximum number of concurrent paths reached")] -7373 MaxPathIdReached, -7374 /// No remote CIDs available to open a new path -7375 #[error("remoted CIDs exhausted")] -7376 RemoteCidsExhausted, -7377 /// Path could not be validated and will be abandoned -7378 #[error("path validation failed")] -7379 ValidationFailed, -7380 /// The remote address for the path is not supported by the endpoint -7381 #[error("invalid remote address")] -7382 InvalidRemoteAddress(SocketAddr), -7383} -7384 -7385/// Errors triggered when abandoning a path -7386#[derive(Debug, Error, Clone, Eq, PartialEq)] -7387pub enum ClosePathError { -7388 /// Multipath is not negotiated -7389 #[error("Multipath extension not negotiated")] -7390 MultipathNotNegotiated, -7391 /// The path is already closed or was never opened -7392 #[error("closed path")] -7393 ClosedPath, -7394 /// Cannot close the last remaining open path via the local API. -7395 /// -7396 /// Use [`Connection::close`] to end the connection instead. -7397 #[error("last open path")] -7398 LastOpenPath, -7399} -7400 -7401/// Error when the multipath extension was not negotiated, but attempted to be used. -7402#[derive(Debug, Error, Clone, Copy)] -7403#[error("Multipath extension not negotiated")] -7404pub struct MultipathNotNegotiated { -7405 _private: (), -7406} -7407 -7408/// Events of interest to the application -7409#[derive(Debug)] -7410pub enum Event { -7411 /// The connection's handshake data is ready -7412 HandshakeDataReady, -7413 /// The connection was successfully established -7414 Connected, -7415 /// The TLS handshake was confirmed -7416 HandshakeConfirmed, -7417 /// The connection was lost -7418 /// -7419 /// Emitted if the peer closes the connection or an error is encountered. -7420 ConnectionLost { -7421 /// Reason that the connection was closed -7422 reason: ConnectionError, -7423 }, -7424 /// Stream events -7425 Stream(StreamEvent), -7426 /// One or more application datagrams have been received -7427 DatagramReceived, -7428 /// One or more application datagrams have been sent after blocking -7429 DatagramsUnblocked, -7430 /// (Multi)Path events -7431 Path(PathEvent), -7432 /// n0's nat traversal events -7433 NatTraversal(n0_nat_traversal::Event), -7434} -7435 -7436impl From<PathEvent> for Event { -7437 fn from(source: PathEvent) -> Self { -7438 Self::Path(source) -7439 } +7183 /// This essentially marks this paths as the best validated space ID. Except during +7184 /// the handshake in which case it does not need to be validated. Several paths could be +7185 /// equally good and all have this set to `true`, in that case packet scheduling can +7186 /// choose which path to use. Currently it chooses the lowest path that is not +7187 /// congestion blocked. +7188 /// +7189 /// Note that once in the closed or draining states this will never be true. +7190 may_send_data: bool, +7191 /// Whether the path may send a CONNECTION_CLOSE frame. +7192 /// +7193 /// This essentially marks this path as the best validated space ID with a fallback +7194 /// to unvalidated spaces if there are no validated spaces. Like for +7195 /// [`Self::may_send_data`] other paths could be equally good. +7196 may_send_close: bool, +7197 may_self_abandon: bool, +7198} +7199 +7200#[derive(Debug, Copy, Clone, PartialEq, Eq)] +7201enum PathBlocked { +7202 No, +7203 AntiAmplification, +7204 Congestion, +7205 Pacing, +7206} +7207 +7208/// Fields of `Connection` specific to it being client-side or server-side +7209enum ConnectionSide { +7210 Client { +7211 /// Sent in every outgoing Initial packet. Always empty after Initial keys are discarded +7212 token: Bytes, +7213 token_store: Arc<dyn TokenStore>, +7214 server_name: String, +7215 }, +7216 Server { +7217 server_config: Arc<ServerConfig>, +7218 }, +7219} +7220 +7221impl ConnectionSide { +7222 fn remote_may_migrate(&self, state: &State) -> bool { +7223 match self { +7224 Self::Server { server_config } => server_config.migration, +7225 Self::Client { .. } => { +7226 if let Some(hs) = state.as_handshake() { +7227 hs.allow_server_migration +7228 } else { +7229 false +7230 } +7231 } +7232 } +7233 } +7234 +7235 fn is_client(&self) -> bool { +7236 self.side().is_client() +7237 } +7238 +7239 fn is_server(&self) -> bool { +7240 self.side().is_server() +7241 } +7242 +7243 fn side(&self) -> Side { +7244 match *self { +7245 Self::Client { .. } => Side::Client, +7246 Self::Server { .. } => Side::Server, +7247 } +7248 } +7249} +7250 +7251impl From<SideArgs> for ConnectionSide { +7252 fn from(side: SideArgs) -> Self { +7253 match side { +7254 SideArgs::Client { +7255 token_store, +7256 server_name, +7257 } => Self::Client { +7258 token: token_store.take(&server_name).unwrap_or_default(), +7259 token_store, +7260 server_name, +7261 }, +7262 SideArgs::Server { +7263 server_config, +7264 pref_addr_cid: _, +7265 path_validated: _, +7266 } => Self::Server { server_config }, +7267 } +7268 } +7269} +7270 +7271/// Parameters to `Connection::new` specific to it being client-side or server-side +7272pub(crate) enum SideArgs { +7273 Client { +7274 token_store: Arc<dyn TokenStore>, +7275 server_name: String, +7276 }, +7277 Server { +7278 server_config: Arc<ServerConfig>, +7279 pref_addr_cid: Option<ConnectionId>, +7280 path_validated: bool, +7281 }, +7282} +7283 +7284impl SideArgs { +7285 pub(crate) fn pref_addr_cid(&self) -> Option<ConnectionId> { +7286 match *self { +7287 Self::Client { .. } => None, +7288 Self::Server { pref_addr_cid, .. } => pref_addr_cid, +7289 } +7290 } +7291 +7292 pub(crate) fn path_validated(&self) -> bool { +7293 match *self { +7294 Self::Client { .. } => true, +7295 Self::Server { path_validated, .. } => path_validated, +7296 } +7297 } +7298 +7299 pub(crate) fn side(&self) -> Side { +7300 match *self { +7301 Self::Client { .. } => Side::Client, +7302 Self::Server { .. } => Side::Server, +7303 } +7304 } +7305} +7306 +7307/// Reasons why a connection might be lost +7308#[derive(Debug, Error, Clone, PartialEq, Eq)] +7309pub enum ConnectionError { +7310 /// The peer doesn't implement any supported version +7311 #[error("peer doesn't implement any supported version")] +7312 VersionMismatch, +7313 /// The peer violated the QUIC specification as understood by this implementation +7314 #[error(transparent)] +7315 TransportError(#[from] TransportError), +7316 /// The peer's QUIC stack aborted the connection automatically +7317 #[error("aborted by peer: {0}")] +7318 ConnectionClosed(frame::ConnectionClose), +7319 /// The peer closed the connection +7320 #[error("closed by peer: {0}")] +7321 ApplicationClosed(frame::ApplicationClose), +7322 /// The peer is unable to continue processing this connection, usually due to having restarted +7323 #[error("reset by peer")] +7324 Reset, +7325 /// Communication with the peer has lapsed for longer than the negotiated idle timeout +7326 /// +7327 /// If neither side is sending keep-alives, a connection will time out after a long enough idle +7328 /// period even if the peer is still reachable. See also [`TransportConfig::max_idle_timeout()`] +7329 /// and [`TransportConfig::keep_alive_interval()`]. +7330 #[error("timed out")] +7331 TimedOut, +7332 /// The local application closed the connection +7333 #[error("closed")] +7334 LocallyClosed, +7335 /// The connection could not be created because not enough of the CID space is available +7336 /// +7337 /// Try using longer connection IDs. +7338 #[error("CIDs exhausted")] +7339 CidsExhausted, +7340} +7341 +7342impl From<Close> for ConnectionError { +7343 fn from(x: Close) -> Self { +7344 match x { +7345 Close::Connection(reason) => Self::ConnectionClosed(reason), +7346 Close::Application(reason) => Self::ApplicationClosed(reason), +7347 } +7348 } +7349} +7350 +7351// For compatibility with API consumers +7352impl From<ConnectionError> for io::Error { +7353 fn from(x: ConnectionError) -> Self { +7354 use ConnectionError::*; +7355 let kind = match x { +7356 TimedOut => io::ErrorKind::TimedOut, +7357 Reset => io::ErrorKind::ConnectionReset, +7358 ApplicationClosed(_) | ConnectionClosed(_) => io::ErrorKind::ConnectionAborted, +7359 TransportError(_) | VersionMismatch | LocallyClosed | CidsExhausted => { +7360 io::ErrorKind::Other +7361 } +7362 }; +7363 Self::new(kind, x) +7364 } +7365} +7366 +7367/// Errors that might trigger a path being closed +7368// TODO(@divma): maybe needs to be reworked based on what we want to do with the public API +7369#[derive(Debug, Error, PartialEq, Eq, Clone, Copy)] +7370pub enum PathError { +7371 /// The extension was not negotiated with the peer +7372 #[error("multipath extension not negotiated")] +7373 MultipathNotNegotiated, +7374 /// Paths can only be opened client-side +7375 #[error("the server side may not open a path")] +7376 ServerSideNotAllowed, +7377 /// Current limits do not allow us to open more paths +7378 #[error("maximum number of concurrent paths reached")] +7379 MaxPathIdReached, +7380 /// No remote CIDs available to open a new path +7381 #[error("remoted CIDs exhausted")] +7382 RemoteCidsExhausted, +7383 /// Path could not be validated and will be abandoned +7384 #[error("path validation failed")] +7385 ValidationFailed, +7386 /// The remote address for the path is not supported by the endpoint +7387 #[error("invalid remote address")] +7388 InvalidRemoteAddress(SocketAddr), +7389} +7390 +7391/// Errors triggered when abandoning a path +7392#[derive(Debug, Error, Clone, Eq, PartialEq)] +7393pub enum ClosePathError { +7394 /// Multipath is not negotiated +7395 #[error("Multipath extension not negotiated")] +7396 MultipathNotNegotiated, +7397 /// The path is already closed or was never opened +7398 #[error("closed path")] +7399 ClosedPath, +7400 /// Cannot close the last remaining open path via the local API. +7401 /// +7402 /// Use [`Connection::close`] to end the connection instead. +7403 #[error("last open path")] +7404 LastOpenPath, +7405} +7406 +7407/// Error when the multipath extension was not negotiated, but attempted to be used. +7408#[derive(Debug, Error, Clone, Copy)] +7409#[error("Multipath extension not negotiated")] +7410pub struct MultipathNotNegotiated { +7411 _private: (), +7412} +7413 +7414/// Events of interest to the application +7415#[derive(Debug)] +7416pub enum Event { +7417 /// The connection's handshake data is ready +7418 HandshakeDataReady, +7419 /// The connection was successfully established +7420 Connected, +7421 /// The TLS handshake was confirmed +7422 HandshakeConfirmed, +7423 /// The connection was lost +7424 /// +7425 /// Emitted if the peer closes the connection or an error is encountered. +7426 ConnectionLost { +7427 /// Reason that the connection was closed +7428 reason: ConnectionError, +7429 }, +7430 /// Stream events +7431 Stream(StreamEvent), +7432 /// One or more application datagrams have been received +7433 DatagramReceived, +7434 /// One or more application datagrams have been sent after blocking +7435 DatagramsUnblocked, +7436 /// (Multi)Path events +7437 Path(PathEvent), +7438 /// n0's nat traversal events +7439 NatTraversal(n0_nat_traversal::Event), 7440} 7441 -7442fn get_max_ack_delay(params: &TransportParameters) -> Duration { -7443 Duration::from_micros(params.max_ack_delay.0 * 1000) -7444} -7445 -7446/// Prevents overflow and improves behavior in extreme circumstances. -7447const MAX_BACKOFF_EXPONENT: u32 = 16; -7448 -7449/// The max interval between successive tail-loss probes. -7450/// -7451/// This is the "normal" value we use. -7452const MAX_PTO_INTERVAL: Duration = Duration::from_secs(2); -7453 -7454/// The idle time, below which we use the shorter [`MAX_PTO_FAST_INTERVAL`]. -7455const MIN_IDLE_FOR_FAST_PTO: Duration = Duration::from_secs(25); -7456 -7457/// The max interval between successive tail-loss probes with short idle times. -7458/// -7459/// If the path or connection idle time is less than [`MIN_IDLE_FOR_FAST_PTO`] then we use -7460/// this value to ensure we have plenty of retransmits before we reach the idle time. -7461const MAX_PTO_FAST_INTERVAL: Duration = Duration::from_secs(1); +7442impl From<PathEvent> for Event { +7443 fn from(source: PathEvent) -> Self { +7444 Self::Path(source) +7445 } +7446} +7447 +7448fn get_max_ack_delay(params: &TransportParameters) -> Duration { +7449 Duration::from_micros(params.max_ack_delay.0 * 1000) +7450} +7451 +7452/// Prevents overflow and improves behavior in extreme circumstances. +7453const MAX_BACKOFF_EXPONENT: u32 = 16; +7454 +7455/// The max interval between successive tail-loss probes. +7456/// +7457/// This is the "normal" value we use. +7458const MAX_PTO_INTERVAL: Duration = Duration::from_secs(2); +7459 +7460/// The idle time, below which we use the shorter [`MAX_PTO_FAST_INTERVAL`]. +7461const MIN_IDLE_FOR_FAST_PTO: Duration = Duration::from_secs(25); 7462 -7463/// The RTT threshold above which we cap the PTO interval to 1.5 * smoothed_rtt +7463/// The max interval between successive tail-loss probes with short idle times. 7464/// -7465/// This is RTT time above which 1.5 * RTT > [`MAX_PTO_INTERVAL`], for these links we want -7466/// to extend the interval between tail-loss probes to not fill the entire pipe with them. -7467const SLOW_RTT_THRESHOLD: Duration = -7468 Duration::from_millis((MAX_PTO_INTERVAL.as_millis() as u64 * 2) / 3); -7469 -7470/// Minimal remaining size to allow packet coalescing, excluding cryptographic tag -7471/// -7472/// This must be at least as large as the header for a well-formed empty packet to be coalesced, -7473/// plus some space for frames. We only care about handshake headers because short header packets -7474/// necessarily have smaller headers, and initial packets are only ever the first packet in a -7475/// datagram (because we coalesce in ascending packet space order and the only reason to split a -7476/// packet is when packet space changes). -7477const MIN_PACKET_SPACE: usize = MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE + 32; -7478 -7479/// Largest amount of space that could be occupied by a Handshake or 0-RTT packet's header -7480/// -7481/// Excludes packet-type-specific fields such as packet number or Initial token -7482// https://www.rfc-editor.org/rfc/rfc9000.html#name-0-rtt: flags + version + dcid len + dcid + -7483// scid len + scid + length + pn -7484const MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE: usize = -7485 1 + 4 + 1 + MAX_CID_SIZE + 1 + MAX_CID_SIZE + VarInt::from_u32(u16::MAX as u32).size() + 4; -7486 -7487#[derive(Default)] -7488struct SentFrames { -7489 retransmits: ThinRetransmits, -7490 /// The packet number of the largest acknowledged packet for each path -7491 largest_acked: FxHashMap<PathId, u64>, -7492 stream_frames: StreamMetaVec, -7493 /// Whether the packet contains non-retransmittable frames (like datagrams) -7494 non_retransmits: bool, -7495 /// If the datagram containing these frames should be padded to the min MTU -7496 requires_padding: bool, -7497} -7498 -7499impl SentFrames { -7500 /// Returns whether the packet contains only ACKs -7501 fn is_ack_only(&self, streams: &StreamsState) -> bool { -7502 !self.largest_acked.is_empty() -7503 && !self.non_retransmits -7504 && self.stream_frames.is_empty() -7505 && self.retransmits.is_empty(streams) -7506 } -7507 -7508 fn retransmits_mut(&mut self) -> &mut Retransmits { -7509 self.retransmits.get_or_create() -7510 } -7511 -7512 fn record_sent_frame(&mut self, frame: frame::EncodableFrame<'_>) { -7513 use frame::EncodableFrame::*; -7514 match frame { -7515 PathAck(path_ack_encoder) => { -7516 if let Some(max) = path_ack_encoder.ranges.max() { -7517 self.largest_acked.insert(path_ack_encoder.path_id, max); -7518 } -7519 } -7520 Ack(ack_encoder) => { -7521 if let Some(max) = ack_encoder.ranges.max() { -7522 self.largest_acked.insert(PathId::ZERO, max); -7523 } -7524 } -7525 Close(_) => { /* non retransmittable, but after this we don't really care */ } -7526 PathResponse(_) => self.non_retransmits = true, -7527 HandshakeDone(_) => self.retransmits_mut().handshake_done = true, -7528 ReachOut(frame::ReachOut { round, ip, port }) => { -7529 let (recorded_round, reach_outs) = self -7530 .retransmits_mut() -7531 .reach_out -7532 .get_or_insert_with(|| (round, FxHashSet::default())); -7533 // Only record reach outs for the current round or a newer than the recorded one. -7534 if *recorded_round == round { -7535 // Same round, simply append. -7536 reach_outs.insert((ip, port)); -7537 } else if *recorded_round < round { -7538 // New round. -7539 *recorded_round = round; -7540 reach_outs.drain(); -7541 reach_outs.insert((ip, port)); -7542 } else { -7543 // ignore old reach out that was sent -7544 } -7545 } -7546 -7547 ObservedAddr(_) => self.retransmits_mut().observed_addr = true, -7548 Ping(_) => self.non_retransmits = true, -7549 ImmediateAck(_) => self.non_retransmits = true, -7550 AckFrequency(_) => self.retransmits_mut().ack_frequency = true, -7551 PathChallenge(_) => self.non_retransmits = true, -7552 Crypto(crypto) => self.retransmits_mut().crypto.push_back(crypto), -7553 PathAbandon(path_abandon) => { -7554 self.retransmits_mut() -7555 .path_abandon -7556 .entry(path_abandon.path_id) -7557 .or_insert(path_abandon.error_code); -7558 } -7559 PathStatusAvailable(frame::PathStatusAvailable { path_id, .. }) -7560 | PathStatusBackup(frame::PathStatusBackup { path_id, .. }) => { -7561 self.retransmits_mut().path_status.insert(path_id); -7562 } -7563 MaxPathId(_) => self.retransmits_mut().max_path_id = true, -7564 PathsBlocked(_) => self.retransmits_mut().paths_blocked = true, -7565 PathCidsBlocked(path_cids_blocked) => { -7566 self.retransmits_mut() -7567 .path_cids_blocked -7568 .insert(path_cids_blocked.path_id); -7569 } -7570 ResetStream(reset) => self -7571 .retransmits_mut() -7572 .reset_stream -7573 .push((reset.id, reset.error_code)), -7574 StopSending(stop_sending) => self.retransmits_mut().stop_sending.push(stop_sending), -7575 NewConnectionId(new_cid) => self.retransmits_mut().new_cids.push(new_cid.issued()), -7576 RetireConnectionId(retire_cid) => self +7465/// If the path or connection idle time is less than [`MIN_IDLE_FOR_FAST_PTO`] then we use +7466/// this value to ensure we have plenty of retransmits before we reach the idle time. +7467const MAX_PTO_FAST_INTERVAL: Duration = Duration::from_secs(1); +7468 +7469/// The RTT threshold above which we cap the PTO interval to 1.5 * smoothed_rtt +7470/// +7471/// This is RTT time above which 1.5 * RTT > [`MAX_PTO_INTERVAL`], for these links we want +7472/// to extend the interval between tail-loss probes to not fill the entire pipe with them. +7473const SLOW_RTT_THRESHOLD: Duration = +7474 Duration::from_millis((MAX_PTO_INTERVAL.as_millis() as u64 * 2) / 3); +7475 +7476/// Minimal remaining size to allow packet coalescing, excluding cryptographic tag +7477/// +7478/// This must be at least as large as the header for a well-formed empty packet to be coalesced, +7479/// plus some space for frames. We only care about handshake headers because short header packets +7480/// necessarily have smaller headers, and initial packets are only ever the first packet in a +7481/// datagram (because we coalesce in ascending packet space order and the only reason to split a +7482/// packet is when packet space changes). +7483const MIN_PACKET_SPACE: usize = MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE + 32; +7484 +7485/// Largest amount of space that could be occupied by a Handshake or 0-RTT packet's header +7486/// +7487/// Excludes packet-type-specific fields such as packet number or Initial token +7488// https://www.rfc-editor.org/rfc/rfc9000.html#name-0-rtt: flags + version + dcid len + dcid + +7489// scid len + scid + length + pn +7490const MAX_HANDSHAKE_OR_0RTT_HEADER_SIZE: usize = +7491 1 + 4 + 1 + MAX_CID_SIZE + 1 + MAX_CID_SIZE + VarInt::from_u32(u16::MAX as u32).size() + 4; +7492 +7493#[derive(Default)] +7494struct SentFrames { +7495 retransmits: ThinRetransmits, +7496 /// The packet number of the largest acknowledged packet for each path +7497 largest_acked: FxHashMap<PathId, u64>, +7498 stream_frames: StreamMetaVec, +7499 /// Whether the packet contains non-retransmittable frames (like datagrams) +7500 non_retransmits: bool, +7501 /// If the datagram containing these frames should be padded to the min MTU +7502 requires_padding: bool, +7503} +7504 +7505impl SentFrames { +7506 /// Returns whether the packet contains only ACKs +7507 fn is_ack_only(&self, streams: &StreamsState) -> bool { +7508 !self.largest_acked.is_empty() +7509 && !self.non_retransmits +7510 && self.stream_frames.is_empty() +7511 && self.retransmits.is_empty(streams) +7512 } +7513 +7514 fn retransmits_mut(&mut self) -> &mut Retransmits { +7515 self.retransmits.get_or_create() +7516 } +7517 +7518 fn record_sent_frame(&mut self, frame: frame::EncodableFrame<'_>) { +7519 use frame::EncodableFrame::*; +7520 match frame { +7521 PathAck(path_ack_encoder) => { +7522 if let Some(max) = path_ack_encoder.ranges.max() { +7523 self.largest_acked.insert(path_ack_encoder.path_id, max); +7524 } +7525 } +7526 Ack(ack_encoder) => { +7527 if let Some(max) = ack_encoder.ranges.max() { +7528 self.largest_acked.insert(PathId::ZERO, max); +7529 } +7530 } +7531 Close(_) => { /* non retransmittable, but after this we don't really care */ } +7532 PathResponse(_) => self.non_retransmits = true, +7533 HandshakeDone(_) => self.retransmits_mut().handshake_done = true, +7534 ReachOut(frame::ReachOut { round, ip, port }) => { +7535 let (recorded_round, reach_outs) = self +7536 .retransmits_mut() +7537 .reach_out +7538 .get_or_insert_with(|| (round, FxHashSet::default())); +7539 // Only record reach outs for the current round or a newer than the recorded one. +7540 if *recorded_round == round { +7541 // Same round, simply append. +7542 reach_outs.insert((ip, port)); +7543 } else if *recorded_round < round { +7544 // New round. +7545 *recorded_round = round; +7546 reach_outs.drain(); +7547 reach_outs.insert((ip, port)); +7548 } else { +7549 // ignore old reach out that was sent +7550 } +7551 } +7552 +7553 ObservedAddr(_) => self.retransmits_mut().observed_addr = true, +7554 Ping(_) => self.non_retransmits = true, +7555 ImmediateAck(_) => self.non_retransmits = true, +7556 AckFrequency(_) => self.retransmits_mut().ack_frequency = true, +7557 PathChallenge(_) => self.non_retransmits = true, +7558 Crypto(crypto) => self.retransmits_mut().crypto.push_back(crypto), +7559 PathAbandon(path_abandon) => { +7560 self.retransmits_mut() +7561 .path_abandon +7562 .entry(path_abandon.path_id) +7563 .or_insert(path_abandon.error_code); +7564 } +7565 PathStatusAvailable(frame::PathStatusAvailable { path_id, .. }) +7566 | PathStatusBackup(frame::PathStatusBackup { path_id, .. }) => { +7567 self.retransmits_mut().path_status.insert(path_id); +7568 } +7569 MaxPathId(_) => self.retransmits_mut().max_path_id = true, +7570 PathsBlocked(_) => self.retransmits_mut().paths_blocked = true, +7571 PathCidsBlocked(path_cids_blocked) => { +7572 self.retransmits_mut() +7573 .path_cids_blocked +7574 .insert(path_cids_blocked.path_id); +7575 } +7576 ResetStream(reset) => self 7577 .retransmits_mut() -7578 .retire_cids -7579 .push((retire_cid.path_id.unwrap_or_default(), retire_cid.sequence)), -7580 Datagram(_) => self.non_retransmits = true, -7581 NewToken(_) => {} -7582 AddAddress(add_address) => { -7583 self.retransmits_mut().add_address.insert(add_address); -7584 } -7585 RemoveAddress(remove_address) => { -7586 self.retransmits_mut().remove_address.insert(remove_address); -7587 } -7588 StreamMeta(stream_meta_encoder) => self.stream_frames.push(stream_meta_encoder.meta), -7589 MaxData(_) => self.retransmits_mut().max_data = true, -7590 MaxStreamData(max) => { -7591 self.retransmits_mut().max_stream_data.insert(max.id); -7592 } -7593 MaxStreams(max_streams) => { -7594 self.retransmits_mut().max_stream_id[max_streams.dir as usize] = true -7595 } -7596 } -7597 } -7598} -7599 -7600/// Compute the negotiated idle timeout based on local and remote max_idle_timeout transport parameters. -7601/// -7602/// According to the definition of max_idle_timeout, a value of `0` means the timeout is disabled; see <https://www.rfc-editor.org/rfc/rfc9000#section-18.2-4.4.1.> -7603/// -7604/// According to the negotiation procedure, either the minimum of the timeouts or one specified is used as the negotiated value; see <https://www.rfc-editor.org/rfc/rfc9000#section-10.1-2.> -7605/// -7606/// Returns the negotiated idle timeout as a `Duration`, or `None` when both endpoints have opted out of idle timeout. -7607fn negotiate_max_idle_timeout(x: Option<VarInt>, y: Option<VarInt>) -> Option<Duration> { -7608 match (x, y) { -7609 (Some(VarInt(0)) | None, Some(VarInt(0)) | None) => None, -7610 (Some(VarInt(0)) | None, Some(y)) => Some(Duration::from_millis(y.0)), -7611 (Some(x), Some(VarInt(0)) | None) => Some(Duration::from_millis(x.0)), -7612 (Some(x), Some(y)) => Some(Duration::from_millis(cmp::min(x, y).0)), -7613 } -7614} -7615 -7616#[cfg(test)] -7617mod tests { -7618 use super::*; -7619 -7620 #[test] -7621 fn negotiate_max_idle_timeout_commutative() { -7622 let test_params = [ -7623 (None, None, None), -7624 (None, Some(VarInt(0)), None), -7625 (None, Some(VarInt(2)), Some(Duration::from_millis(2))), -7626 (Some(VarInt(0)), Some(VarInt(0)), None), -7627 ( -7628 Some(VarInt(2)), -7629 Some(VarInt(0)), -7630 Some(Duration::from_millis(2)), -7631 ), -7632 ( -7633 Some(VarInt(1)), -7634 Some(VarInt(4)), -7635 Some(Duration::from_millis(1)), -7636 ), -7637 ]; -7638 -7639 for (left, right, result) in test_params { -7640 assert_eq!(negotiate_max_idle_timeout(left, right), result); -7641 assert_eq!(negotiate_max_idle_timeout(right, left), result); -7642 } -7643 } -7644}

\ No newline at end of file +7578 .reset_stream +7579 .push((reset.id, reset.error_code)), +7580 StopSending(stop_sending) => self.retransmits_mut().stop_sending.push(stop_sending), +7581 NewConnectionId(new_cid) => self.retransmits_mut().new_cids.push(new_cid.issued()), +7582 RetireConnectionId(retire_cid) => self +7583 .retransmits_mut() +7584 .retire_cids +7585 .push((retire_cid.path_id.unwrap_or_default(), retire_cid.sequence)), +7586 Datagram(_) => self.non_retransmits = true, +7587 NewToken(_) => {} +7588 AddAddress(add_address) => { +7589 self.retransmits_mut().add_address.insert(add_address); +7590 } +7591 RemoveAddress(remove_address) => { +7592 self.retransmits_mut().remove_address.insert(remove_address); +7593 } +7594 StreamMeta(stream_meta_encoder) => self.stream_frames.push(stream_meta_encoder.meta), +7595 MaxData(_) => self.retransmits_mut().max_data = true, +7596 MaxStreamData(max) => { +7597 self.retransmits_mut().max_stream_data.insert(max.id); +7598 } +7599 MaxStreams(max_streams) => { +7600 self.retransmits_mut().max_stream_id[max_streams.dir as usize] = true +7601 } +7602 } +7603 } +7604} +7605 +7606/// Compute the negotiated idle timeout based on local and remote max_idle_timeout transport parameters. +7607/// +7608/// According to the definition of max_idle_timeout, a value of `0` means the timeout is disabled; see <https://www.rfc-editor.org/rfc/rfc9000#section-18.2-4.4.1.> +7609/// +7610/// According to the negotiation procedure, either the minimum of the timeouts or one specified is used as the negotiated value; see <https://www.rfc-editor.org/rfc/rfc9000#section-10.1-2.> +7611/// +7612/// Returns the negotiated idle timeout as a `Duration`, or `None` when both endpoints have opted out of idle timeout. +7613fn negotiate_max_idle_timeout(x: Option<VarInt>, y: Option<VarInt>) -> Option<Duration> { +7614 match (x, y) { +7615 (Some(VarInt(0)) | None, Some(VarInt(0)) | None) => None, +7616 (Some(VarInt(0)) | None, Some(y)) => Some(Duration::from_millis(y.0)), +7617 (Some(x), Some(VarInt(0)) | None) => Some(Duration::from_millis(x.0)), +7618 (Some(x), Some(y)) => Some(Duration::from_millis(cmp::min(x, y).0)), +7619 } +7620} +7621 +7622#[cfg(test)] +7623mod tests { +7624 use super::*; +7625 +7626 #[test] +7627 fn negotiate_max_idle_timeout_commutative() { +7628 let test_params = [ +7629 (None, None, None), +7630 (None, Some(VarInt(0)), None), +7631 (None, Some(VarInt(2)), Some(Duration::from_millis(2))), +7632 (Some(VarInt(0)), Some(VarInt(0)), None), +7633 ( +7634 Some(VarInt(2)), +7635 Some(VarInt(0)), +7636 Some(Duration::from_millis(2)), +7637 ), +7638 ( +7639 Some(VarInt(1)), +7640 Some(VarInt(4)), +7641 Some(Duration::from_millis(1)), +7642 ), +7643 ]; +7644 +7645 for (left, right, result) in test_params { +7646 assert_eq!(negotiate_max_idle_timeout(left, right), result); +7647 assert_eq!(negotiate_max_idle_timeout(right, left), result); +7648 } +7649 } +7650}

\ No newline at end of file